Skip to content

Commit 62eb271

Browse files
committed
[Syntax] Parse 'init', 'deinit' and 'subscript' decl syntax
1 parent 77e417f commit 62eb271

File tree

4 files changed

+115
-23
lines changed

4 files changed

+115
-23
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,9 +2475,13 @@ Parser::parseDecl(ParseDeclOptions Flags,
24752475
break;
24762476
}
24772477
case tok::kw_init:
2478+
DeclParsingContext.collectNodesInPlace(SyntaxKind::ModifierList);
2479+
DeclParsingContext.setCreateSyntax(SyntaxKind::InitializerDecl);
24782480
DeclResult = parseDeclInit(Flags, Attributes);
24792481
break;
24802482
case tok::kw_deinit:
2483+
DeclParsingContext.collectNodesInPlace(SyntaxKind::ModifierList);
2484+
DeclParsingContext.setCreateSyntax(SyntaxKind::DeinitializerDecl);
24812485
DeclResult = parseDeclDeinit(Flags, Attributes);
24822486
break;
24832487
case tok::kw_operator:
@@ -2501,6 +2505,8 @@ Parser::parseDecl(ParseDeclOptions Flags,
25012505
break;
25022506

25032507
case tok::kw_subscript: {
2508+
DeclParsingContext.collectNodesInPlace(SyntaxKind::ModifierList);
2509+
DeclParsingContext.setCreateSyntax(SyntaxKind::SubscriptDecl);
25042510
if (StaticLoc.isValid()) {
25052511
diagnose(Tok, diag::subscript_static, StaticSpelling)
25062512
.fixItRemove(SourceRange(StaticLoc));
@@ -5821,30 +5827,36 @@ Parser::parseDeclSubscript(ParseDeclOptions Flags,
58215827
if (SignatureHasCodeCompletion && !CodeCompletion)
58225828
return makeParserCodeCompletionStatus();
58235829

5824-
// '->'
58255830
SourceLoc ArrowLoc;
5826-
if (!consumeIf(tok::arrow, ArrowLoc)) {
5827-
if (!Indices.isParseError())
5828-
diagnose(Tok, diag::expected_arrow_subscript);
5829-
Status.setIsParseError();
5830-
}
5831+
ParserResult<TypeRepr> ElementTy;
5832+
{
5833+
SyntaxParsingContext ReturnCtxt(SyntaxContext, SyntaxKind::ReturnClause);
58315834

5832-
if (!ArrowLoc.isValid() && (Indices.isNull() || Indices.get()->size() == 0)) {
5833-
// This doesn't look much like a subscript, so let regular recovery take
5834-
// care of it.
5835-
return Status;
5836-
}
5837-
5838-
// type
5839-
ParserResult<TypeRepr> ElementTy = parseType(diag::expected_type_subscript);
5840-
Status |= ElementTy;
5841-
SignatureHasCodeCompletion |= ElementTy.hasCodeCompletion();
5842-
if (SignatureHasCodeCompletion && !CodeCompletion) {
5843-
return makeParserCodeCompletionStatus();
5844-
}
5845-
if (ElementTy.isNull()) {
5846-
// Always set an element type.
5847-
ElementTy = makeParserResult(ElementTy, new (Context) ErrorTypeRepr());
5835+
// '->'
5836+
if (!consumeIf(tok::arrow, ArrowLoc)) {
5837+
if (!Indices.isParseError())
5838+
diagnose(Tok, diag::expected_arrow_subscript);
5839+
Status.setIsParseError();
5840+
}
5841+
5842+
if (!ArrowLoc.isValid() &&
5843+
(Indices.isNull() || Indices.get()->size() == 0)) {
5844+
// This doesn't look much like a subscript, so let regular recovery take
5845+
// care of it.
5846+
return Status;
5847+
}
5848+
5849+
// type
5850+
ElementTy = parseType(diag::expected_type_subscript);
5851+
Status |= ElementTy;
5852+
SignatureHasCodeCompletion |= ElementTy.hasCodeCompletion();
5853+
if (SignatureHasCodeCompletion && !CodeCompletion) {
5854+
return makeParserCodeCompletionStatus();
5855+
}
5856+
if (ElementTy.isNull()) {
5857+
// Always set an element type.
5858+
ElementTy = makeParserResult(ElementTy, new (Context) ErrorTypeRepr());
5859+
}
58485860
}
58495861

58505862
diagnoseWhereClauseInGenericParamList(GenericParams);

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,19 @@ class C <MemberDeclBlock>{<FunctionDecl>
8686
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><ImplicitMemberExpr>.foo </ImplicitMemberExpr><ClosureExpr>{ <IntegerLiteralExpr>12 </IntegerLiteralExpr>}</ClosureExpr></FunctionCallExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
8787
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><SubscriptExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr>[<FunctionCallArgument><IntegerLiteralExpr>12</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
8888
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr>.bar</MemberAccessExpr></SequenceExpr>
89-
}</CodeBlock></FunctionDecl>
89+
}</CodeBlock></FunctionDecl><InitializerDecl>
90+
91+
init<ParameterClause>() </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl><InitializerDecl><Attribute>
92+
@objc </Attribute><DeclModifier>private </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>)</ParameterClause></InitializerDecl><InitializerDecl>
93+
init!<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl><InitializerDecl>
94+
init?<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl><InitializerDecl><DeclModifier>
95+
public </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>throws <CodeBlock>{}</CodeBlock></InitializerDecl><DeinitializerDecl><Attribute>
96+
97+
@objc </Attribute>deinit <CodeBlock>{}</CodeBlock></DeinitializerDecl><DeinitializerDecl><DeclModifier>
98+
private </DeclModifier>deinit <CodeBlock>{}</CodeBlock></DeinitializerDecl><SubscriptDecl><DeclModifier>
99+
100+
internal </DeclModifier>subscript<ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><AccessorBlock>{ <AccessorDecl>get <CodeBlock>{} </CodeBlock></AccessorDecl><AccessorDecl>set <CodeBlock>{} </CodeBlock></AccessorDecl>}</AccessorBlock></SubscriptDecl><SubscriptDecl>
101+
subscript<ParameterClause>() </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><AccessorBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</AccessorBlock></SubscriptDecl>
90102
}</MemberDeclBlock></ClassDecl>
91103

92104
#endif</IfConfigDecl><IfConfigDecl>

test/Syntax/round_trip_parse_gen.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ class C {
8787
_ = .foo[12]
8888
_ = .foo.bar
8989
}
90+
91+
init() {}
92+
@objc private init(a: Int)
93+
init!(a: Int) {}
94+
init?(a: Int) {}
95+
public init(a: Int) throws {}
96+
97+
@objc deinit {}
98+
private deinit {}
99+
100+
internal subscript(x: Int) -> Int { get {} set {} }
101+
subscript() -> Int { return 1 }
90102
}
91103

92104
#endif

utils/gyb_syntax_support/DeclNodes.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,62 @@
321321
Child('Body', kind='CodeBlock', is_optional=True),
322322
]),
323323

