From: Daniel Jasper Date: Thu, 22 May 2014 08:36:53 +0000 (+0000) Subject: clang-format: Correctly calculate line lenghts for nest blocks. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5da13c6a4f668a84fad68558ad05c67501fbadd5;p=clang clang-format: Correctly calculate line lenghts for nest blocks. If simple (one-statement) blocks can be inlined, the length needs to be calculated correctly. Before (in JavaScript but this also affects lambdas, etc.): var x = { valueOf: function() { return 1; } }; After: var x = {valueOf: function() { return 1; }}; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209410 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 891a7188bb..03177e586a 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -828,8 +828,10 @@ public: if (TheLine.Last->TotalLength + Indent <= ColumnLimit) { LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun); - while (State.NextToken) + while (State.NextToken) { + formatChildren(State, /*Newline=*/false, /*DryRun=*/false, Penalty); Indenter->addTokenToState(State, /*Newline=*/false, DryRun); + } } else if (Style.ColumnLimit == 0) { // FIXME: Implement nested blocks for ColumnLimit = 0. NoColumnLimitFormatter Formatter(Indenter); diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 47ecd6a4dc..dca20d2d75 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -1178,6 +1178,12 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { } void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { + for (SmallVectorImpl::iterator I = Line.Children.begin(), + E = Line.Children.end(); + I != E; ++I) { + calculateFormattingInformation(**I); + } + Line.First->TotalLength = Line.First->IsMultiline ? Style.ColumnLimit : Line.First->ColumnWidth; if (!Line.First->Next) @@ -1222,12 +1228,18 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { Current->CanBreakBefore = Current->MustBreakBefore || canBreakBefore(Line, *Current); - if (Current->MustBreakBefore || !Current->Children.empty() || + unsigned ChildSize = 0; + if (Current->Previous->Children.size() == 1) { + FormatToken &LastOfChild = *Current->Previous->Children[0]->Last; + ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit + : LastOfChild.TotalLength + 1; + } + if (Current->MustBreakBefore || Current->Previous->Children.size() > 1 || Current->IsMultiline) Current->TotalLength = Current->Previous->TotalLength + Style.ColumnLimit; else Current->TotalLength = Current->Previous->TotalLength + - Current->ColumnWidth + + Current->ColumnWidth + ChildSize + Current->SpacesRequiredBefore; if (Current->Type == TT_CtorInitializerColon) @@ -1249,12 +1261,6 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { } DEBUG({ printDebugInfo(Line); }); - - for (SmallVectorImpl::iterator I = Line.Children.begin(), - E = Line.Children.end(); - I != E; ++I) { - calculateFormattingInformation(**I); - } } void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) { diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index cff851c4f7..3dbada81f0 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -8586,21 +8586,11 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) { } TEST_F(FormatTest, FormatsLambdas) { - verifyFormat("int c = [b]() mutable {\n" - " return [&b] { return b++; }();\n" - "}();\n"); - verifyFormat("int c = [&] {\n" - " [=] { return b++; }();\n" - "}();\n"); - verifyFormat("int c = [&, &a, a] {\n" - " [=, c, &d] { return b++; }();\n" - "}();\n"); - verifyFormat("int c = [&a, &a, a] {\n" - " [=, a, b, &c] { return b++; }();\n" - "}();\n"); - verifyFormat("auto c = {[&a, &a, a] {\n" - " [=, a, b, &c] { return b++; }();\n" - "}}\n"); + verifyFormat("int c = [b]() mutable { return [&b] { return b++; }(); }();\n"); + verifyFormat("int c = [&] { [=] { return b++; }(); }();\n"); + verifyFormat("int c = [&, &a, a] { [=, c, &d] { return b++; }(); }();\n"); + verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n"); + verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] { return b++; }(); }}\n"); verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] {}(); }}\n"); verifyFormat("void f() {\n" " other(x.begin(), x.end(), [&](int, int) { return 1; });\n" @@ -8676,7 +8666,7 @@ TEST_F(FormatTest, FormatsBlocks) { verifyFormat("int a = [operation block:^int(int *i) { return 1; }];"); verifyFormat("[myObject doSomethingWith:arg1\n" " aaa:^int(int *a) { return 1; }\n" - " bbb:f(a * b)];"); + " bbb:f(a * bbbbbbbb)];"); verifyFormat("[operation setCompletionBlock:^{\n" " [self.delegate newDataAvailable];\n" diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 2aac89eac8..33bfe06e5f 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -137,6 +137,13 @@ TEST_F(FormatTestJS, Closures) { " foo();\n" " bar();\n" "}, this);"); + + verifyFormat("var x = {a: function() { return 1; }};", + getGoogleJSStyleWithColumns(38)); + verifyFormat("var x = {\n" + " a: function() { return 1; }\n" + "};", + getGoogleJSStyleWithColumns(37)); } TEST_F(FormatTestJS, ReturnStatements) {