зеркало из https://github.com/microsoft/clang-1.git
Added AnnotatedToken::isOneOf + a few other refactorings
Summary: <subj> Reviewers: djasper Reviewed By: djasper CC: cfe-commits, klimek Differential Revision: http://llvm-reviews.chandlerc.com/D536 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176951 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
bb3699543e
Коммит
e74de28ec3
|
@ -499,9 +499,8 @@ private:
|
|||
State.Stack.back().FirstLessLess != 0) {
|
||||
State.Column = State.Stack.back().FirstLessLess;
|
||||
} else if (State.ParenLevel != 0 &&
|
||||
(Previous.is(tok::equal) || Previous.is(tok::coloncolon) ||
|
||||
Current.is(tok::period) || Current.is(tok::arrow) ||
|
||||
Current.is(tok::question))) {
|
||||
(Previous.isOneOf(tok::equal, tok::coloncolon) ||
|
||||
Current.isOneOf(tok::period, tok::arrow, tok::question))) {
|
||||
// Indent and extra 4 spaces after if we know the current expression is
|
||||
// continued. Don't do that on the top level, as we already indent 4
|
||||
// there.
|
||||
|
@ -534,7 +533,7 @@ private:
|
|||
|
||||
if (Current.is(tok::question))
|
||||
State.Stack.back().BreakBeforeParameter = true;
|
||||
if ((Previous.is(tok::comma) || Previous.is(tok::semi)) &&
|
||||
if (Previous.isOneOf(tok::comma, tok::semi) &&
|
||||
!State.Stack.back().AvoidBinPacking)
|
||||
State.Stack.back().BreakBeforeParameter = false;
|
||||
|
||||
|
@ -562,7 +561,7 @@ private:
|
|||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
|
||||
State.Stack[i].BreakBeforeParameter = true;
|
||||
}
|
||||
if (Current.is(tok::period) || Current.is(tok::arrow))
|
||||
if (Current.isOneOf(tok::period, tok::arrow))
|
||||
State.Stack.back().BreakBeforeParameter = true;
|
||||
|
||||
// If we break after {, we should also break before the corresponding }.
|
||||
|
@ -600,7 +599,7 @@ private:
|
|||
}
|
||||
|
||||
if (Current.Type != TT_LineComment &&
|
||||
(Previous.is(tok::l_paren) || Previous.is(tok::l_brace) ||
|
||||
(Previous.isOneOf(tok::l_paren, tok::l_brace) ||
|
||||
State.NextToken->Parent->Type == TT_TemplateOpener))
|
||||
State.Stack.back().Indent = State.Column + Spaces;
|
||||
if (Previous.is(tok::comma) && !isTrailingComment(Current))
|
||||
|
@ -622,8 +621,7 @@ private:
|
|||
else if (Previous.Type == TT_InheritanceColon)
|
||||
State.Stack.back().Indent = State.Column;
|
||||
else if (Previous.ParameterCount > 1 &&
|
||||
(Previous.is(tok::l_paren) || Previous.is(tok::l_square) ||
|
||||
Previous.is(tok::l_brace) ||
|
||||
(Previous.isOneOf(tok::l_paren, tok::l_square, tok::l_brace) ||
|
||||
Previous.Type == TT_TemplateOpener))
|
||||
// If this function has multiple parameters, indent nested calls from
|
||||
// the start of the first parameter.
|
||||
|
@ -645,7 +643,7 @@ private:
|
|||
State.Stack.back().FirstLessLess = State.Column;
|
||||
if (Current.is(tok::question))
|
||||
State.Stack.back().QuestionColumn = State.Column;
|
||||
if ((Current.is(tok::period) || Current.is(tok::arrow)) &&
|
||||
if (Current.isOneOf(tok::period, tok::arrow) &&
|
||||
Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0)
|
||||
State.Stack.back().StartOfFunctionCall =
|
||||
Current.LastInChainOfCalls ? 0 : State.Column;
|
||||
|
@ -665,8 +663,7 @@ private:
|
|||
|
||||
// If we encounter an opening (, [, { or <, we add a level to our stacks to
|
||||
// prepare for the following tokens.
|
||||
if (Current.is(tok::l_paren) || Current.is(tok::l_square) ||
|
||||
Current.is(tok::l_brace) ||
|
||||
if (Current.isOneOf(tok::l_paren, tok::l_square, tok::l_brace) ||
|
||||
State.NextToken->Type == TT_TemplateOpener) {
|
||||
unsigned NewIndent;
|
||||
bool AvoidBinPacking;
|
||||
|
@ -695,7 +692,7 @@ private:
|
|||
|
||||
// If we encounter a closing ), ], } or >, we can remove a level from our
|
||||
// stacks.
|
||||
if (Current.is(tok::r_paren) || Current.is(tok::r_square) ||
|
||||
if (Current.isOneOf(tok::r_paren, tok::r_square) ||
|
||||
(Current.is(tok::r_brace) && State.NextToken != &RootToken) ||
|
||||
State.NextToken->Type == TT_TemplateCloser) {
|
||||
State.Stack.pop_back();
|
||||
|
@ -985,8 +982,7 @@ private:
|
|||
if (State.NextToken->Parent->is(tok::semi) &&
|
||||
State.LineContainsContinuedForLoopSection)
|
||||
return true;
|
||||
if ((State.NextToken->Parent->is(tok::comma) ||
|
||||
State.NextToken->Parent->is(tok::semi) ||
|
||||
if ((State.NextToken->Parent->isOneOf(tok::comma, tok::semi) ||
|
||||
State.NextToken->is(tok::question) ||
|
||||
State.NextToken->Type == TT_ConditionalExpr) &&
|
||||
State.Stack.back().BreakBeforeParameter &&
|
||||
|
@ -1126,6 +1122,88 @@ public:
|
|||
|
||||
virtual ~Formatter() {}
|
||||
|
||||
tooling::Replacements format() {
|
||||
LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);
|
||||
UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
|
||||
StructuralError = Parser.parse();
|
||||
unsigned PreviousEndOfLineColumn = 0;
|
||||
TokenAnnotator Annotator(Style, SourceMgr, Lex,
|
||||
Tokens.getIdentTable().get("in"));
|
||||
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
|
||||
Annotator.annotate(AnnotatedLines[i]);
|
||||
}
|
||||
deriveLocalStyle();
|
||||
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
|
||||
Annotator.calculateFormattingInformation(AnnotatedLines[i]);
|
||||
}
|
||||
std::vector<int> IndentForLevel;
|
||||
bool PreviousLineWasTouched = false;
|
||||
for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
|
||||
E = AnnotatedLines.end();
|
||||
I != E; ++I) {
|
||||
const AnnotatedLine &TheLine = *I;
|
||||
const FormatToken &FirstTok = TheLine.First.FormatTok;
|
||||
int Offset = getIndentOffset(TheLine.First);
|
||||
while (IndentForLevel.size() <= TheLine.Level)
|
||||
IndentForLevel.push_back(-1);
|
||||
IndentForLevel.resize(TheLine.Level + 1);
|
||||
bool WasMoved =
|
||||
PreviousLineWasTouched && FirstTok.NewlinesBefore == 0;
|
||||
if (TheLine.First.is(tok::eof)) {
|
||||
if (PreviousLineWasTouched) {
|
||||
unsigned NewLines = std::min(FirstTok.NewlinesBefore, 1u);
|
||||
Whitespaces.replaceWhitespace(TheLine.First, NewLines, /*Indent*/ 0,
|
||||
/*WhitespaceStartColumn*/ 0, Style);
|
||||
}
|
||||
} else if (TheLine.Type != LT_Invalid &&
|
||||
(WasMoved || touchesLine(TheLine))) {
|
||||
unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level);
|
||||
unsigned Indent = LevelIndent;
|
||||
if (static_cast<int>(Indent) + Offset >= 0)
|
||||
Indent += Offset;
|
||||
if (!FirstTok.WhiteSpaceStart.isValid() || StructuralError) {
|
||||
Indent = LevelIndent = SourceMgr.getSpellingColumnNumber(
|
||||
FirstTok.Tok.getLocation()) - 1;
|
||||
} else {
|
||||
formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
|
||||
PreviousEndOfLineColumn);
|
||||
}
|
||||
tryFitMultipleLinesInOne(Indent, I, E);
|
||||
UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
|
||||
TheLine.First, Whitespaces,
|
||||
StructuralError);
|
||||
PreviousEndOfLineColumn =
|
||||
Formatter.format(I + 1 != E ? &*(I + 1) : NULL);
|
||||
IndentForLevel[TheLine.Level] = LevelIndent;
|
||||
PreviousLineWasTouched = true;
|
||||
} else {
|
||||
if (FirstTok.NewlinesBefore > 0 || FirstTok.IsFirst) {
|
||||
unsigned Indent =
|
||||
SourceMgr.getSpellingColumnNumber(FirstTok.Tok.getLocation()) - 1;
|
||||
unsigned LevelIndent = Indent;
|
||||
if (static_cast<int>(LevelIndent) - Offset >= 0)
|
||||
LevelIndent -= Offset;
|
||||
IndentForLevel[TheLine.Level] = LevelIndent;
|
||||
|
||||
// Remove trailing whitespace of the previous line if it was touched.
|
||||
if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine))
|
||||
formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
|
||||
PreviousEndOfLineColumn);
|
||||
}
|
||||
// If we did not reformat this unwrapped line, the column at the end of
|
||||
// the last token is unchanged - thus, we can calculate the end of the
|
||||
// last token.
|
||||
SourceLocation LastLoc = TheLine.Last->FormatTok.Tok.getLocation();
|
||||
PreviousEndOfLineColumn =
|
||||
SourceMgr.getSpellingColumnNumber(LastLoc) +
|
||||
Lex.MeasureTokenLength(LastLoc, SourceMgr, Lex.getLangOpts()) - 1;
|
||||
PreviousLineWasTouched = false;
|
||||
}
|
||||
}
|
||||
return Whitespaces.generateReplacements();
|
||||
}
|
||||
|
||||
private:
|
||||
void deriveLocalStyle() {
|
||||
unsigned CountBoundToVariable = 0;
|
||||
unsigned CountBoundToType = 0;
|
||||
|
@ -1163,91 +1241,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
tooling::Replacements format() {
|
||||
LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);
|
||||
UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
|
||||
StructuralError = Parser.parse();
|
||||
unsigned PreviousEndOfLineColumn = 0;
|
||||
TokenAnnotator Annotator(Style, SourceMgr, Lex,
|
||||
Tokens.getIdentTable().get("in"));
|
||||
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
|
||||
Annotator.annotate(AnnotatedLines[i]);
|
||||
}
|
||||
deriveLocalStyle();
|
||||
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
|
||||
Annotator.calculateFormattingInformation(AnnotatedLines[i]);
|
||||
}
|
||||
std::vector<int> IndentForLevel;
|
||||
bool PreviousLineWasTouched = false;
|
||||
for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
|
||||
E = AnnotatedLines.end();
|
||||
I != E; ++I) {
|
||||
const AnnotatedLine &TheLine = *I;
|
||||
int Offset = getIndentOffset(TheLine.First);
|
||||
while (IndentForLevel.size() <= TheLine.Level)
|
||||
IndentForLevel.push_back(-1);
|
||||
IndentForLevel.resize(TheLine.Level + 1);
|
||||
bool WasMoved =
|
||||
PreviousLineWasTouched && TheLine.First.FormatTok.NewlinesBefore == 0;
|
||||
if (TheLine.First.is(tok::eof)) {
|
||||
if (PreviousLineWasTouched) {
|
||||
unsigned NewLines =
|
||||
std::min(TheLine.First.FormatTok.NewlinesBefore, 1u);
|
||||
Whitespaces.replaceWhitespace(TheLine.First, NewLines, /*Indent*/ 0,
|
||||
/*WhitespaceStartColumn*/ 0, Style);
|
||||
}
|
||||
} else if (TheLine.Type != LT_Invalid &&
|
||||
(WasMoved || touchesLine(TheLine))) {
|
||||
unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level);
|
||||
unsigned Indent = LevelIndent;
|
||||
if (static_cast<int>(Indent) + Offset >= 0)
|
||||
Indent += Offset;
|
||||
if (!TheLine.First.FormatTok.WhiteSpaceStart.isValid() ||
|
||||
StructuralError) {
|
||||
Indent = LevelIndent = SourceMgr.getSpellingColumnNumber(
|
||||
TheLine.First.FormatTok.Tok.getLocation()) - 1;
|
||||
} else {
|
||||
formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
|
||||
PreviousEndOfLineColumn);
|
||||
}
|
||||
tryFitMultipleLinesInOne(Indent, I, E);
|
||||
UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
|
||||
TheLine.First, Whitespaces,
|
||||
StructuralError);
|
||||
PreviousEndOfLineColumn =
|
||||
Formatter.format(I + 1 != E ? &*(I + 1) : NULL);
|
||||
IndentForLevel[TheLine.Level] = LevelIndent;
|
||||
PreviousLineWasTouched = true;
|
||||
} else {
|
||||
if (TheLine.First.FormatTok.NewlinesBefore > 0 ||
|
||||
TheLine.First.FormatTok.IsFirst) {
|
||||
unsigned Indent = SourceMgr.getSpellingColumnNumber(
|
||||
TheLine.First.FormatTok.Tok.getLocation()) - 1;
|
||||
unsigned LevelIndent = Indent;
|
||||
if (static_cast<int>(LevelIndent) - Offset >= 0)
|
||||
LevelIndent -= Offset;
|
||||
IndentForLevel[TheLine.Level] = LevelIndent;
|
||||
|
||||
// Remove trailing whitespace of the previous line if it was touched.
|
||||
if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine))
|
||||
formatFirstToken(TheLine.First, Indent, TheLine.InPPDirective,
|
||||
PreviousEndOfLineColumn);
|
||||
}
|
||||
// If we did not reformat this unwrapped line, the column at the end of
|
||||
// the last token is unchanged - thus, we can calculate the end of the
|
||||
// last token.
|
||||
PreviousEndOfLineColumn =
|
||||
SourceMgr.getSpellingColumnNumber(
|
||||
TheLine.Last->FormatTok.Tok.getLocation()) +
|
||||
Lex.MeasureTokenLength(TheLine.Last->FormatTok.Tok.getLocation(),
|
||||
SourceMgr, Lex.getLangOpts()) - 1;
|
||||
PreviousLineWasTouched = false;
|
||||
}
|
||||
}
|
||||
return Whitespaces.generateReplacements();
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief Get the indent of \p Level from \p IndentForLevel.
|
||||
///
|
||||
/// \p IndentForLevel must contain the indent for the level \c l
|
||||
|
@ -1267,8 +1260,7 @@ private:
|
|||
/// characters to the left from their level.
|
||||
int getIndentOffset(const AnnotatedToken &RootToken) {
|
||||
bool IsAccessModifier = false;
|
||||
if (RootToken.is(tok::kw_public) || RootToken.is(tok::kw_protected) ||
|
||||
RootToken.is(tok::kw_private))
|
||||
if (RootToken.isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private))
|
||||
IsAccessModifier = true;
|
||||
else if (RootToken.is(tok::at) && !RootToken.Children.empty() &&
|
||||
(RootToken.Children[0].isObjCAtKeyword(tok::objc_public) ||
|
||||
|
@ -1361,15 +1353,11 @@ private:
|
|||
// we're not in a control flow statement and the last token is an opening
|
||||
// brace.
|
||||
AnnotatedLine &Line = *I;
|
||||
bool AllowedTokens =
|
||||
Line.First.isNot(tok::kw_if) && Line.First.isNot(tok::kw_while) &&
|
||||
Line.First.isNot(tok::kw_do) && Line.First.isNot(tok::r_brace) &&
|
||||
Line.First.isNot(tok::kw_else) && Line.First.isNot(tok::kw_try) &&
|
||||
Line.First.isNot(tok::kw_catch) && Line.First.isNot(tok::kw_for) &&
|
||||
// This gets rid of all ObjC @ keywords and methods.
|
||||
Line.First.isNot(tok::at) && Line.First.isNot(tok::minus) &&
|
||||
Line.First.isNot(tok::plus);
|
||||
if (!AllowedTokens)
|
||||
if (Line.First.isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace,
|
||||
tok::kw_else, tok::kw_try, tok::kw_catch,
|
||||
tok::kw_for,
|
||||
// This gets rid of all ObjC @ keywords and methods.
|
||||
tok::at, tok::minus, tok::plus))
|
||||
return;
|
||||
|
||||
AnnotatedToken *Tok = &(I + 1)->First;
|
||||
|
@ -1391,7 +1379,7 @@ private:
|
|||
if ((I + 1)->Last->Type == TT_LineComment || Tok->MustBreakBefore)
|
||||
return;
|
||||
do {
|
||||
if (Tok->is(tok::l_brace) || Tok->is(tok::r_brace))
|
||||
if (Tok->isOneOf(tok::l_brace, tok::r_brace))
|
||||
return;
|
||||
Tok = Tok->Children.empty() ? NULL : &Tok->Children.back();
|
||||
} while (Tok != NULL);
|
||||
|
|
|
@ -71,6 +71,16 @@ static const AnnotatedToken *getNextToken(const AnnotatedToken &Tok) {
|
|||
return NextToken;
|
||||
}
|
||||
|
||||
static bool closesScope(const AnnotatedToken &Tok) {
|
||||
return Tok.isOneOf(tok::r_paren, tok::r_brace, tok::r_square) ||
|
||||
Tok.Type == TT_TemplateCloser;
|
||||
}
|
||||
|
||||
static bool opensScope(const AnnotatedToken &Tok) {
|
||||
return Tok.isOneOf(tok::l_paren, tok::l_brace, tok::l_square) ||
|
||||
Tok.Type == TT_TemplateOpener;
|
||||
}
|
||||
|
||||
/// \brief A parser that gathers additional information about tokens.
|
||||
///
|
||||
/// The \c TokenAnnotator tries to match parenthesis and square brakets and
|
||||
|
@ -100,11 +110,9 @@ private:
|
|||
next();
|
||||
return true;
|
||||
}
|
||||
if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square) ||
|
||||
CurrentToken->is(tok::r_brace))
|
||||
return false;
|
||||
if (CurrentToken->is(tok::pipepipe) || CurrentToken->is(tok::ampamp) ||
|
||||
CurrentToken->is(tok::question) || CurrentToken->is(tok::colon))
|
||||
if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace,
|
||||
tok::pipepipe, tok::ampamp, tok::question,
|
||||
tok::colon))
|
||||
return false;
|
||||
updateParameterCount(Left, CurrentToken);
|
||||
if (!consumeToken())
|
||||
|
@ -149,7 +157,7 @@ private:
|
|||
AnnotatedToken &Prev = *CurrentToken->Parent;
|
||||
AnnotatedToken &Next = CurrentToken->Children[0];
|
||||
if (Prev.Parent->is(tok::identifier) &&
|
||||
(Prev.is(tok::star) || Prev.is(tok::amp) || Prev.is(tok::ampamp)) &&
|
||||
Prev.isOneOf(tok::star, tok::amp, tok::ampamp) &&
|
||||
CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) {
|
||||
Prev.Type = TT_BinaryOperator;
|
||||
LookForDecls = false;
|
||||
|
@ -171,7 +179,7 @@ private:
|
|||
next();
|
||||
return true;
|
||||
}
|
||||
if (CurrentToken->is(tok::r_square) || CurrentToken->is(tok::r_brace))
|
||||
if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
|
||||
return false;
|
||||
updateParameterCount(Left, CurrentToken);
|
||||
if (!consumeToken())
|
||||
|
@ -191,10 +199,10 @@ private:
|
|||
AnnotatedToken *Parent = getPreviousToken(*Left);
|
||||
bool StartsObjCMethodExpr =
|
||||
Contexts.back().CanBeExpression &&
|
||||
(!Parent || Parent->is(tok::colon) || Parent->is(tok::l_square) ||
|
||||
Parent->is(tok::l_paren) || Parent->is(tok::kw_return) ||
|
||||
Parent->is(tok::kw_throw) || isUnaryOperator(*Parent) ||
|
||||
Parent->Type == TT_ObjCForIn || Parent->Type == TT_CastRParen ||
|
||||
(!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
|
||||
tok::kw_return, tok::kw_throw) ||
|
||||
isUnaryOperator(*Parent) || Parent->Type == TT_ObjCForIn ||
|
||||
Parent->Type == TT_CastRParen ||
|
||||
getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) >
|
||||
prec::Unknown);
|
||||
ScopedContextCreator ContextCreator(*this, 10);
|
||||
|
@ -235,7 +243,7 @@ private:
|
|||
next();
|
||||
return true;
|
||||
}
|
||||
if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_brace))
|
||||
if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
|
||||
return false;
|
||||
updateParameterCount(Left, CurrentToken);
|
||||
if (!consumeToken())
|
||||
|
@ -257,7 +265,7 @@ private:
|
|||
next();
|
||||
return true;
|
||||
}
|
||||
if (CurrentToken->is(tok::r_paren) || CurrentToken->is(tok::r_square))
|
||||
if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
|
||||
return false;
|
||||
updateParameterCount(Left, CurrentToken);
|
||||
if (!consumeToken())
|
||||
|
@ -380,7 +388,7 @@ private:
|
|||
break;
|
||||
case tok::kw_operator:
|
||||
while (CurrentToken && CurrentToken->isNot(tok::l_paren)) {
|
||||
if (CurrentToken->is(tok::star) || CurrentToken->is(tok::amp))
|
||||
if (CurrentToken->isOneOf(tok::star, tok::amp))
|
||||
CurrentToken->Type = TT_PointerOrReference;
|
||||
consumeToken();
|
||||
}
|
||||
|
@ -472,7 +480,7 @@ public:
|
|||
while (CurrentToken != NULL) {
|
||||
if (CurrentToken->is(tok::kw_virtual))
|
||||
KeywordVirtualFound = true;
|
||||
if (CurrentToken->is(tok::period) || CurrentToken->is(tok::arrow)) {
|
||||
if (CurrentToken->isOneOf(tok::period, tok::arrow)) {
|
||||
++PeriodsAndArrows;
|
||||
LastPeriodOrArrow = CurrentToken;
|
||||
}
|
||||
|
@ -560,18 +568,17 @@ private:
|
|||
if (Previous->is(tok::r_square))
|
||||
Previous = Previous->MatchingParen;
|
||||
if (Previous->Type == TT_BinaryOperator &&
|
||||
(Previous->is(tok::star) || Previous->is(tok::amp))) {
|
||||
Previous->isOneOf(tok::star, tok::amp)) {
|
||||
Previous->Type = TT_PointerOrReference;
|
||||
}
|
||||
}
|
||||
} else if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) ||
|
||||
} else if (Current.isOneOf(tok::kw_return, tok::kw_throw) ||
|
||||
(Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
|
||||
(!Current.Parent || Current.Parent->isNot(tok::kw_for)))) {
|
||||
Contexts.back().IsExpression = true;
|
||||
} else if (Current.is(tok::r_paren) || Current.is(tok::greater) ||
|
||||
Current.is(tok::comma)) {
|
||||
} else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
|
||||
for (AnnotatedToken *Previous = Current.Parent;
|
||||
Previous && (Previous->is(tok::star) || Previous->is(tok::amp));
|
||||
Previous && Previous->isOneOf(tok::star, tok::amp);
|
||||
Previous = Previous->Parent)
|
||||
Previous->Type = TT_PointerOrReference;
|
||||
} else if (Current.Parent &&
|
||||
|
@ -589,14 +596,12 @@ private:
|
|||
Current.Parent->Type == TT_PointerOrReference ||
|
||||
Current.Parent->Type == TT_TemplateCloser)) {
|
||||
Current.Type = TT_StartOfName;
|
||||
} else if (Current.is(tok::star) || Current.is(tok::amp) ||
|
||||
Current.is(tok::ampamp)) {
|
||||
} else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
|
||||
Current.Type =
|
||||
determineStarAmpUsage(Current, Contexts.back().IsExpression);
|
||||
} else if (Current.is(tok::minus) || Current.is(tok::plus) ||
|
||||
Current.is(tok::caret)) {
|
||||
} else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
|
||||
Current.Type = determinePlusMinusCaretUsage(Current);
|
||||
} else if (Current.is(tok::minusminus) || Current.is(tok::plusplus)) {
|
||||
} else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
|
||||
Current.Type = determineIncrementUsage(Current);
|
||||
} else if (Current.is(tok::exclaim)) {
|
||||
Current.Type = TT_UnaryOperator;
|
||||
|
@ -614,9 +619,8 @@ private:
|
|||
Current.Parent->Type == TT_PointerOrReference ||
|
||||
Current.Parent->Type == TT_TemplateCloser;
|
||||
bool ParensCouldEndDecl =
|
||||
!Current.Children.empty() && (Current.Children[0].is(tok::equal) ||
|
||||
Current.Children[0].is(tok::semi) ||
|
||||
Current.Children[0].is(tok::l_brace));
|
||||
!Current.Children.empty() &&
|
||||
Current.Children[0].isOneOf(tok::equal, tok::semi, tok::l_brace);
|
||||
if (ParensNotExpr && !ParensCouldEndDecl &&
|
||||
Contexts.back().IsExpression)
|
||||
// FIXME: We need to get smarter and understand more cases of casts.
|
||||
|
@ -652,20 +656,20 @@ private:
|
|||
if (PrevToken->is(tok::l_paren) && !IsExpression)
|
||||
return TT_PointerOrReference;
|
||||
|
||||
if (PrevToken->is(tok::l_paren) || PrevToken->is(tok::l_square) ||
|
||||
PrevToken->is(tok::l_brace) || PrevToken->is(tok::comma) ||
|
||||
PrevToken->is(tok::kw_return) || PrevToken->is(tok::colon) ||
|
||||
PrevToken->is(tok::equal) || PrevToken->Type == TT_BinaryOperator ||
|
||||
if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
|
||||
tok::comma, tok::kw_return, tok::colon,
|
||||
tok::equal) ||
|
||||
PrevToken->Type == TT_BinaryOperator ||
|
||||
PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen)
|
||||
return TT_UnaryOperator;
|
||||
|
||||
if (NextToken->is(tok::l_square))
|
||||
return TT_PointerOrReference;
|
||||
|
||||
if (PrevToken->FormatTok.Tok.isLiteral() || PrevToken->is(tok::r_paren) ||
|
||||
PrevToken->is(tok::r_square) || NextToken->FormatTok.Tok.isLiteral() ||
|
||||
isUnaryOperator(*NextToken) || NextToken->is(tok::l_paren) ||
|
||||
NextToken->is(tok::l_square))
|
||||
if (PrevToken->FormatTok.Tok.isLiteral() ||
|
||||
PrevToken->isOneOf(tok::r_paren, tok::r_square) ||
|
||||
NextToken->FormatTok.Tok.isLiteral() || isUnaryOperator(*NextToken) ||
|
||||
NextToken->isOneOf(tok::l_paren, tok::l_square))
|
||||
return TT_BinaryOperator;
|
||||
|
||||
// It is very unlikely that we are going to find a pointer or reference type
|
||||
|
@ -682,11 +686,9 @@ private:
|
|||
return TT_UnaryOperator;
|
||||
|
||||
// Use heuristics to recognize unary operators.
|
||||
if (PrevToken->is(tok::equal) || PrevToken->is(tok::l_paren) ||
|
||||
PrevToken->is(tok::comma) || PrevToken->is(tok::l_square) ||
|
||||
PrevToken->is(tok::question) || PrevToken->is(tok::colon) ||
|
||||
PrevToken->is(tok::kw_return) || PrevToken->is(tok::kw_case) ||
|
||||
PrevToken->is(tok::at) || PrevToken->is(tok::l_brace))
|
||||
if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
|
||||
tok::question, tok::colon, tok::kw_return,
|
||||
tok::kw_case, tok::at, tok::l_brace))
|
||||
return TT_UnaryOperator;
|
||||
|
||||
// There can't be two consecutive binary operators.
|
||||
|
@ -702,8 +704,7 @@ private:
|
|||
const AnnotatedToken *PrevToken = getPreviousToken(Tok);
|
||||
if (PrevToken == NULL)
|
||||
return TT_UnaryOperator;
|
||||
if (PrevToken->is(tok::r_paren) || PrevToken->is(tok::r_square) ||
|
||||
PrevToken->is(tok::identifier))
|
||||
if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
|
||||
return TT_TrailingUnaryOperator;
|
||||
|
||||
return TT_UnaryOperator;
|
||||
|
@ -798,16 +799,6 @@ private:
|
|||
Current = Current->Children.empty() ? NULL : &Current->Children[0];
|
||||
}
|
||||
|
||||
bool closesScope(const AnnotatedToken &Tok) {
|
||||
return Current->is(tok::r_paren) || Current->Type == TT_TemplateCloser ||
|
||||
Current->is(tok::r_brace) || Current->is(tok::r_square);
|
||||
}
|
||||
|
||||
bool opensScope(const AnnotatedToken &Tok) {
|
||||
return Current->is(tok::l_paren) || Current->Type == TT_TemplateOpener ||
|
||||
Current->is(tok::l_brace) || Current->is(tok::l_square);
|
||||
}
|
||||
|
||||
AnnotatedToken *Current;
|
||||
};
|
||||
|
||||
|
@ -901,11 +892,11 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
|
|||
Left.Type == TT_InheritanceColon)
|
||||
return 2;
|
||||
|
||||
if (Right.is(tok::arrow) || Right.is(tok::period)) {
|
||||
if (Right.isOneOf(tok::arrow, tok::period)) {
|
||||
if (Line.Type == LT_BuilderTypeCall)
|
||||
return 5;
|
||||
if ((Left.is(tok::r_paren) || Left.is(tok::r_square)) &&
|
||||
Left.MatchingParen && Left.MatchingParen->ParameterCount > 0)
|
||||
if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen &&
|
||||
Left.MatchingParen->ParameterCount > 0)
|
||||
return 20; // Should be smaller than breaking at a nested comma.
|
||||
return 150;
|
||||
}
|
||||
|
@ -926,8 +917,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
|
|||
if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
|
||||
return 20;
|
||||
|
||||
if (Left.is(tok::l_paren) || Left.is(tok::l_square) ||
|
||||
Left.is(tok::l_brace) || Left.Type == TT_TemplateOpener)
|
||||
if (opensScope(Left))
|
||||
return 20;
|
||||
|
||||
if (Right.is(tok::lessless)) {
|
||||
|
@ -955,9 +945,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
|
|||
const AnnotatedToken &Right) {
|
||||
if (Right.is(tok::hashhash))
|
||||
return Left.is(tok::hash);
|
||||
if (Left.is(tok::hashhash) || Left.is(tok::hash))
|
||||
if (Left.isOneOf(tok::hashhash, tok::hash))
|
||||
return Right.is(tok::hash);
|
||||
if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma))
|
||||
if (Right.isOneOf(tok::r_paren, tok::semi, tok::comma))
|
||||
return false;
|
||||
if (Right.is(tok::less) &&
|
||||
(Left.is(tok::kw_template) ||
|
||||
|
@ -965,20 +955,18 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
|
|||
return true;
|
||||
if (Left.is(tok::arrow) || Right.is(tok::arrow))
|
||||
return false;
|
||||
if (Left.is(tok::exclaim) || Left.is(tok::tilde))
|
||||
if (Left.isOneOf(tok::exclaim, tok::tilde))
|
||||
return false;
|
||||
if (Left.is(tok::at) &&
|
||||
(Right.is(tok::identifier) || Right.is(tok::string_literal) ||
|
||||
Right.is(tok::char_constant) || Right.is(tok::numeric_constant) ||
|
||||
Right.is(tok::l_paren) || Right.is(tok::l_brace) ||
|
||||
Right.is(tok::kw_true) || Right.is(tok::kw_false)))
|
||||
Right.isOneOf(tok::identifier, tok::string_literal, tok::char_constant,
|
||||
tok::numeric_constant, tok::l_paren, tok::l_brace,
|
||||
tok::kw_true, tok::kw_false))
|
||||
return false;
|
||||
if (Left.is(tok::coloncolon))
|
||||
return false;
|
||||
if (Right.is(tok::coloncolon))
|
||||
return Left.isNot(tok::identifier) && Left.isNot(tok::greater) &&
|
||||
Left.isNot(tok::l_paren);
|
||||
if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less))
|
||||
return !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren);
|
||||
if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less))
|
||||
return false;
|
||||
if (Right.Type == TT_PointerOrReference)
|
||||
return Left.FormatTok.Tok.isLiteral() ||
|
||||
|
@ -1004,11 +992,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
|
|||
if (Left.is(tok::l_paren))
|
||||
return false;
|
||||
if (Right.is(tok::l_paren)) {
|
||||
return Line.Type == LT_ObjCDecl || Left.is(tok::kw_if) ||
|
||||
Left.is(tok::kw_for) || Left.is(tok::kw_while) ||
|
||||
Left.is(tok::kw_switch) || Left.is(tok::kw_return) ||
|
||||
Left.is(tok::kw_catch) || Left.is(tok::kw_new) ||
|
||||
Left.is(tok::kw_delete);
|
||||
return Line.Type == LT_ObjCDecl ||
|
||||
Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
|
||||
tok::kw_return, tok::kw_catch, tok::kw_new,
|
||||
tok::kw_delete);
|
||||
}
|
||||
if (Left.is(tok::at) &&
|
||||
Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword)
|
||||
|
@ -1045,9 +1032,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
|||
if (Tok.Type == TT_OverloadedOperatorLParen)
|
||||
return false;
|
||||
if (Tok.is(tok::colon))
|
||||
return Line.First.isNot(tok::kw_case) &&
|
||||
Line.First.isNot(tok::kw_default) && !Tok.Children.empty() &&
|
||||
Tok.Type != TT_ObjCMethodExpr;
|
||||
return !Line.First.isOneOf(tok::kw_case, tok::kw_default) &&
|
||||
!Tok.Children.empty() && Tok.Type != TT_ObjCMethodExpr;
|
||||
if (Tok.is(tok::l_paren) && !Tok.Children.empty() &&
|
||||
Tok.Children[0].Type == TT_PointerOrReference &&
|
||||
!Tok.Children[0].Children.empty() &&
|
||||
|
@ -1056,8 +1042,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
|||
if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen)
|
||||
return false;
|
||||
if (Tok.Type == TT_UnaryOperator)
|
||||
return Tok.Parent->isNot(tok::l_paren) &&
|
||||
Tok.Parent->isNot(tok::l_square) && Tok.Parent->isNot(tok::at) &&
|
||||
return !Tok.Parent->isOneOf(tok::l_paren, tok::l_square, tok::at) &&
|
||||
(Tok.Parent->isNot(tok::colon) ||
|
||||
Tok.Parent->Type != TT_ObjCMethodExpr);
|
||||
if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) {
|
||||
|
@ -1103,7 +1088,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
|
|||
return false;
|
||||
if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser ||
|
||||
Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr ||
|
||||
Left.is(tok::question) || Left.is(tok::kw_operator))
|
||||
Left.isOneOf(tok::question, tok::kw_operator))
|
||||
return false;
|
||||
if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl)
|
||||
return false;
|
||||
|
@ -1120,25 +1105,22 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
|
|||
// unless it is follow by ';', '{' or '='.
|
||||
if (Left.is(tok::kw_const) && Left.Parent != NULL &&
|
||||
Left.Parent->is(tok::r_paren))
|
||||
return Right.isNot(tok::l_brace) && Right.isNot(tok::semi) &&
|
||||
Right.isNot(tok::equal);
|
||||
return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal);
|
||||
|
||||
// We only break before r_brace if there was a corresponding break before
|
||||
// the l_brace, which is tracked by BreakBeforeClosingBrace.
|
||||
if (Right.is(tok::r_brace))
|
||||
return false;
|
||||
|
||||
if (Right.is(tok::r_paren) || Right.is(tok::greater))
|
||||
if (Right.isOneOf(tok::r_paren, tok::greater))
|
||||
return false;
|
||||
if (Left.is(tok::identifier) && Right.is(tok::string_literal))
|
||||
return true;
|
||||
return (isBinaryOperator(Left) && Left.isNot(tok::lessless)) ||
|
||||
Left.is(tok::comma) || Right.is(tok::lessless) ||
|
||||
Right.is(tok::arrow) || Right.is(tok::period) ||
|
||||
Right.is(tok::colon) || Left.is(tok::coloncolon) ||
|
||||
Left.is(tok::semi) || Left.is(tok::l_brace) ||
|
||||
Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace) ||
|
||||
Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) ||
|
||||
(Left.is(tok::r_paren) && Left.Type != TT_CastRParen &&
|
||||
(Right.is(tok::identifier) || Right.is(tok::kw___attribute))) ||
|
||||
Right.isOneOf(tok::identifier, tok::kw___attribute)) ||
|
||||
(Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
|
||||
(Left.is(tok::l_square) && !Right.is(tok::r_square));
|
||||
}
|
||||
|
|
|
@ -79,6 +79,27 @@ public:
|
|||
}
|
||||
|
||||
bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); }
|
||||
|
||||
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
|
||||
return is(K1) || is(K2);
|
||||
}
|
||||
|
||||
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3) const {
|
||||
return is(K1) || is(K2) || is(K3);
|
||||
}
|
||||
|
||||
bool isOneOf(
|
||||
tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3,
|
||||
tok::TokenKind K4, tok::TokenKind K5 = tok::NUM_TOKENS,
|
||||
tok::TokenKind K6 = tok::NUM_TOKENS, tok::TokenKind K7 = tok::NUM_TOKENS,
|
||||
tok::TokenKind K8 = tok::NUM_TOKENS, tok::TokenKind K9 = tok::NUM_TOKENS,
|
||||
tok::TokenKind K10 = tok::NUM_TOKENS,
|
||||
tok::TokenKind K11 = tok::NUM_TOKENS,
|
||||
tok::TokenKind K12 = tok::NUM_TOKENS) const {
|
||||
return is(K1) || is(K2) || is(K3) || is(K4) || is(K5) || is(K6) || is(K7) ||
|
||||
is(K8) || is(K9) || is(K10) || is(K11) || is(K12);
|
||||
}
|
||||
|
||||
bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); }
|
||||
|
||||
bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
|
||||
|
|
Загрузка…
Ссылка в новой задаче