324+
Node('InitializerDecl', kind='Decl',
325+
children=[
326+
Child('Attributes', kind='AttributeList',
327+
is_optional=True),
328+
Child('Modifiers', kind='ModifierList',
329+
is_optional=True),
330+
Child('InitKeyword', kind='InitToken'),
331+
Child('OptionalMark', kind='Token',
332+
token_choices=[
333+
'PostfixQuestionMarkToken',
334+
'InfixQuestionMarkToken',
335+
'ExclamationMarkToken',
336+
],
337+
is_optional=True),
338+
Child('GenericParameterClause', kind='GenericParameterClause',
339+
is_optional=True),
340+
Child('Parameters', kind='ParameterClause'),
341+
Child('ThrowsOrRethrowsKeyword', kind='Token',
342+
is_optional=True,
343+
token_choices=[
344+
'ThrowsToken',
345+
'RethrowsToken',
346+
]),
347+
Child('GenericWhereClause', kind='GenericWhereClause',
348+
is_optional=True),
349+
# the body is not necessary inside a protocol definition
350+
Child('Body', kind='CodeBlock', is_optional=True),
351+
]),
352+
353+
Node('DeinitializerDecl', kind='Decl',
354+
children=[
355+
Child('Attributes', kind='AttributeList',
356+
is_optional=True),
357+
Child('Modifiers', kind='ModifierList',
358+
is_optional=True),
359+
Child('DeinitKeyword', kind='DeinitToken'),
360+
Child('Body', kind='CodeBlock'),
361+
]),
362+
363+
Node('SubscriptDecl', kind='Decl',
364+
children=[
365+
Child('Attributes', kind='AttributeList',
366+
is_optional=True),
367+
Child('Modifiers', kind='ModifierList',
368+
is_optional=True),
369+
Child('SubscriptKeyword', kind='SubscriptToken'),
370+
Child('GenericParameterClause', kind='GenericParameterClause',
371+
is_optional=True),
372+
Child('Indices', kind='ParameterClause'),
373+
Child('Result', kind='ReturnClause'),
374+
Child('GenericWhereClause', kind='GenericWhereClause',
375+
is_optional=True),
376+
# the body is not necessary inside a protocol definition
377+
Child('Accessor', kind='AccessorBlock', is_optional=True),
378+
]),
379+
324380
# else-if-directive-clause-list -> else-if-directive-clause
325381
# else-if-directive-clause-list?
326382
Node('ElseifDirectiveClauseList', kind='SyntaxCollection',

0 commit comments

Comments
 (0)