mirror of
https://github.com/github/codeql.git
synced 2026-05-29 10:31:23 +02:00
Unified: add tuple_pattern and sequence_condition; refine if-let/guard mapping
ast_types.yml additions:
- tuple_pattern { element*: pattern } in the pattern supertype.
- sequence_condition { stmt*: stmt, condition: condition } in the
condition supertype.
swift.rs:
- Map Swift tuple destructuring (e.g. `let (a, b) = pair`) to the new
tuple_pattern instead of synthesizing an apply_pattern.
- if-let / guard-let: explicitly match the value_binding_pattern
(the `let` keyword) and bind the source expression as the next
condition child, so `let` no longer leaks into the output.
This commit is contained in:
@@ -18,6 +18,7 @@ supertypes:
|
||||
condition:
|
||||
- expr_condition
|
||||
- let_pattern_condition
|
||||
- sequence_condition
|
||||
- unsupported_node
|
||||
pattern:
|
||||
- var_pattern
|
||||
@@ -92,6 +93,13 @@ named:
|
||||
expr_condition:
|
||||
expr: expr
|
||||
|
||||
# A series of statements that are executed before evaluating the trailing condition.
|
||||
# Useful for languages where a conditional clause may be preceded by side-effecting
|
||||
# syntactic elements (e.g. binding clauses) that don't themselves form a condition.
|
||||
sequence_condition:
|
||||
stmt*: stmt
|
||||
condition: condition
|
||||
|
||||
# Evaluate 'expr' and match its result against 'pattern', and return true if it matches.
|
||||
# Variables bound by the pattern will be in scope within the 'true' branch controlled by this condition.
|
||||
let_pattern_condition:
|
||||
|
||||
@@ -157,29 +157,33 @@ fn translation_rules() -> Vec<yeast::Rule> {
|
||||
),
|
||||
// ---- Guard statement ----
|
||||
// `guard let x = e else { ... }` — currently only handles the
|
||||
// let-binding form, since plain `guard cond else { ... }` is not
|
||||
// exercised by any existing corpus test.
|
||||
// let-binding form. The Swift parser models the `let` keyword as a
|
||||
// `value_binding_pattern` child of `condition`, followed by an
|
||||
// unnamed `=` and the source expression.
|
||||
rule!(
|
||||
(guard_statement
|
||||
bound_identifier: (simple_identifier) @id
|
||||
condition: (_)* @cond_children
|
||||
condition: (value_binding_pattern)
|
||||
condition: (_) @value
|
||||
(else)
|
||||
(statements) @else_branch)
|
||||
=>
|
||||
(guard_if_stmt
|
||||
condition: (let_pattern_condition
|
||||
pattern: (var_pattern identifier: (identifier #{id}))
|
||||
value: {*cond_children.last().unwrap()})
|
||||
value: {value})
|
||||
else: {else_branch})
|
||||
),
|
||||
// ---- If statement ----
|
||||
// if-let binding (with optional else branch). The Swift parser puts
|
||||
// the bound name in `bound_identifier` and the source expression as
|
||||
// the last child of the multi-child `condition` field.
|
||||
// the bound name in `bound_identifier`, the `let` keyword as a
|
||||
// `value_binding_pattern` child of `condition`, and the source
|
||||
// expression as a separate child of `condition`.
|
||||
rule!(
|
||||
(if_statement
|
||||
bound_identifier: (simple_identifier) @id
|
||||
condition: (_)* @cond_children
|
||||
condition: (value_binding_pattern)
|
||||
condition: (_) @value
|
||||
(statements) @then
|
||||
(else)
|
||||
(_) @else_branch)
|
||||
@@ -187,20 +191,21 @@ fn translation_rules() -> Vec<yeast::Rule> {
|
||||
(if_stmt
|
||||
condition: (let_pattern_condition
|
||||
pattern: (var_pattern identifier: (identifier #{id}))
|
||||
value: {*cond_children.last().unwrap()})
|
||||
value: {value})
|
||||
then: {then}
|
||||
else: {else_branch})
|
||||
),
|
||||
rule!(
|
||||
(if_statement
|
||||
bound_identifier: (simple_identifier) @id
|
||||
condition: (_)* @cond_children
|
||||
condition: (value_binding_pattern)
|
||||
condition: (_) @value
|
||||
(statements) @then)
|
||||
=>
|
||||
(if_stmt
|
||||
condition: (let_pattern_condition
|
||||
pattern: (var_pattern identifier: (identifier #{id}))
|
||||
value: {*cond_children.last().unwrap()})
|
||||
value: {value})
|
||||
then: {then})
|
||||
),
|
||||
// With explicit else branch (block or chained if).
|
||||
|
||||
Reference in New Issue
Block a user