From 7793702e8a6ef92000a7a58c0dcbe84e611fd6f7 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 24 Jun 2026 22:24:18 +0000 Subject: [PATCH] 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. --- .../extractor/src/languages/swift/swift.rs | 47 +++++++------ .../extractor/tests/corpus/swift/types.txt | 66 +++++++++++++++++++ 2 files changed, 94 insertions(+), 19 deletions(-) diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index b2264dd590f..786b4c867ba 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -270,14 +270,18 @@ fn translation_rules() -> Vec> { => (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> { (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> { (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 = mods.iter().map(|&m| m.into()).collect(); - let case_ids: Vec = 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!( diff --git a/unified/extractor/tests/corpus/swift/types.txt b/unified/extractor/tests/corpus/swift/types.txt index dc3eb9db305..9c22ae74798 100644 --- a/unified/extractor/tests/corpus/swift/types.txt +++ b/unified/extractor/tests/corpus/swift/types.txt @@ -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"