galenelias updated this revision to Diff 537383.
galenelias edited the summary of this revision.
galenelias added a comment.
I re-wrote the alignment to stop using AlignTokens so that I can now handle all
the edge cases that came up. Specifically:
- Allowing empty case labels (implicit fall through) to not break the
alignment, but only if they are sandwiched by short case statements.
- Don't align the colon of a non-short case label that follows short case
labels when using 'AlignCaseColons=true'.
- Empty case labels will also now push out the alignment of the statements when
using AlignCaseColons=false.
Also, this now avoids having to add the `IgnoreNestedScopes` parameter to
`AlignTokens` which didn't feel great.
I refactored `AlignMacroSequence` so I could re-use the core aligning method,
since it's the same logic I need, but I removed some of the dead code just to
simplify things along the way. But even with that, this version is quite a bit
more code (~100 lines vs. ~30 lines).
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151761/new/
https://reviews.llvm.org/D151761
Files:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/WhitespaceManager.cpp
clang/lib/Format/WhitespaceManager.h
clang/unittests/Format/ConfigParseTest.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -19244,6 +19244,255 @@
BracedAlign);
}
+TEST_F(FormatTest, AlignConsecutiveShortCaseStatements) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AllowShortCaseLabelsOnASingleLine = true;
+ Alignment.AlignConsecutiveShortCaseStatements.Enabled = true;
+
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "default: return \"default\";\n"
+ "}",
+ Alignment);
+
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "}",
+ "switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning:\n"
+ " return \"warning\";\n"
+ "}",
+ Alignment);
+
+ // Empty case statements push out the alignment, but non-short case labels don't.
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::critical:\n"
+ "case log::warning:\n"
+ "case log::severe: return \"severe\";\n"
+ "case log::extra_severe:\n"
+ " // comment\n"
+ " return \"extra_severe\";\n"
+ "}",
+ Alignment);
+
+ // Verify comments and empty lines break the alignment.
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "// comment\n"
+ "case log::critical: return \"critical\";\n"
+ "default: return \"default\";\n"
+ "\n"
+ "case log::severe: return \"severe\";\n"
+ "}",
+ "switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "// comment\n"
+ "case log::critical: return \"critical\";\n"
+ "default: return \"default\";\n"
+ "\n"
+ "case log::severe: return \"severe\";\n"
+ "}",
+ Alignment);
+
+ // Empty case statements don't break the alignment, and potentially push it out
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning:\n"
+ "case log::critical:\n"
+ "default: return \"default\";\n"
+ "}",
+ Alignment);
+
+ // Implicit fallthrough cases can be aligned with either a comment or
+ // [[fallthrough]]
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: // fallthrough\n"
+ "case log::error: return \"error\";\n"
+ "case log::critical: /*fallthrough*/\n"
+ "case log::severe: return \"severe\";\n"
+ "case log::diag: [[fallthrough]];\n"
+ "default: return \"default\";\n"
+ "}",
+ Alignment);
+
+ // Verify trailing comment that needs a reflow also gets aligned properly.
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: // fallthrough\n"
+ "case log::error: return \"error\";\n"
+ "}",
+ "switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: //fallthrough\n"
+ "case log::error: return \"error\";\n"
+ "}",
+ Alignment);
+
+ // Verify adjacent non-short case statements don't change the alignment, and
+ // properly break the set of consecutive statements.
+ verifyFormat("switch (level) {\n"
+ "case log::critical:\n"
+ " // comment\n"
+ " return \"critical\";\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "default:\n"
+ " // comment\n"
+ " return \"\";\n"
+ "case log::error: return \"error\";\n"
+ "case log::severe: return \"severe\";\n"
+ "case log::extra_critical:\n"
+ " // comment\n"
+ " return \"extra critical\";\n"
+ "}",
+ Alignment);
+
+ Alignment.SpaceBeforeCaseColon = true;
+ verifyFormat("switch (level) {\n"
+ "case log::info : return \"info\";\n"
+ "case log::warning : return \"warning\";\n"
+ "default : return \"default\";\n"
+ "}",
+ Alignment);
+ Alignment.SpaceBeforeCaseColon = false;
+
+ // Make sure we don't incorrectly align correctly across nested switch cases.
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "case log::other:\n"
+ " switch (sublevel) {\n"
+ " case log::info: return \"info\";\n"
+ " case log::warning: return \"warning\";\n"
+ " }\n"
+ " break;\n"
+ "case log::error: return \"error\";\n"
+ "default: return \"default\";\n"
+ "}",
+ "switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "case log::other: switch (sublevel) {\n"
+ " case log::info: return \"info\";\n"
+ " case log::warning: return \"warning\";\n"
+ "}\n"
+ "break;\n"
+ "case log::error: return \"error\";\n"
+ "default: return \"default\";\n"
+ "}",
+ Alignment);
+
+ Alignment.AlignConsecutiveShortCaseStatements.AcrossEmptyLines = true;
+
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "\n"
+ "case log::warning: return \"warning\";\n"
+ "}",
+ "switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "\n"
+ "case log::warning: return \"warning\";\n"
+ "}",
+ Alignment);
+
+ Alignment.AlignConsecutiveShortCaseStatements.AcrossComments = true;
+
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "\n"
+ "/* block comment */\n"
+ "\n"
+ "// line comment\n"
+ "case log::warning: return \"warning\";\n"
+ "}",
+ "switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "\n"
+ "/* block comment */\n"
+ "\n"
+ "// line comment\n"
+ "case log::warning: return \"warning\";\n"
+ "}",
+ Alignment);
+
+ Alignment.AlignConsecutiveShortCaseStatements.AcrossEmptyLines = false;
+
+ verifyFormat("switch (level) {\n"
+ "case log::info: return \"info\";\n"
+ "//\n"
+ "case log::warning: return \"warning\";\n"
+ "}",
+ Alignment);
+
+ Alignment.AlignConsecutiveShortCaseStatements.AlignCaseColons = true;
+
+ verifyFormat("switch (level) {\n"
+ "case log::info : return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "default : return \"default\";\n"
+ "}",
+ Alignment);
+
+ // With AlignCaseColons, empty case statements don't break alignment of
+ // consecutive case statements (and are aligned).
+ verifyFormat("switch (level) {\n"
+ "case log::info : return \"info\";\n"
+ "case log::warning :\n"
+ "case log::critical:\n"
+ "default : return \"default\";\n"
+ "}",
+ Alignment);
+
+ // Final non-short case labels shouldn't have their colon aligned
+ verifyFormat("switch (level) {\n"
+ "case log::info : return \"info\";\n"
+ "case log::warning :\n"
+ "case log::critical:\n"
+ "case log::severe : return \"severe\";\n"
+ "default:\n"
+ " // comment\n"
+ " return \"default\";\n"
+ "}",
+ Alignment);
+
+ // Verify adjacent non-short case statements break the set of consecutive
+ // alignments and aren't aligned with adjacent non-short case statements if
+ // AlignCaseColons is set.
+ verifyFormat("switch (level) {\n"
+ "case log::critical:\n"
+ " // comment\n"
+ " return \"critical\";\n"
+ "case log::info : return \"info\";\n"
+ "case log::warning: return \"warning\";\n"
+ "default:\n"
+ " // comment\n"
+ " return \"\";\n"
+ "case log::error : return \"error\";\n"
+ "case log::severe: return \"severe\";\n"
+ "case log::extra_critical:\n"
+ " // comment\n"
+ " return \"extra critical\";\n"
+ "}",
+ Alignment);
+
+ Alignment.SpaceBeforeCaseColon = true;
+ verifyFormat("switch (level) {\n"
+ "case log::info : return \"info\";\n"
+ "case log::warning : return \"warning\";\n"
+ "case log::error :\n"
+ "default : return \"default\";\n"
+ "}",
+ Alignment);
+}
+
TEST_F(FormatTest, AlignWithLineBreaks) {
auto Style = getLLVMStyleWithColumns(120);
Index: clang/unittests/Format/ConfigParseTest.cpp
===================================================================
--- clang/unittests/Format/ConfigParseTest.cpp
+++ clang/unittests/Format/ConfigParseTest.cpp
@@ -318,6 +318,7 @@
CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);
CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros);
CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations);
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveShortCaseStatements);
#undef CHECK_ALIGN_CONSECUTIVE
Index: clang/lib/Format/WhitespaceManager.h
===================================================================
--- clang/lib/Format/WhitespaceManager.h
+++ clang/lib/Format/WhitespaceManager.h
@@ -232,6 +232,9 @@
/// Align consecutive declarations over all \c Changes.
void alignChainedConditionals();
+ /// Align consecutive short case statements over all \c Changes.
+ void alignConsecutiveShortCaseStatements();
+
/// Align trailing comments over all \c Changes.
void alignTrailingComments();
Index: clang/lib/Format/WhitespaceManager.cpp
===================================================================
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -105,6 +105,7 @@
alignConsecutiveDeclarations();
alignConsecutiveBitFields();
alignConsecutiveAssignments();
+ alignConsecutiveShortCaseStatements();
alignChainedConditionals();
alignTrailingComments();
alignEscapedNewlines();
@@ -663,14 +664,12 @@
//
// We need to adjust the StartOfTokenColumn of each Change that is on a line
// containing any matching token to be aligned and located after such token.
-static void AlignMacroSequence(
+static void AlignMatchingTokenSequence(
unsigned &StartOfSequence, unsigned &EndOfSequence, unsigned &MinColumn,
- unsigned &MaxColumn, bool &FoundMatchOnLine,
- std::function<bool(const WhitespaceManager::Change &C)> AlignMacrosMatches,
+ std::function<bool(const WhitespaceManager::Change &C)> Matches,
SmallVector<WhitespaceManager::Change, 16> &Changes) {
if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) {
-
- FoundMatchOnLine = false;
+ bool FoundMatchOnLine = false;
int Shift = 0;
for (unsigned I = StartOfSequence; I != EndOfSequence; ++I) {
@@ -681,8 +680,8 @@
// If this is the first matching token to be aligned, remember by how many
// spaces it has to be shifted, so the rest of the changes on the line are
- // shifted by the same amount
- if (!FoundMatchOnLine && AlignMacrosMatches(Changes[I])) {
+ // shifted by the same amount.
+ if (!FoundMatchOnLine && Matches(Changes[I])) {
FoundMatchOnLine = true;
Shift = MinColumn - Changes[I].StartOfTokenColumn;
Changes[I].Spaces += Shift;
@@ -696,7 +695,6 @@
}
MinColumn = 0;
- MaxColumn = UINT_MAX;
StartOfSequence = 0;
EndOfSequence = 0;
}
@@ -735,7 +733,6 @@
};
unsigned MinColumn = 0;
- unsigned MaxColumn = UINT_MAX;
// Start and end of the token sequence we're processing.
unsigned StartOfSequence = 0;
@@ -763,8 +760,8 @@
!(LineIsComment && Style.AlignConsecutiveMacros.AcrossComments);
if (EmptyLineBreak || NoMatchBreak) {
- AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
- FoundMatchOnLine, AlignMacrosMatches, Changes);
+ AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
+ AlignMacrosMatches, Changes);
}
// A new line starts, re-initialize line status tracking bools.
@@ -784,18 +781,12 @@
StartOfSequence = I;
unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn;
- int LineLengthAfter = -Changes[I].Spaces;
- for (unsigned j = I; j != E && Changes[j].NewlinesBefore == 0; ++j)
- LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
- unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
-
MinColumn = std::max(MinColumn, ChangeMinColumn);
- MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
}
EndOfSequence = I;
- AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
- FoundMatchOnLine, AlignMacrosMatches, Changes);
+ AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
+ AlignMacrosMatches, Changes);
}
void WhitespaceManager::alignConsecutiveAssignments() {
@@ -851,6 +842,111 @@
Changes, /*StartAt=*/0, Style.AlignConsecutiveBitFields);
}
+void WhitespaceManager::alignConsecutiveShortCaseStatements() {
+ if (!Style.AlignConsecutiveShortCaseStatements.Enabled ||
+ !Style.AllowShortCaseLabelsOnASingleLine) {
+ return;
+ }
+
+ auto Matches = [&](const Change &C) {
+ if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons) {
+ return C.Tok->is(TT_CaseLabelColon);
+ } else {
+ // Ignore 'IsInsideToken' to allow matching trailing comments which
+ // need to be reflowed as that causes the token to appear in two
+ // different changes, which will cause incorrect alignment as we'll
+ // reflow early due to detecting multiple aligning tokens per line.
+ return (!C.IsInsideToken && C.Tok->Previous &&
+ C.Tok->Previous->is(TT_CaseLabelColon));
+ }
+ };
+
+ unsigned MinColumn = 0;
+
+ // Empty case statements don't break the alignment, but don't necessarily
+ // match our predicate, so we need to track their column so they can push out
+ // our alignment.
+ unsigned MinEmptyCaseColumn = 0;
+
+ // Start and end of the token sequence we're processing.
+ unsigned StartOfSequence = 0;
+ unsigned EndOfSequence = 0;
+
+ // Whether a matching token has been found on the current line.
+ bool FoundMatchOnLine = false;
+
+ bool LineIsComment = true;
+ bool LineIsEmptyCase = false;
+
+ unsigned I = 0;
+ for (unsigned E = Changes.size(); I != E; ++I) {
+ if (Changes[I].NewlinesBefore != 0) {
+ // Whether to break the alignment sequence because of an empty line.
+ bool EmptyLineBreak =
+ (Changes[I].NewlinesBefore > 1) &&
+ !Style.AlignConsecutiveShortCaseStatements.AcrossEmptyLines;
+
+ // Whether to break the alignment sequence because of a line without a
+ // match.
+ bool NoMatchBreak =
+ !FoundMatchOnLine &&
+ !(LineIsComment &&
+ Style.AlignConsecutiveShortCaseStatements.AcrossComments) &&
+ !LineIsEmptyCase;
+
+ if (EmptyLineBreak || NoMatchBreak) {
+ AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
+ Matches, Changes);
+ MinEmptyCaseColumn = 0;
+ }
+
+ // A new line starts, re-initialize line status tracking bools.
+ FoundMatchOnLine = false;
+ LineIsComment = true;
+ LineIsEmptyCase = false;
+ }
+
+ if (!Changes[I].Tok->is(tok::comment))
+ LineIsComment = false;
+
+ if (Changes[I].Tok->is(TT_CaseLabelColon)) {
+ LineIsEmptyCase = Changes[I].Tok->Next == nullptr ||
+ Changes[I].Tok->Next->isTrailingComment();
+
+ if (LineIsEmptyCase) {
+ if (Style.AlignConsecutiveShortCaseStatements.AlignCaseColons) {
+ MinEmptyCaseColumn =
+ std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn);
+ } else {
+ MinEmptyCaseColumn =
+ std::max(MinEmptyCaseColumn, Changes[I].StartOfTokenColumn + 2);
+ }
+ }
+ }
+
+ if (!Matches(Changes[I]))
+ continue;
+
+ if (LineIsEmptyCase)
+ continue;
+
+ FoundMatchOnLine = true;
+
+ if (StartOfSequence == 0)
+ StartOfSequence = I;
+
+ EndOfSequence = I + 1;
+
+ MinColumn = std::max(MinColumn, Changes[I].StartOfTokenColumn);
+
+ // Allow empty case statements to push out our alignment.
+ MinColumn = std::max(MinColumn, MinEmptyCaseColumn);
+ }
+
+ AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches,
+ Changes);
+}
+
void WhitespaceManager::alignConsecutiveDeclarations() {
if (!Style.AlignConsecutiveDeclarations.Enabled)
return;
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -108,6 +108,7 @@
IO.mapOptional("AcrossComments", Value.AcrossComments);
IO.mapOptional("AlignCompound", Value.AlignCompound);
IO.mapOptional("PadOperators", Value.PadOperators);
+ IO.mapOptional("AlignCaseColons", Value.AlignCaseColons);
}
};
@@ -847,6 +848,8 @@
IO.mapOptional("AlignConsecutiveDeclarations",
Style.AlignConsecutiveDeclarations);
IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
+ IO.mapOptional("AlignConsecutiveShortCaseStatements",
+ Style.AlignConsecutiveShortCaseStatements);
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
IO.mapOptional("AlignOperands", Style.AlignOperands);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
@@ -1321,6 +1324,7 @@
LLVMStyle.AlignConsecutiveBitFields = {};
LLVMStyle.AlignConsecutiveDeclarations = {};
LLVMStyle.AlignConsecutiveMacros = {};
+ LLVMStyle.AlignConsecutiveShortCaseStatements = {};
LLVMStyle.AlignTrailingComments = {};
LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always;
LLVMStyle.AlignTrailingComments.OverEmptyLines = 0;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -241,10 +241,26 @@
/// bbb >>= 2;
/// \endcode
bool PadOperators;
+ /// Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels
+ /// are aligned on the colon, or on the tokens after the colon.
+ /// \code
+ /// true:
+ /// case log::info : return "info:";
+ /// case log::warning: return "warning:";
+ /// default : return "";
+ ///
+ /// false:
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ /// default: return "";
+ /// \endcode
+ bool AlignCaseColons;
bool operator==(const AlignConsecutiveStyle &R) const {
return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
AcrossComments == R.AcrossComments &&
- AlignCompound == R.AlignCompound && PadOperators == R.PadOperators;
+ AlignCompound == R.AlignCompound &&
+ PadOperators == R.PadOperators &&
+ AlignCaseColons == R.AlignCaseColons;
}
bool operator!=(const AlignConsecutiveStyle &R) const {
return !(*this == R);
@@ -295,6 +311,20 @@
/// \endcode
/// \version 3.8
AlignConsecutiveStyle AlignConsecutiveDeclarations;
+ /// Style of aligning consecutive short case labels.
+ /// Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``.
+ ///
+ /// ``Consecutive`` will result in formattings like:
+ /// \code
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ /// default: return "";
+ /// \endcode
+ ///
+ /// Empty case statements will currently break the alignment unless
+ /// ``AlignCaseColons`` is ``true``.
+ /// \version 17
+ AlignConsecutiveStyle AlignConsecutiveShortCaseStatements;
/// Different styles for aligning escaped newlines.
enum EscapedNewlineAlignmentStyle : int8_t {
@@ -4296,6 +4326,8 @@
AlignConsecutiveBitFields == R.AlignConsecutiveBitFields &&
AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
+ AlignConsecutiveShortCaseStatements ==
+ R.AlignConsecutiveShortCaseStatements &&
AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
AlignTrailingComments == R.AlignTrailingComments &&
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -801,6 +801,8 @@
- Add ``BracedInitializerIndentWidth`` which can be used to configure
the indentation level of the contents of braced init lists.
- Add ``KeepEmptyLinesAtEOF`` to keep empty lines at end of file.
+- Add ``AlignConsecutiveShortCaseStatements`` which can be used to align case
+ labels in conjunction with ``AllowShortCaseLabelsOnASingleLine``.
libclang
--------
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -408,6 +408,21 @@
a = 2;
bbb >>= 2;
+ * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels
+ are aligned on the colon, or on the tokens after the colon.
+
+ .. code-block:: c++
+
+ true:
+ case log::info : return "info:";
+ case log::warning: return "warning:";
+ default : return "";
+
+ false:
+ case log::info: return "info:";
+ case log::warning: return "warning:";
+ default: return "";
+
.. _AlignConsecutiveBitFields:
@@ -533,6 +548,21 @@
a = 2;
bbb >>= 2;
+ * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels
+ are aligned on the colon, or on the tokens after the colon.
+
+ .. code-block:: c++
+
+ true:
+ case log::info : return "info:";
+ case log::warning: return "warning:";
+ default : return "";
+
+ false:
+ case log::info: return "info:";
+ case log::warning: return "warning:";
+ default: return "";
+
.. _AlignConsecutiveDeclarations:
@@ -658,6 +688,21 @@
a = 2;
bbb >>= 2;
+ * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels
+ are aligned on the colon, or on the tokens after the colon.
+
+ .. code-block:: c++
+
+ true:
+ case log::info : return "info:";
+ case log::warning: return "warning:";
+ default : return "";
+
+ false:
+ case log::info: return "info:";
+ case log::warning: return "warning:";
+ default: return "";
+
.. _AlignConsecutiveMacros:
@@ -784,6 +829,164 @@
a = 2;
bbb >>= 2;
+ * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels
+ are aligned on the colon, or on the tokens after the colon.
+
+ .. code-block:: c++
+
+ true:
+ case log::info : return "info:";
+ case log::warning: return "warning:";
+ default : return "";
+
+ false:
+ case log::info: return "info:";
+ case log::warning: return "warning:";
+ default: return "";
+
+
+.. _AlignConsecutiveShortCaseStatements:
+
+**AlignConsecutiveShortCaseStatements** (``AlignConsecutiveStyle``) :versionbadge:`clang-format 17` :ref:`¶ <AlignConsecutiveShortCaseStatements>`
+ Style of aligning consecutive short case labels.
+ Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``.
+
+ ``Consecutive`` will result in formattings like:
+
+ .. code-block:: c++
+
+ case log::info: return "info:";
+ case log::warning: return "warning:";
+ default: return "";
+
+ Empty case statements will currently break the alignment unless
+ ``AlignCaseColons`` is ``true``.
+
+ Nested configuration flags:
+
+ Alignment options.
+
+ They can also be read as a whole for compatibility. The choices are:
+ - None
+ - Consecutive
+ - AcrossEmptyLines
+ - AcrossComments
+ - AcrossEmptyLinesAndComments
+
+ For example, to align across empty lines and not across comments, either
+ of these work.
+
+ .. code-block:: c++
+
+ AlignConsecutiveMacros: AcrossEmptyLines
+
+ AlignConsecutiveMacros:
+ Enabled: true
+ AcrossEmptyLines: true
+ AcrossComments: false
+
+ * ``bool Enabled`` Whether aligning is enabled.
+
+ .. code-block:: c++
+
+ #define SHORT_NAME 42
+ #define LONGER_NAME 0x007f
+ #define EVEN_LONGER_NAME (2)
+ #define foo(x) (x * x)
+ #define bar(y, z) (y + z)
+
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int aaaa : 1;
+ int b : 12;
+ int ccc : 8;
+
+ int aaaa = 12;
+ float b = 23;
+ std::string ccc;
+
+ * ``bool AcrossEmptyLines`` Whether to align across empty lines.
+
+ .. code-block:: c++
+
+ true:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int d = 3;
+
+ false:
+ int a = 1;
+ int somelongname = 2;
+ double c = 3;
+
+ int d = 3;
+
+ * ``bool AcrossComments`` Whether to align across comments.
+
+ .. code-block:: c++
+
+ true:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ false:
+ int d = 3;
+ /* A comment. */
+ double e = 4;
+
+ * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound assignments
+ like ``+=`` are aligned along with ``=``.
+
+ .. code-block:: c++
+
+ true:
+ a &= 2;
+ bbb = 2;
+
+ false:
+ a &= 2;
+ bbb = 2;
+
+ * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment
+ operators are left-padded to the same length as long ones in order to
+ put all assignment operators to the right of the left hand side.
+
+ .. code-block:: c++
+
+ true:
+ a >>= 2;
+ bbb = 2;
+
+ a = 2;
+ bbb >>= 2;
+
+ false:
+ a >>= 2;
+ bbb = 2;
+
+ a = 2;
+ bbb >>= 2;
+
+ * ``bool AlignCaseColons`` Only for ``AlignConsecutiveShortCaseStatements``. Whether aligned case labels
+ are aligned on the colon, or on the tokens after the colon.
+
+ .. code-block:: c++
+
+ true:
+ case log::info : return "info:";
+ case log::warning: return "warning:";
+ default : return "";
+
+ false:
+ case log::info: return "info:";
+ case log::warning: return "warning:";
+ default: return "";
+
.. _AlignEscapedNewlines:
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits