mirror of
https://github.com/github/codeql.git
synced 2026-06-25 22:57:01 +02:00
unified/swift: add closure and capture mappings
This commit is contained in:
@@ -386,6 +386,70 @@ fn translation_rules() -> Vec<yeast::Rule> {
|
||||
rule!((control_transfer_statement kind: "continue" result: @lbl) => (continue_expr label: (identifier #{lbl}))),
|
||||
rule!((control_transfer_statement kind: "continue") => (continue_expr)),
|
||||
rule!((control_transfer_statement kind: (throw_keyword) result: @val) => (throw_expr value: {val})),
|
||||
// ---- Closures ----
|
||||
// Lambda literal with optional type header (parameters + optional return type).
|
||||
// The return_type capture is optional, so this rule covers both cases.
|
||||
rule!(
|
||||
(lambda_literal
|
||||
attribute: _* @attrs
|
||||
captures: (capture_list item: _* @captures)?
|
||||
type: (lambda_function_type
|
||||
params: (lambda_function_type_parameters parameter: _* @params)
|
||||
return_type: _? @ret)?
|
||||
statement: _* @body)
|
||||
=>
|
||||
(function_expr
|
||||
modifier: {..attrs}
|
||||
capture_declaration: {..captures}
|
||||
parameter: {..params}
|
||||
return_type: {..ret}
|
||||
body: (block stmt: {..body}))
|
||||
),
|
||||
// capture_list_item with ownership modifier (e.g. [weak self], [unowned x])
|
||||
rule!(
|
||||
(capture_list_item ownership: _? @ownership name: @name value: _? @val)
|
||||
=>
|
||||
(variable_declaration
|
||||
modifier: {..ownership}
|
||||
pattern: (name_pattern identifier: (identifier #{name}))
|
||||
value: {..val})
|
||||
),
|
||||
// Lambda parameter with type and optional external name
|
||||
rule!(
|
||||
(lambda_parameter external_name: @ext name: @name type: @ty)
|
||||
=>
|
||||
(parameter
|
||||
external_name: (identifier #{ext})
|
||||
pattern: (name_pattern identifier: (identifier #{name}))
|
||||
type: {ty})
|
||||
),
|
||||
rule!(
|
||||
(lambda_parameter name: @name type: @ty)
|
||||
=>
|
||||
(parameter
|
||||
pattern: (name_pattern identifier: (identifier #{name}))
|
||||
type: {ty})
|
||||
),
|
||||
rule!(
|
||||
(lambda_parameter external_name: @ext name: @name)
|
||||
=>
|
||||
(parameter
|
||||
external_name: (identifier #{ext})
|
||||
pattern: (name_pattern identifier: (identifier #{name})))
|
||||
),
|
||||
rule!(
|
||||
(lambda_parameter name: @name)
|
||||
=>
|
||||
(parameter pattern: (name_pattern identifier: (identifier #{name})))
|
||||
),
|
||||
// Call expression with trailing closure (no value_arguments)
|
||||
rule!(
|
||||
(call_expression function: @func suffix: (call_suffix lambda: (lambda_literal) @closure))
|
||||
=>
|
||||
(call_expr
|
||||
callee: {func}
|
||||
argument: (argument value: {closure}))
|
||||
),
|
||||
// ---- Fallbacks ----
|
||||
rule!(
|
||||
(_)
|
||||
|
||||
@@ -57,7 +57,24 @@ top_level
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "f"
|
||||
value: unsupported_node "{ (x: Int) -> Int in x * 2 }"
|
||||
value:
|
||||
function_expr
|
||||
body:
|
||||
block
|
||||
stmt:
|
||||
binary_expr
|
||||
operator: infix_operator "*"
|
||||
left:
|
||||
name_expr
|
||||
identifier: identifier "x"
|
||||
right: int_literal "2"
|
||||
parameter:
|
||||
parameter
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "x"
|
||||
type: unsupported_node "Int"
|
||||
return_type: unsupported_node "Int"
|
||||
|
||||
===
|
||||
Closure with shorthand parameters
|
||||
@@ -97,7 +114,19 @@ top_level
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "f"
|
||||
value: unsupported_node "{ $0 + $1 }"
|
||||
value:
|
||||
function_expr
|
||||
body:
|
||||
block
|
||||
stmt:
|
||||
binary_expr
|
||||
operator: infix_operator "+"
|
||||
left:
|
||||
name_expr
|
||||
identifier: identifier "$0"
|
||||
right:
|
||||
name_expr
|
||||
identifier: identifier "$1"
|
||||
|
||||
===
|
||||
Trailing closure
|
||||
@@ -131,7 +160,27 @@ source_file
|
||||
top_level
|
||||
body:
|
||||
block
|
||||
stmt: unsupported_node "xs.map { $0 * 2 }"
|
||||
stmt:
|
||||
call_expr
|
||||
argument:
|
||||
argument
|
||||
value:
|
||||
function_expr
|
||||
body:
|
||||
block
|
||||
stmt:
|
||||
binary_expr
|
||||
operator: infix_operator "*"
|
||||
left:
|
||||
name_expr
|
||||
identifier: identifier "$0"
|
||||
right: int_literal "2"
|
||||
callee:
|
||||
member_access_expr
|
||||
base:
|
||||
name_expr
|
||||
identifier: identifier "xs"
|
||||
member: identifier "map"
|
||||
|
||||
===
|
||||
Closure with capture list
|
||||
@@ -188,7 +237,22 @@ top_level
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "f"
|
||||
value: unsupported_node "{ [weak self] in self?.doThing() }"
|
||||
value:
|
||||
function_expr
|
||||
body:
|
||||
block
|
||||
stmt:
|
||||
call_expr
|
||||
callee:
|
||||
member_access_expr
|
||||
base: unsupported_node "self?"
|
||||
member: identifier "doThing"
|
||||
capture_declaration:
|
||||
variable_declaration
|
||||
modifier: unsupported_node "weak" <-- ERROR: The field variable_declaration.modifier should contain modifier, but got unsupported_node
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "self"
|
||||
|
||||
===
|
||||
Multi-statement closure
|
||||
@@ -269,4 +333,35 @@ top_level
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "f"
|
||||
value: unsupported_node "{ (x: Int) -> Int in\n let y = x + 1\n return y * 2\n}"
|
||||
value:
|
||||
function_expr
|
||||
body:
|
||||
block
|
||||
stmt:
|
||||
variable_declaration
|
||||
modifier: modifier "let"
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "y"
|
||||
value:
|
||||
binary_expr
|
||||
operator: infix_operator "+"
|
||||
left:
|
||||
name_expr
|
||||
identifier: identifier "x"
|
||||
right: int_literal "1"
|
||||
return_expr
|
||||
value:
|
||||
binary_expr
|
||||
operator: infix_operator "*"
|
||||
left:
|
||||
name_expr
|
||||
identifier: identifier "y"
|
||||
right: int_literal "2"
|
||||
parameter:
|
||||
parameter
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "x"
|
||||
type: unsupported_node "Int"
|
||||
return_type: unsupported_node "Int"
|
||||
|
||||
Reference in New Issue
Block a user