]> granicus.if.org Git - clang/commitdiff
clang-format: Be slightly more cautious when formatting subsequent lines after a...
authorDaniel Jasper <djasper@google.com>
Sun, 1 Nov 2015 00:27:35 +0000 (00:27 +0000)
committerDaniel Jasper <djasper@google.com>
Sun, 1 Nov 2015 00:27:35 +0000 (00:27 +0000)
Summary:
With this change, clang-format stops formatting when either it leaves
the current scope or when it comes back to the initial scope after
going into a nested one.

Reviewers: klimek

Subscribers: cfe-commits, klimek

Differential Revision: http://reviews.llvm.org/D14213

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@251760 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/UnwrappedLineFormatter.cpp
unittests/Format/FormatTestSelective.cpp

index fcf45c9286f9a9c2b4dce96ea069a8474e5939d1..5b4f5d5b09c331a559a67d0ac35636c7716ffa08 100644 (file)
@@ -812,13 +812,28 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines,
                                    AdditionalIndent);
   const AnnotatedLine *PreviousLine = nullptr;
   const AnnotatedLine *NextLine = nullptr;
-  bool PreviousLineFormatted = false;
+
+  // The minimum level of consecutive lines that have been formatted.
+  unsigned RangeMinLevel = UINT_MAX;
+  // The level of the previous line.
+  unsigned PreviousLineLevel = Lines.front()->Level;
+
   for (const AnnotatedLine *Line =
            Joiner.getNextMergedLine(DryRun, IndentTracker);
        Line; Line = NextLine) {
     const AnnotatedLine &TheLine = *Line;
     unsigned Indent = IndentTracker.getIndent();
-    bool FixIndentation = (FixBadIndentation || PreviousLineFormatted) &&
+
+    // We continue formatting unchanged lines to adjust their indent, e.g. if a
+    // scope was added. However, we need to carefully stop doing this when we
+    // exit the scope of affected lines to prevent indenting a the entire
+    // remaining file if it currently missing a closing brace.
+    bool ContinueFormatting =
+        TheLine.Level > RangeMinLevel ||
+        (TheLine.Level == RangeMinLevel && PreviousLineLevel <= TheLine.Level);
+    PreviousLineLevel = TheLine.Level;
+
+    bool FixIndentation = (FixBadIndentation || ContinueFormatting) &&
                           Indent != TheLine.First->OriginalColumn;
     bool ShouldFormat = TheLine.Affected || FixIndentation;
     // We cannot format this line; if the reason is that the line had a
@@ -846,7 +861,7 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines,
       else
         Penalty += OptimizingLineFormatter(Indenter, Whitespaces, Style, this)
                        .formatLine(TheLine, Indent, DryRun);
-      PreviousLineFormatted = true;
+      RangeMinLevel = std::min(RangeMinLevel, TheLine.Level);
     } else {
       // If no token in the current line is affected, we still need to format
       // affected children.
@@ -877,7 +892,7 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines,
           Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
       }
       NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
-      PreviousLineFormatted = false;
+      RangeMinLevel = UINT_MAX;
     }
     if (!DryRun)
       markFinalized(TheLine.First);
index a28dfd32e1ca72c654b64bab7d32c11a5928de8b..9c4d1c3d2b011ad50a7026b9442afe5ad3b0700f 100644 (file)
@@ -446,6 +446,27 @@ TEST_F(FormatTestSelective, UnderstandsTabs) {
                    21, 0));
 }
 
+TEST_F(FormatTestSelective, StopFormattingWhenLeavingScope) {
+  EXPECT_EQ(
+      "void f() {\n"
+      "  if (a) {\n"
+      "    g();\n"
+      "    h();\n"
+      "}\n"
+      "\n"
+      "void g() {\n"
+      "}",
+      format("void f() {\n"
+             "  if (a) {\n" // Assume this was added without the closing brace.
+             "  g();\n"
+             "  h();\n"
+             "}\n"
+             "\n"
+             "void g() {\n" // Make sure not to format this.
+             "}",
+             15, 0));
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang