diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Format/ContinuationIndenter.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineFormatter.cpp | 3 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 22 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTestJS.cpp | 11 |
4 files changed, 44 insertions, 4 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 3fed32f6f4c..44e6ad4232e 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -701,8 +701,18 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, State.Stack.back().BreakBeforeParameter = false; if (!DryRun) { + unsigned MaxEmptyLinesToKeep = Style.MaxEmptyLinesToKeep + 1; + if (Current.is(tok::r_brace) && Current.MatchingParen && + // Only strip trailing empty lines for l_braces that have children, i.e. + // for function expressions (lambdas, arrows, etc). + !Current.MatchingParen->Children.empty()) { + // lambdas and arrow functions are expressions, thus their r_brace is not + // on its own line, and thus not covered by UnwrappedLineFormatter's logic + // about removing empty lines on closing blocks. Special case them here. + MaxEmptyLinesToKeep = 1; + } unsigned Newlines = std::max( - 1u, std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1)); + 1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep)); bool ContinuePPDirective = State.Line->InPPDirective && State.Line->Type != LT_ImportStatement; Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column, diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index a82cd5abe27..2e9d803a191 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -1117,6 +1117,9 @@ void UnwrappedLineFormatter::formatFirstToken(const AnnotatedLine &Line, (!RootToken.Next || (RootToken.Next->is(tok::semi) && !RootToken.Next->Next))) Newlines = std::min(Newlines, 1u); + // Remove empty lines at the start of nested blocks (lambdas/arrow functions) + if (PreviousLine == nullptr && Line.Level > 0) + Newlines = std::min(Newlines, 1u); if (Newlines == 0 && !RootToken.IsFirst) Newlines = 1; if (RootToken.IsFirst && !RootToken.HasUnescapedNewline) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 7fbf01dc129..acff8d32320 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -70,18 +70,23 @@ protected: return getStyleWithColumns(getGoogleStyle(), ColumnLimit); } - void verifyFormat(llvm::StringRef Code, + void verifyFormat(llvm::StringRef Expected, llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { - EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); + 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. FormatStyle ObjCStyle = Style; ObjCStyle.Language = FormatStyle::LK_ObjC; - EXPECT_EQ(Code.str(), format(test::messUp(Code), ObjCStyle)); + EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle)); } } + void verifyFormat(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle()) { + verifyFormat(Code, test::messUp(Code), Style); + } + void verifyIncompleteFormat(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { EXPECT_EQ(Code.str(), @@ -11089,6 +11094,17 @@ TEST_F(FormatTest, FormatsLambdas) { " });"); } +TEST_F(FormatTest, EmptyLinesInLambdas) { + verifyFormat("auto lambda = []() {\n" + " x(); //\n" + "};", + "auto lambda = []() {\n" + "\n" + " x(); //\n" + "\n" + "};"); +} + TEST_F(FormatTest, FormatsBlocks) { FormatStyle ShortBlocks = getLLVMStyle(); ShortBlocks.AllowShortBlocksOnASingleLine = true; diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 3df01663e9d..3e5abdc098a 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -1606,6 +1606,17 @@ TEST_F(FormatTestJS, TypeInterfaceLineWrapping) { Style); } +TEST_F(FormatTestJS, RemoveEmptyLinesInArrowFunctions) { + verifyFormat("x = () => {\n" + " foo();\n" + "};\n", + "x = () => {\n" + "\n" + " foo();\n" + "\n" + "};\n"); +} + TEST_F(FormatTestJS, Modules) { verifyFormat("import SomeThing from 'some/module.js';"); verifyFormat("import {X, Y} from 'some/module.js';"); |