Skip to content

Commit d6692b6

Browse files
authored
Merge pull request swiftlang#15682 from rintaro/syntax-ifconfig
[Syntax] Redesign IfConfigDecl syntax
2 parents 3ee5954 + fc3cbcd commit d6692b6

File tree

4 files changed

+52
-70
lines changed

4 files changed

+52
-70
lines changed

lib/Parse/ParseIfConfig.cpp

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -648,46 +648,25 @@ static Expr *findAnyLikelySimulatorEnvironmentTest(Expr *Condition) {
648648
ParserResult<IfConfigDecl> Parser::parseIfConfig(
649649
llvm::function_ref<void(SmallVectorImpl<ASTNode> &, bool)> parseElements) {
650650
SyntaxParsingContext IfConfigCtx(SyntaxContext, SyntaxKind::IfConfigDecl);
651+
651652
SmallVector<IfConfigClause, 4> Clauses;
652653
Parser::StructureMarkerRAII ParsingDecl(
653654
*this, Tok.getLoc(), Parser::StructureMarkerKind::IfConfig);
654655

655656
bool foundActive = false;
656657
bool isVersionCondition = false;
657-
enum class ClauseKind {
658-
If,
659-
ElseIf,
660-
Else,
661-
};
662658
while (1) {
663-
ClauseKind ClKind;
664-
if (Tok.is(tok::pound_if)) {
665-
ClKind = ClauseKind::If;
666-
} else if (Tok.is(tok::pound_elseif)) {
667-
ClKind = ClauseKind::ElseIf;
668-
} else {
669-
ClKind = ClauseKind::Else;
670-
}
671-
if (ClKind == ClauseKind::Else) {
672-
// Collect all #elseif to a list.
673-
SyntaxContext->collectNodesInPlace(SyntaxKind::ElseifDirectiveClauseList);
674-
}
675659
SyntaxParsingContext ClauseContext(SyntaxContext,
676-
ClKind == ClauseKind::Else ?
677-
SyntaxKind::ElseDirectiveClause :
678-
SyntaxKind::ElseifDirectiveClause);
679-
SWIFT_DEFER {
680-
// Avoid making a clause for if
681-
if (ClKind == ClauseKind::If)
682-
ClauseContext.setTransparent();
683-
};
660+
SyntaxKind::IfConfigClause);
661+
662+
bool isElse = Tok.is(tok::pound_else);
684663
SourceLoc ClauseLoc = consumeToken();
685664
Expr *Condition = nullptr;
686665
bool isActive = false;
687666

688667
// Parse the condition. Evaluate it to determine the active
689668
// clause unless we're doing a parse-only pass.
690-
if (ClKind == ClauseKind::Else) {
669+
if (isElse) {
691670
isActive = !foundActive && State->PerformConditionEvaluation;
692671
} else {
693672
llvm::SaveAndRestore<bool> S(InPoundIfEnvironment, true);
@@ -739,9 +718,10 @@ ParserResult<IfConfigDecl> Parser::parseIfConfig(
739718
if (Tok.isNot(tok::pound_elseif, tok::pound_else))
740719
break;
741720

742-
if (ClKind == ClauseKind::Else)
721+
if (isElse)
743722
diagnose(Tok, diag::expected_close_after_else_directive);
744723
}
724+
SyntaxContext->collectNodesInPlace(SyntaxKind::IfConfigClauseList);
745725

746726
SourceLoc EndLoc;
747727
bool HadMissingEnd = parseEndIfDirective(EndLoc);

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import <AccessPathComponent>A.</AccessPathComponent><AccessPathComponent>B.</Acc
1616
import struct <AccessPathComponent>A.</AccessPathComponent><AccessPathComponent>B</AccessPathComponent></ImportDecl><PoundWarningDecl>
1717

1818
#warning(<StringLiteralExpr>"test warning"</StringLiteralExpr>)</PoundWarningDecl><PoundErrorDecl>
19-
#error(<StringLiteralExpr>"test error"</StringLiteralExpr>)</PoundErrorDecl><IfConfigDecl>
19+
#error(<StringLiteralExpr>"test error"</StringLiteralExpr>)</PoundErrorDecl><IfConfigDecl><IfConfigClause>
2020

2121
#if <IdentifierExpr>Blah</IdentifierExpr><ClassDecl>
2222
class C <MemberDeclBlock>{<FunctionDecl>
@@ -118,16 +118,16 @@ protocol PP <MemberDeclBlock>{<AssociatedtypeDecl>
118118
associatedtype E<TypeInheritanceClause>: <InheritedType><SimpleTypeIdentifier>Sequence </SimpleTypeIdentifier></InheritedType></TypeInheritanceClause><TypeInitializerClause>= <ArrayType>[<ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>]</ArrayType>] </ArrayType></TypeInitializerClause><GenericWhereClause>where <ConformanceRequirement><MemberTypeIdentifier><SimpleTypeIdentifier>A</SimpleTypeIdentifier>.Element </MemberTypeIdentifier>: <SimpleTypeIdentifier>Sequence</SimpleTypeIdentifier></ConformanceRequirement></GenericWhereClause></AssociatedtypeDecl><AssociatedtypeDecl><DeclModifier>
119119
private </DeclModifier>associatedtype F</AssociatedtypeDecl><AssociatedtypeDecl><Attribute>
120120
@objc </Attribute>associatedtype G</AssociatedtypeDecl>
121-
}</MemberDeclBlock></ProtocolDecl>
121+
}</MemberDeclBlock></ProtocolDecl></IfConfigClause>
122122

123-
#endif</IfConfigDecl><IfConfigDecl>
123+
#endif</IfConfigDecl><IfConfigDecl><IfConfigClause>
124124

125125
#if <IdentifierExpr>blah</IdentifierExpr><TypealiasDecl>
126-
typealias A <TypeInitializerClause>= <SimpleTypeIdentifier>Any</SimpleTypeIdentifier></TypeInitializerClause></TypealiasDecl><ElseifDirectiveClause>
126+
typealias A <TypeInitializerClause>= <SimpleTypeIdentifier>Any</SimpleTypeIdentifier></TypeInitializerClause></TypealiasDecl></IfConfigClause><IfConfigClause>
127127
#elseif <IdentifierExpr>blahblah</IdentifierExpr><TypealiasDecl>
128-
typealias B <TypeInitializerClause>= <TupleType>(<TupleTypeElement><MemberTypeIdentifier><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Any</SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier>.Element</MemberTypeIdentifier>, </TupleTypeElement><TupleTypeElement>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TupleTypeElement>)</TupleType></TypeInitializerClause></TypealiasDecl></ElseifDirectiveClause><ElseDirectiveClause>
128+
typealias B <TypeInitializerClause>= <TupleType>(<TupleTypeElement><MemberTypeIdentifier><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Any</SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier>.Element</MemberTypeIdentifier>, </TupleTypeElement><TupleTypeElement>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TupleTypeElement>)</TupleType></TypeInitializerClause></TypealiasDecl></IfConfigClause><IfConfigClause>
129129
#else<TypealiasDecl>
130-
typealias C <TypeInitializerClause>= <ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>]</ArrayType></TypeInitializerClause></TypealiasDecl></ElseDirectiveClause>
130+
typealias C <TypeInitializerClause>= <ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>]</ArrayType></TypeInitializerClause></TypealiasDecl></IfConfigClause>
131131
#endif</IfConfigDecl><TypealiasDecl>
132132
typealias D <TypeInitializerClause>= <DictionaryType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>]</DictionaryType></TypeInitializerClause></TypealiasDecl><TypealiasDecl>
133133
typealias E <TypeInitializerClause>= <MetatypeType><OptionalType><SimpleTypeIdentifier>Int</SimpleTypeIdentifier>?</OptionalType>.Protocol</MetatypeType></TypeInitializerClause></TypealiasDecl><TypealiasDecl>
@@ -207,15 +207,15 @@ private </DeclModifier>protocol foo <TypeInheritanceClause>: <InheritedType><Sim
207207
protocol foo <MemberDeclBlock>{ <FunctionDecl>func foo<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature></FunctionDecl>}</MemberDeclBlock></ProtocolDecl><ProtocolDecl><DeclModifier>
208208
private </DeclModifier>protocol foo<MemberDeclBlock>{}</MemberDeclBlock></ProtocolDecl><ProtocolDecl><Attribute>
209209
@objc</Attribute><DeclModifier>
210-
public </DeclModifier>protocol foo <GenericWhereClause>where <ConformanceRequirement><SimpleTypeIdentifier>A</SimpleTypeIdentifier>:<SimpleTypeIdentifier>B </SimpleTypeIdentifier></ConformanceRequirement></GenericWhereClause><MemberDeclBlock>{}</MemberDeclBlock></ProtocolDecl><IfConfigDecl>
210+
public </DeclModifier>protocol foo <GenericWhereClause>where <ConformanceRequirement><SimpleTypeIdentifier>A</SimpleTypeIdentifier>:<SimpleTypeIdentifier>B </SimpleTypeIdentifier></ConformanceRequirement></GenericWhereClause><MemberDeclBlock>{}</MemberDeclBlock></ProtocolDecl><IfConfigDecl><IfConfigClause>
211211

