Skip to content

Commit f1202c4

Browse files
authored
Merge pull request #15891 from rintaro/syntax-operator-selector
[Syntax] Parse 'operator' decl and '#selector' expr syntax.
2 parents 0c44efd + 338cedd commit f1202c4

File tree

7 files changed

+91
-11
lines changed

7 files changed

+91
-11
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2519,6 +2519,7 @@ Parser::parseDecl(ParseDeclOptions Flags,
25192519
DeclResult = parseDeclDeinit(Flags, Attributes);
25202520
break;
25212521
case tok::kw_operator:
2522+
DeclParsingContext.setCreateSyntax(SyntaxKind::OperatorDecl);
25222523
DeclResult = parseDeclOperator(Flags, Attributes);
25232524
break;
25242525
case tok::kw_precedencegroup:
@@ -6304,7 +6305,9 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
63046305
SourceLoc colonLoc;
63056306
Identifier precedenceGroupName;
63066307
SourceLoc precedenceGroupNameLoc;
6307-
if (consumeIf(tok::colon, colonLoc)) {
6308+
if (Tok.is(tok::colon)) {
6309+
SyntaxParsingContext GroupCtxt(SyntaxContext, SyntaxKind::InfixOperatorGroup);
6310+
colonLoc = consumeToken();
63086311
if (Tok.is(tok::identifier)) {
63096312
precedenceGroupName = Context.getIdentifier(Tok.getText());
63106313
precedenceGroupNameLoc = consumeToken(tok::identifier);

lib/Parse/ParseExpr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ ParserResult<Expr> Parser::parseExprKeyPathObjC() {
727727
/// '#selector' '(' 'setter' ':' expr ')'
728728
///
729729
ParserResult<Expr> Parser::parseExprSelector() {
730+
SyntaxParsingContext ExprCtxt(SyntaxContext, SyntaxKind::ObjcSelectorExpr);
730731
// Consume '#selector'.
731732
SourceLoc keywordLoc = consumeToken(tok::pound_selector);
732733

@@ -750,7 +751,8 @@ ParserResult<Expr> Parser::parseExprSelector() {
750751
else
751752
selectorKind = ObjCSelectorExpr::Setter;
752753

753-
modifierLoc = consumeToken(tok::identifier);
754+
Tok.setKind(tok::contextual_keyword);
755+
modifierLoc = consumeToken();
754756
(void)consumeToken(tok::colon);
755757
} else {
756758
selectorKind = ObjCSelectorExpr::Method;

lib/Syntax/Status.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
* IsExpr
4444
* AsExpr
4545
* ArrowExpr
46-
47-
### Not-started (UnknownExpr):
4846
* ObjCSelectorExpr
4947

5048
## Declaration
@@ -67,13 +65,9 @@
6765
* DestructorDecl
6866
* EnumDecl
6967
* EnumCaseDecl
68+
* OperatorDecl
7069
* PrecedenceGroupDecl
7170

72-
### Not-started (UnknownDecl):
73-
* InfixOperatorDecl
74-
* PrefixOperatorDecl
75-
* PostfixOperatorDecl
76-
7771
## Statement
7872
### Done:
7973
* BraceStmt

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,15 @@ func keypath<FunctionSignature><ParameterClause>() </ParameterClause></FunctionS
440440
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><KeyPathExpr>\<MemberAccessExpr>.a.b</MemberAccessExpr></KeyPathExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
441441
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ObjcKeyPathExpr>#keyPath(<ObjcNamePiece>a.</ObjcNamePiece><ObjcNamePiece>b.</ObjcNamePiece><ObjcNamePiece>c</ObjcNamePiece>)</ObjcKeyPathExpr></SequenceExpr>
442442
}</CodeBlock></FunctionDecl><FunctionDecl>
443+
func objcSelector<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
444+
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ArrayExpr>[<ArrayElement><ObjcSelectorExpr>
445+
#selector(getter: <MemberAccessExpr><IdentifierExpr>Foo</IdentifierExpr>.bar</MemberAccessExpr>)</ObjcSelectorExpr>,</ArrayElement><ArrayElement><ObjcSelectorExpr>
446+
#selector(setter: <MemberAccessExpr><MemberAccessExpr><IdentifierExpr>Foo</IdentifierExpr>.Bar</MemberAccessExpr>.baz</MemberAccessExpr>)</ObjcSelectorExpr>,</ArrayElement><ArrayElement><ObjcSelectorExpr>
447+
#selector(<MemberAccessExpr><IdentifierExpr>Foo</IdentifierExpr>.method<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></MemberAccessExpr>)</ObjcSelectorExpr>,</ArrayElement><ArrayElement><ObjcSelectorExpr>
448+
#selector(<FunctionCallExpr><MemberAccessExpr><SubscriptExpr><IdentifierExpr>foo</IdentifierExpr>[<FunctionCallArgument><IntegerLiteralExpr>42</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr>.bar</MemberAccessExpr>(<FunctionCallArgument><IdentifierExpr>x</IdentifierExpr></FunctionCallArgument>)</FunctionCallExpr>)</ObjcSelectorExpr>,</ArrayElement><ArrayElement><ObjcSelectorExpr>
449+
#selector(<ClosureExpr>{ <ClosureSignature><ClosureCaptureSignature>[<ClosureCaptureItem><IdentifierExpr>x</IdentifierExpr></ClosureCaptureItem>] </ClosureCaptureSignature>in </ClosureSignature><ReturnStmt>return <NilLiteralExpr>nil </NilLiteralExpr></ReturnStmt>}</ClosureExpr>)</ObjcSelectorExpr></ArrayElement>
450+
]</ArrayExpr></SequenceExpr>
451+
}</CodeBlock></FunctionDecl><FunctionDecl>
443452

444453
func objectLiterals<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<ObjectLiteralExpr>
445454
#fileLiteral(<FunctionCallArgument><IdentifierExpr>a</IdentifierExpr></FunctionCallArgument>)</ObjectLiteralExpr><ObjectLiteralExpr>
@@ -472,4 +481,8 @@ precedencegroup BazPrecedence {<PrecedenceGroupAssociativity>
472481
assignment: true</PrecedenceGroupAssignment><PrecedenceGroupAssociativity>
473482
associativity: right</PrecedenceGroupAssociativity><PrecedenceGroupRelation>
474483
lowerThan: <PrecedenceGroupNameElement>DefaultPrecedence</PrecedenceGroupNameElement></PrecedenceGroupRelation>
475-
}</PrecedenceGroupDecl>
484+
}</PrecedenceGroupDecl><OperatorDecl><DeclModifier>
485+
486+
infix </DeclModifier>operator<++><InfixOperatorGroup>:FooPrecedence</InfixOperatorGroup></OperatorDecl><OperatorDecl><DeclModifier>
487+
prefix </DeclModifier>operator..<<</OperatorDecl><OperatorDecl><DeclModifier>
488+
postfix </DeclModifier>operator <-</OperatorDecl>

test/Syntax/round_trip_parse_gen.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,15 @@ func keypath() {
440440
_ = \.a.b
441441
_ = #keyPath(a.b.c)
442442
}
443+
func objcSelector() {
444+
_ = [
445+
#selector(getter: Foo.bar),
446+
#selector(setter: Foo.Bar.baz),
447+
#selector(Foo.method(x:y:)),
448+
#selector(foo[42].bar(x)),
449+
#selector({ [x] in return nil })
450+
]
451+
}
443452

444453
func objectLiterals() {
445454
#fileLiteral(a)
@@ -473,3 +482,7 @@ precedencegroup BazPrecedence {
473482
associativity: right
474483
lowerThan: DefaultPrecedence
475484
}
485+
486+
infix operator<++>:FooPrecedence
487+
prefix operator..<<
488+
postfix operator <-

utils/gyb_syntax_support/DeclNodes.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,6 @@
335335
Child('Identifier', kind='Token',
336336
token_choices=[
337337
'IdentifierToken',
338-
'OperatorToken',
339338
'UnspacedBinaryOperatorToken',
340339
'SpacedBinaryOperatorToken',
341340
'PrefixOperatorToken',
@@ -592,6 +591,47 @@
592591
''')
593592
]),
594593

594+
# operator-decl -> attribute? modifiers? 'operator' operator
595+
Node('OperatorDecl', kind='Decl', traits=['IdentifiedDecl'],
596+
description='A Swift `operator` declaration.',
597+
children=[
598+
Child('Attributes', kind='AttributeList', is_optional=True,
599+
description='''
600+
The attributes applied to the 'operator' declaration.
601+
'''),
602+
Child('Modifiers', kind='ModifierList', is_optional=True,
603+
description='''
604+
The declaration modifiers applied to the 'operator'
605+
declaration.
606+
'''),
607+
Child('OperatorKeyword', kind='OperatorToken'),
608+
Child('Identifier', kind='Token',
609+
token_choices=[
610+
'UnspacedBinaryOperatorToken',
611+
'SpacedBinaryOperatorToken',
612+
'PrefixOperatorToken',
613+
'PostfixOperatorToken',
614+
]),
615+
Child('InfixOperatorGroup', kind='InfixOperatorGroup',
616+
description='''
617+
Optionally specifiy a precedence group
618+
''',
619+
is_optional=True),
620+
]),
621+
622+
# infix-operator-group -> ':' identifier
623+
Node('InfixOperatorGroup', kind='Syntax',
624+
description='''
625+
A clause to specify precedence group in infix operator declaration.
626+
''',
627+
children=[
628+
Child('Colon', kind='ColonToken'),
629+
Child('PrecedenceGroupName', kind='IdentifierToken',
630+
description='''
631+
The name of the precedence group for the operator
632+
'''),
633+
]),
634+
595635
# precedence-group-decl -> attributes? modifiers? 'precedencegroup'
596636
# identifier '{' precedence-group-attribute-list
597637
# '}'

utils/gyb_syntax_support/ExprNodes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,21 @@
518518
Child('RightParen', kind='RightParenToken'),
519519
]),
520520

521+
# e.g. "#selector(getter:Foo.bar)"
522+
Node('ObjcSelectorExpr', kind='Expr',
523+
traits=['Parenthesized'],
524+
children=[
525+
Child('PoundSelector', kind='PoundSelectorToken'),
526+
Child('LeftParen', kind='LeftParenToken'),
527+
Child('Kind', kind='ContextualKeywordToken',
528+
text_choices=['getter', 'setter'],
529+
is_optional=True),
530+
Child('Colon', kind='ColonToken',
531+
is_optional=True),
532+
Child('Name', kind='Expr'),
533+
Child('RightParen', kind='RightParenToken'),
534+
]),
535+
521536
# <#content#>
522537
Node('EditorPlaceholderExpr', kind='Expr',
523538
children=[

0 commit comments

Comments
 (0)