summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Probst <martin@probst.io>2017-11-17 18:06:33 +0000
committerMartin Probst <martin@probst.io>2017-11-17 18:06:33 +0000
commita004b3f50f3e8fd097f481f531439e783d8b54d6 (patch)
tree937fe6299739105ee23e80cf157a5ddfd4e83e47
parentf836537516801d2f3f9c103182348c95d4f98d3b (diff)
downloadbcm5719-llvm-a004b3f50f3e8fd097f481f531439e783d8b54d6.tar.gz
bcm5719-llvm-a004b3f50f3e8fd097f481f531439e783d8b54d6.zip
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 llvm-svn: 318537
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp12
-rw-r--r--clang/lib/Format/UnwrappedLineFormatter.cpp3
-rw-r--r--clang/unittests/Format/FormatTest.cpp22
-rw-r--r--clang/unittests/Format/FormatTestJS.cpp11
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';");
OpenPOWER on IntegriCloud