aboutsummaryrefslogtreecommitdiff
path: root/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2013-01-09 15:25:02 +0000
committerManuel Klimek <klimek@google.com>2013-01-09 15:25:02 +0000
commit526ed11ad9743c773df76bd1649d33fb92c2b8cb (patch)
treea2043c193caafb553102c6c1f413db8cdc404a87 /lib/Format/UnwrappedLineParser.cpp
parent35eb8c3e12cac22f91d1cd4c74ae092ebc94fc40 (diff)
Enables layouting unwrapped lines around preprocessor directives.
Previously, we'd always start at indent level 0 after a preprocessor directive, now we layout the following snippet (column limit 69) as follows: functionCallTo(someOtherFunction( withSomeParameters, whichInSequence, areLongerThanALine(andAnotherCall, B withMoreParamters, whichStronglyInfluenceTheLayout), andMoreParameters), trailing); Note that the different jumping indent is a different issue that will be addressed separately. This is the first step towards handling #ifdef->#else->#endif chains correctly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/UnwrappedLineParser.cpp')
-rw-r--r--lib/Format/UnwrappedLineParser.cpp78
1 files changed, 48 insertions, 30 deletions
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 905758993e..99d5f6279d 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -74,8 +74,9 @@ private:
UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
FormatTokenSource &Tokens,
UnwrappedLineConsumer &Callback)
- : RootTokenInitialized(false), Style(Style), Tokens(&Tokens),
- Callback(Callback) {
+ : Line(new UnwrappedLine), RootTokenInitialized(false),
+ LastInCurrentLine(NULL), MustBreakBeforeNextToken(false), Style(Style),
+ Tokens(&Tokens), Callback(Callback) {
}
bool UnwrappedLineParser::parse() {
@@ -126,9 +127,9 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) {
addUnwrappedLine();
- Line.Level += AddLevels;
+ Line->Level += AddLevels;
parseLevel(/*HasOpeningBrace=*/true);
- Line.Level -= AddLevels;
+ Line->Level -= AddLevels;
if (!FormatTok.Tok.is(tok::r_brace))
return true;
@@ -139,7 +140,7 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) {
void UnwrappedLineParser::parsePPDirective() {
assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
- ScopedMacroState MacroState(Line, Tokens, FormatTok);
+ ScopedMacroState MacroState(*Line, Tokens, FormatTok);
nextToken();
if (FormatTok.Tok.getIdentifierInfo() == NULL) {
@@ -169,7 +170,7 @@ void UnwrappedLineParser::parsePPDefine() {
parseParens();
}
addUnwrappedLine();
- Line.Level = 1;
+ Line->Level = 1;
// Errors during a preprocessor directive can only affect the layout of the
// preprocessor directive, and thus we ignore them. An alternative approach
@@ -319,9 +320,9 @@ void UnwrappedLineParser::parseIfThenElse() {
NeedsUnwrappedLine = true;
} else {
addUnwrappedLine();
- ++Line.Level;
+ ++Line->Level;
parseStructuralElement();
- --Line.Level;
+ --Line->Level;
}
if (FormatTok.Tok.is(tok::kw_else)) {
nextToken();
@@ -332,9 +333,9 @@ void UnwrappedLineParser::parseIfThenElse() {
parseIfThenElse();
} else {
addUnwrappedLine();
- ++Line.Level;
+ ++Line->Level;
parseStructuralElement();
- --Line.Level;
+ --Line->Level;
}
} else if (NeedsUnwrappedLine) {
addUnwrappedLine();
@@ -363,9 +364,9 @@ void UnwrappedLineParser::parseForOrWhileLoop() {
addUnwrappedLine();
} else {
addUnwrappedLine();
- ++Line.Level;
+ ++Line->Level;
parseStructuralElement();
- --Line.Level;
+ --Line->Level;
}
}
@@ -376,9 +377,9 @@ void UnwrappedLineParser::parseDoWhile() {
parseBlock();
} else {
addUnwrappedLine();
- ++Line.Level;
+ ++Line->Level;
parseStructuralElement();
- --Line.Level;
+ --Line->Level;
}
// FIXME: Add error handling.
@@ -395,14 +396,14 @@ void UnwrappedLineParser::parseLabel() {
// FIXME: remove all asserts.
assert(FormatTok.Tok.is(tok::colon) && "':' expected");
nextToken();
- unsigned OldLineLevel = Line.Level;
- if (Line.Level > 0)
- --Line.Level;
+ unsigned OldLineLevel = Line->Level;
+ if (Line->Level > 0)
+ --Line->Level;
if (FormatTok.Tok.is(tok::l_brace)) {
parseBlock();
}
addUnwrappedLine();
- Line.Level = OldLineLevel;
+ Line->Level = OldLineLevel;
}
void UnwrappedLineParser::parseCaseLabel() {
@@ -423,9 +424,9 @@ void UnwrappedLineParser::parseSwitch() {
addUnwrappedLine();
} else {
addUnwrappedLine();
- Line.Level += (Style.IndentCaseLabels ? 2 : 1);
+ Line->Level += (Style.IndentCaseLabels ? 2 : 1);
parseStructuralElement();
- Line.Level -= (Style.IndentCaseLabels ? 2 : 1);
+ Line->Level -= (Style.IndentCaseLabels ? 2 : 1);
}
}
@@ -444,7 +445,7 @@ void UnwrappedLineParser::parseEnum() {
case tok::l_brace:
nextToken();
addUnwrappedLine();
- ++Line.Level;
+ ++Line->Level;
parseComments();
break;
case tok::l_paren:
@@ -458,7 +459,7 @@ void UnwrappedLineParser::parseEnum() {
case tok::r_brace:
if (HasContents)
addUnwrappedLine();
- --Line.Level;
+ --Line->Level;
nextToken();
break;
case tok::semi:
@@ -501,8 +502,9 @@ void UnwrappedLineParser::addUnwrappedLine() {
FormatTok.Tok.is(tok::comment)) {
nextToken();
}
- Callback.consumeUnwrappedLine(Line);
+ Callback.consumeUnwrappedLine(*Line);
RootTokenInitialized = false;
+ LastInCurrentLine = NULL;
}
bool UnwrappedLineParser::eof() const {
@@ -513,26 +515,42 @@ void UnwrappedLineParser::nextToken() {
if (eof())
return;
if (RootTokenInitialized) {
+ assert(LastInCurrentLine->Children.empty());
LastInCurrentLine->Children.push_back(FormatTok);
LastInCurrentLine = &LastInCurrentLine->Children.back();
} else {
- Line.RootToken = FormatTok;
+ Line->RootToken = FormatTok;
RootTokenInitialized = true;
- LastInCurrentLine = &Line.RootToken;
+ LastInCurrentLine = &Line->RootToken;
+ }
+ if (MustBreakBeforeNextToken) {
+ LastInCurrentLine->MustBreakBefore = true;
+ MustBreakBeforeNextToken = false;
}
readToken();
}
void UnwrappedLineParser::readToken() {
FormatTok = Tokens->getNextToken();
- while (!Line.InPPDirective && FormatTok.Tok.is(tok::hash) &&
+ while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
FormatTok.IsFirst)) {
- // FIXME: This is incorrect - the correct way is to create a
- // data structure that will construct the parts around the preprocessor
- // directive as a structured \c UnwrappedLine.
- addUnwrappedLine();
+ UnwrappedLine* StoredLine = Line.take();
+ Line.reset(new UnwrappedLine(*StoredLine));
+ assert(LastInCurrentLine == NULL || LastInCurrentLine->Children.empty());
+ FormatToken *StoredLastInCurrentLine = LastInCurrentLine;
+ bool PreviousInitialized = RootTokenInitialized;
+ RootTokenInitialized = false;
+ LastInCurrentLine = NULL;
+
parsePPDirective();
+
+ assert(!RootTokenInitialized);
+ Line.reset(StoredLine);
+ RootTokenInitialized = PreviousInitialized;
+ LastInCurrentLine = StoredLastInCurrentLine;
+ assert(LastInCurrentLine == NULL || LastInCurrentLine->Children.empty());
+ MustBreakBeforeNextToken = true;
}
}