Skip to content

Commit 8f747a3

Browse files
committed
unified/swift: add function and parameter mappings
1 parent d17fd2d commit 8f747a3

4 files changed

Lines changed: 294 additions & 14 deletions

File tree

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

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,106 @@ fn translation_rules() -> Vec<yeast::Rule> {
286286
rule!((pattern bound_identifier: @name) => (name_pattern identifier: (identifier #{name}))),
287287
// Tuple pattern (destructuring)
288288
rule!((pattern (pattern)* @elems) => (tuple_pattern element: {..elems})),
289+
// ---- Functions ----
290+
// Function declaration
291+
// Function declaration (return type optional, body statements optional).
292+
rule!(
293+
(function_declaration
294+
name: @name
295+
parameter: _* @params
296+
return_type: _? @ret
297+
body: (block statement: _* @body_stmts))
298+
=>
299+
(function_declaration
300+
name: (identifier #{name})
301+
parameter: {..params}
302+
return_type: {..ret}
303+
body: (block stmt: {..body_stmts}))
304+
),
305+
// Parameters are wrapped in function_parameter, which also carries
306+
// optional default values.
307+
rule!(
308+
(function_parameter parameter: @p default_value: _? @def)
309+
=>
310+
{..{
311+
let p_id: usize = p.into();
312+
for &d in def.iter().rev() {
313+
__yeast_ctx.prepend_field(p_id, "default", d.into());
314+
}
315+
vec![p_id]
316+
}}
317+
),
318+
// Parameter with external name and type
319+
rule!(
320+
(parameter external_name: @ext name: @name)
321+
=>
322+
(parameter
323+
external_name: (identifier #{ext})
324+
pattern: (name_pattern identifier: (identifier #{name})))
325+
),
326+
rule!(
327+
(parameter external_name: @ext name: @name type: @ty)
328+
=>
329+
(parameter
330+
external_name: (identifier #{ext})
331+
pattern: (name_pattern identifier: (identifier #{name}))
332+
type: {ty})
333+
),
334+
// Parameter with just name and type (no external name)
335+
rule!(
336+
(parameter name: @name)
337+
=>
338+
(parameter
339+
pattern: (name_pattern identifier: (identifier #{name})))
340+
),
341+
rule!(
342+
(parameter name: @name type: @ty)
343+
=>
344+
(parameter
345+
pattern: (name_pattern identifier: (identifier #{name}))
346+
type: {ty})
347+
),
348+
// Reference to a function, f(x:y:z:). This is parsed as a call with a single argument with multiple reference_specifier labels.
349+
// We don't want downstream QL to try to handle this as a call_expr with a weird argument, so explicitly mark it as unsupported for now.
350+
// In the future we probably want to translate this to a lambda expression.
351+
rule!(
352+
(call_expression suffix: (call_suffix arguments: (value_arguments argument: (value_argument reference_specifier: _+) @ref_arg)))
353+
=>
354+
(unsupported_node)
355+
),
356+
// Call expression: function(args...)
357+
rule!(
358+
(call_expression function: @func suffix: (call_suffix arguments: (value_arguments argument: (value_argument)* @args)))
359+
=>
360+
(call_expr callee: {func} argument: {..args})
361+
),
362+
// Value argument with label (value: _ matches both named nodes and anonymous tokens like nil)
363+
rule!(
364+
(value_argument name: (value_argument_label name: @label) value: @val)
365+
=>
366+
(argument name: (identifier #{label}) value: {val})
367+
),
368+
// Value argument without label
369+
rule!(
370+
(value_argument value: @val)
371+
=>
372+
(argument value: {val})
373+
),
374+
// Navigation expression → member_access_expr
375+
rule!(
376+
(navigation_expression target: @target suffix: (navigation_suffix suffix: @member))
377+
=>
378+
(member_access_expr base: {target} member: (identifier #{member}))
379+
),
380+
// Return / break / continue, one rule per keyword.
381+
// The anonymous "return"/"break"/"continue" keywords are matched as
382+
// string literals.
383+
rule!((control_transfer_statement kind: "return" result: _? @val) => (return_expr value: {..val})),
384+
rule!((control_transfer_statement kind: "break" result: @lbl) => (break_expr label: (identifier #{lbl}))),
385+
rule!((control_transfer_statement kind: "break") => (break_expr)),
386+
rule!((control_transfer_statement kind: "continue" result: @lbl) => (continue_expr label: (identifier #{lbl}))),
387+
rule!((control_transfer_statement kind: "continue") => (continue_expr)),
388+
rule!((control_transfer_statement kind: (throw_keyword) result: @val) => (throw_expr value: {val})),
289389
// ---- Fallbacks ----
290390
rule!(
291391
(_)

unified/extractor/tests/corpus/swift/collections.txt

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,14 @@ top_level
281281
pattern:
282282
name_pattern
283283
identifier: identifier "first"
284-
value: unsupported_node "xs[0]"
284+
value:
285+
call_expr
286+
argument:
287+
argument
288+
value: int_literal "0"
289+
callee:
290+
name_expr
291+
identifier: identifier "xs"
285292

286293
===
287294
Dictionary subscript
@@ -330,7 +337,14 @@ top_level
330337
pattern:
331338
name_pattern
332339
identifier: identifier "v"
333-
value: unsupported_node "d[\"key\"]"
340+
value:
341+
call_expr
342+
argument:
343+
argument
344+
value: string_literal "\"key\""
345+
callee:
346+
name_expr
347+
identifier: identifier "d"
334348

335349
===
336350
Tuple member access
@@ -369,4 +383,9 @@ top_level
369383
pattern:
370384
name_pattern
371385
identifier: identifier "n"
372-
value: unsupported_node "t.0"
386+
value:
387+
member_access_expr
388+
base:
389+
name_expr
390+
identifier: identifier "t"
391+
member: identifier "0"

unified/extractor/tests/corpus/swift/functions.txt

Lines changed: 159 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,19 @@ source_file
3232
top_level
3333
body:
3434
block
35-
stmt: unsupported_node "func greet() {\n print(\"hello\")\n}"
35+
stmt:
36+
function_declaration
37+
body:
38+
block
39+
stmt:
40+
call_expr
41+
argument:
42+
argument
43+
value: string_literal "\"hello\""
44+
callee:
45+
name_expr
46+
identifier: identifier "print"
47+
name: identifier "greet"
3648

3749
===
3850
Function with parameters and return type
@@ -96,7 +108,34 @@ source_file
96108
top_level
97109
body:
98110
block
99-
stmt: unsupported_node "func add(_ a: Int, _ b: Int) -> Int {\n return a + b\n}"
111+
stmt:
112+
function_declaration
113+
body:
114+
block
115+
stmt:
116+
return_expr
117+
value:
118+
binary_expr
119+
operator: infix_operator "+"
120+
left:
121+
name_expr
122+
identifier: identifier "a"
123+
right:
124+
name_expr
125+
identifier: identifier "b"
126+
name: identifier "add"
127+
parameter:
128+
parameter
129+
external_name: identifier "_"
130+
pattern:
131+
name_pattern
132+
identifier: identifier "a"
133+
parameter
134+
external_name: identifier "_"
135+
pattern:
136+
name_pattern
137+
identifier: identifier "b"
138+
return_type: unsupported_node "Int"
100139

101140
===
102141
Function with named parameters
@@ -143,7 +182,27 @@ source_file
143182
top_level
144183
body:
145184
block
146-
stmt: unsupported_node "func greet(person name: String) {\n print(name)\n}"
185+
stmt:
186+
function_declaration
187+
body:
188+
block
189+
stmt:
190+
call_expr
191+
argument:
192+
argument
193+
value:
194+
name_expr
195+
identifier: identifier "name"
196+
callee:
197+
name_expr
198+
identifier: identifier "print"
199+
name: identifier "greet"
200+
parameter:
201+
parameter
202+
external_name: identifier "person"
203+
pattern:
204+
name_pattern
205+
identifier: identifier "name"
147206

148207
===
149208
Function with default parameter value
@@ -192,7 +251,27 @@ source_file
192251
top_level
193252
body:
194253
block
195-
stmt: unsupported_node "func greet(name: String = \"world\") {\n print(name)\n}"
254+
stmt:
255+
function_declaration
256+
body:
257+
block
258+
stmt:
259+
call_expr
260+
argument:
261+
argument
262+
value:
263+
name_expr
264+
identifier: identifier "name"
265+
callee:
266+
name_expr
267+
identifier: identifier "print"
268+
name: identifier "greet"
269+
parameter:
270+
parameter
271+
default: string_literal "\"world\""
272+
pattern:
273+
name_pattern
274+
identifier: identifier "name"
196275

197276
===
198277
Variadic function
@@ -258,7 +337,35 @@ source_file
258337
top_level
259338
body:
260339
block
261-
stmt: unsupported_node "func sum(_ values: Int...) -> Int {\n return values.reduce(0, +)\n}"
340+
stmt:
341+
function_declaration
342+
body:
343+
block
344+
stmt:
345+
return_expr
346+
value:
347+
call_expr
348+
argument:
349+
argument
350+
value: int_literal "0"
351+
argument
352+
value:
353+
name_expr
354+
identifier: identifier "+"
355+
callee:
356+
member_access_expr
357+
base:
358+
name_expr
359+
identifier: identifier "values"
360+
member: identifier "reduce"
361+
name: identifier "sum"
362+
parameter:
363+
parameter
364+
external_name: identifier "_"
365+
pattern:
366+
name_pattern
367+
identifier: identifier "values"
368+
return_type: unsupported_node "Int"
262369

263370
===
264371
Function call
@@ -287,7 +394,16 @@ source_file
287394
top_level
288395
body:
289396
block
290-
stmt: unsupported_node "foo(1, 2)"
397+
stmt:
398+
call_expr
399+
argument:
400+
argument
401+
value: int_literal "1"
402+
argument
403+
value: int_literal "2"
404+
callee:
405+
name_expr
406+
identifier: identifier "foo"
291407

292408
===
293409
Function call with labelled arguments
@@ -319,7 +435,15 @@ source_file
319435
top_level
320436
body:
321437
block
322-
stmt: unsupported_node "greet(person: \"Bob\")"
438+
stmt:
439+
call_expr
440+
argument:
441+
argument
442+
name: identifier "person"
443+
value: string_literal "\"Bob\""
444+
callee:
445+
name_expr
446+
identifier: identifier "greet"
323447

324448
===
325449
Method call
@@ -351,7 +475,17 @@ source_file
351475
top_level
352476
body:
353477
block
354-
stmt: unsupported_node "list.append(1)"
478+
stmt:
479+
call_expr
480+
argument:
481+
argument
482+
value: int_literal "1"
483+
callee:
484+
member_access_expr
485+
base:
486+
name_expr
487+
identifier: identifier "list"
488+
member: identifier "append"
355489

356490
===
357491
Generic function
@@ -404,4 +538,20 @@ source_file
404538
top_level
405539
body:
406540
block
407-
stmt: unsupported_node "func identity<T>(_ x: T) -> T {\n return x\n}"
541+
stmt:
542+
function_declaration
543+
body:
544+
block
545+
stmt:
546+
return_expr
547+
value:
548+
name_expr
549+
identifier: identifier "x"
550+
name: identifier "identity"
551+
parameter:
552+
parameter
553+
external_name: identifier "_"
554+
pattern:
555+
name_pattern
556+
identifier: identifier "x"
557+
return_type: unsupported_node "T"

0 commit comments

Comments
 (0)