r236722 - Implements a way to retrieve information about whether some lines were not formatted due to syntax errors.
Manuel Klimek
klimek at google.com
Thu May 7 05:26:31 PDT 2015
Author: klimek
Date: Thu May 7 07:26:30 2015
New Revision: 236722
URL: http://llvm.org/viewvc/llvm-project?rev=236722&view=rev
Log:
Implements a way to retrieve information about whether some lines were not formatted due to syntax errors.
Modified:
cfe/trunk/include/clang/Format/Format.h
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
cfe/trunk/lib/Format/UnwrappedLineFormatter.h
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/include/clang/Format/Format.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=236722&r1=236721&r2=236722&view=diff
==============================================================================
--- cfe/trunk/include/clang/Format/Format.h (original)
+++ cfe/trunk/include/clang/Format/Format.h Thu May 7 07:26:30 2015
@@ -546,16 +546,22 @@ std::string configurationAsText(const Fo
///
/// Returns the \c Replacements necessary to make all \p Ranges comply with
/// \p Style.
+///
+/// If \c IncompleteFormat is non-null, its value will be set to true if any
+/// of the affected ranges were not formatted due to a non-recoverable syntax
+/// error.
tooling::Replacements reformat(const FormatStyle &Style,
SourceManager &SourceMgr, FileID ID,
- ArrayRef<CharSourceRange> Ranges);
+ ArrayRef<CharSourceRange> Ranges,
+ bool *IncompleteFormat = nullptr);
/// \brief Reformats the given \p Ranges in \p Code.
///
-/// Otherwise identical to the reformat() function consuming a \c Lexer.
+/// Otherwise identical to the reformat() function using a file ID.
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
- StringRef FileName = "<stdin>");
+ StringRef FileName = "<stdin>",
+ bool *IncompleteFormat = nullptr);
/// \brief Returns the \c LangOpts that the formatter expects you to set.
///
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=236722&r1=236721&r2=236722&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Thu May 7 07:26:30 2015
@@ -1219,7 +1219,7 @@ public:
<< "\n");
}
- tooling::Replacements format() {
+ tooling::Replacements format(bool *IncompleteFormat) {
tooling::Replacements Result;
FormatTokenLexer Tokens(SourceMgr, ID, Style, Encoding);
@@ -1234,7 +1234,8 @@ public:
for (unsigned i = 0, e = UnwrappedLines[Run].size(); i != e; ++i) {
AnnotatedLines.push_back(new AnnotatedLine(UnwrappedLines[Run][i]));
}
- tooling::Replacements RunResult = format(AnnotatedLines, Tokens);
+ tooling::Replacements RunResult =
+ format(AnnotatedLines, Tokens, IncompleteFormat);
DEBUG({
llvm::dbgs() << "Replacements for run " << Run << ":\n";
for (tooling::Replacements::iterator I = RunResult.begin(),
@@ -1253,7 +1254,7 @@ public:
}
tooling::Replacements format(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
- FormatTokenLexer &Tokens) {
+ FormatTokenLexer &Tokens, bool *IncompleteFormat) {
TokenAnnotator Annotator(Style, Tokens.getKeywords());
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
Annotator.annotate(*AnnotatedLines[i]);
@@ -1269,7 +1270,7 @@ public:
Whitespaces, Encoding,
BinPackInconclusiveFunctions);
UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style,
- Tokens.getKeywords());
+ Tokens.getKeywords(), IncompleteFormat);
Formatter.format(AnnotatedLines, /*DryRun=*/false);
return Whitespaces.generateReplacements();
}
@@ -1489,16 +1490,18 @@ private:
tooling::Replacements reformat(const FormatStyle &Style,
SourceManager &SourceMgr, FileID ID,
- ArrayRef<CharSourceRange> Ranges) {
+ ArrayRef<CharSourceRange> Ranges,
+ bool *IncompleteFormat) {
if (Style.DisableFormat)
return tooling::Replacements();
Formatter formatter(Style, SourceMgr, ID, Ranges);
- return formatter.format();
+ return formatter.format(IncompleteFormat);
}
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
- StringRef FileName) {
+ StringRef FileName,
+ bool *IncompleteFormat) {
if (Style.DisableFormat)
return tooling::Replacements();
@@ -1521,7 +1524,7 @@ tooling::Replacements reformat(const For
SourceLocation End = Start.getLocWithOffset(Range.getLength());
CharRanges.push_back(CharSourceRange::getCharRange(Start, End));
}
- return reformat(Style, SourceMgr, ID, CharRanges);
+ return reformat(Style, SourceMgr, ID, CharRanges, IncompleteFormat);
}
LangOptions getFormattingLangOpts(const FormatStyle &Style) {
Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=236722&r1=236721&r2=236722&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Thu May 7 07:26:30 2015
@@ -403,6 +403,7 @@ UnwrappedLineFormatter::format(const Sma
bool FixIndentation =
FixBadIndentation && (LevelIndent != FirstTok->OriginalColumn);
+ bool ShouldFormat = TheLine.Affected || FixIndentation;
if (TheLine.First->is(tok::eof)) {
if (PreviousLine && PreviousLine->Affected && !DryRun) {
// Remove the file's trailing whitespace.
@@ -411,8 +412,7 @@ UnwrappedLineFormatter::format(const Sma
/*IndentLevel=*/0, /*Spaces=*/0,
/*TargetColumn=*/0);
}
- } else if (TheLine.Type != LT_Invalid &&
- (TheLine.Affected || FixIndentation)) {
+ } else if (TheLine.Type != LT_Invalid && ShouldFormat) {
if (FirstTok->WhitespaceRange.isValid()) {
if (!DryRun)
formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, Indent,
@@ -476,6 +476,8 @@ UnwrappedLineFormatter::format(const Sma
}
}
}
+ if (TheLine.Type == LT_Invalid && ShouldFormat && IncompleteFormat)
+ *IncompleteFormat = true;
if (!DryRun)
markFinalized(TheLine.First);
PreviousLine = *I;
Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.h?rev=236722&r1=236721&r2=236722&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.h (original)
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.h Thu May 7 07:26:30 2015
@@ -33,9 +33,10 @@ public:
UnwrappedLineFormatter(ContinuationIndenter *Indenter,
WhitespaceManager *Whitespaces,
const FormatStyle &Style,
- const AdditionalKeywords &Keywords)
+ const AdditionalKeywords &Keywords,
+ bool *IncompleteFormat)
: Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),
- Keywords(Keywords) {}
+ Keywords(Keywords), IncompleteFormat(IncompleteFormat) {}
unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
int AdditionalIndent = 0, bool FixBadIndentation = false);
@@ -169,6 +170,8 @@ private:
// are many nested blocks.
std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>,
unsigned> PenaltyCache;
+
+ bool *IncompleteFormat;
};
} // end namespace format
} // end namespace clang
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=236722&r1=236721&r2=236722&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu May 7 07:26:30 2015
@@ -21,12 +21,25 @@ FormatStyle getGoogleStyle() { return ge
class FormatTest : public ::testing::Test {
protected:
+ enum IncompleteCheck {
+ IC_ExpectComplete,
+ IC_ExpectIncomplete,
+ IC_DoNotCheck
+ };
+
std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length,
- const FormatStyle &Style) {
+ const FormatStyle &Style,
+ IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
DEBUG(llvm::errs() << "---\n");
DEBUG(llvm::errs() << Code << "\n\n");
std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
- tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+ bool IncompleteFormat = false;
+ tooling::Replacements Replaces =
+ reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
+ if (CheckIncomplete != IC_DoNotCheck) {
+ bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete;
+ EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
+ }
ReplacementCount = Replaces.size();
std::string Result = applyAllReplacements(Code, Replaces);
EXPECT_NE("", Result);
@@ -35,8 +48,9 @@ protected:
}
std::string format(llvm::StringRef Code,
- const FormatStyle &Style = getLLVMStyle()) {
- return format(Code, 0, Code.size(), Style);
+ const FormatStyle &Style = getLLVMStyle(),
+ IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
+ return format(Code, 0, Code.size(), Style, CheckIncomplete);
}
FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
@@ -56,6 +70,12 @@ protected:
EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
}
+ void verifyIncompleteFormat(llvm::StringRef Code,
+ const FormatStyle &Style = getLLVMStyle()) {
+ EXPECT_EQ(Code.str(),
+ format(test::messUp(Code), Style, IC_ExpectIncomplete));
+ }
+
void verifyGoogleFormat(llvm::StringRef Code) {
verifyFormat(Code, getGoogleStyle());
}
@@ -68,7 +88,7 @@ protected:
/// \brief Verify that clang-format does not crash on the given input.
void verifyNoCrash(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle()) {
- format(Code, Style);
+ format(Code, Style, IC_DoNotCheck);
}
int ReplacementCount;
@@ -2324,7 +2344,7 @@ TEST_F(FormatTest, FormatTryCatch) {
"};\n");
// Incomplete try-catch blocks.
- verifyFormat("try {} catch (");
+ verifyIncompleteFormat("try {} catch (");
}
TEST_F(FormatTest, FormatSEHTryCatch) {
@@ -2727,23 +2747,23 @@ TEST_F(FormatTest, EmptyLinesInMacroDefi
}
TEST_F(FormatTest, MacroDefinitionsWithIncompleteCode) {
- verifyFormat("#define A :");
+ verifyIncompleteFormat("#define A :");
verifyFormat("#define SOMECASES \\\n"
" case 1: \\\n"
" case 2\n",
getLLVMStyleWithColumns(20));
verifyFormat("#define A template <typename T>");
- verifyFormat("#define STR(x) #x\n"
- "f(STR(this_is_a_string_literal{));");
+ verifyIncompleteFormat("#define STR(x) #x\n"
+ "f(STR(this_is_a_string_literal{));");
verifyFormat("#pragma omp threadprivate( \\\n"
" y)), // expected-warning",
getLLVMStyleWithColumns(28));
verifyFormat("#d, = };");
verifyFormat("#if \"a");
- verifyFormat("({\n"
- "#define b }\\\n"
- " a\n"
- "a");
+ verifyIncompleteFormat("({\n"
+ "#define b }\\\n"
+ " a\n"
+ "a");
verifyFormat("#define A \\\n"
" { \\\n"
" {\n"
@@ -2751,7 +2771,6 @@ TEST_F(FormatTest, MacroDefinitionsWithI
" } \\\n"
" }",
getLLVMStyleWithColumns(15));
-
verifyNoCrash("#if a\na(\n#else\n#endif\n{a");
verifyNoCrash("a={0,1\n#if a\n#else\n;\n#endif\n}");
verifyNoCrash("#if a\na(\n#else\n#endif\n) a {a,b,c,d,f,g};");
@@ -3076,11 +3095,11 @@ TEST_F(FormatTest, LayoutStatementsAroun
"#else\n"
"#endif");
- verifyFormat("void f(\n"
- "#if A\n"
- " );\n"
- "#else\n"
- "#endif");
+ verifyIncompleteFormat("void f(\n"
+ "#if A\n"
+ " );\n"
+ "#else\n"
+ "#endif");
}
TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) {
@@ -6010,16 +6029,16 @@ TEST_F(FormatTest, IncorrectCodeDoNoWhil
TEST_F(FormatTest, IncorrectCodeMissingParens) {
verifyFormat("if {\n foo;\n foo();\n}");
verifyFormat("switch {\n foo;\n foo();\n}");
- verifyFormat("for {\n foo;\n foo();\n}");
+ verifyIncompleteFormat("for {\n foo;\n foo();\n}");
verifyFormat("while {\n foo;\n foo();\n}");
verifyFormat("do {\n foo;\n foo();\n} while;");
}
TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) {
- verifyFormat("namespace {\n"
- "class Foo { Foo (\n"
- "};\n"
- "} // comment");
+ verifyIncompleteFormat("namespace {\n"
+ "class Foo { Foo (\n"
+ "};\n"
+ "} // comment");
}
TEST_F(FormatTest, IncorrectCodeErrorDetection) {
@@ -7302,8 +7321,8 @@ TEST_F(FormatTest, ObjCDictLiterals) {
"}");
verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
- verifyFormat("[self setDict:@{}");
- verifyFormat("[self setDict:@{@1 : @2}");
+ verifyIncompleteFormat("[self setDict:@{}");
+ verifyIncompleteFormat("[self setDict:@{@1 : @2}");
verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
verifyFormat(
"NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
@@ -7346,7 +7365,7 @@ TEST_F(FormatTest, ObjCDictLiterals) {
}
TEST_F(FormatTest, ObjCArrayLiterals) {
- verifyFormat("@[");
+ verifyIncompleteFormat("@[");
verifyFormat("@[]");
verifyFormat(
"NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
More information about the cfe-commits
mailing list