Skip to content

Commit 7d9a885

Browse files
authored
Merge pull request #13576 from rintaro/syntax-stmt
[Syntax] Parse several statement nodes.
2 parents b5bc7bd + cd429a4 commit 7d9a885

File tree

6 files changed

+105
-31
lines changed

6 files changed

+105
-31
lines changed

lib/Parse/ParseStmt.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,12 +569,15 @@ ParserResult<Stmt> Parser::parseStmt() {
569569
if (LabelInfo) diagnose(LabelInfo.Loc, diag::invalid_label_on_stmt);
570570
if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
571571
return parseStmtContinue();
572-
case tok::kw_fallthrough:
572+
case tok::kw_fallthrough: {
573573
if (LabelInfo) diagnose(LabelInfo.Loc, diag::invalid_label_on_stmt);
574574
if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
575+
576+
SyntaxContext->setCreateSyntax(SyntaxKind::FallthroughStmt);
575577
return makeParserResult(
576578
new (Context) FallthroughStmt(consumeToken(tok::kw_fallthrough)));
577579
}
580+
}
578581
}
579582

580583
/// parseBraceItemList - A brace enclosed expression/statement/decl list. For
@@ -615,6 +618,7 @@ ParserResult<BraceStmt> Parser::parseBraceItemList(Diag<> ID) {
615618
/// 'break' identifier?
616619
///
617620
ParserResult<Stmt> Parser::parseStmtBreak() {
621+
SyntaxContext->setCreateSyntax(SyntaxKind::BreakStmt);
618622
SourceLoc Loc = consumeToken(tok::kw_break);
619623
SourceLoc TargetLoc;
620624
Identifier Target;
@@ -637,6 +641,7 @@ ParserResult<Stmt> Parser::parseStmtBreak() {
637641
/// 'continue' identifier?
638642
///
639643
ParserResult<Stmt> Parser::parseStmtContinue() {
644+
SyntaxContext->setCreateSyntax(SyntaxKind::ContinueStmt);
640645
SourceLoc Loc = consumeToken(tok::kw_continue);
641646
SourceLoc TargetLoc;
642647
Identifier Target;
@@ -660,7 +665,7 @@ ParserResult<Stmt> Parser::parseStmtContinue() {
660665
/// 'return' expr?
661666
///
662667
ParserResult<Stmt> Parser::parseStmtReturn(SourceLoc tryLoc) {
663-
SyntaxParsingContext LocalContext(SyntaxContext, SyntaxKind::ReturnStmt);
668+
SyntaxContext->setCreateSyntax(SyntaxKind::ReturnStmt);
664669
SourceLoc ReturnLoc = consumeToken(tok::kw_return);
665670

666671
if (Tok.is(tok::code_complete)) {
@@ -725,6 +730,7 @@ ParserResult<Stmt> Parser::parseStmtReturn(SourceLoc tryLoc) {
725730
/// 'throw' expr
726731
///
727732
ParserResult<Stmt> Parser::parseStmtThrow(SourceLoc tryLoc) {
733+
SyntaxContext->setCreateSyntax(SyntaxKind::ThrowStmt);
728734
SourceLoc throwLoc = consumeToken(tok::kw_throw);
729735
SourceLoc exprLoc;
730736
if (Tok.isNot(tok::eof))
@@ -759,6 +765,7 @@ ParserResult<Stmt> Parser::parseStmtThrow(SourceLoc tryLoc) {
759765
/// 'defer' brace-stmt
760766
///
761767
ParserResult<Stmt> Parser::parseStmtDefer() {
768+
SyntaxContext->setCreateSyntax(SyntaxKind::DeferStmt);
762769
SourceLoc DeferLoc = consumeToken(tok::kw_defer);
763770

764771
// Macro expand out the defer into a closure and call, which we can typecheck
@@ -991,7 +998,10 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result,
991998
VD->setHasNonPatternBindingInit();
992999

9931000
// Parse the optional 'where' guard.
994-
if (P.consumeIf(tok::kw_where, result.WhereLoc)) {
1001+
if (P.Tok.is(tok::kw_where)) {
1002+
SyntaxParsingContext WhereClauseCtxt(P.SyntaxContext,
1003+
SyntaxKind::WhereClause);
1004+
result.WhereLoc = P.consumeToken(tok::kw_where);
9951005
SourceLoc startOfGuard = P.Tok.getLoc();
9961006

9971007
auto diagKind = [=]() -> Diag<> {
@@ -1615,6 +1625,7 @@ ParserResult<Stmt> Parser::parseStmtWhile(LabeledStmtInfo LabelInfo) {
16151625
/// stmt-repeat:
16161626
/// (identifier ':')? 'repeat' stmt-brace 'while' expr
16171627
ParserResult<Stmt> Parser::parseStmtRepeat(LabeledStmtInfo labelInfo) {
1628+
SyntaxContext->setCreateSyntax(SyntaxKind::RepeatWhileStmt);
16181629
SourceLoc repeatLoc = consumeToken(tok::kw_repeat);
16191630

16201631
ParserStatus status;
@@ -1658,6 +1669,7 @@ ParserResult<Stmt> Parser::parseStmtRepeat(LabeledStmtInfo labelInfo) {
16581669
/// (identifier ':')? 'do' stmt-brace
16591670
/// (identifier ':')? 'do' stmt-brace stmt-catch+
16601671
ParserResult<Stmt> Parser::parseStmtDo(LabeledStmtInfo labelInfo) {
1672+
SyntaxContext->setCreateSyntax(SyntaxKind::DoStmt);
16611673
SourceLoc doLoc = consumeToken(tok::kw_do);
16621674

16631675
ParserStatus status;
@@ -1671,6 +1683,8 @@ ParserResult<Stmt> Parser::parseStmtDo(LabeledStmtInfo labelInfo) {
16711683

16721684
// If the next token is 'catch', this is a 'do'/'catch' statement.
16731685
if (Tok.is(tok::kw_catch)) {
1686+
SyntaxParsingContext CatchListCtxt(SyntaxContext,
1687+
SyntaxKind::CatchClauseList);
16741688
// Parse 'catch' clauses
16751689
SmallVector<CatchStmt*, 4> allClauses;
16761690
do {
@@ -1736,6 +1750,7 @@ ParserResult<Stmt> Parser::parseStmtDo(LabeledStmtInfo labelInfo) {
17361750
/// This routine promises to return a non-null result unless there was
17371751
/// a code-completion token in the pattern.
17381752
ParserResult<CatchStmt> Parser::parseStmtCatch() {
1753+
SyntaxParsingContext CatchClauseCtxt(SyntaxContext, SyntaxKind::CatchClause);
17391754
// A catch block has its own scope for variables bound out of the pattern.
17401755
Scope S(this, ScopeKind::CatchVars);
17411756

lib/Syntax/Status.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,25 +91,21 @@
9191
### Done:
9292
* BraceStmt
9393
* ReturnStmt
94-
95-
### Not-started (UnknownStmt):
9694
* DeferStmt
97-
* IfStmt
98-
* GuardStmt
99-
* WhileStmt
10095
* DoStmt
101-
* DoCatchStmt
10296
* RepeatWhileStmt
103-
* ForEachStmt
104-
* SwitchStmt
105-
* CaseStmt
106-
* CatchStmt
10797
* BreakStmt
10898
* ContinueStmt
10999
* FallthroughStmt
110-
* FailStmt
111100
* ThrowStmt
112101

102+
### Not-started (UnknownStmt):
103+
* IfStmt
104+
* GuardStmt
105+
* WhileStmt
106+
* ForEachStmt
107+
* SwitchStmt
108+
113109
## Pattern
114110
### Done:
115111
* IdentifierPattern

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -221,18 +221,49 @@ class C <MemberDeclBlock>{<VariableDecl><Attribute>
221221
for <ValueBindingPattern>let <TuplePattern>(<TuplePatternElement><IdentifierPattern>x</IdentifierPattern>, </TuplePatternElement><TuplePatternElement><WildcardPattern>_</WildcardPattern></TuplePatternElement>) </TuplePattern></ValueBindingPattern>in <IdentifierExpr>foo </IdentifierExpr><CodeBlock>{}</CodeBlock>
222222
for <ValueBindingPattern>var <IdentifierPattern>x</IdentifierPattern></ValueBindingPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation>in <IdentifierExpr>foo </IdentifierExpr><CodeBlock>{}</CodeBlock>
223223
}</CodeBlock></FunctionDecl>
224-
}</MemberDeclBlock></ClassDecl>
224+
}</MemberDeclBlock></ClassDecl><DoStmt>
225225

226226
do <CodeBlock>{
227227
switch <IdentifierExpr>foo </IdentifierExpr>{
228-
case <ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern>: break
229-
case <ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern>: break
230-
case <ValueBindingPattern>let <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><IdentifierPattern>b</IdentifierPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern></ValueBindingPattern>: break
231-
case <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><ValueBindingPattern>var <IdentifierPattern>b</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern>: break
232-
case <IsTypePattern>is <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></IsTypePattern>: break
233-
case <ValueBindingPattern>let <ExpressionPattern>.bar(<FunctionCallArgument><UnresolvedPatternExpr><IdentifierPattern>x</IdentifierPattern></UnresolvedPatternExpr></FunctionCallArgument>)</ExpressionPattern></ValueBindingPattern>: break
234-
case <ExpressionPattern><MemberAccessExpr><IdentifierExpr>MyEnum</IdentifierExpr>.foo</MemberAccessExpr></ExpressionPattern>: break
235-
case <ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern>: break
236-
case <ValueBindingPattern>let <ExpressionPattern><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>?</ExpressionPattern></ValueBindingPattern>: break
228+
case <ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
229+
case <ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
230+
case <ValueBindingPattern>let <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><IdentifierPattern>b</IdentifierPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
231+
case <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><ValueBindingPattern>var <IdentifierPattern>b</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern>: <BreakStmt>break</BreakStmt>
232+
case <IsTypePattern>is <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></IsTypePattern>: <BreakStmt>break</BreakStmt>
233+
case <ValueBindingPattern>let <ExpressionPattern>.bar(<FunctionCallArgument><UnresolvedPatternExpr><IdentifierPattern>x</IdentifierPattern></UnresolvedPatternExpr></FunctionCallArgument>)</ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
234+
case <ExpressionPattern><MemberAccessExpr><IdentifierExpr>MyEnum</IdentifierExpr>.foo</MemberAccessExpr></ExpressionPattern>: <BreakStmt>break</BreakStmt>
235+
case <ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
236+
case <ValueBindingPattern>let <ExpressionPattern><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>?</ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
237+
}
238+
}</CodeBlock></DoStmt><FunctionDecl>
239+
240+
func statementTests<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<DoStmt>
241+
do <CodeBlock>{
242+
} </CodeBlock><CatchClause>catch <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>var <IdentifierPattern>x</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>y</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></TupleElement>) </TupleExpr></ExpressionPattern><CodeBlock>{
243+
} </CodeBlock></CatchClause><CatchClause>catch <WhereClause>where <BooleanLiteralExpr>false </BooleanLiteralExpr></WhereClause><CodeBlock>{
244+
} </CodeBlock></CatchClause><CatchClause>catch <ValueBindingPattern>let <IdentifierPattern>e </IdentifierPattern></ValueBindingPattern><WhereClause>where <SequenceExpr><MemberAccessExpr><IdentifierExpr>e</IdentifierExpr>.foo </MemberAccessExpr><BinaryOperatorExpr>== </BinaryOperatorExpr><IdentifierExpr>bar </IdentifierExpr></SequenceExpr></WhereClause><CodeBlock>{
245+
} </CodeBlock></CatchClause><CatchClause>catch <CodeBlock>{
246+
}</CodeBlock></CatchClause></DoStmt><RepeatWhileStmt>
247+
repeat <CodeBlock>{ } </CodeBlock>while <BooleanLiteralExpr>true</BooleanLiteralExpr></RepeatWhileStmt><RepeatWhileStmt>
248+
LABEL: repeat <CodeBlock>{ } </CodeBlock>while <BooleanLiteralExpr>false</BooleanLiteralExpr></RepeatWhileStmt><DoStmt>
249+
LABEL: do <CodeBlock>{}</CodeBlock></DoStmt>
250+
LABEL: switch <IdentifierExpr>foo </IdentifierExpr>{
251+
case <ExpressionPattern><IntegerLiteralExpr>1</IntegerLiteralExpr></ExpressionPattern>:<FallthroughStmt>
252+
fallthrough</FallthroughStmt>
253+
case <ExpressionPattern><IntegerLiteralExpr>2</IntegerLiteralExpr></ExpressionPattern>:<BreakStmt>
254+
break LABEL</BreakStmt>
255+
case <ExpressionPattern><IntegerLiteralExpr>3</IntegerLiteralExpr></ExpressionPattern>:<BreakStmt>
256+
break</BreakStmt>
237257
}
238-
}</CodeBlock>
258+
259+
for <IdentifierPattern>a </IdentifierPattern>in <IdentifierExpr>b </IdentifierExpr><CodeBlock>{<DeferStmt>
260+
defer <CodeBlock>{ <TupleExpr>() </TupleExpr>}</CodeBlock></DeferStmt>
261+
if <IdentifierExpr>c </IdentifierExpr><CodeBlock>{<ThrowStmt>
262+
throw <IdentifierExpr>MyError</IdentifierExpr>()</ThrowStmt><ContinueStmt>
263+
continue</ContinueStmt>
264+
} </CodeBlock>else <CodeBlock>{<ContinueStmt>
265+
continue LABEL</ContinueStmt>
266+
}</CodeBlock>
267+
}</CodeBlock>
268+
269+
}</CodeBlock></FunctionDecl>

test/Syntax/round_trip_parse_gen.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,34 @@ do {
236236
case let a?: break
237237
}
238238
}
239+
240+
func statementTests() {
241+
do {
242+
} catch (var x, let y) {
243+
} catch where false {
244+
} catch let e where e.foo == bar {
245+
} catch {
246+
}
247+
repeat { } while true
248+
LABEL: repeat { } while false
249+
LABEL: do {}
250+
LABEL: switch foo {
251+
case 1:
252+
fallthrough
253+
case 2:
254+
break LABEL
255+
case 3:
256+
break
257+
}
258+
259+
for a in b {
260+
defer { () }
261+
if c {
262+
throw MyError()
263+
continue
264+
} else {
265+
continue LABEL
266+
}
267+
}
268+
269+
}

utils/gyb_syntax_support/ExprNodes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@
7474
Child('Elements', kind='ExprList'),
7575
]),
7676

77+
Node('ExprList', kind='SyntaxCollection',
78+
element='Expr',
79+
element_name='Expression'),
80+
7781
# A #line expression.
7882
Node('PoundLineExpr', kind='Expr',
7983
children=[

utils/gyb_syntax_support/StmtNodes.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,10 @@
7373
is_optional=True),
7474
]),
7575

76-
Node('ExprList', kind='SyntaxCollection',
77-
element='Expr',
78-
element_name='Expression'),
79-
8076
Node('WhereClause', kind='Syntax',
8177
children=[
8278
Child('WhereKeyword', kind='WhereToken'),
83-
Child('Expressions', kind='ExprList'),
79+
Child('GuardResult', kind='Expr'),
8480
]),
8581

8682
# for-in-stmt -> label? ':'? 'for' 'case'? pattern 'in' expr 'where'?
@@ -134,7 +130,8 @@
134130
is_optional=True),
135131
Child('DoKeyword', kind='DoToken'),
136132
Child('Body', kind='CodeBlock'),
137-
Child('CatchClauses', kind='CatchClauseList'),
133+
Child('CatchClauses', kind='CatchClauseList',
134+
is_optional=True),
138135
Child('Semicolon', kind='SemicolonToken',
139136
is_optional=True),
140137
]),

0 commit comments

Comments
 (0)