Skip to content

Commit 280a7fe

Browse files
authored
Merge pull request #22718 from github/unified/swift-optional-binding-condition
Unified: Swift optional binding condition
2 parents e37391e + 25f59e8 commit 280a7fe

5 files changed

Lines changed: 153 additions & 5 deletions

File tree

‎unified/extractor/src/languages/swift/swift.rs‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -873,13 +873,13 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
873873
=>
874874
(pattern_guard_expr pattern: {pat} value: {val})
875875
),
876-
// Optional binding (`if let x = foo`, or shorthand `if let x`) desugars
877-
// to a `pattern_guard_expr` matching `Optional.some(x)`. The initialized
878-
// form is matched first.
876+
// Optional binding conditions with an initializer (the `let p = y` in
877+
// `if let p = y { ... }`). We translate this to a `pattern_guard_expr`
878+
// matching `Optional.some(p)`.
879879
rule!(
880880
(optionalBindingCondition
881881
bindingSpecifier: @@spec
882-
pattern: (identifierPattern identifier: @@name)
882+
pattern: @pattern
883883
initializer: (initializerClause value: @val))
884884
=>
885885
(pattern_guard_expr
@@ -888,8 +888,11 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
888888
callee: (member_access_expr base: (identifier "Optional") member_name_node: (identifier "some"))
889889
argument: (argument value: (expr_pattern
890890
modifier: (modifier #{spec})
891-
expr: (identifier #{name})))))
891+
expr: {pattern}))))
892892
),
893+
// Optional binding conditions in shorthand form, that is, _without_ an
894+
// initializer (the `let p` in `if let p { ... }`). In this case the
895+
// pattern is always an identifier.
893896
rule!(
894897
(optionalBindingCondition
895898
bindingSpecifier: @@spec
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
guard let (call, thread) = optional else {
2+
return
3+
}
4+
5+
---
6+
7+
sourceFile
8+
endOfFileToken: endOfFile
9+
statements:
10+
codeBlockItem
11+
item:
12+
guardStmt
13+
body:
14+
codeBlock
15+
leftBrace: {
16+
rightBrace: }
17+
statements:
18+
codeBlockItem
19+
item:
20+
returnStmt
21+
returnKeyword: return
22+
conditions:
23+
conditionElement
24+
condition:
25+
optionalBindingCondition
26+
initializer:
27+
initializerClause
28+
equal: =
29+
value:
30+
declReferenceExpr
31+
baseName: identifier "optional"
32+
pattern:
33+
expressionPattern
34+
expression:
35+
tupleExpr
36+
leftParen: (
37+
rightParen: )
38+
elements:
39+
labeledExpr
40+
expression:
41+
patternExpr
42+
pattern:
43+
identifierPattern
44+
identifier: identifier "call"
45+
trailingComma: ,
46+
labeledExpr
47+
expression:
48+
patternExpr
49+
pattern:
50+
identifierPattern
51+
identifier: identifier "thread"
52+
bindingSpecifier: let
53+
elseKeyword: else
54+
guardKeyword: guard
55+
56+
---
57+
58+
top_level source="⟨body⟩"
59+
body:
60+
block source="⟨stmt⟩"
61+
stmt:
62+
guard_if_stmt source="guard ⟨condition⟩ else ⟨else⟩"
63+
condition:
64+
pattern_guard_expr source="⟨pattern⟩ = ⟨value⟩"
65+
pattern:
66+
call_expr source="⟨argument⟩"
67+
callee:
68+
member_access_expr source=""
69+
base: identifier "Optional" source=""
70+
member_name_node: identifier "some" source=""
71+
argument:
72+
argument source="⟨value⟩"
73+
value:
74+
expr_pattern source="⟨modifier⟩ ⟨expr⟩"
75+
modifier: modifier "let" source="let"
76+
expr:
77+
tuple_expr source="(⟨element⟩, ⟨element⟩)"
78+
element:
79+
argument source="⟨value⟩"
80+
value: identifier "call" source="call"
81+
argument source="⟨value⟩"
82+
value: identifier "thread" source="thread"
83+
value: identifier "optional" source="optional"
84+
else:
85+
block source="{\n ⟨stmt⟩\n}"
86+
stmt: return_expr "return" source="return"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
guard let (call, thread) = optional else {
2+
return
3+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
guard let value else { return }
2+
3+
---
4+
5+
sourceFile
6+
endOfFileToken: endOfFile
7+
statements:
8+
codeBlockItem
9+
item:
10+
guardStmt
11+
body:
12+
codeBlock
13+
leftBrace: {
14+
rightBrace: }
15+
statements:
16+
codeBlockItem
17+
item:
18+
returnStmt
19+
returnKeyword: return
20+
conditions:
21+
conditionElement
22+
condition:
23+
optionalBindingCondition
24+
pattern:
25+
identifierPattern
26+
identifier: identifier "value"
27+
bindingSpecifier: let
28+
elseKeyword: else
29+
guardKeyword: guard
30+
31+
---
32+
33+
top_level source="⟨body⟩"
34+
body:
35+
block source="⟨stmt⟩"
36+
stmt:
37+
guard_if_stmt source="guard ⟨condition⟩ else ⟨else⟩"
38+
condition:
39+
pattern_guard_expr source="⟨pattern⟩⟨value⟩"
40+
pattern:
41+
call_expr source="⟨argument⟩"
42+
callee:
43+
member_access_expr source=""
44+
base: identifier "Optional" source=""
45+
member_name_node: identifier "some" source=""
46+
argument:
47+
argument source="⟨value⟩"
48+
value:
49+
expr_pattern source="⟨modifier⟩ ⟨expr⟩"
50+
modifier: modifier "let" source="let"
51+
expr: identifier "value" source="value"
52+
value: identifier "value" source="value"
53+
else:
54+
block source="{ ⟨stmt⟩ }"
55+
stmt: return_expr "return" source="return"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
guard let value else { return }

0 commit comments

Comments
 (0)