[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