Skip to content

Commit cf337a7

Browse files
authored
Merge pull request #60731 from rintaro/syntax-unresolved-as-is
[Syntax] Introduce UnresolvedIsExpr/UnresolvedAsExpr
2 parents e121dd3 + ed34dfc commit cf337a7

File tree

5 files changed

+61
-18
lines changed

5 files changed

+61
-18
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,15 @@ ParserResult<Expr> Parser::parseExprImpl(Diag<> Message,
7272
/// expr-is:
7373
/// 'is' type
7474
ParserResult<Expr> Parser::parseExprIs() {
75-
SourceLoc isLoc = consumeToken(tok::kw_is);
75+
SourceLoc isLoc;
76+
{
77+
SyntaxParsingContext IsExprCtx(SyntaxContext, SyntaxKind::UnresolvedIsExpr);
78+
isLoc = consumeToken(tok::kw_is);
79+
}
7680

7781
ParserResult<TypeRepr> type = parseType(diag::expected_type_after_is);
82+
SyntaxContext->createNodeInPlace(SyntaxKind::TypeExpr);
83+
7884
if (type.hasCodeCompletion())
7985
return makeParserCodeCompletionResult<Expr>();
8086
if (type.isNull())
@@ -89,19 +95,25 @@ ParserResult<Expr> Parser::parseExprIs() {
8995
/// 'as?' type
9096
/// 'as!' type
9197
ParserResult<Expr> Parser::parseExprAs() {
92-
// Parse the 'as'.
93-
SourceLoc asLoc = consumeToken(tok::kw_as);
94-
95-
// Parse the postfix '?'.
98+
SourceLoc asLoc;
9699
SourceLoc questionLoc;
97100
SourceLoc exclaimLoc;
98-
if (Tok.is(tok::question_postfix)) {
99-
questionLoc = consumeToken(tok::question_postfix);
100-
} else if (Tok.is(tok::exclaim_postfix)) {
101-
exclaimLoc = consumeToken(tok::exclaim_postfix);
101+
102+
{
103+
SyntaxParsingContext AsExprCtx(SyntaxContext, SyntaxKind::UnresolvedAsExpr);
104+
// Parse the 'as'.
105+
asLoc = consumeToken(tok::kw_as);
106+
107+
// Parse the postfix '?'.
108+
if (Tok.is(tok::question_postfix)) {
109+
questionLoc = consumeToken(tok::question_postfix);
110+
} else if (Tok.is(tok::exclaim_postfix)) {
111+
exclaimLoc = consumeToken(tok::exclaim_postfix);
112+
}
102113
}
103114

104115
ParserResult<TypeRepr> type = parseType(diag::expected_type_after_as);
116+
SyntaxContext->createNodeInPlace(SyntaxKind::TypeExpr);
105117

106118
if (type.hasCodeCompletion())
107119
return makeParserCodeCompletionResult<Expr>();
@@ -295,7 +307,6 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
295307
}
296308

297309
case tok::kw_is: {
298-
SyntaxParsingContext IsContext(SyntaxContext, SyntaxKind::IsExpr);
299310
// Parse a type after the 'is' token instead of an expression.
300311
ParserResult<Expr> is = parseExprIs();
301312
if (is.isNull() || is.hasCodeCompletion())
@@ -313,7 +324,6 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
313324
}
314325

315326
case tok::kw_as: {
316-
SyntaxParsingContext AsContext(SyntaxContext, SyntaxKind::AsExpr);
317327
ParserResult<Expr> as = parseExprAs();
318328
if (as.isNull() || as.hasCodeCompletion())
319329
return as;

lib/Parse/SyntaxParsingContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind,
278278
case SyntaxKind::AvailabilityLabeledArgument:
279279
case SyntaxKind::MetatypeType:
280280
case SyntaxKind::OptionalType:
281-
case SyntaxKind::ImplicitlyUnwrappedOptionalType: {
281+
case SyntaxKind::ImplicitlyUnwrappedOptionalType:
282+
case SyntaxKind::TypeExpr: {
282283
auto Pair = SyntaxFactory::countChildren(Kind);
283284
assert(Pair.first == Pair.second);
284285
createNodeInPlace(Kind, Pair.first, nodeCreateK);

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ class C <MemberDeclBlock>{<MemberDeclListItem><FunctionDecl>
7878
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><IdentifierExpr>a</IdentifierExpr>.b</MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
7979
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><IntegerLiteralExpr>1</IntegerLiteralExpr>.a</MemberAccessExpr></SequenceExpr><MemberAccessExpr><MemberAccessExpr><MemberAccessExpr><TupleExpr>
8080
(<TupleExprElement><SequenceExpr><IntegerLiteralExpr>1 </IntegerLiteralExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><IntegerLiteralExpr>1</IntegerLiteralExpr></SequenceExpr></TupleExprElement>)</TupleExpr>.a</MemberAccessExpr>.b</MemberAccessExpr>.foo</MemberAccessExpr><SequenceExpr><DiscardAssignmentExpr>
81-
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>a </IdentifierExpr><AsExpr>as <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></AsExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><IdentifierExpr>a </IdentifierExpr><AsExpr>as! <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></AsExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><IdentifierExpr>a </IdentifierExpr><AsExpr>as? <SimpleTypeIdentifier>Bool</SimpleTypeIdentifier></AsExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
82-
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>a </IdentifierExpr><IsExpr>is <SimpleTypeIdentifier>Bool</SimpleTypeIdentifier></IsExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
81+
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>a </IdentifierExpr><UnresolvedAsExpr>as </UnresolvedAsExpr><TypeExpr><SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></TypeExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><IdentifierExpr>a </IdentifierExpr><UnresolvedAsExpr>as! </UnresolvedAsExpr><TypeExpr><SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></TypeExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><IdentifierExpr>a </IdentifierExpr><UnresolvedAsExpr>as? </UnresolvedAsExpr><TypeExpr><SimpleTypeIdentifier>Bool</SimpleTypeIdentifier></TypeExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
82+
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>a </IdentifierExpr><UnresolvedIsExpr>is </UnresolvedIsExpr><TypeExpr><SimpleTypeIdentifier>Bool</SimpleTypeIdentifier></TypeExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
8383
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>self</IdentifierExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
8484
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>Self</IdentifierExpr></SequenceExpr>
8585
}</CodeBlock></FunctionDecl></MemberDeclListItem><MemberDeclListItem><FunctionDecl>
@@ -326,13 +326,13 @@ private </DeclModifier><DeclModifier>final </DeclModifier>class D <MemberDeclBlo
326326
do <CodeBlock>{<SwitchStmt>
327327
switch <IdentifierExpr>foo </IdentifierExpr>{<SwitchCase><SwitchCaseLabel>
328328
case <CaseItem><ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
329-
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
329+
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><UnresolvedAsExpr>as </UnresolvedAsExpr><TypeExpr><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TypeExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
330330
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><TupleExpr>(<TupleExprElement><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>, </TupleExprElement><TupleExprElement><UnresolvedPatternExpr><IdentifierPattern>b</IdentifierPattern></UnresolvedPatternExpr></TupleExprElement>)</TupleExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
331331
case <CaseItem><ExpressionPattern><TupleExpr>(<TupleExprElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleExprElement><TupleExprElement><UnresolvedPatternExpr><ValueBindingPattern>var <IdentifierPattern>b</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></TupleExprElement>)</TupleExpr></ExpressionPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
332332
case <CaseItem><IsTypePattern>is <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></IsTypePattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
333333
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><FunctionCallExpr><MemberAccessExpr>.bar</MemberAccessExpr>(<TupleExprElement><UnresolvedPatternExpr><IdentifierPattern>x</IdentifierPattern></UnresolvedPatternExpr></TupleExprElement>)</FunctionCallExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
334334
case <CaseItem><ExpressionPattern><MemberAccessExpr><IdentifierExpr>MyEnum</IdentifierExpr>.foo</MemberAccessExpr></ExpressionPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
335-
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
335+
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><UnresolvedAsExpr>as </UnresolvedAsExpr><TypeExpr><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TypeExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
336336
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><OptionalChainingExpr><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>?</OptionalChainingExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase>
337337
}</SwitchStmt>
338338
}</CodeBlock></DoStmt><FunctionDecl>

utils/gyb_syntax_support/ExprNodes.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,16 +351,46 @@
351351
is_optional=True),
352352
]),
353353

354-
# is TypeName
354+
# 'is'
355+
# "is" type casting ooperator without operands.
356+
# NOTE: This appears only in SequenceExpr.
357+
Node('UnresolvedIsExpr', kind='Expr',
358+
children=[
359+
Child("IsTok", kind='IsToken'),
360+
]),
361+
362+
# expression is TypeName
363+
# NOTE: This won't come directly out of the parser. Rather, it is the
364+
# result of "folding" a SequenceExpr based on knowing the precedence
365+
# relationships amongst the different infix operators.
355366
Node('IsExpr', kind='Expr',
356367
children=[
368+
Child("Expression", kind="Expr"),
357369
Child("IsTok", kind='IsToken'),
358370
Child("TypeName", kind='Type')
359371
]),
360372

361-
# as TypeName
373+
# 'as' ('?'|'!')
374+
# "as" type casting ooperator without operands.
375+
# NOTE: This appears only in SequenceExpr.
376+
Node('UnresolvedAsExpr', kind='Expr',
377+
children=[
378+
Child("AsTok", kind='AsToken'),
379+
Child("QuestionOrExclamationMark", kind='Token',
380+
is_optional=True,
381+
token_choices=[
382+
'PostfixQuestionMarkToken',
383+
'ExclamationMarkToken',
384+
]),
385+
]),
386+
387+
# expression as TypeName
388+
# NOTE: This won't come directly out of the parser. Rather, it is the
389+
# result of "folding" a SequenceExpr based on knowing the precedence
390+
# relationships amongst the different infix operators.
362391
Node('AsExpr', kind='Expr',
363392
children=[
393+
Child("Expression", kind="Expr"),
364394
Child("AsTok", kind='AsToken'),
365395
Child("QuestionOrExclamationMark", kind='Token',
366396
is_optional=True,

utils/gyb_syntax_support/NodeSerializationCodes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@
272272
'InfixOperatorExpr': 268,
273273
'MoveExpr': 269,
274274
'UnresolvedTernaryExpr': 270,
275+
'UnresolvedIsExpr': 271,
276+
'UnresolvedAsExpr': 272,
275277
}
276278

277279

0 commit comments

Comments
 (0)