mirror of
https://github.com/github/codeql.git
synced 2026-06-25 14:47:04 +02:00
unified/swift: Propagate enum_entry outer modifiers via context
Same as in the preceding commit, we added a test beforehand for testing this syntax, and verified that it was unchanged by the cleanup in this commit.
This commit is contained in:
@@ -270,14 +270,18 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
|
||||
=>
|
||||
(parameter type: {ty})
|
||||
),
|
||||
// enum_case_entry with associated values → class_like_declaration containing
|
||||
// a constructor whose parameters are the data parameters.
|
||||
// enum_case_entry with associated values → class_like_declaration
|
||||
// containing a constructor whose parameters are the data
|
||||
// parameters. Reads outer modifiers / chained tag from `ctx`
|
||||
// (set by the outer `enum_entry` rule).
|
||||
rule!(
|
||||
(enum_case_entry
|
||||
name: @name
|
||||
data_contents: (enum_type_parameters parameter: _* @params))
|
||||
=>
|
||||
(class_like_declaration
|
||||
modifier: {..ctx.outer_modifiers.clone()}
|
||||
modifier: {..chained_modifier(&mut ctx)}
|
||||
modifier: (modifier "enum_case")
|
||||
name: (identifier #{name})
|
||||
member: (constructor_declaration parameter: {..params} body: (block)))
|
||||
@@ -287,6 +291,8 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
|
||||
(enum_case_entry name: @name raw_value: @val)
|
||||
=>
|
||||
(variable_declaration
|
||||
modifier: {..ctx.outer_modifiers.clone()}
|
||||
modifier: {..chained_modifier(&mut ctx)}
|
||||
modifier: (modifier "enum_case")
|
||||
pattern: (name_pattern identifier: (identifier #{name}))
|
||||
value: {val})
|
||||
@@ -296,28 +302,31 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
|
||||
(enum_case_entry name: @name)
|
||||
=>
|
||||
(variable_declaration
|
||||
modifier: {..ctx.outer_modifiers.clone()}
|
||||
modifier: {..chained_modifier(&mut ctx)}
|
||||
modifier: (modifier "enum_case")
|
||||
pattern: (name_pattern identifier: (identifier #{name})))
|
||||
),
|
||||
// enum_entry: flatten case entries; attach outer modifiers to each, and
|
||||
// chained_declaration on every entry after the first.
|
||||
rule!(
|
||||
// enum_entry: flatten case entries; publish outer modifiers
|
||||
// into `ctx` and translate each case with `ctx.is_chained`
|
||||
// toggled per iteration so the inner `enum_case_entry` rules
|
||||
// emit complete `modifier:` lists from the start.
|
||||
manual_rule!(
|
||||
(enum_entry case: _+ @cases (modifiers)* @mods)
|
||||
=>
|
||||
{..{
|
||||
let mod_ids: Vec<usize> = mods.iter().map(|&m| m.into()).collect();
|
||||
let case_ids: Vec<usize> = cases.iter().map(|&c| c.into()).collect();
|
||||
for (i, &case_id) in case_ids.iter().enumerate() {
|
||||
if i > 0 {
|
||||
let chained = ctx.literal("modifier", "chained_declaration");
|
||||
ctx.prepend_field(case_id, "modifier", chained);
|
||||
}
|
||||
for &mod_id in mod_ids.iter().rev() {
|
||||
ctx.prepend_field(case_id, "modifier", mod_id);
|
||||
}
|
||||
{
|
||||
let mut modifiers = Vec::new();
|
||||
for m in mods {
|
||||
modifiers.extend(ctx.translate(m)?);
|
||||
}
|
||||
case_ids
|
||||
}}
|
||||
ctx.outer_modifiers = modifiers;
|
||||
|
||||
let mut result = Vec::new();
|
||||
for (i, case) in cases.into_iter().enumerate() {
|
||||
ctx.is_chained = i > 0;
|
||||
result.extend(ctx.translate(case)?);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
),
|
||||
// Plain assignment: `x = expr`
|
||||
rule!(
|
||||
|
||||
@@ -1014,3 +1014,69 @@ top_level
|
||||
accessor_kind: accessor_kind "set"
|
||||
modifier: modifier "protocol"
|
||||
name: identifier "P"
|
||||
|
||||
===
|
||||
Enum with comma-separated cases (chained_declaration)
|
||||
===
|
||||
|
||||
enum Suit {
|
||||
case clubs, diamonds, hearts, spades
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
source_file
|
||||
statement:
|
||||
class_declaration
|
||||
body:
|
||||
enum_class_body
|
||||
member:
|
||||
enum_entry
|
||||
case:
|
||||
enum_case_entry
|
||||
name: simple_identifier "clubs"
|
||||
enum_case_entry
|
||||
name: simple_identifier "diamonds"
|
||||
enum_case_entry
|
||||
name: simple_identifier "hearts"
|
||||
enum_case_entry
|
||||
name: simple_identifier "spades"
|
||||
declaration_kind: enum
|
||||
name: type_identifier "Suit"
|
||||
|
||||
---
|
||||
|
||||
top_level
|
||||
body:
|
||||
block
|
||||
stmt:
|
||||
class_like_declaration
|
||||
member:
|
||||
variable_declaration
|
||||
modifier: modifier "enum_case"
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "clubs"
|
||||
variable_declaration
|
||||
modifier:
|
||||
modifier "chained_declaration"
|
||||
modifier "enum_case"
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "diamonds"
|
||||
variable_declaration
|
||||
modifier:
|
||||
modifier "chained_declaration"
|
||||
modifier "enum_case"
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "hearts"
|
||||
variable_declaration
|
||||
modifier:
|
||||
modifier "chained_declaration"
|
||||
modifier "enum_case"
|
||||
pattern:
|
||||
name_pattern
|
||||
identifier: identifier "spades"
|
||||
modifier: modifier "enum"
|
||||
name: identifier "Suit"
|
||||
|
||||
Reference in New Issue
Block a user