[clang] a11ff39 - [clang-format] Merge name and colon into a single token for C# named arguments
Jonathan Coe via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 20 11:24:50 PST 2020
Author: Jonathan Coe
Date: 2020-02-20T19:23:38Z
New Revision: a11ff39ba2ad3975a40e2684948a4dd2ada89bd3
URL: https://github.com/llvm/llvm-project/commit/a11ff39ba2ad3975a40e2684948a4dd2ada89bd3
DIFF: https://github.com/llvm/llvm-project/commit/a11ff39ba2ad3975a40e2684948a4dd2ada89bd3.diff
LOG: [clang-format] Merge name and colon into a single token for C# named arguments
Summary:
Merge 'argumentName' and ':' into a single token in foo(argumentName: bar).
Add C# named argument as a token type.
Reviewers: krasimir, MyDeveloperDay
Reviewed By: krasimir
Tags: #clang-format
Differential Revision: https://reviews.llvm.org/D74894
Added:
Modified:
clang/lib/Format/FormatToken.h
clang/lib/Format/FormatTokenLexer.cpp
clang/lib/Format/FormatTokenLexer.h
clang/unittests/Format/FormatTestCSharp.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index e9cd327754ef..dc68cbc79734 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -103,6 +103,7 @@ namespace format {
TYPE(UnaryOperator) \
TYPE(CSharpStringLiteral) \
TYPE(CSharpNullCoalescing) \
+ TYPE(CSharpNamedArgument) \
TYPE(Unknown)
enum TokenType {
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index e76d74571ebc..8acae56e2232 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -76,6 +76,8 @@ void FormatTokenLexer::tryMergePreviousTokens() {
return;
if (Style.isCSharp()) {
+ if (tryMergeCSharpNamedArgument())
+ return;
if (tryMergeCSharpAttributeAndTarget())
return;
if (tryMergeCSharpKeywordVariables())
@@ -184,6 +186,39 @@ bool FormatTokenLexer::tryMergeJSPrivateIdentifier() {
return true;
}
+// Merge 'argName' and ':' into a single token in `foo(argName: bar)`.
+bool FormatTokenLexer::tryMergeCSharpNamedArgument() {
+ if (Tokens.size() < 2)
+ return false;
+ auto &Colon = *(Tokens.end() - 1);
+ if (!Colon->is(tok::colon))
+ return false;
+
+ auto &Name = *(Tokens.end() - 2);
+ if (!Name->is(tok::identifier))
+ return false;
+
+ const FormatToken *CommaOrLeftParen = nullptr;
+ for (auto I = Tokens.rbegin() + 2, E = Tokens.rend(); I != E; ++I) {
+ // NB: Because previous pointers are not initialized yet, this cannot use
+ // Token.getPreviousNonComment.
+ if ((*I)->isNot(tok::comment)) {
+ CommaOrLeftParen = *I;
+ break;
+ }
+ }
+
+ if (!CommaOrLeftParen || !CommaOrLeftParen->isOneOf(tok::l_paren, tok::comma))
+ return false;
+
+ Name->TokenText = StringRef(Name->TokenText.begin(),
+ Colon->TokenText.end() - Name->TokenText.begin());
+ Name->ColumnWidth += Colon->ColumnWidth;
+ Name->Type = TT_CSharpNamedArgument;
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+}
+
// Search for verbatim or interpolated string literals @"ABC" or
// $"aaaaa{abc}aaaaa" i and mark the token as TT_CSharpStringLiteral, and to
// prevent splitting of @, $ and ".
diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h
index 4fffb36272f7..1f930d75e805 100644
--- a/clang/lib/Format/FormatTokenLexer.h
+++ b/clang/lib/Format/FormatTokenLexer.h
@@ -56,6 +56,7 @@ class FormatTokenLexer {
bool tryMergeCSharpDoubleQuestion();
bool tryTransformCSharpForEach();
bool tryMergeCSharpAttributeAndTarget();
+ bool tryMergeCSharpNamedArgument();
bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType);
diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp
index e859aeb0d22d..1800768d6771 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -513,7 +513,7 @@ var x = foo(className, $@"some code:
TEST_F(FormatTestCSharp, CSharpObjectInitializers) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
- // Start code fragemnts with a comment line so that C++ raw string literals
+ // Start code fragments with a comment line so that C++ raw string literals
// as seen are identical to expected formatted code.
verifyFormat(R"(//
@@ -539,5 +539,20 @@ Shape[] shapes = new[] {new Circle {Radius = 2.7281, Colour = Colours.Red},
Style);
}
+TEST_F(FormatTestCSharp, CSharpNamedArguments) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+ verifyFormat(R"(//
+PrintOrderDetails(orderNum: 31, productName: "Red Mug",
+ sellerName: "Gift Shop");)",
+ Style);
+
+ // Ensure that trailing comments do not cause problems.
+ verifyFormat(R"(//
+PrintOrderDetails(orderNum: 31, productName: "Red Mug", // comment
+ sellerName: "Gift Shop");)",
+ Style);
+}
+
} // namespace format
} // end namespace clang
More information about the cfe-commits
mailing list