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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits