Skip to content

Commit 2855c9e

Browse files
rintaronkcsgexi
authored andcommitted
[Syntax] Add support for compound name in expressions (#13630)
1 parent a1a285d commit 2855c9e

File tree

5 files changed

+50
-16
lines changed

5 files changed

+50
-16
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,12 +2064,16 @@ DeclName Parser::parseUnqualifiedDeclName(bool afterDot,
20642064
return baseName;
20652065
}
20662066

2067+
20672068
// If the next token is a ')' then we have a 0-arg compound name. This is
20682069
// explicitly differentiated from "simple" (non-compound) name in DeclName.
20692070
// Unfortunately only some places in the grammar are ok with accepting this
20702071
// kind of name; in other places it's ambiguous with trailing calls.
20712072
if (allowZeroArgCompoundNames && peekToken().is(tok::r_paren)) {
2073+
SyntaxParsingContext ArgsCtxt(SyntaxContext, SyntaxKind::DeclNameArguments);
20722074
consumeToken(tok::l_paren);
2075+
if (SyntaxContext->isEnabled())
2076+
SyntaxContext->addSyntax(SyntaxFactory::makeBlankDeclNameArgumentList());
20732077
consumeToken(tok::r_paren);
20742078
loc = DeclNameLoc(baseNameLoc);
20752079
SmallVector<Identifier, 2> argumentLabels;
@@ -2084,26 +2088,21 @@ DeclName Parser::parseUnqualifiedDeclName(bool afterDot,
20842088
return baseName;
20852089
}
20862090

2087-
// TODO: Support compound name in libSyntax.
2088-
20892091
// Try to parse a compound name.
2092+
SyntaxParsingContext ArgsCtxt(SyntaxContext, SyntaxKind::DeclNameArguments);
20902093
BacktrackingScope backtrack(*this);
20912094

20922095
SmallVector<Identifier, 2> argumentLabels;
20932096
SmallVector<SourceLoc, 2> argumentLabelLocs;
20942097
SourceLoc lparenLoc = consumeToken(tok::l_paren);
20952098
SourceLoc rparenLoc;
2096-
while (true) {
2097-
// Terminate at ')'.
2098-
if (Tok.is(tok::r_paren)) {
2099-
rparenLoc = consumeToken(tok::r_paren);
2100-
break;
2101-
}
2099+
while (Tok.isNot(tok::r_paren)) {
2100+
SyntaxParsingContext ArgCtxt(SyntaxContext, SyntaxKind::DeclNameArgument);
21022101

21032102
// If we see a ':', the user forgot the '_';
21042103
if (Tok.is(tok::colon)) {
21052104
diagnose(Tok, diag::empty_arg_label_underscore)
2106-
.fixItInsert(Tok.getLoc(), "_");
2105+
.fixItInsert(Tok.getLoc(), "_");
21072106
argumentLabels.push_back(Identifier());
21082107
argumentLabelLocs.push_back(consumeToken(tok::colon));
21092108
}
@@ -2120,14 +2119,18 @@ DeclName Parser::parseUnqualifiedDeclName(bool afterDot,
21202119
// This is not a compound name.
21212120
// FIXME: Could recover better if we "know" it's a compound name.
21222121
loc = DeclNameLoc(baseNameLoc);
2122+
ArgsCtxt.setDiscard();
21232123
return baseName;
21242124
}
2125+
// We have a compound name. Cancel backtracking and build that name.
2126+
backtrack.cancelBacktrack();
2127+
2128+
ArgsCtxt.collectNodesInPlace(SyntaxKind::DeclNameArgumentList);
2129+
rparenLoc = consumeToken(tok::r_paren);
21252130

21262131
assert(!argumentLabels.empty() && "Logic above should prevent this");
21272132
assert(argumentLabels.size() == argumentLabelLocs.size());
21282133

2129-
// We have a compound name. Cancel backtracking and build that name.
2130-
backtrack.cancelBacktrack();
21312134
loc = DeclNameLoc(Context, baseNameLoc, lparenLoc, argumentLabelLocs,
21322135
rparenLoc);
21332136
return DeclName(Context, baseName, argumentLabels);

lib/Syntax/SyntaxParsingContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind) {
107107

108108
switch (Kind) {
109109
case SyntaxKind::SuperRefExpr:
110-
case SyntaxKind::MemberAccessExpr:
111-
case SyntaxKind::ImplicitMemberExpr:
112110
case SyntaxKind::OptionalChainingExpr:
113111
case SyntaxKind::ForcedValueExpr:
114112
case SyntaxKind::PostfixUnaryExpr:
@@ -118,6 +116,8 @@ void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind) {
118116
createNodeInPlace(Kind, Pair.first);
119117
break;
120118
}
119+
case SyntaxKind::MemberAccessExpr:
120+
case SyntaxKind::ImplicitMemberExpr:
121121
case SyntaxKind::SimpleTypeIdentifier:
122122
case SyntaxKind::MemberTypeIdentifier:
123123
case SyntaxKind::FunctionCallExpr:

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,11 @@ func postfix<FunctionSignature><ParameterClause>() </ParameterClause></FunctionS
218218
foo</IdentifierExpr>[] <ClosureExpr>{}</ClosureExpr></SubscriptExpr><SubscriptExpr><IdentifierExpr>
219219
foo</IdentifierExpr>[<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>] <ClosureExpr>{}</ClosureExpr></SubscriptExpr><SubscriptExpr><SubscriptExpr><IdentifierExpr>
220220
foo</IdentifierExpr>[<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr>[<FunctionCallArgument><IntegerLiteralExpr>2</IntegerLiteralExpr>,</FunctionCallArgument><FunctionCallArgument>x:<IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr><FunctionCallExpr><ForcedValueExpr><MemberAccessExpr><PostfixUnaryExpr><OptionalChainingExpr><IdentifierExpr>
221-
foo</IdentifierExpr>?</OptionalChainingExpr>++</PostfixUnaryExpr>.bar</MemberAccessExpr>!</ForcedValueExpr>(<FunctionCallArgument><IdentifierExpr>baz</IdentifierExpr></FunctionCallArgument>)</FunctionCallExpr>
221+
foo</IdentifierExpr>?</OptionalChainingExpr>++</PostfixUnaryExpr>.bar</MemberAccessExpr>!</ForcedValueExpr>(<FunctionCallArgument><IdentifierExpr>baz</IdentifierExpr></FunctionCallArgument>)</FunctionCallExpr><FunctionCallExpr><IdentifierExpr>
222+
223+
foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></IdentifierExpr>()</FunctionCallExpr><SequenceExpr><DiscardAssignmentExpr>
224+
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ImplicitMemberExpr>.foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></ImplicitMemberExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
225+
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><IdentifierExpr>x</IdentifierExpr>.foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></MemberAccessExpr></SequenceExpr>
222226
}</CodeBlock></FunctionDecl><IfConfigDecl>
223227

224228
#if <IdentifierExpr>blah</IdentifierExpr><ElseDirectiveClause>

test/Syntax/round_trip_parse_gen.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ func postfix() {
219219
foo[1] {}
220220
foo[1][2,x:3]
221221
foo?++.bar!(baz)
222+
223+
foo(x:y:)()
224+
_ = .foo(x:y:)
225+
_ = x.foo(x:y:)
222226
}
223227

224228
#if blah

utils/gyb_syntax_support/ExprNodes.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,29 @@
4444
Child('Expression', kind='Expr'),
4545
]),
4646

47+
# declname-arguments -> '(' declname-argument-list ')'
48+
# declname-argument-list -> declname-argument*
49+
# declname-argument -> identifier ':'
50+
Node('DeclNameArgument', kind='Syntax',
51+
children=[
52+
Child('Name', kind='Token'),
53+
Child('Colon', kind='ColonToken'),
54+
]),
55+
Node('DeclNameArgumentList', kind='SyntaxCollection',
56+
element='DeclNameArgument'),
57+
Node('DeclNameArguments', kind='Syntax',
58+
children=[
59+
Child('LeftParen', kind='LeftParenToken'),
60+
Child('Arguments', kind='DeclNameArgumentList'),
61+
Child('RightParen', kind='RightParenToken'),
62+
]),
63+
4764
# An identifier expression.
4865
Node('IdentifierExpr', kind='Expr',
4966
children=[
5067
Child('Identifier', kind='IdentifierToken'),
68+
Child('DeclNameArguments', kind='DeclNameArguments',
69+
is_optional=True),
5170
]),
5271

5372
# An 'super' expression.
@@ -166,7 +185,9 @@
166185
Node('ImplicitMemberExpr', kind='Expr',
167186
children=[
168187
Child("Dot", kind='PrefixPeriodToken'),
169-
Child("Name", kind='Token')
188+
Child("Name", kind='Token'),
189+
Child('DeclNameArguments', kind='DeclNameArguments',
190+
is_optional=True),
170191
]),
171192

172193
# function-call-argument -> label? ':'? expression ','?
@@ -248,7 +269,9 @@
248269
children=[
249270
Child("Base", kind='Expr'),
250271
Child("Dot", kind='PeriodToken'),
251-
Child("Name", kind='Token')
272+
Child("Name", kind='Token'),
273+
Child('DeclNameArguments', kind='DeclNameArguments',
274+
is_optional=True),
252275
]),
253276

254277
# is TypeName

0 commit comments

Comments
 (0)