[clang-format] Adds space around angle brackets in text protos
Summary:
This patch adds spaces around angle brackets in text proto Google style.
Previously these were detected as template openers and closers, which happened
to have the expected effect. Now we detect them as scope openers and closers
similarly to the way braces are handled in this context.
Reviewers: djasper
Reviewed By: djasper
Subscribers: klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D42727
llvm-svn: 324337
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index db4fe8f..00f79ad 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -857,7 +857,7 @@
(Current.Next->is(TT_DictLiteral) ||
((Style.Language == FormatStyle::LK_Proto ||
Style.Language == FormatStyle::LK_TextProto) &&
- Current.Next->isOneOf(TT_TemplateOpener, tok::l_brace))))
+ Current.Next->isOneOf(tok::less, tok::l_brace))))
return State.Stack.back().Indent;
if (NextNonComment->is(TT_ObjCStringLiteral) &&
State.StartOfStringLiteral != 0)
@@ -1293,7 +1293,8 @@
if (State.Stack.size() > 1 &&
(Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
(Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
- State.NextToken->is(TT_TemplateCloser)))
+ State.NextToken->is(TT_TemplateCloser) ||
+ (Current.is(tok::greater) && Current.is(TT_DictLiteral))))
State.Stack.pop_back();
if (Current.is(tok::r_square)) {
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 60c11a3..071230a 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -348,17 +348,23 @@
Next->isObjCAtKeyword(tok::objc_private));
}
- /// \brief Returns whether \p Tok is ([{ or a template opening <.
+ /// \brief Returns whether \p Tok is ([{ or an opening < of a template or in
+ /// protos.
bool opensScope() const {
if (is(TT_TemplateString) && TokenText.endswith("${"))
return true;
+ if (is(TT_DictLiteral) && is(tok::less))
+ return true;
return isOneOf(tok::l_paren, tok::l_brace, tok::l_square,
TT_TemplateOpener);
}
- /// \brief Returns whether \p Tok is )]} or a template closing >.
+ /// \brief Returns whether \p Tok is )]} or a closing > of a template or in
+ /// protos.
bool closesScope() const {
if (is(TT_TemplateString) && TokenText.startswith("}"))
return true;
+ if (is(TT_DictLiteral) && is(tok::greater))
+ return true;
return isOneOf(tok::r_paren, tok::r_brace, tok::r_square,
TT_TemplateCloser);
}
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 05629ed..bb7c5ad 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -79,7 +79,17 @@
if (CurrentToken->is(tok::greater)) {
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
- CurrentToken->Type = TT_TemplateCloser;
+ // In TT_Proto, we must distignuish between:
+ // map<key, value>
+ // msg < item: data >
+ // msg: < item: data >
+ // In TT_TextProto, map<key, value> does not occur.
+ if (Style.Language == FormatStyle::LK_TextProto ||
+ (Style.Language == FormatStyle::LK_Proto && Left->Previous &&
+ Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral)))
+ CurrentToken->Type = TT_DictLiteral;
+ else
+ CurrentToken->Type = TT_TemplateCloser;
next();
return true;
}
@@ -670,7 +680,15 @@
case tok::less:
if (parseAngle()) {
Tok->Type = TT_TemplateOpener;
- if (Style.Language == FormatStyle::LK_TextProto) {
+ // In TT_Proto, we must distignuish between:
+ // map<key, value>
+ // msg < item: data >
+ // msg: < item: data >
+ // In TT_TextProto, map<key, value> does not occur.
+ if (Style.Language == FormatStyle::LK_TextProto ||
+ (Style.Language == FormatStyle::LK_Proto && Tok->Previous &&
+ Tok->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) {
+ Tok->Type = TT_DictLiteral;
FormatToken *Previous = Tok->getPreviousNonComment();
if (Previous && Previous->Type != TT_DictLiteral)
Previous->Type = TT_SelectorName;
@@ -691,7 +709,8 @@
return false;
break;
case tok::greater:
- Tok->Type = TT_BinaryOperator;
+ if (Style.Language != FormatStyle::LK_TextProto)
+ Tok->Type = TT_BinaryOperator;
break;
case tok::kw_operator:
while (CurrentToken &&
@@ -1157,7 +1176,9 @@
Current.Type = TT_ConditionalExpr;
}
} else if (Current.isBinaryOperator() &&
- (!Current.Previous || Current.Previous->isNot(tok::l_square))) {
+ (!Current.Previous || Current.Previous->isNot(tok::l_square)) &&
+ (!Current.is(tok::greater) &&
+ Style.Language != FormatStyle::LK_TextProto)) {
Current.Type = TT_BinaryOperator;
} else if (Current.is(tok::comment)) {
if (Current.TokenText.startswith("/*")) {
@@ -2226,8 +2247,17 @@
return !Left.is(TT_ObjCMethodExpr);
if (Left.is(tok::coloncolon))
return false;
- if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less))
+ if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
+ if (Style.Language == FormatStyle::LK_TextProto ||
+ (Style.Language == FormatStyle::LK_Proto &&
+ (Left.is(TT_DictLiteral) || Right.is(TT_DictLiteral)))) {
+ // Format empty list as `<>`.
+ if (Left.is(tok::less) && Right.is(tok::greater))
+ return false;
+ return !Style.Cpp11BracedListStyle;
+ }
return false;
+ }
if (Right.is(tok::ellipsis))
return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
Left.Previous->is(tok::kw_case));
@@ -2502,9 +2532,13 @@
return Style.SpaceAfterCStyleCast ||
Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
- if (Left.is(tok::greater) && Right.is(tok::greater))
+ if (Left.is(tok::greater) && Right.is(tok::greater)) {
+ if (Style.Language == FormatStyle::LK_TextProto ||
+ (Style.Language == FormatStyle::LK_Proto && Left.is(TT_DictLiteral)))
+ return !Style.Cpp11BracedListStyle;
return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
(Style.Standard != FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
+ }
if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
(Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod)))