aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/FormatTokenLexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/FormatTokenLexer.cpp')
-rw-r--r--clang/lib/Format/FormatTokenLexer.cpp117
1 files changed, 53 insertions, 64 deletions
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index e9b096370dbb..a9cfb4a247f0 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -39,6 +39,8 @@ FormatTokenLexer::FormatTokenLexer(
for (const std::string &ForEachMacro : Style.ForEachMacros)
Macros.insert({&IdentTable.get(ForEachMacro), TT_ForEachMacro});
+ for (const std::string &IfMacro : Style.IfMacros)
+ Macros.insert({&IdentTable.get(IfMacro), TT_IfMacro});
for (const std::string &AttributeMacro : Style.AttributeMacros)
Macros.insert({&IdentTable.get(AttributeMacro), TT_AttributeMacro});
for (const std::string &StatementMacro : Style.StatementMacros)
@@ -92,20 +94,46 @@ void FormatTokenLexer::tryMergePreviousTokens() {
if (Style.isCpp() && tryTransformTryUsageForC())
return;
+ if (Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
+ static const tok::TokenKind NullishCoalescingOperator[] = {tok::question,
+ tok::question};
+ static const tok::TokenKind NullPropagatingOperator[] = {tok::question,
+ tok::period};
+ static const tok::TokenKind FatArrow[] = {tok::equal, tok::greater};
+
+ if (tryMergeTokens(FatArrow, TT_FatArrow))
+ return;
+ if (tryMergeTokens(NullishCoalescingOperator, TT_NullCoalescingOperator)) {
+ // Treat like the "||" operator (as opposed to the ternary ?).
+ Tokens.back()->Tok.setKind(tok::pipepipe);
+ return;
+ }
+ if (tryMergeTokens(NullPropagatingOperator, TT_NullPropagatingOperator)) {
+ // Treat like a regular "." access.
+ Tokens.back()->Tok.setKind(tok::period);
+ return;
+ }
+ if (tryMergeNullishCoalescingEqual()) {
+ return;
+ }
+ }
+
if (Style.isCSharp()) {
+ static const tok::TokenKind CSharpNullConditionalLSquare[] = {
+ tok::question, tok::l_square};
+
if (tryMergeCSharpKeywordVariables())
return;
if (tryMergeCSharpStringLiteral())
return;
- if (tryMergeCSharpDoubleQuestion())
- return;
- if (tryMergeCSharpNullConditional())
- return;
if (tryTransformCSharpForEach())
return;
- static const tok::TokenKind JSRightArrow[] = {tok::equal, tok::greater};
- if (tryMergeTokens(JSRightArrow, TT_JsFatArrow))
+ if (tryMergeTokens(CSharpNullConditionalLSquare,
+ TT_CSharpNullConditionalLSquare)) {
+ // Treat like a regular "[" operator.
+ Tokens.back()->Tok.setKind(tok::l_square);
return;
+ }
}
if (tryMergeNSStringLiteral())
@@ -117,16 +145,9 @@ void FormatTokenLexer::tryMergePreviousTokens() {
tok::equal};
static const tok::TokenKind JSShiftEqual[] = {tok::greater, tok::greater,
tok::greaterequal};
- static const tok::TokenKind JSRightArrow[] = {tok::equal, tok::greater};
static const tok::TokenKind JSExponentiation[] = {tok::star, tok::star};
static const tok::TokenKind JSExponentiationEqual[] = {tok::star,
tok::starequal};
- static const tok::TokenKind JSNullPropagatingOperator[] = {tok::question,
- tok::period};
- static const tok::TokenKind JSNullishOperator[] = {tok::question,
- tok::question};
- static const tok::TokenKind JSNullishEqual[] = {tok::question,
- tok::question, tok::equal};
static const tok::TokenKind JSPipePipeEqual[] = {tok::pipepipe, tok::equal};
static const tok::TokenKind JSAndAndEqual[] = {tok::ampamp, tok::equal};
@@ -137,28 +158,14 @@ void FormatTokenLexer::tryMergePreviousTokens() {
return;
if (tryMergeTokens(JSShiftEqual, TT_BinaryOperator))
return;
- if (tryMergeTokens(JSRightArrow, TT_JsFatArrow))
- return;
if (tryMergeTokens(JSExponentiation, TT_JsExponentiation))
return;
if (tryMergeTokens(JSExponentiationEqual, TT_JsExponentiationEqual)) {
Tokens.back()->Tok.setKind(tok::starequal);
return;
}
- if (tryMergeTokens(JSNullishOperator, TT_JsNullishCoalescingOperator)) {
- // Treat like the "||" operator (as opposed to the ternary ?).
- Tokens.back()->Tok.setKind(tok::pipepipe);
- return;
- }
- if (tryMergeTokens(JSNullPropagatingOperator,
- TT_JsNullPropagatingOperator)) {
- // Treat like a regular "." access.
- Tokens.back()->Tok.setKind(tok::period);
- return;
- }
if (tryMergeTokens(JSAndAndEqual, TT_JsAndAndEqual) ||
- tryMergeTokens(JSPipePipeEqual, TT_JsPipePipeEqual) ||
- tryMergeTokens(JSNullishEqual, TT_JsNullishCoalescingEqual)) {
+ tryMergeTokens(JSPipePipeEqual, TT_JsPipePipeEqual)) {
// Treat like the "=" assignment operator.
Tokens.back()->Tok.setKind(tok::equal);
return;
@@ -310,45 +317,20 @@ const llvm::StringSet<> FormatTokenLexer::CSharpAttributeTargets = {
"param", "property", "return", "type",
};
-bool FormatTokenLexer::tryMergeCSharpDoubleQuestion() {
+bool FormatTokenLexer::tryMergeNullishCoalescingEqual() {
if (Tokens.size() < 2)
return false;
- auto &FirstQuestion = *(Tokens.end() - 2);
- auto &SecondQuestion = *(Tokens.end() - 1);
- if (!FirstQuestion->is(tok::question) || !SecondQuestion->is(tok::question))
+ auto &NullishCoalescing = *(Tokens.end() - 2);
+ auto &Equal = *(Tokens.end() - 1);
+ if (NullishCoalescing->getType() != TT_NullCoalescingOperator ||
+ !Equal->is(tok::equal))
return false;
- FirstQuestion->Tok.setKind(tok::question); // no '??' in clang tokens.
- FirstQuestion->TokenText = StringRef(FirstQuestion->TokenText.begin(),
- SecondQuestion->TokenText.end() -
- FirstQuestion->TokenText.begin());
- FirstQuestion->ColumnWidth += SecondQuestion->ColumnWidth;
- FirstQuestion->setType(TT_CSharpNullCoalescing);
- Tokens.erase(Tokens.end() - 1);
- return true;
-}
-
-// Merge '?[' and '?.' pairs into single tokens.
-bool FormatTokenLexer::tryMergeCSharpNullConditional() {
- if (Tokens.size() < 2)
- return false;
- auto &Question = *(Tokens.end() - 2);
- auto &PeriodOrLSquare = *(Tokens.end() - 1);
- if (!Question->is(tok::question) ||
- !PeriodOrLSquare->isOneOf(tok::l_square, tok::period))
- return false;
- Question->TokenText =
- StringRef(Question->TokenText.begin(),
- PeriodOrLSquare->TokenText.end() - Question->TokenText.begin());
- Question->ColumnWidth += PeriodOrLSquare->ColumnWidth;
-
- if (PeriodOrLSquare->is(tok::l_square)) {
- Question->Tok.setKind(tok::question); // no '?[' in clang tokens.
- Question->setType(TT_CSharpNullConditionalLSquare);
- } else {
- Question->Tok.setKind(tok::question); // no '?.' in clang tokens.
- Question->setType(TT_CSharpNullConditional);
- }
-
+ NullishCoalescing->Tok.setKind(tok::equal); // no '??=' in clang tokens.
+ NullishCoalescing->TokenText =
+ StringRef(NullishCoalescing->TokenText.begin(),
+ Equal->TokenText.end() - NullishCoalescing->TokenText.begin());
+ NullishCoalescing->ColumnWidth += Equal->ColumnWidth;
+ NullishCoalescing->setType(TT_NullCoalescingEqual);
Tokens.erase(Tokens.end() - 1);
return true;
}
@@ -1034,6 +1016,13 @@ FormatToken *FormatTokenLexer::getNextToken() {
tok::pp_define) &&
it != Macros.end()) {
FormatTok->setType(it->second);
+ if (it->second == TT_IfMacro) {
+ // The lexer token currently has type tok::kw_unknown. However, for this
+ // substitution to be treated correctly in the TokenAnnotator, faking
+ // the tok value seems to be needed. Not sure if there's a more elegant
+ // way.
+ FormatTok->Tok.setKind(tok::kw_if);
+ }
} else if (FormatTok->is(tok::identifier)) {
if (MacroBlockBeginRegex.match(Text)) {
FormatTok->setType(TT_MacroBlockBegin);