tinloaf updated this revision to Diff 314361.
tinloaf added a comment.
Address reviewer comments, noteworthy changes:
- Add an option to span alignment only across comments, not across newlines
- Factor out spanning options to `AlignTokens` to an enum
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93986/new/
https://reviews.llvm.org/D93986
Files:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/WhitespaceManager.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -11330,7 +11330,7 @@
"*/\n"
"}",
Tab));
- Tab.AlignConsecutiveAssignments = true;
+ Tab.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
Tab.AlignConsecutiveDeclarations = true;
Tab.TabWidth = 4;
Tab.IndentWidth = 4;
@@ -11569,7 +11569,7 @@
"*/\n"
"}",
Tab));
- Tab.AlignConsecutiveAssignments = true;
+ Tab.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
Tab.AlignConsecutiveDeclarations = true;
Tab.TabWidth = 4;
Tab.IndentWidth = 4;
@@ -12271,7 +12271,7 @@
TEST_F(FormatTest, AlignConsecutiveMacros) {
FormatStyle Style = getLLVMStyle();
- Style.AlignConsecutiveAssignments = true;
+ Style.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
Style.AlignConsecutiveDeclarations = true;
Style.AlignConsecutiveMacros = false;
@@ -12364,10 +12364,486 @@
Style);
}
+TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLines) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveMacros = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_AcrossEmptyLines;
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "int oneTwoThree= 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+}
+
+TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossComments) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveMacros = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_AcrossComments;
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "int oneTwoThree= 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+}
+
+TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLinesAndComments) {
+ FormatStyle Alignment = getLLVMStyle();
+ Alignment.AlignConsecutiveMacros = true;
+ Alignment.AlignConsecutiveAssignments =
+ FormatStyle::ACA_AcrossEmptyLinesAndComments;
+ verifyFormat("int a = 5;\n"
+ "int oneTwoThree = 123;",
+ Alignment);
+ verifyFormat("int a = method();\n"
+ "int oneTwoThree = 133;",
+ Alignment);
+ verifyFormat("a &= 5;\n"
+ "bcd *= 5;\n"
+ "ghtyf += 5;\n"
+ "dvfvdb -= 5;\n"
+ "a /= 5;\n"
+ "vdsvsv %= 5;\n"
+ "sfdbddfbdfbb ^= 5;\n"
+ "dvsdsv |= 5;\n"
+ "int dsvvdvsdvvv = 123;",
+ Alignment);
+ verifyFormat("int i = 1, j = 10;\n"
+ "something = 2000;",
+ Alignment);
+ verifyFormat("something = 2000;\n"
+ "int i = 1, j = 10;\n",
+ Alignment);
+ verifyFormat("something = 2000;\n"
+ "another = 911;\n"
+ "int i = 1, j = 10;\n"
+ "oneMore = 1;\n"
+ "i = 2;",
+ Alignment);
+ verifyFormat("int a = 5;\n"
+ "int one = 1;\n"
+ "method();\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ Alignment);
+ verifyFormat("int oneTwoThree = 123;\n"
+ "int oneTwo = 12;\n"
+ "method();\n",
+ Alignment);
+ verifyFormat("int oneTwoThree = 123; // comment\n"
+ "int oneTwo = 12; // comment",
+ Alignment);
+
+ // Bug 25167
+ /* Uncomment when fixed
+ verifyFormat("#if A\n"
+ "#else\n"
+ "int aaaaaaaa = 12;\n"
+ "#endif\n"
+ "#if B\n"
+ "#else\n"
+ "int a = 12;\n"
+ "#endif\n",
+ Alignment);
+ verifyFormat("enum foo {\n"
+ "#if A\n"
+ "#else\n"
+ " aaaaaaaa = 12;\n"
+ "#endif\n"
+ "#if B\n"
+ "#else\n"
+ " a = 12;\n"
+ "#endif\n"
+ "};\n",
+ Alignment);
+ */
+
+ Alignment.MaxEmptyLinesToKeep = 10;
+ /* Test alignment across empty lines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "int oneTwoThree= 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ Alignment));
+ EXPECT_EQ("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ format("int a = 5;\n"
+ "int one = 1;\n"
+ "\n"
+ "int oneTwoThree = 123;\n"
+ "int oneTwo = 12;",
+ Alignment));
+
+ /* Test across comments */
+ EXPECT_EQ("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ /* Test across comments and newlines */
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "//\n"
+ "// multi-line line comment\n"
+ "//\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "/*\n"
+ " * multi-line block comment\n"
+ " */\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "/* block comment */\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ EXPECT_EQ("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree = 123;",
+ format("int a = 5;\n"
+ "\n"
+ "// line comment\n"
+ "\n"
+ "\n"
+ "\n"
+ "int oneTwoThree=123;",
+ Alignment));
+
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " int b = 23; \\\n"
+ " int ccc = 234; \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " int b = 23; \\\n"
+ " int ccc = 234; \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right;
+ verifyFormat("#define A "
+ " \\\n"
+ " int aaaa = 12; "
+ " \\\n"
+ " int b = 23; "
+ " \\\n"
+ " int ccc = 234; "
+ " \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ verifyFormat("void SomeFunction(int parameter = 1, int i = 2, int j = 3, int "
+ "k = 4, int l = 5,\n"
+ " int m = 6) {\n"
+ " int j = 10;\n"
+ " otherThing = 1;\n"
+ "}",
+ Alignment);
+ verifyFormat("void SomeFunction(int parameter = 0) {\n"
+ " int i = 1;\n"
+ " int j = 2;\n"
+ " int big = 10000;\n"
+ "}",
+ Alignment);
+ verifyFormat("class C {\n"
+ "public:\n"
+ " int i = 1;\n"
+ " virtual void f() = 0;\n"
+ "};",
+ Alignment);
+ verifyFormat("int i = 1;\n"
+ "if (SomeType t = getSomething()) {\n"
+ "}\n"
+ "int j = 2;\n"
+ "int big = 10000;",
+ Alignment);
+ verifyFormat("int j = 7;\n"
+ "for (int k = 0; k < N; ++k) {\n"
+ "}\n"
+ "int j = 2;\n"
+ "int big = 10000;\n"
+ "}",
+ Alignment);
+ Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+ verifyFormat("int i = 1;\n"
+ "LooooooooooongType loooooooooooooooooooooongVariable\n"
+ " = someLooooooooooooooooongFunction();\n"
+ "int j = 2;",
+ Alignment);
+ Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
+ verifyFormat("int i = 1;\n"
+ "LooooooooooongType loooooooooooooooooooooongVariable =\n"
+ " someLooooooooooooooooongFunction();\n"
+ "int j = 2;",
+ Alignment);
+
+ verifyFormat("auto lambda = []() {\n"
+ " auto i = 0;\n"
+ " return 0;\n"
+ "};\n"
+ "int i = 0;\n"
+ "auto v = type{\n"
+ " i = 1, //\n"
+ " (i = 2), //\n"
+ " i = 3 //\n"
+ "};",
+ Alignment);
+
+ verifyFormat(
+ "int i = 1;\n"
+ "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n"
+ " loooooooooooooooooooooongParameterB);\n"
+ "int j = 2;",
+ Alignment);
+
+ verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n"
+ " typename B = very_long_type_name_1,\n"
+ " typename T_2 = very_long_type_name_2>\n"
+ "auto foo() {}\n",
+ Alignment);
+ verifyFormat("int a, b = 1;\n"
+ "int c = 2;\n"
+ "int dd = 3;\n",
+ Alignment);
+ verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
+ "float b[1][] = {{3.f}};\n",
+ Alignment);
+ verifyFormat("for (int i = 0; i < 1; i++)\n"
+ " int x = 1;\n",
+ Alignment);
+ verifyFormat("for (i = 0; i < 1; i++)\n"
+ " x = 1;\n"
+ "y = 1;\n",
+ Alignment);
+
+ Alignment.ReflowComments = true;
+ Alignment.ColumnLimit = 50;
+ EXPECT_EQ("int x = 0;\n"
+ "int yy = 1; /// specificlennospace\n"
+ "int zzz = 2;\n",
+ format("int x = 0;\n"
+ "int yy = 1; ///specificlennospace\n"
+ "int zzz = 2;\n",
+ Alignment));
+}
+
TEST_F(FormatTest, AlignConsecutiveAssignments) {
FormatStyle Alignment = getLLVMStyle();
Alignment.AlignConsecutiveMacros = true;
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_None;
verifyFormat("int a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -12375,7 +12851,7 @@
"int oneTwoThree = 123;",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
verifyFormat("int a = 5;\n"
"int oneTwoThree = 123;",
Alignment);
@@ -12614,7 +13090,7 @@
"int oneTwoThree : 23 = 0;",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
verifyFormat("int const a : 5 = 1;\n"
"int oneTwoThree : 23 = 0;",
Alignment);
@@ -12754,7 +13230,7 @@
verifyFormat("int a(int x, void (*fp)(int y));\n"
"double b();",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
// Ensure recursive alignment is broken by function braces, so that the
// "a = 1" does not align with subsequent assignments inside the function
// body.
@@ -12817,7 +13293,7 @@
"int ll=10000;\n"
"}",
Alignment));
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_None;
Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
@@ -12886,7 +13362,7 @@
"int j = 2;",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
verifyFormat("auto lambda = []() {\n"
" auto ii = 0;\n"
" float j = 0;\n"
@@ -12900,7 +13376,7 @@
" i = 3 //\n"
"};",
Alignment);
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_None;
verifyFormat(
"int i = 1;\n"
@@ -12913,7 +13389,7 @@
// We expect declarations and assignments to align, as long as it doesn't
// exceed the column limit, starting a new alignment sequence whenever it
// happens.
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
Alignment.ColumnLimit = 30;
verifyFormat("float ii = 1;\n"
"unsigned j = 2;\n"
@@ -12923,7 +13399,7 @@
"int myvar = 1;",
Alignment);
Alignment.ColumnLimit = 80;
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_None;
verifyFormat(
"template <typename LongTemplate, typename VeryLongTemplateTypeName,\n"
@@ -12937,7 +13413,7 @@
verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
"float b[1][] = {{3.f}};\n",
Alignment);
- Alignment.AlignConsecutiveAssignments = true;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
verifyFormat("float a, b = 1;\n"
"int c = 2;\n"
"int dd = 3;\n",
@@ -12945,7 +13421,7 @@
verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
"float b[1][] = {{3.f}};\n",
Alignment);
- Alignment.AlignConsecutiveAssignments = false;
+ Alignment.AlignConsecutiveAssignments = FormatStyle::ACA_None;
Alignment.ColumnLimit = 30;
Alignment.BinPackParameters = false;
@@ -14123,7 +14599,6 @@
FormatStyle Style = {};
Style.Language = FormatStyle::LK_Cpp;
CHECK_PARSE_BOOL(AlignTrailingComments);
- CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
CHECK_PARSE_BOOL(AlignConsecutiveBitFields);
CHECK_PARSE_BOOL(AlignConsecutiveDeclarations);
CHECK_PARSE_BOOL(AlignConsecutiveMacros);
@@ -14221,6 +14696,22 @@
CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u);
CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
+ Style.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
+ CHECK_PARSE("AlignConsecutiveAssignments: None", AlignConsecutiveAssignments,
+ FormatStyle::ACA_None);
+ CHECK_PARSE("AlignConsecutiveAssignments: Consecutive",
+ AlignConsecutiveAssignments, FormatStyle::ACA_Consecutive);
+ CHECK_PARSE("AlignConsecutiveAssignments: AcrossEmptyLines",
+ AlignConsecutiveAssignments, FormatStyle::ACA_AcrossEmptyLines);
+ CHECK_PARSE("AlignConsecutiveAssignments: AcrossEmptyLinesAndComments",
+ AlignConsecutiveAssignments,
+ FormatStyle::ACA_AcrossEmptyLinesAndComments);
+ // For backwards compability, false / true should still parse
+ CHECK_PARSE("AlignConsecutiveAssignments: false", AlignConsecutiveAssignments,
+ FormatStyle::ACA_None);
+ CHECK_PARSE("AlignConsecutiveAssignments: true", AlignConsecutiveAssignments,
+ FormatStyle::ACA_Consecutive);
+
Style.PointerAlignment = FormatStyle::PAS_Middle;
CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
FormatStyle::PAS_Left);
@@ -17144,7 +17635,7 @@
format("FOO(String-ized&Messy+But,: :\n"
" Still=Intentional);",
Style));
- Style.AlignConsecutiveAssignments = true;
+ Style.AlignConsecutiveAssignments = FormatStyle::ACA_Consecutive;
EXPECT_EQ("FOO(String-ized=&Messy+But,: :\n"
" Still=Intentional);",
format("FOO(String-ized=&Messy+But,: :\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===================================================================
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -333,6 +333,15 @@
}
}
+/// Mirrors the values of AlignConsecutiveAssignmentsStyle etc.
+/// for concise passing of the requested style to AlignTokens.
+enum TokenAlignmentStyle {
+ TAS_Consecutive,
+ TAS_AcrossEmptyLines,
+ TAS_AcrossComments,
+ TAS_AcrossEmptyLinesAndComments
+};
+
// Walk through a subset of the changes, starting at StartAt, and find
// sequences of matching tokens to align. To do so, keep track of the lines and
// whether or not a matching token was found on a line. If a matching token is
@@ -363,7 +372,8 @@
template <typename F>
static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
SmallVector<WhitespaceManager::Change, 16> &Changes,
- unsigned StartAt) {
+ unsigned StartAt,
+ const TokenAlignmentStyle &TAS = TAS_Consecutive) {
unsigned MinColumn = 0;
unsigned MaxColumn = UINT_MAX;
@@ -386,6 +396,9 @@
// Whether a matching token has been found on the current line.
bool FoundMatchOnLine = false;
+ // Whether the current line consists purely of comments.
+ bool LineIsComment = true;
+
// Aligns a sequence of matching tokens, on the MinColumn column.
//
// Sequences start from the first matching token to align, and end at the
@@ -411,19 +424,36 @@
if (Changes[i].NewlinesBefore != 0) {
CommasBeforeMatch = 0;
EndOfSequence = i;
- // If there is a blank line, or if the last line didn't contain any
- // matching token, the sequence ends here.
- if (Changes[i].NewlinesBefore > 1 || !FoundMatchOnLine)
+
+ // Whether to break the alignment sequence because of an empty line.
+ bool EmptyLineBreak = (Changes[i].NewlinesBefore > 1) &&
+ (TAS != TAS_AcrossEmptyLines) &&
+ (TAS != TAS_AcrossEmptyLinesAndComments);
+
+ // Whether to break the alignment sequence because of a line without a
+ // match
+ bool NoMatchBreak =
+ !FoundMatchOnLine &&
+ !(LineIsComment && ((TAS == TAS_AcrossComments) ||
+ (TAS == TAS_AcrossEmptyLinesAndComments)));
+
+ if (EmptyLineBreak || NoMatchBreak)
AlignCurrentSequence();
+ // A new line starts, re-initialize line status tracking bools.
FoundMatchOnLine = false;
+ LineIsComment = true;
+ }
+
+ if (!Changes[i].Tok->is(tok::comment)) {
+ LineIsComment = false;
}
if (Changes[i].Tok->is(tok::comma)) {
++CommasBeforeMatch;
} else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
// Call AlignTokens recursively, skipping over this scope block.
- unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
+ unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, TAS);
i = StoppedAt - 1;
continue;
}
@@ -597,8 +627,25 @@
}
void WhitespaceManager::alignConsecutiveAssignments() {
- if (!Style.AlignConsecutiveAssignments)
+ TokenAlignmentStyle tas;
+ switch (Style.AlignConsecutiveAssignments) {
+ case FormatStyle::ACA_None:
return;
+ case FormatStyle::ACA_Consecutive:
+ tas = TokenAlignmentStyle::TAS_Consecutive;
+ break;
+ case FormatStyle::ACA_AcrossComments:
+ tas = TokenAlignmentStyle::TAS_AcrossComments;
+ break;
+ case FormatStyle::ACA_AcrossEmptyLines:
+ tas = TokenAlignmentStyle::TAS_AcrossEmptyLines;
+ break;
+ case FormatStyle::ACA_AcrossEmptyLinesAndComments:
+ tas = TokenAlignmentStyle::TAS_AcrossEmptyLinesAndComments;
+ break;
+ default:
+ break;
+ }
AlignTokens(
Style,
@@ -613,7 +660,7 @@
return C.Tok->is(tok::equal);
},
- Changes, /*StartAt=*/0);
+ Changes, /*StartAt=*/0, tas);
}
void WhitespaceManager::alignConsecutiveBitFields() {
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -128,6 +128,23 @@
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::AlignConsecutiveAssignmentsStyle> {
+ static void
+ enumeration(IO &IO, FormatStyle::AlignConsecutiveAssignmentsStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::ACA_None);
+ IO.enumCase(Value, "Consecutive", FormatStyle::ACA_Consecutive);
+ IO.enumCase(Value, "AcrossEmptyLines", FormatStyle::ACA_AcrossEmptyLines);
+ IO.enumCase(Value, "AcrossComments", FormatStyle::ACA_AcrossComments);
+ IO.enumCase(Value, "AcrossEmptyLinesAndComments",
+ FormatStyle::ACA_AcrossEmptyLinesAndComments);
+
+ // For backward compability.
+ IO.enumCase(Value, "true", FormatStyle::ACA_Consecutive);
+ IO.enumCase(Value, "false", FormatStyle::ACA_None);
+ }
+};
+
template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
@@ -854,7 +871,7 @@
LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
LLVMStyle.AlignTrailingComments = true;
- LLVMStyle.AlignConsecutiveAssignments = false;
+ LLVMStyle.AlignConsecutiveAssignments = FormatStyle::ACA_None;
LLVMStyle.AlignConsecutiveBitFields = false;
LLVMStyle.AlignConsecutiveDeclarations = false;
LLVMStyle.AlignConsecutiveMacros = false;
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -97,16 +97,53 @@
/// \endcode
bool AlignConsecutiveMacros;
- /// If ``true``, aligns consecutive assignments.
- ///
- /// This will align the assignment operators of consecutive lines. This
- /// will result in formattings like
- /// \code
- /// int aaaa = 12;
- /// int b = 23;
- /// int ccc = 23;
- /// \endcode
- bool AlignConsecutiveAssignments;
+ /// Styles for alignment of consecutive assignments
+ enum AlignConsecutiveAssignmentsStyle {
+ /// Do not align consecutive assignments.
+ ACA_None,
+ /// Align assignments on consecutive lines. This will result in
+ /// formattings like
+ /// \code
+ /// int aaaa = 12;
+ /// int b = 23;
+ /// int ccc = 23;
+ /// \endcode
+ ACA_Consecutive,
+ /// Same as ACA_Consecutive, but alignment also spans over empty
+ /// lines, e.g.
+ /// \code
+ /// int aaaa = 12;
+ /// int b = 23;
+ ///
+ /// int ccc = 23;
+ /// \endcode
+ ACA_AcrossEmptyLines,
+ /// Same as ACA_Consecutive, but alignment also spans over lines containing
+ /// only comments, e.g.
+ /// \code
+ /// int aaaa = 12;
+ /// /* This is a comment */
+ /// int b = 23;
+ ///
+ /// /* Empty lines still break alignment */
+ /// int ccc = 23;
+ /// \endcode
+ ACA_AcrossComments,
+ /// Same as ACA_Consecutive, but alignment also spans over lines containing
+ /// only comments and empty lines, e.g.
+ /// \code
+ /// int aaaa = 12;
+ /// /* This is a comment */
+ /// int b = 23;
+ ///
+ /// /* Empty lines do not break alignment */
+ /// int ccc = 23;
+ /// \endcode
+ ACA_AcrossEmptyLinesAndComments
+ };
+
+ /// Style of aligning assignments on consecutive lines.
+ AlignConsecutiveAssignmentsStyle AlignConsecutiveAssignments;
/// If ``true``, aligns consecutive bitfield members.
///
Index: clang/docs/ClangFormatStyleOptions.rst
===================================================================
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -195,17 +195,62 @@
-**AlignConsecutiveAssignments** (``bool``)
- If ``true``, aligns consecutive assignments.
+**AlignConsecutiveAssignments** (``AlignConsecutiveAssignmentsStyle``)
+ Style of aligning assignments on consecutive lines.
- This will align the assignment operators of consecutive lines. This
- will result in formattings like
+ Possible values:
+
+ * ``ACA_None`` (in configuration: ``None``)
+ Do not align consecutive assignments.
+
+ * ``ACA_Consecutive`` (in configuration: ``Consecutive``)
+ Align assignments on consecutive lines. This will result in
+ formattings like
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ int b = 23;
+ int ccc = 23;
+
+ * ``ACA_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
+ Same as ACA_Consecutive, but alignment also spans over empty
+ lines, e.g.
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ int b = 23;
+
+ int ccc = 23;
+
+ * ``ACA_AcrossComments`` (in configuration: ``AcrossComments``)
+ Same as ACA_Consecutive, but alignment also spans over lines containing
+ only comments, e.g.
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ /* This is a comment */
+ int b = 23;
+
+ /* Empty lines still break alignment */
+ int ccc = 23;
+
+ * ``ACA_AcrossEmptyLinesAndComments`` (in configuration: ``AcrossEmptyLinesAndComments``)
+ Same as ACA_Consecutive, but alignment also spans over lines containing
+ only comments and empty lines, e.g.
+
+ .. code-block:: c++
+
+ int aaaa = 12;
+ /* This is a comment */
+ int b = 23;
+
+ /* Empty lines do not break alignment */
+ int ccc = 23;
- .. code-block:: c++
- int aaaa = 12;
- int b = 23;
- int ccc = 23;
**AlignConsecutiveBitFields** (``bool``)
If ``true``, aligns consecutive bitfield members.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits