Author: mprobst Date: Fri Nov 17 10:06:33 2017 New Revision: 318537 URL: http://llvm.org/viewvc/llvm-project?rev=318537&view=rev Log: clang-format: remove trailing lines in lamdas and arrow functions.
Summary: clang-format already removes empty lines at the beginning & end of blocks: int x() { foo(); // lines before and after will be removed. } However because lamdas and arrow functions are parsed as expressions, the existing logic to remove empty lines in UnwrappedLineFormatter doesn't handle them. This change special cases arrow functions in ContinuationIndenter to remove empty lines: x = []() { foo(); // lines before and after will now be removed. }; Reviewers: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D40178 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/unittests/Format/FormatTest.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=318537&r1=318536&r2=318537&view=diff ============================================================================== --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Fri Nov 17 10:06:33 2017 @@ -701,8 +701,18 @@ unsigned ContinuationIndenter::addTokenO 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, Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=318537&r1=318536&r2=318537&view=diff ============================================================================== --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Fri Nov 17 10:06:33 2017 @@ -1117,6 +1117,9 @@ void UnwrappedLineFormatter::formatFirst (!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) Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=318537&r1=318536&r2=318537&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Nov 17 10:06:33 2017 @@ -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; Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=318537&r1=318536&r2=318537&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTestJS.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestJS.cpp Fri Nov 17 10:06:33 2017 @@ -1606,6 +1606,17 @@ TEST_F(FormatTestJS, TypeInterfaceLineWr 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';"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits