[cfe-commits] r169286 - in /cfe/trunk: lib/Format/Format.cpp lib/Format/UnwrappedLineParser.cpp lib/Format/UnwrappedLineParser.h unittests/Format/FormatTest.cpp
Alexander Kornienko
alexfh at google.com
Tue Dec 4 09:27:51 PST 2012
Author: alexfh
Date: Tue Dec 4 11:27:50 2012
New Revision: 169286
URL: http://llvm.org/viewvc/llvm-project?rev=169286&view=rev
Log:
Error recovery part 2
Summary: Adds recovery for structural errors in clang-format.
Reviewers: djasper
Reviewed By: djasper
CC: cfe-commits, silvas
Differential Revision: http://llvm-reviews.chandlerc.com/D164
Modified:
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/UnwrappedLineParser.cpp
cfe/trunk/lib/Format/UnwrappedLineParser.h
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=169286&r1=169285&r2=169286&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Tue Dec 4 11:27:50 2012
@@ -72,28 +72,29 @@
UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,
const UnwrappedLine &Line,
const std::vector<TokenAnnotation> &Annotations,
- tooling::Replacements &Replaces)
+ tooling::Replacements &Replaces, bool StructuralError)
: Style(Style),
SourceMgr(SourceMgr),
Line(Line),
Annotations(Annotations),
- Replaces(Replaces) {
+ Replaces(Replaces),
+ StructuralError(StructuralError) {
Parameters.PenaltyExtraLine = 100;
Parameters.PenaltyIndentLevel = 5;
}
void format() {
- formatFirstToken();
+ unsigned Indent = formatFirstToken();
count = 0;
IndentState State;
- State.Column = Line.Level * 2 + Line.Tokens[0].Tok.getLength();
+ State.Column = Indent + Line.Tokens[0].Tok.getLength();
State.CtorInitializerOnNewLine = false;
State.InCtorInitializer = false;
State.ConsumedTokens = 1;
//State.UsedIndent.push_back(Line.Level * 2);
- State.Indent.push_back(Line.Level * 2 + 4);
- State.LastSpace.push_back(Line.Level * 2);
+ State.Indent.push_back(Indent + 4);
+ State.LastSpace.push_back(Indent);
// Start iterating at 1 as we have correctly formatted of Token #0 above.
for (unsigned i = 1, n = Line.Tokens.size(); i != n; ++i) {
@@ -315,20 +316,22 @@
/// \brief Add a new line and the required indent before the first Token
/// of the \c UnwrappedLine.
- void formatFirstToken() {
+ unsigned formatFirstToken() {
const FormatToken &Token = Line.Tokens[0];
- if (Token.WhiteSpaceStart.isValid()) {
- unsigned Newlines =
- std::min(Token.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
- unsigned Offset = SourceMgr.getFileOffset(Token.WhiteSpaceStart);
- if (Newlines == 0 && Offset != 0)
- Newlines = 1;
- unsigned Indent = Line.Level * 2;
- if (Token.Tok.is(tok::kw_public) || Token.Tok.is(tok::kw_protected) ||
- Token.Tok.is(tok::kw_private))
- Indent += Style.AccessModifierOffset;
- replaceWhitespace(Token, Newlines, Indent);
- }
+ if (!Token.WhiteSpaceStart.isValid() || StructuralError)
+ return SourceMgr.getSpellingColumnNumber(Token.Tok.getLocation()) - 1;
+
+ unsigned Newlines =
+ std::min(Token.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
+ unsigned Offset = SourceMgr.getFileOffset(Token.WhiteSpaceStart);
+ if (Newlines == 0 && Offset != 0)
+ Newlines = 1;
+ unsigned Indent = Line.Level * 2;
+ if (Token.Tok.is(tok::kw_public) || Token.Tok.is(tok::kw_protected) ||
+ Token.Tok.is(tok::kw_private))
+ Indent += Style.AccessModifierOffset;
+ replaceWhitespace(Token, Newlines, Indent);
+ return Indent;
}
FormatStyle Style;
@@ -337,6 +340,7 @@
const std::vector<TokenAnnotation> &Annotations;
tooling::Replacements &Replaces;
unsigned int count;
+ bool StructuralError;
OptimizationParameters Parameters;
};
@@ -678,17 +682,26 @@
: Style(Style),
Lex(Lex),
SourceMgr(SourceMgr),
- Ranges(Ranges) {
+ Ranges(Ranges),
+ StructuralError(false) {
}
tooling::Replacements format() {
UnwrappedLineParser Parser(Lex, SourceMgr, *this);
- Parser.parse();
+ StructuralError = Parser.parse();
+ for (std::vector<UnwrappedLine>::iterator I = UnwrappedLines.begin(),
+ E = UnwrappedLines.end();
+ I != E; ++I)
+ doFormatUnwrappedLine(*I);
return Replaces;
}
private:
virtual void formatUnwrappedLine(const UnwrappedLine &TheLine) {
+ UnwrappedLines.push_back(TheLine);
+ }
+
+ void doFormatUnwrappedLine(const UnwrappedLine &TheLine) {
if (TheLine.Tokens.size() == 0)
return;
@@ -706,7 +719,8 @@
TokenAnnotator Annotator(TheLine, Style, SourceMgr);
Annotator.annotate();
UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine,
- Annotator.getAnnotations(), Replaces);
+ Annotator.getAnnotations(), Replaces,
+ StructuralError);
Formatter.format();
return;
}
@@ -717,6 +731,8 @@
SourceManager &SourceMgr;
tooling::Replacements Replaces;
std::vector<CharSourceRange> Ranges;
+ std::vector<UnwrappedLine> UnwrappedLines;
+ bool StructuralError;
};
tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=169286&r1=169285&r2=169286&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Tue Dec 4 11:27:50 2012
@@ -32,12 +32,13 @@
Lex.SetKeepWhitespaceMode(true);
}
-void UnwrappedLineParser::parse() {
+bool UnwrappedLineParser::parse() {
parseToken();
- parseLevel();
+ return parseLevel();
}
-void UnwrappedLineParser::parseLevel() {
+bool UnwrappedLineParser::parseLevel() {
+ bool Error = false;
do {
switch (FormatTok.Tok.getKind()) {
case tok::hash:
@@ -47,19 +48,20 @@
parseComment();
break;
case tok::l_brace:
- parseBlock();
+ Error |= parseBlock();
addUnwrappedLine();
break;
case tok::r_brace:
- return;
+ return false;
default:
parseStatement();
break;
}
} while (!eof());
+ return Error;
}
-void UnwrappedLineParser::parseBlock() {
+bool UnwrappedLineParser::parseBlock() {
nextToken();
// FIXME: Remove this hack to handle namespaces.
@@ -74,11 +76,12 @@
--Line.Level;
// FIXME: Add error handling.
if (!FormatTok.Tok.is(tok::r_brace))
- return;
+ return true;
nextToken();
if (FormatTok.Tok.is(tok::semi))
nextToken();
+ return false;
}
void UnwrappedLineParser::parsePPDirective() {
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=169286&r1=169285&r2=169286&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.h (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.h Tue Dec 4 11:27:50 2012
@@ -79,11 +79,12 @@
UnwrappedLineParser(Lexer &Lex, SourceManager &SourceMgr,
UnwrappedLineConsumer &Callback);
- void parse();
+ /// Returns true in case of a structural error.
+ bool parse();
private:
- void parseLevel();
- void parseBlock();
+ bool parseLevel();
+ bool parseBlock();
void parsePPDirective();
void parseComment();
void parseStatement();
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=169286&r1=169285&r2=169286&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Dec 4 11:27:50 2012
@@ -381,5 +381,23 @@
"};");
}
+TEST_F(FormatTest, IncorrectCodeErrorDetection) {
+ EXPECT_EQ("{\n{\n}\n", format("{\n{\n}\n"));
+ EXPECT_EQ("{\n {\n}\n", format("{\n {\n}\n"));
+ EXPECT_EQ("{\n {\n }\n", format("{\n {\n }\n"));
+
+ FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = 10;
+ EXPECT_EQ("{\n"
+ " {\n"
+ " breakme(\n"
+ " qwe);\n"
+ "}\n", format("{\n"
+ " {\n"
+ " breakme(qwe);\n"
+ "}\n", Style));
+
+}
+
} // end namespace tooling
} // end namespace clang
More information about the cfe-commits
mailing list