212212
#if <IdentifierExpr>blah</IdentifierExpr><FunctionDecl>
213213
func tryfoo<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<TryExpr>
214214
try <FunctionCallExpr><IdentifierExpr>foo</IdentifierExpr>()</FunctionCallExpr></TryExpr><TryExpr>
215215
try! <FunctionCallExpr><IdentifierExpr>foo</IdentifierExpr>()</FunctionCallExpr></TryExpr><TryExpr>
216216
try? <FunctionCallExpr><IdentifierExpr>foo</IdentifierExpr>()</FunctionCallExpr></TryExpr><TryExpr>
217217
try! <FunctionCallExpr><MemberAccessExpr><FunctionCallExpr><MemberAccessExpr><FunctionCallExpr><MemberAccessExpr><FunctionCallExpr><IdentifierExpr>foo</IdentifierExpr>()</FunctionCallExpr>.bar</MemberAccessExpr>()</FunctionCallExpr>.foo</MemberAccessExpr>()</FunctionCallExpr>.bar</MemberAccessExpr>()</FunctionCallExpr></TryExpr>
218-
}</CodeBlock></FunctionDecl><ElseDirectiveClause>
218+
}</CodeBlock></FunctionDecl></IfConfigClause><IfConfigClause>
219219
#else<FunctionDecl>
220220
func closure<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
221221
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ClosureExpr>{<ClosureSignature><ClosureCaptureSignature>[<ClosureCaptureItem>weak <IdentifierExpr>a</IdentifierExpr>,</ClosureCaptureItem><ClosureCaptureItem>
@@ -241,7 +241,7 @@ func closure<FunctionSignature><ParameterClause>() </ParameterClause></FunctionS
241241
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ClosureExpr>{}</ClosureExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
242242
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ClosureExpr>{ <ClosureSignature><ClosureParam>s1, </ClosureParam><ClosureParam>s2 </ClosureParam>in </ClosureSignature><SequenceExpr><IdentifierExpr>s1 </IdentifierExpr><BinaryOperatorExpr>> </BinaryOperatorExpr><IdentifierExpr>s2 </IdentifierExpr></SequenceExpr>}</ClosureExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
243243
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ClosureExpr>{ <SequenceExpr><IdentifierExpr>$0 </IdentifierExpr><BinaryOperatorExpr>> </BinaryOperatorExpr><IdentifierExpr>$1 </IdentifierExpr></SequenceExpr>}</ClosureExpr></SequenceExpr>
244-
}</CodeBlock></FunctionDecl></ElseDirectiveClause>
244+
}</CodeBlock></FunctionDecl></IfConfigClause>
245245
#endif</IfConfigDecl><FunctionDecl>
246246

