forked from OSchip/llvm-project
[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
This commit is contained in:
parent
e2c2eb0a55
commit
a11ff39ba2
|
@ -103,6 +103,7 @@ namespace format {
|
|||
TYPE(UnaryOperator) \
|
||||
TYPE(CSharpStringLiteral) \
|
||||
TYPE(CSharpNullCoalescing) \
|
||||
TYPE(CSharpNamedArgument) \
|
||||
TYPE(Unknown)
|
||||
|
||||
enum TokenType {
|
||||
|
|
|
@ -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 ".
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
bool tryMergeCSharpDoubleQuestion();
|
||||
bool tryTransformCSharpForEach();
|
||||
bool tryMergeCSharpAttributeAndTarget();
|
||||
bool tryMergeCSharpNamedArgument();
|
||||
|
||||
bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue