From 1027c6e5dd660dada16ee589cbd321c95b1602ac Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Mon, 3 Jun 2013 16:16:41 +0000 Subject: [PATCH] Let clang-format remove empty lines before "}". These lines almost never aid readability. Before: void f() { int i; // some variable } After: void f() { int i; // some variable } llvm-svn: 183112 --- clang/lib/Format/Format.cpp | 5 +++ clang/lib/Format/TokenAnnotator.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 47 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index aa42bdb643a2..63bf09317e3c 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1592,6 +1592,11 @@ private: bool InPPDirective) { unsigned Newlines = std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); + // Remove empty lines before "}" where applicable. + if (RootToken.is(tok::r_brace) && + (!RootToken.Next || + (RootToken.Next->is(tok::semi) && !RootToken.Next->Next))) + Newlines = std::min(Newlines, 1u); if (Newlines == 0 && !RootToken.IsFirst) Newlines = 1; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 61f43a020100..83dea841b5ec 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -54,7 +54,7 @@ private: tok::question, tok::colon)) return false; // If a && or || is found and interpreted as a binary operator, this set - // of angles is like part of something like "a < b && c > d". If the + // of angles is likely part of something like "a < b && c > d". If the // angles are inside an expression, the ||/&& might also be a binary // operator that was misinterpreted because we are parsing template // parameters. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 2dea38f79081..80072b5ab57c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -192,6 +192,53 @@ TEST_F(FormatTest, RemovesWhitespaceWhenTriggeredOnEmptyLine) { format("int a;\n \n\n int b;", 9, 0, getLLVMStyle())); } +TEST_F(FormatTest, RemovesEmptyLines) { + EXPECT_EQ("class C {\n" + " int i;\n" + "};", + format("class C {\n" + " int i;\n" + "\n" + "};")); + + // Don't remove empty lines in more complex control statements. + EXPECT_EQ("void f() {\n" + " if (a) {\n" + " f();\n" + "\n" + " } else if (b) {\n" + " f();\n" + " }\n" + "}", + format("void f() {\n" + " if (a) {\n" + " f();\n" + "\n" + " } else if (b) {\n" + " f();\n" + "\n" + " }\n" + "\n" + "}")); + + // FIXME: This is slightly inconsistent. + EXPECT_EQ("namespace {\n" + "int i;\n" + "}", + format("namespace {\n" + "int i;\n" + "\n" + "}")); + EXPECT_EQ("namespace {\n" + "int i;\n" + "\n" + "} // namespace", + format("namespace {\n" + "int i;\n" + "\n" + "} // namespace")); +} + TEST_F(FormatTest, ReformatsMovedLines) { EXPECT_EQ( "template T *getFETokenInfo() const {\n"