247247
func postfix<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<FunctionCallExpr><IdentifierExpr>
@@ -268,10 +268,10 @@ func postfix<FunctionSignature><ParameterClause>() </ParameterClause></FunctionS
268268
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><IdentifierExpr>x</IdentifierExpr>.foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
269269
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><IdentifierExpr>foo</IdentifierExpr>(<FunctionCallArgument><InOutExpr>&<IdentifierExpr>d</IdentifierExpr></InOutExpr></FunctionCallArgument>)</FunctionCallExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
270270
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><EditorPlaceholderExpr><#Placeholder#> </EditorPlaceholderExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><EditorPlaceholderExpr><#T##(Int) -> Int#></EditorPlaceholderExpr></SequenceExpr>
271-
}</CodeBlock></FunctionDecl><IfConfigDecl>
271+
}</CodeBlock></FunctionDecl><IfConfigDecl><IfConfigClause>
272272

273-
#if <IdentifierExpr>blah</IdentifierExpr><ElseDirectiveClause>
274-
#else</ElseDirectiveClause>
273+
#if <IdentifierExpr>blah</IdentifierExpr></IfConfigClause><IfConfigClause>
274+
#else</IfConfigClause>
275275
#endif</IfConfigDecl><ClassDecl>
276276

277277
class C <MemberDeclBlock>{<VariableDecl>
@@ -367,10 +367,16 @@ func statementTests<FunctionSignature><ParameterClause>() </ParameterClause></Fu
367367
case <CaseItem><ExpressionPattern><IdentifierExpr>n1</IdentifierExpr></ExpressionPattern></CaseItem>:</SwitchCaseLabel><BreakStmt>
368368
break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
369369
case <CaseItem><ExpressionPattern><IdentifierExpr>n2</IdentifierExpr></ExpressionPattern>, </CaseItem><CaseItem><ExpressionPattern><IdentifierExpr>n3l</IdentifierExpr></ExpressionPattern></CaseItem>:</SwitchCaseLabel><BreakStmt>
370-
break</BreakStmt></SwitchCase><IfConfigDecl>
370+
break</BreakStmt></SwitchCase><IfConfigDecl><IfConfigClause>
371371
#if <IdentifierExpr>FOO</IdentifierExpr><SwitchCase><SwitchCaseLabel>
372372
case <CaseItem><ValueBindingPattern>let <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><IdentifierPattern>x</IdentifierPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><IdentifierPattern>y</IdentifierPattern></UnresolvedPatternExpr></TupleElement>) </TupleExpr></ExpressionPattern></ValueBindingPattern><WhereClause>where <PrefixOperatorExpr>!<IdentifierExpr>x</IdentifierExpr></PrefixOperatorExpr></WhereClause>, </CaseItem><CaseItem><ExpressionPattern><IdentifierExpr>n3l </IdentifierExpr></ExpressionPattern><WhereClause>where <BooleanLiteralExpr>false</BooleanLiteralExpr></WhereClause></CaseItem>:</SwitchCaseLabel><BreakStmt>
373-
break</BreakStmt></SwitchCase>
373+
break</BreakStmt></SwitchCase></IfConfigClause><IfConfigClause>
374+
#elseif <IdentifierExpr>BAR</IdentifierExpr><SwitchCase><SwitchCaseLabel>
375+
case <CaseItem><ValueBindingPattern>let <IdentifierPattern>y</IdentifierPattern></ValueBindingPattern></CaseItem>:</SwitchCaseLabel><BreakStmt>
376+
break</BreakStmt></SwitchCase></IfConfigClause><IfConfigClause>
377+
#else<SwitchCase><SwitchCaseLabel>
378+
case <CaseItem><ExpressionPattern><FunctionCallExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr>(<FunctionCallArgument><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>x</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></FunctionCallArgument>)</FunctionCallExpr></ExpressionPattern></CaseItem>:</SwitchCaseLabel><BreakStmt>
379+
break</BreakStmt></SwitchCase></IfConfigClause>
374380
#endif</IfConfigDecl><SwitchCase><SwitchDefaultLabel>
375381
default:</SwitchDefaultLabel><BreakStmt>
376382
break</BreakStmt></SwitchCase>

test/Syntax/round_trip_parse_gen.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ func statementTests() {
371371
#if FOO
372372
case let (x, y) where !x, n3l where false:
373373
break
374+
#elseif BAR
375+
case let y:
376+
break
377+
#else
378+
case .foo(let x):
379+
break
374380
#endif
375381
default:
376382
break

utils/gyb_syntax_support/DeclNodes.py

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -84,29 +84,32 @@
8484
Child('Output', kind='ReturnClause', is_optional=True),
8585
]),
8686

87-
# else-if-directive-clause -> '#elseif' expr stmt-list
88-
Node('ElseifDirectiveClause', kind='Syntax',
89-
traits=['WithStatements'],
87+
# if-config-clause ->
88+
# ('#if' | '#elseif' | '#else') expr? (stmt-list | switch-case-list)
89+
Node('IfConfigClause', kind='Syntax',
9090
children=[
91-
Child('PoundElseif', kind='PoundElseifToken'),
92-
Child('Condition', kind='Expr'),
93-
Child('Statements', kind='CodeBlockItemList'),
91+
Child('PoundKeyword', kind='Token',
92+
token_choices=[
93+
'PoundIfToken',
94+
'PoundElseifToken',
95+
'PoundElseToken',
96+
]),
97+
Child('Condition', kind='Expr',
98+
is_optional=True),
99+
Child('Elements', kind='Syntax',
100+
node_choices=[
101+
Child('Statements', kind='CodeBlockItemList'),
102+
Child('SwitchCases', kind='SwitchCaseList')]),
94103
]),
95104

105+
Node('IfConfigClauseList', kind='SyntaxCollection',
106+
element='IfConfigClause'),
107+
96108
# if-config-decl -> '#if' expr stmt-list else-if-directive-clause-list
97109
# else-clause? '#endif'
98110
Node('IfConfigDecl', kind='Decl',
99111
children=[
100-
Child('PoundIf', kind='PoundIfToken'),
101-
Child('Condition', kind='Expr'),
102-
Child('Elements', kind='Syntax',
103-
node_choices=[
104-
Child('Statements', kind='CodeBlockItemList'),
105-
Child('SwitchCases', kind='SwitchCaseList')]),
106-
Child('ElseifDirectiveClauses', kind='ElseifDirectiveClauseList',
107-
is_optional=True),
108-
Child('ElseClause', kind='ElseDirectiveClause',
109-
is_optional=True),
112+
Child('Clauses', kind='IfConfigClauseList'),
110113
Child('PoundEndif', kind='PoundEndifToken'),
111114
]),
112115

@@ -406,19 +409,6 @@
406409
Child('Accessor', kind='AccessorBlock', is_optional=True),
407410
]),
408411

409-
# else-if-directive-clause-list -> else-if-directive-clause
410-
# else-if-directive-clause-list?
411-
Node('ElseifDirectiveClauseList', kind='SyntaxCollection',
412-
element='ElseifDirectiveClause'),
413-
414-
# else-directive-clause -> '#else' stmt-list
415-
Node('ElseDirectiveClause', kind='Syntax',
416-
traits=['WithStatements'],
417-
children=[
418-
Child('PoundElse', kind='PoundElseToken'),
419-
Child('Statements', kind='CodeBlockItemList'),
420-
]),
421-
422412
# access-level-modifier -> 'private' | 'private' '(' 'set' ')'
423413
# | 'fileprivate' | 'fileprivate' '(' 'set' ')'
424414
# | 'internal' | 'internal' '(' 'set' ')'

0 commit comments

Comments
 (0)