Skip to content

Commit 46da672

Browse files
hvitvedCopilot
andcommitted
Unified: Synthesize implicit Swift initializers
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent e37391e commit 46da672

16 files changed

Lines changed: 113 additions & 11 deletions

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

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,8 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
12281228
=>
12291229
(equality_type_constraint left: {left} right: {right})
12301230
),
1231-
// Class declaration with body containing members
1231+
// Class declaration with body containing members. If the class has no
1232+
// explicit initializer, add Swift's implicit parameter-less `init`.
12321233
rule!(
12331234
(classDecl
12341235
classKeyword: @@kind
@@ -1241,15 +1242,29 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
12411242
genericWhereClause: (genericWhereClause requirements: _* @declaration_constraints)?
12421243
memberBlock: (memberBlock members: _* @members))
12431244
=>
1244-
(class_like_declaration
1245-
modifier: (modifier #{kind})
1246-
modifier: {mods}
1247-
name_node: (identifier #{name})
1248-
type_parameter: {params}
1249-
type_constraint: {parameter_constraints}
1250-
type_constraint: {declaration_constraints}
1251-
base_type: {bases.into_iter().map(|ty| tree!((base_type type: {ty})))}
1252-
member: {members})
1245+
class_like_declaration {
1246+
let has_explicit_initializer = members.iter().any(|member| {
1247+
ctx.ast
1248+
.get_node(*member)
1249+
.is_some_and(|node| node.kind_name() == "constructor_declaration")
1250+
});
1251+
let implicit_initializer = (!has_explicit_initializer).then(|| {
1252+
tree!((constructor_declaration
1253+
modifier: (modifier "generated")
1254+
name_node: (identifier "init")
1255+
body: (block)))
1256+
});
1257+
tree!((class_like_declaration
1258+
modifier: (modifier #{kind})
1259+
modifier: {mods}
1260+
name_node: (identifier #{name})
1261+
type_parameter: {params}
1262+
type_constraint: {parameter_constraints}
1263+
type_constraint: {declaration_constraints}
1264+
base_type: {bases.into_iter().map(|ty| tree!((base_type type: {ty})))}
1265+
member: {members}
1266+
member: {implicit_initializer}))
1267+
}
12531268
),
12541269
// Enum class declaration: same as a regular class but with an enum body.
12551270
rule!(

‎unified/extractor/tests/corpus/swift/expressions/super-expression.output‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ top_level source="⟨body⟩"
157157
function_declaration source="func ⟨name_node⟩() ⟨body⟩"
158158
name_node: identifier "update" source="update"
159159
body: block "{}" source="{}"
160+
constructor_declaration source=""
161+
modifier: modifier "generated" source=""
162+
name_node: identifier "init" source=""
163+
body: block source=""
160164
class_like_declaration source="⟨modifier⟩ ⟨name_node⟩: ⟨base_type⟩ {\n ⟨member⟩\n}"
161165
modifier: modifier "class" source="class"
162166
name_node: identifier "Derived" source="Derived"
@@ -182,3 +186,7 @@ top_level source="⟨body⟩"
182186
member_access_expr source="⟨base⟩.⟨member_name_node⟩"
183187
base: super_expr "super" source="super"
184188
member_name_node: identifier "update" source="update"
189+
constructor_declaration source=""
190+
modifier: modifier "generated" source=""
191+
name_node: identifier "init" source=""
192+
body: block source=""

‎unified/extractor/tests/corpus/swift/functions/constructor-call-with-type-arguments.output‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,22 @@ top_level source="⟨body⟩"
8383
class_like_declaration source="⟨modifier⟩ ⟨name_node⟩ {}"
8484
modifier: modifier "class" source="class"
8585
name_node: identifier "Foo" source="Foo"
86+
member:
87+
constructor_declaration source=""
88+
modifier: modifier "generated" source=""
89+
name_node: identifier "init" source=""
90+
body: block source=""
8691
class_like_declaration source="⟨modifier⟩ ⟨name_node⟩<⟨type_parameter⟩> {}"
8792
modifier: modifier "class" source="class"
8893
name_node: identifier "C" source="C"
8994
type_parameter:
9095
type_parameter source="⟨name_node⟩"
9196
name_node: identifier "T" source="T"
97+
member:
98+
constructor_declaration source=""
99+
modifier: modifier "generated" source=""
100+
name_node: identifier "init" source=""
101+
body: block source=""
92102
variable_declaration source="⟨modifier⟩ ⟨pattern⟩ = ⟨value⟩"
93103
modifier: modifier "let" source="let"
94104
pattern: identifier "x" source="x"

‎unified/extractor/tests/corpus/swift/types/class-function.output‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,7 @@ top_level source="⟨body⟩"
5555
modifier: modifier "class" source="class"
5656
name_node: identifier "make" source="make"
5757
body: block "{}" source="{}"
58+
constructor_declaration source=""
59+
modifier: modifier "generated" source=""
60+
name_node: identifier "init" source=""
61+
body: block source=""

‎unified/extractor/tests/corpus/swift/types/class-inheritance.output‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,8 @@ top_level source="⟨body⟩"
3838
base_type:
3939
base_type source="⟨type⟩"
4040
type: identifier "Animal" source="Animal"
41+
member:
42+
constructor_declaration source=""
43+
modifier: modifier "generated" source=""
44+
name_node: identifier "init" source=""
45+
body: block source=""

‎unified/extractor/tests/corpus/swift/types/class-with-method.output‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,7 @@ top_level source="⟨body⟩"
9494
left: identifier "n" source="n"
9595
operator: infix_operator "+=" source="+="
9696
right: int_literal "1" source="1"
97+
constructor_declaration source=""
98+
modifier: modifier "generated" source=""
99+
name_node: identifier "init" source=""
100+
body: block source=""

‎unified/extractor/tests/corpus/swift/types/class-with-multiple-base-types.output‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ top_level source="⟨body⟩"
4545
type: identifier "Control" source="Control"
4646
base_type source="⟨type⟩"
4747
type: identifier "Drawable" source="Drawable"
48+
member:
49+
constructor_declaration source=""
50+
modifier: modifier "generated" source=""
51+
name_node: identifier "init" source=""
52+
body: block source=""

‎unified/extractor/tests/corpus/swift/types/class-with-stored-properties.output‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,7 @@ top_level source="⟨body⟩"
7373
modifier: modifier "var" source="var"
7474
pattern: identifier "y" source="y"
7575
type: identifier "Int" source="Int"
76+
constructor_declaration source=""
77+
modifier: modifier "generated" source=""
78+
name_node: identifier "init" source=""
79+
body: block source=""

‎unified/extractor/tests/corpus/swift/types/computed-property.output‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,7 @@ top_level source="⟨body⟩"
127127
left: identifier "w" source="w"
128128
operator: infix_operator "*" source="*"
129129
right: identifier "h" source="h"
130+
constructor_declaration source=""
131+
modifier: modifier "generated" source=""
132+
name_node: identifier "init" source=""
133+
body: block source=""

‎unified/extractor/tests/corpus/swift/types/conditional-compilation-in-class-body.output‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,9 @@ top_level source="⟨body⟩"
8484
class_like_declaration source="⟨modifier⟩ ⟨name_node⟩ {\n⟨member⟩\n}"
8585
modifier: modifier "class" source="class"
8686
name_node: identifier "C" source="C"
87-
member: unsupported_node "#if DEBUG\n init(x: Int) {}\n deinit {}\n#endif" source="#if DEBUG\n init(x: Int) {}\n deinit {}\n#endif"
87+
member:
88+
unsupported_node "#if DEBUG\n init(x: Int) {}\n deinit {}\n#endif" source="#if DEBUG\n init(x: Int) {}\n deinit {}\n#endif"
89+
constructor_declaration source=""
90+
modifier: modifier "generated" source=""
91+
name_node: identifier "init" source=""
92+
body: block source=""

0 commit comments

Comments
 (0)