Skip to content

Commit 7218865

Browse files
authored
Merge pull request #22813 from github/unified/swift-extract-attributed-types
Unified: Extract Swift attributed types
2 parents 5858ca2 + ddad489 commit 7218865

14 files changed

Lines changed: 416 additions & 7 deletions

‎unified/extractor/ast_types.yml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ supertypes:
4141
- bulk_importing_pattern
4242
- ignore_pattern
4343
- generic_type_expr
44+
- modified_type_expr
4445
- inferred_type_expr
4546
# An element of an `unresolved_operator_sequence`: either an operand (`expr`)
4647
# or one of the infix operators separating the operands.
@@ -553,5 +554,11 @@ named:
553554
base: expr
554555
type_argument*: expr
555556

557+
# A type with a modifier. In Swift this can be specifiers or attributes, such
558+
# as `inout T`, `sending T` or `@escaping () -> Void`.
559+
modified_type_expr:
560+
modifier*: modifier
561+
type: expr
562+
556563
# A modifier such as 'static', 'public', or 'async'. For now this is just a leaf node with a string value.
557564
modifier:

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,24 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
11681168
// becomes a `modifier`; its source text is the modifier spelling.
11691169
rule!((attribute) @m => (modifier #{m})),
11701170
rule!((declModifier) @m => (modifier #{m})),
1171+
// Type specifiers (`inout`, `sending`, ...) are mapped to modifiers.
1172+
rule!((simpleTypeSpecifier) @m => (modifier #{m})),
1173+
rule!((lifetimeTypeSpecifier) @m => (modifier #{m})),
1174+
rule!((nonisolatedTypeSpecifier) @m => (modifier #{m})),
1175+
// An attributed type is mapped to a modified type of its base type.
1176+
rule!(
1177+
(attributedType
1178+
specifiers: _* @specs
1179+
attributes: _* @attrs
1180+
lateSpecifiers: _* @late
1181+
baseType: @base)
1182+
=>
1183+
(modified_type_expr
1184+
modifier: {specs}
1185+
modifier: {attrs}
1186+
modifier: {late}
1187+
type: {base})
1188+
),
11711189
// Preserve the `super` keyword as a dedicated expression, normally used
11721190
// as the base of a member access (`super.foo`).
11731191
rule!((superExpr superKeyword: @@keyword) => (super_expr #{keyword})),
@@ -1475,7 +1493,6 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
14751493
// currently map them to the unified AST. Syntax nested inside one of
14761494
// these roots is discarded with its parent and needs no separate rule.
14771495
rule!((actorDecl) => (unsupported_node)),
1478-
rule!((attributedType) => (unsupported_node)),
14791496
rule!((borrowExpr) => (unsupported_node)),
14801497
rule!((classRestrictionType) => (unsupported_node)),
14811498
rule!((compositionType) => (unsupported_node)),
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
func f<D, T>(
2+
a: inout D,
3+
b: sending T,
4+
c: borrowing T,
5+
d: consuming T,
6+
e: @escaping (T) -> Void,
7+
g: @Sendable @escaping () -> D
8+
) {}
9+
10+
---
11+
12+
sourceFile
13+
endOfFileToken: endOfFile
14+
statements:
15+
codeBlockItem
16+
item:
17+
functionDecl
18+
attributes:
19+
body:
20+
codeBlock
21+
leftBrace: {
22+
rightBrace: }
23+
statements:
24+
name: identifier "f"
25+
genericParameterClause:
26+
genericParameterClause
27+
parameters:
28+
genericParameter
29+
attributes:
30+
name: identifier "D"
31+
trailingComma: ,
32+
genericParameter
33+
attributes:
34+
name: identifier "T"
35+
leftAngle: <
36+
rightAngle: >
37+
modifiers:
38+
signature:
39+
functionSignature
40+
parameterClause:
41+
functionParameterClause
42+
leftParen: (
43+
rightParen: )
44+
parameters:
45+
functionParameter
46+
colon: :
47+
attributes:
48+
modifiers:
49+
trailingComma: ,
50+
type:
51+
attributedType
52+
attributes:
53+
baseType:
54+
identifierType
55+
name: identifier "D"
56+
lateSpecifiers:
57+
specifiers:
58+
simpleTypeSpecifier
59+
specifier: inout
60+
firstName: identifier "a"
61+
functionParameter
62+
colon: :
63+
attributes:
64+
modifiers:
65+
trailingComma: ,
66+
type:
67+
attributedType
68+
attributes:
69+
baseType:
70+
identifierType
71+
name: identifier "T"
72+
lateSpecifiers:
73+
specifiers:
74+
simpleTypeSpecifier
75+
specifier: sending
76+
firstName: identifier "b"
77+
functionParameter
78+
colon: :
79+
attributes:
80+
modifiers:
81+
trailingComma: ,
82+
type:
83+
attributedType
84+
attributes:
85+
baseType:
86+
identifierType
87+
name: identifier "T"
88+
lateSpecifiers:
89+
specifiers:
90+
simpleTypeSpecifier
91+
specifier: borrowing
92+
firstName: identifier "c"
93+
functionParameter
94+
colon: :
95+
attributes:
96+
modifiers:
97+
trailingComma: ,
98+
type:
99+
attributedType
100+
attributes:
101+
baseType:
102+
identifierType
103+
name: identifier "T"
104+
lateSpecifiers:
105+
specifiers:
106+
simpleTypeSpecifier
107+
specifier: consuming
108+
firstName: identifier "d"
109+
functionParameter
110+
colon: :
111+
attributes:
112+
modifiers:
113+
trailingComma: ,
114+
type:
115+
attributedType
116+
attributes:
117+
attribute
118+
atSign: @
119+
attributeName:
120+
identifierType
121+
name: identifier "escaping"
122+
baseType:
123+
functionType
124+
leftParen: (
125+
rightParen: )
126+
parameters:
127+
tupleTypeElement
128+
type:
129+
identifierType
130+
name: identifier "T"
131+
returnClause:
132+
returnClause
133+
arrow: ->
134+
type:
135+
identifierType
136+
name: identifier "Void"
137+
lateSpecifiers:
138+
specifiers:
139+
firstName: identifier "e"
140+
functionParameter
141+
colon: :
142+
attributes:
143+
modifiers:
144+
type:
145+
attributedType
146+
attributes:
147+
attribute
148+
atSign: @
149+
attributeName:
150+
identifierType
151+
name: identifier "Sendable"
152+
attribute
153+
atSign: @
154+
attributeName:
155+
identifierType
156+
name: identifier "escaping"
157+
baseType:
158+
functionType
159+
leftParen: (
160+
rightParen: )
161+
parameters:
162+
returnClause:
163+
returnClause
164+
arrow: ->
165+
type:
166+
identifierType
167+
name: identifier "D"
168+
lateSpecifiers:
169+
specifiers:
170+
firstName: identifier "g"
171+
funcKeyword: func
172+
173+
---
174+
175+
top_level source="⟨body⟩"
176+
body:
177+
block source="⟨stmt⟩"
178+
stmt:
179+
function_declaration source="func ⟨name_node⟩<⟨type_parameter⟩, ⟨type_parameter⟩>(\n ⟨parameter⟩,\n ⟨parameter⟩,\n ⟨parameter⟩,\n ⟨parameter⟩,\n ⟨parameter⟩,\n ⟨parameter⟩\n) ⟨body⟩"
180+
name_node: identifier "f" source="f"
181+
type_parameter:
182+
type_parameter source="⟨name_node⟩"
183+
name_node: identifier "D" source="D"
184+
type_parameter source="⟨name_node⟩"
185+
name_node: identifier "T" source="T"
186+
parameter:
187+
parameter source="⟨external_name_node⟩⟨pattern⟩: ⟨type⟩"
188+
external_name_node: identifier "a" source="a"
189+
type:
190+
modified_type_expr source="⟨modifier⟩ ⟨type⟩"
191+
modifier: modifier "inout" source="inout"
192+
type: identifier "D" source="D"
193+
pattern: identifier "a" source="a"
194+
parameter source="⟨external_name_node⟩⟨pattern⟩: ⟨type⟩"
195+
external_name_node: identifier "b" source="b"
196+
type:
197+
modified_type_expr source="⟨modifier⟩ ⟨type⟩"
198+
modifier: modifier "sending" source="sending"
199+
type: identifier "T" source="T"
200+
pattern: identifier "b" source="b"
201+
parameter source="⟨external_name_node⟩⟨pattern⟩: ⟨type⟩"
202+
external_name_node: identifier "c" source="c"
203+
type:
204+
modified_type_expr source="⟨modifier⟩ ⟨type⟩"
205+
modifier: modifier "borrowing" source="borrowing"
206+
type: identifier "T" source="T"
207+
pattern: identifier "c" source="c"
208+
parameter source="⟨external_name_node⟩⟨pattern⟩: ⟨type⟩"
209+
external_name_node: identifier "d" source="d"
210+
type:
211+
modified_type_expr source="⟨modifier⟩ ⟨type⟩"
212+
modifier: modifier "consuming" source="consuming"
213+
type: identifier "T" source="T"
214+
pattern: identifier "d" source="d"
215+
parameter source="⟨external_name_node⟩⟨pattern⟩: ⟨type⟩"
216+
external_name_node: identifier "e" source="e"
217+
type:
218+
modified_type_expr source="⟨modifier⟩ ⟨type⟩"
219+
modifier: modifier "@escaping" source="@escaping"
220+
type:
221+
function_expr source="(⟨parameter⟩) -> ⟨return_type⟩"
222+
parameter:
223+
parameter source="⟨type⟩"
224+
type: identifier "T" source="T"
225+
return_type: identifier "Void" source="Void"
226+
pattern: identifier "e" source="e"
227+
parameter source="⟨external_name_node⟩⟨pattern⟩: ⟨type⟩"
228+
external_name_node: identifier "g" source="g"
229+
type:
230+
modified_type_expr source="⟨modifier⟩ ⟨modifier⟩ ⟨type⟩"
231+
modifier:
232+
modifier "@Sendable" source="@Sendable"
233+
modifier "@escaping" source="@escaping"
234+
type:
235+
function_expr source="() -> ⟨return_type⟩"
236+
return_type: identifier "D" source="D"
237+
pattern: identifier "g" source="g"
238+
body: block "{}" source="{}"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
func f<D, T>(
2+
a: inout D,
3+
b: sending T,
4+
c: borrowing T,
5+
d: consuming T,
6+
e: @escaping (T) -> Void,
7+
g: @Sendable @escaping () -> D
8+
) {}

‎unified/extractor/tests/corpus/swift/functions/function-with-inout-parameter.output‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ top_level source="⟨body⟩"
6666
parameter:
6767
parameter source="⟨external_name_node⟩ ⟨pattern⟩: ⟨type⟩"
6868
external_name_node: identifier "_" source="_"
69-
type: unsupported_node "inout Int" source="inout Int"
69+
type:
70+
modified_type_expr source="⟨modifier⟩ ⟨type⟩"
71+
modifier: modifier "inout" source="inout"
72+
type: identifier "Int" source="Int"
7073
pattern: identifier "x" source="x"
7174
body:
7275
block source="{\n ⟨stmt⟩\n}"

‎unified/extractor/tests/corpus/swift/types/function-type-with-convention-attribute.output‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ top_level source="⟨body⟩"
6565
variable_declaration source="⟨modifier⟩ ⟨pattern⟩: ⟨type⟩ = ⟨value⟩"
6666
modifier: modifier "let" source="let"
6767
pattern: identifier "callback" source="callback"
68-
type: unsupported_node "@convention(c) () -> Void" source="@convention(c) () -> Void"
68+
type:
69+
modified_type_expr source="⟨modifier⟩ ⟨type⟩"
70+
modifier: modifier "@convention(c)" source="@convention(c)"
71+
type:
72+
function_expr source="() -> ⟨return_type⟩"
73+
return_type: identifier "Void" source="Void"
6974
value:
7075
function_expr source="{}"
7176
body: block source=""

0 commit comments

Comments
 (0)