diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -294,6 +294,17 @@ /// \endcode /// \version 3.8 AlignConsecutiveStyle AlignConsecutiveDeclarations; + /// Style of aligning consecutive trailing comments. + /// + /// ``Consecutive`` will align the trailing comments of consecutive lines. + /// This will result in formattings like: + /// \code + /// int aaaa // comment + /// int b // comment + /// int ccc // comment + /// \endcode + /// \version ??? + AlignConsecutiveStyle AlignConsecutiveTrailingComments; /// Different styles for aligning escaped newlines. enum EscapedNewlineAlignmentStyle : int8_t { @@ -369,12 +380,7 @@ /// \version 3.5 OperandAlignmentStyle AlignOperands; - /// If ``true``, aligns trailing comments. - /// \code - /// true: false: - /// int a; // My comment a vs. int a; // My comment a - /// int b = 2; // comment b int b = 2; // comment about b - /// \endcode + /// This option is **deprecated**. See ``AlignConsecutiveTrailingComments``. /// \version 3.7 bool AlignTrailingComments; @@ -3854,9 +3860,9 @@ AlignConsecutiveBitFields == R.AlignConsecutiveBitFields && AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations && AlignConsecutiveMacros == R.AlignConsecutiveMacros && + AlignConsecutiveTrailingComments == R.AlignConsecutiveTrailingComments && AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && - AlignTrailingComments == R.AlignTrailingComments && AllowAllArgumentsOnNextLine == R.AllowAllArgumentsOnNextLine && AllowAllParametersOfDeclarationOnNextLine == R.AllowAllParametersOfDeclarationOnNextLine && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -632,6 +632,7 @@ IO.mapOptional("PointerBindsToType", Style.PointerAlignment); IO.mapOptional("SpaceAfterControlStatementKeyword", Style.SpaceBeforeParens); + IO.mapOptional("AlignTrailingComments", Style.AlignConsecutiveTrailingComments.Enabled); } IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); @@ -644,9 +645,9 @@ IO.mapOptional("AlignConsecutiveDeclarations", Style.AlignConsecutiveDeclarations); IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros); + IO.mapOptional("AlignConsecutiveTrailingComments", Style.AlignConsecutiveTrailingComments); IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); IO.mapOptional("AlignOperands", Style.AlignOperands); - IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); IO.mapOptional("AllowAllArgumentsOnNextLine", Style.AllowAllArgumentsOnNextLine); IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", @@ -1181,7 +1182,6 @@ LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None; LLVMStyle.AlignOperands = FormatStyle::OAS_Align; - LLVMStyle.AlignTrailingComments = true; LLVMStyle.AlignConsecutiveAssignments = {}; LLVMStyle.AlignConsecutiveAssignments.Enabled = false; LLVMStyle.AlignConsecutiveAssignments.AcrossEmptyLines = false; @@ -1191,6 +1191,8 @@ LLVMStyle.AlignConsecutiveBitFields = {}; LLVMStyle.AlignConsecutiveDeclarations = {}; LLVMStyle.AlignConsecutiveMacros = {}; + LLVMStyle.AlignConsecutiveTrailingComments = {}; + LLVMStyle.AlignConsecutiveTrailingComments.Enabled = true; LLVMStyle.AllowAllArgumentsOnNextLine = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortEnumsOnASingleLine = true; @@ -1447,7 +1449,7 @@ if (Language == FormatStyle::LK_Java) { GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; - GoogleStyle.AlignTrailingComments = false; + GoogleStyle.AlignConsecutiveTrailingComments.Enabled = false; GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; @@ -1595,7 +1597,7 @@ Style.AccessModifierOffset = -4; Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; Style.AlignOperands = FormatStyle::OAS_DontAlign; - Style.AlignTrailingComments = false; + Style.AlignConsecutiveTrailingComments.Enabled = false; Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; Style.BreakBeforeBraces = FormatStyle::BS_WebKit; diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -927,6 +927,7 @@ unsigned StartOfSequence = 0; bool BreakBeforeNext = false; unsigned Newlines = 0; + unsigned int NewLineThreshold = Style.AlignConsecutiveTrailingComments.AcrossEmptyLines ? 2 : 1; for (unsigned i = 0, e = Changes.size(); i != e; ++i) { if (Changes[i].StartOfBlockComment) continue; @@ -974,12 +975,13 @@ break; } } - if (!Style.AlignTrailingComments || FollowsRBraceInColumn0) { + if (!Style.AlignConsecutiveTrailingComments.Enabled || FollowsRBraceInColumn0) { alignTrailingComments(StartOfSequence, i, MinColumn); MinColumn = ChangeMinColumn; MaxColumn = ChangeMinColumn; StartOfSequence = i; - } else if (BreakBeforeNext || Newlines > 1 || + } + else if (BreakBeforeNext || Newlines > NewLineThreshold || (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) || // Break the comment sequence if the previous line did not end // in a trailing comment. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -71,7 +71,10 @@ ScopedTrace t(File, Line, ::testing::Message() << Code.str()); EXPECT_EQ(Expected.str(), format(Expected, Style)) << "Expected code is not stable"; + + // FIXME: expectedとCodeをformatしたものがEQ EXPECT_EQ(Expected.str(), format(Code, Style)); + if (Style.Language == FormatStyle::LK_Cpp) { // Objective-C++ is a superset of C++, so everything checked for C++ // needs to be checked for Objective-C++ as well. @@ -20041,7 +20044,6 @@ TEST_F(FormatTest, ParsesConfigurationBools) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; - CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); @@ -20212,6 +20214,10 @@ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields); CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros); CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations); + CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveTrailingComments); + // For backwards compatibility + CHECK_PARSE("AlignTrailingComments: true", AlignConsecutiveTrailingComments.Enabled, true); + CHECK_PARSE("AlignTrailingComments: false", AlignConsecutiveTrailingComments.Enabled, false); #undef CHECK_ALIGN_CONSECUTIVE diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -2858,6 +2858,107 @@ "int a; //\n"); } +TEST_F(FormatTestComments, AlignTrailingCommentsAcrossEmptyLines) { + FormatStyle Style = getLLVMStyle(); + Style.AlignConsecutiveTrailingComments.AcrossEmptyLines = true; + verifyFormat("#include \"a.h\" //\n" + "\n" + "#include \"aa.h\" //\n", + Style); + + verifyFormat("#include \"a.h\" //\n" + "\n" + "#include \"aa.h\" //\n" + "\n" + "#include \"aaa.h\" //\n", + Style); + + verifyFormat("#include \"a.h\" //\n" + "#include \"aa.h\" //\n" + "#include \"aaa.h\" //\n" + "\n" + "#include \"aaaa.h\" //\n" + "#include \"aaaaa.h\" //\n" + "#include \"aaaaaa.h\" //\n", + Style); + + verifyFormat("#include \"a.h\" //\n" + "#include \"a.h\"\n" + "#include \"aa.h\" //\n", + Style); + + verifyFormat("#include \"a.h\" //\n" + "#include \"a.h\"\n" + "#include \"aa.h\" //\n" + "#include \"a.h\"\n" + "#include \"aaa.h\" //\n", + Style); + + verifyFormat("#include \"a.h\" //\n" + "#include \"aa.h\" //\n" + "#include \"aaa.h\" //\n" + "#include \"a.h\"\n" + "#include \"aaaa.h\" //\n" + "#include \"aaaaa.h\" //\n" + "#include \"aaaaaa.h\" //\n", + Style); + + verifyFormat("#include \"a.h\" //\n" + "\n" + "#include \"aa.h\" //\n" + "#include \"aaa.h\"\n" + "#include \"aaa.h\"\n" + "#include \"aaa.h\" // Do not align this because there are two lines without comments above\n", + Style); + + Style.ColumnLimit = 15; + EXPECT_EQ("int ab; // line\n" + "int a; // long\n" + " // long\n" + "\n" + " // long", + format("int ab; // line\n" + "int a; // long long\n" + "\n" + "// long", + Style)); + + Style.ColumnLimit = 15; + EXPECT_EQ("int ab; // line\n" + "\n" + "int a; // long\n" + " // long\n", + format("int ab; // line\n" + "\n" + "int a; // long long\n", + Style)); + + // FIXME: I think we need to change the implementations to pass tests below. + Style.ColumnLimit = 80; + EXPECT_EQ("int a; // line about a\n" + "\n" + "// line about b\n" + "long b;", + format("int a; // line about a\n" + "\n" + " // line about b\n" + " long b;", + Style)); + + Style.ColumnLimit = 80; + EXPECT_EQ("int a; // line about a\n" + "\n" + "// line 1 about b\n" + "// line 2 about b\n" + "long b;", + format("int a; // line about a\n" + "\n" + " // line 1 about b\n" + " // line 2 about b\n" + " long b;", + Style)); +} + TEST_F(FormatTestComments, AlignsBlockCommentDecorations) { EXPECT_EQ("/*\n" " */",