Kaynağa Gözat

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
}

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183112 91177308-0d34-0410-b5e6-96231b3b80d8
Daniel Jasper 12 yıl önce
ebeveyn
işleme
15f33f03e7

+ 5 - 0
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;
 

+ 1 - 1
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.

+ 47 - 0
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 <typename T> T *getFETokenInfo() const {\n"