From 015280a8320e1ce80792b9bd6346a2105c2efd95 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Wed, 4 Dec 2013 12:21:08 +0000 Subject: [PATCH] Leave constructor initializer lists on one line in styles with no column limit. Summary: Allow tryFitMultipleLinesInOne join unwrapped lines when ContinuationIndenter::mustBreak doesn't agree. But don't merge any lines, that are separate in the input. Reviewers: djasper Reviewed By: djasper CC: cfe-commits, klimek Differential Revision: http://llvm-reviews.chandlerc.com/D2321 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196378 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/Format.cpp | 22 +++++++++++++----- unittests/Format/FormatTest.cpp | 40 ++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index ee9fe7625d..156ff6429c 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -439,12 +439,13 @@ public: /// \brief Formats the line starting at \p State, simply keeping all of the /// input's line breaking decisions. - void format(unsigned FirstIndent, const AnnotatedLine *Line) { + void format(unsigned FirstIndent, const AnnotatedLine *Line, + bool LineIsMerged) { LineState State = Indenter->getInitialState(FirstIndent, Line, /*DryRun=*/false); while (State.NextToken != NULL) { bool Newline = - Indenter->mustBreak(State) || + (!LineIsMerged && Indenter->mustBreak(State)) || (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0); Indenter->addTokenToState(State, Newline, /*DryRun=*/false); } @@ -468,9 +469,6 @@ public: if (TheLine->Last->Type == TT_LineComment) return 0; - if (Indent > Style.ColumnLimit) - return 0; - unsigned Limit = Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent; // If we already exceed the column limit, we set 'Limit' to 0. The different @@ -479,6 +477,9 @@ public: ? 0 : Limit - TheLine->Last->TotalLength; + if (Indent > Limit) + return 0; + if (I + 1 == E || I[1]->Type == LT_Invalid) return 0; @@ -658,6 +659,14 @@ public: if (static_cast(Indent) + Offset >= 0) Indent += Offset; unsigned MergedLines = Joiner.tryFitMultipleLinesInOne(Indent, I, E); + if (MergedLines > 0 && Style.ColumnLimit == 0) { + // Disallow line merging if there is a break at the start of one of the + // input lines. + for (unsigned i = 0; i < MergedLines; ++i) { + if (I[i + 1]->First->NewlinesBefore > 0) + MergedLines = 0; + } + } if (!DryRun) { for (unsigned i = 0; i < MergedLines; ++i) { join(*I[i], *I[i + 1]); @@ -702,7 +711,8 @@ public: // FIXME: Implement nested blocks for ColumnLimit = 0. NoColumnLimitFormatter Formatter(Indenter); if (!DryRun) - Formatter.format(Indent, &TheLine); + Formatter.format(Indent, &TheLine, + /*LineIsMerged=*/MergedLines > 0); } else { Penalty += format(TheLine, Indent, DryRun); } diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 88b2a0b31a..f5a0bdd634 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -4891,6 +4891,28 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { verifyFormat("void f() {}", getLLVMStyleWithColumns(11)); verifyFormat("void f() {\n}", getLLVMStyleWithColumns(10)); + + FormatStyle NoColumnLimit = getLLVMStyle(); + NoColumnLimit.ColumnLimit = 0; + EXPECT_EQ("A() : b(0) {}", format("A():b(0){}", NoColumnLimit)); + EXPECT_EQ("class C {\n" + " A() : b(0) {}\n" + "};", format("class C{A():b(0){}};", NoColumnLimit)); + EXPECT_EQ("A()\n" + " : b(0) {\n" + "}", + format("A()\n:b(0)\n{\n}", NoColumnLimit)); + + FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit; + DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine = false; + EXPECT_EQ("A()\n" + " : b(0) {\n" + "}", + format("A():b(0){}", DoNotMergeNoColumnLimit)); + EXPECT_EQ("A()\n" + " : b(0) {\n" + "}", + format("A()\n:b(0)\n{\n}", DoNotMergeNoColumnLimit)); } TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { @@ -7340,12 +7362,18 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) { // Constructor initializers are formatted one per line with the "," on the // new line. - verifyFormat("Constructor()\n" - " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" - " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n" - " aaaaaaaaaaaaaa)\n" - " , aaaaaaaaaaaaaaaaaaaaaaa() {}", - Style); + EXPECT_EQ( + "Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n" + " aaaaaaaaaaaaaa)\n" + " , aaaaaaaaaaaaaaaaaaaaaaa() {}", + format("Constructor()\n" + " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n" + " aaaaaaaaaaaaaa)\n" + " , aaaaaaaaaaaaaaaaaaaaaaa() {}", + Style)); // Access specifiers should be aligned left. verifyFormat("class C {\n" -- 2.40.0