summaryrefslogtreecommitdiffstats
path: root/lib/Format
diff options
context:
space:
mode:
authorKrasimir Georgiev <krasimir@google.com>2017-06-27 13:43:07 +0000
committerKrasimir Georgiev <krasimir@google.com>2017-06-27 13:43:07 +0000
commitace84ec3ef5538e6249e57961324448552b80f40 (patch)
treec316e7a6fcf7982fd4c96d153475ca0baa503233 /lib/Format
parent7a2b28407501faafdbd0c3c6785895e49d13d514 (diff)
[clang-format] Support <>-style proto message fields
Summary: This patch adds support for <>-style proto message fields inside proto options. Previously these were wrongly treated as binary operators and as such were working only by chance for a limited number of cases. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D34621 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306406 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format')
-rw-r--r--lib/Format/ContinuationIndenter.cpp20
-rw-r--r--lib/Format/FormatToken.h3
-rw-r--r--lib/Format/TokenAnnotator.cpp25
-rw-r--r--lib/Format/UnwrappedLineParser.cpp16
-rw-r--r--lib/Format/UnwrappedLineParser.h3
5 files changed, 52 insertions, 15 deletions
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index cca773cfe3..92c8ad835a 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -56,6 +56,8 @@ static bool startsNextParameter(const FormatToken &Current,
if (Current.is(TT_CtorInitializerComma) &&
Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
return true;
+ if (Style.Language == FormatStyle::LK_Proto && Current.is(TT_SelectorName))
+ return true;
return Previous.is(tok::comma) && !Current.isTrailingComment() &&
((Previous.isNot(TT_CtorInitializerComma) ||
Style.BreakConstructorInitializers !=
@@ -499,6 +501,13 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
}
}
+static bool lessOpensProtoMessageField(const FormatToken &LessTok,
+ const LineState &State) {
+ assert(LessTok.is(tok::less));
+ return LessTok.NestingLevel > 0 ||
+ (LessTok.Previous && LessTok.Previous->is(tok::equal));
+}
+
unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
bool DryRun) {
FormatToken &Current = *State.NextToken;
@@ -641,6 +650,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
// before the corresponding } or ].
if (PreviousNonComment &&
(PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
+ (Style.Language == FormatStyle::LK_Proto &&
+ PreviousNonComment->is(tok::less) &&
+ lessOpensProtoMessageField(*PreviousNonComment, State)) ||
(PreviousNonComment->is(TT_TemplateString) &&
PreviousNonComment->opensScope())))
State.Stack.back().BreakBeforeClosingBrace = true;
@@ -682,7 +694,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block)
return Current.NestingLevel == 0 ? State.FirstIndent
: State.Stack.back().Indent;
- if (Current.isOneOf(tok::r_brace, tok::r_square) && State.Stack.size() > 1) {
+ if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
+ (Current.is(tok::greater) && Style.Language == FormatStyle::LK_Proto)) &&
+ State.Stack.size() > 1) {
if (Current.closesBlockOrBlockTypeList(Style))
return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
if (Current.MatchingParen &&
@@ -1035,7 +1049,9 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
bool BreakBeforeParameter = false;
unsigned NestedBlockIndent = std::max(State.Stack.back().StartOfFunctionCall,
State.Stack.back().NestedBlockIndent);
- if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) {
+ if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
+ (Style.Language == FormatStyle::LK_Proto && Current.is(tok::less) &&
+ lessOpensProtoMessageField(Current, State))) {
if (Current.opensBlockOrBlockTypeList(Style)) {
NewIndent = Style.IndentWidth +
std::min(State.Column, State.Stack.back().NestedBlockIndent);
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h
index c5bf48cdcc..ddec578f89 100644
--- a/lib/Format/FormatToken.h
+++ b/lib/Format/FormatToken.h
@@ -465,7 +465,8 @@ struct FormatToken {
return is(TT_ArrayInitializerLSquare) ||
(is(tok::l_brace) &&
(BlockKind == BK_Block || is(TT_DictLiteral) ||
- (!Style.Cpp11BracedListStyle && NestingLevel == 0)));
+ (!Style.Cpp11BracedListStyle && NestingLevel == 0))) ||
+ (is(tok::less) && Style.Language == FormatStyle::LK_Proto);
}
/// \brief Same as opensBlockOrBlockTypeList, but for the closing token.
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 505f42ec9a..767096b60e 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -89,7 +89,8 @@ private:
continue;
}
if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
- (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext))
+ (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
+ Style.Language != FormatStyle::LK_Proto))
return false;
// If a && or || is found and interpreted as a binary operator, this set
// of angles is likely part of something like "a < b && c > d". If the
@@ -103,6 +104,14 @@ private:
!Line.startsWith(tok::kw_template))
return false;
updateParameterCount(Left, CurrentToken);
+ if (Style.Language == FormatStyle::LK_Proto) {
+ if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
+ if (CurrentToken->is(tok::colon) ||
+ (CurrentToken->isOneOf(tok::l_brace, tok::less) &&
+ Previous->isNot(tok::colon)))
+ Previous->Type = TT_SelectorName;
+ }
+ }
if (!consumeToken())
return false;
}
@@ -440,7 +449,7 @@ private:
if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
return false;
updateParameterCount(Left, CurrentToken);
- if (CurrentToken->isOneOf(tok::colon, tok::l_brace)) {
+ if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
FormatToken *Previous = CurrentToken->getPreviousNonComment();
if (((CurrentToken->is(tok::colon) &&
(!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
@@ -2549,10 +2558,16 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// deliberate choice and might have aligned the contents of the string
// literal accordingly. Thus, we try keep existing line breaks.
return Right.NewlinesBefore > 0;
- if (Right.Previous->is(tok::l_brace) && Right.NestingLevel == 1 &&
- Style.Language == FormatStyle::LK_Proto)
- // Don't put enums onto single lines in protocol buffers.
+ if ((Right.Previous->is(tok::l_brace) ||
+ (Right.Previous->is(tok::less) &&
+ Right.Previous->Previous &&
+ Right.Previous->Previous->is(tok::equal))
+ ) &&
+ Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
+ // Don't put enums or option definitions onto single lines in protocol
+ // buffers.
return true;
+ }
if (Right.is(TT_InlineASMBrace))
return Right.HasUnescapedNewline;
if (isAllmanBrace(Left) || isAllmanBrace(Right))
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index f7678bb6b2..261ae3030d 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -1176,9 +1176,11 @@ void UnwrappedLineParser::parseStructuralElement() {
}
nextToken();
- if (FormatTok->Tok.is(tok::l_brace)) {
+ if (FormatTok->Tok.is(tok::l_brace))
parseBracedList();
- }
+ else if (Style.Language == FormatStyle::LK_Proto &&
+ FormatTok->Tok.is(tok::less))
+ parseBracedList(/*ClosingBraceKind=*/tok::greater);
break;
case tok::l_square:
parseSquare();
@@ -1346,7 +1348,8 @@ bool UnwrappedLineParser::tryToParseBracedList() {
return true;
}
-bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
+bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons,
+ tok::TokenKind ClosingBraceKind) {
bool HasError = false;
nextToken();
@@ -1375,6 +1378,10 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
parseChildBlock();
}
}
+ if (FormatTok->Tok.getKind() == ClosingBraceKind) {
+ nextToken();
+ return !HasError;
+ }
switch (FormatTok->Tok.getKind()) {
case tok::caret:
nextToken();
@@ -1401,9 +1408,6 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
FormatTok->BlockKind = BK_BracedInit;
parseBracedList();
break;
- case tok::r_brace:
- nextToken();
- return !HasError;
case tok::semi:
// JavaScript (or more precisely TypeScript) can have semicolons in braced
// lists (in so-called TypeMemberLists). Thus, the semicolon cannot be
diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h
index 15d1d9cda7..a2aa2f0067 100644
--- a/lib/Format/UnwrappedLineParser.h
+++ b/lib/Format/UnwrappedLineParser.h
@@ -93,7 +93,8 @@ private:
void readTokenWithJavaScriptASI();
void parseStructuralElement();
bool tryToParseBracedList();
- bool parseBracedList(bool ContinueOnSemicolons = false);
+ bool parseBracedList(bool ContinueOnSemicolons = false,
+ tok::TokenKind ClosingBraceKind = tok::r_brace);
void parseParens();
void parseSquare();
void parseIfThenElse();