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,
(!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)
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(),
" });");
}
+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;
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';");