r251760 - clang-format: Be slightly more cautious when formatting subsequent lines after a change. With r251474, clang-format could indent the entire rest of the file, if there is a missing closing brace, e.g. while writing code in an editor.
Daniel Jasper via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 31 17:27:36 PDT 2015
Author: djasper
Date: Sat Oct 31 19:27:35 2015
New Revision: 251760
URL: http://llvm.org/viewvc/llvm-project?rev=251760&view=rev
Log:
clang-format: Be slightly more cautious when formatting subsequent lines after a change. With r251474, clang-format could indent the entire rest of the file, if there is a missing closing brace, e.g. while writing code in an editor.
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
Modified:
cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
cfe/trunk/unittests/Format/FormatTestSelective.cpp
Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=251760&r1=251759&r2=251760&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Sat Oct 31 19:27:35 2015
@@ -812,13 +812,28 @@ UnwrappedLineFormatter::format(const Sma
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 Sma
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 Sma
Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
}
NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
- PreviousLineFormatted = false;
+ RangeMinLevel = UINT_MAX;
}
if (!DryRun)
markFinalized(TheLine.First);
Modified: cfe/trunk/unittests/Format/FormatTestSelective.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestSelective.cpp?rev=251760&r1=251759&r2=251760&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestSelective.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestSelective.cpp Sat Oct 31 19:27:35 2015
@@ -446,6 +446,27 @@ TEST_F(FormatTestSelective, UnderstandsT
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
More information about the cfe-commits
mailing list