Skip to content

Commit 7793702

Browse files
committed
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.
1 parent 4730898 commit 7793702

2 files changed

Lines changed: 94 additions & 19 deletions

File tree

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

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -270,14 +270,18 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
270270
=>
271271
(parameter type: {ty})
272272
),
273-
// enum_case_entry with associated values → class_like_declaration containing
274-
// a constructor whose parameters are the data parameters.
273+
// enum_case_entry with associated values → class_like_declaration
274+
// containing a constructor whose parameters are the data
275+
// parameters. Reads outer modifiers / chained tag from `ctx`
276+
// (set by the outer `enum_entry` rule).
275277
rule!(
276278
(enum_case_entry
277279
name: @name
278280
data_contents: (enum_type_parameters parameter: _* @params))
279281
=>
280282
(class_like_declaration
283+
modifier: {..ctx.outer_modifiers.clone()}
284+
modifier: {..chained_modifier(&mut ctx)}
281285
modifier: (modifier "enum_case")
282286
name: (identifier #{name})
283287
member: (constructor_declaration parameter: {..params} body: (block)))
@@ -287,6 +291,8 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
287291
(enum_case_entry name: @name raw_value: @val)
288292
=>
289293
(variable_declaration
294+
modifier: {..ctx.outer_modifiers.clone()}
295+
modifier: {..chained_modifier(&mut ctx)}
290296
modifier: (modifier "enum_case")
291297
pattern: (name_pattern identifier: (identifier #{name}))
292298
value: {val})
@@ -296,28 +302,31 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
296302
(enum_case_entry name: @name)
297303
=>
298304
(variable_declaration
305+
modifier: {..ctx.outer_modifiers.clone()}
306+
modifier: {..chained_modifier(&mut ctx)}
299307
modifier: (modifier "enum_case")
300308
pattern: (name_pattern identifier: (identifier #{name})))
301309
),
302-
// enum_entry: flatten case entries; attach outer modifiers to each, and
303-
// chained_declaration on every entry after the first.
304-
rule!(
310+
// enum_entry: flatten case entries; publish outer modifiers
311+
// into `ctx` and translate each case with `ctx.is_chained`
312+
// toggled per iteration so the inner `enum_case_entry` rules
313+
// emit complete `modifier:` lists from the start.
314+
manual_rule!(
305315
(enum_entry case: _+ @cases (modifiers)* @mods)
306-
=>
307-
{..{
308-
let mod_ids: Vec<usize> = mods.iter().map(|&m| m.into()).collect();
309-
let case_ids: Vec<usize> = cases.iter().map(|&c| c.into()).collect();
310-
for (i, &case_id) in case_ids.iter().enumerate() {
311-
if i > 0 {
312-
let chained = ctx.literal("modifier", "chained_declaration");
313-
ctx.prepend_field(case_id, "modifier", chained);
314-
}
315-
for &mod_id in mod_ids.iter().rev() {
316-
ctx.prepend_field(case_id, "modifier", mod_id);
317-
}
316+
{
317+
let mut modifiers = Vec::new();
318+
for m in mods {
319+
modifiers.extend(ctx.translate(m)?);
318320
}
319-
case_ids
320-
}}
321+
ctx.outer_modifiers = modifiers;
322+
323+
let mut result = Vec::new();
324+
for (i, case) in cases.into_iter().enumerate() {
325+
ctx.is_chained = i > 0;
326+
result.extend(ctx.translate(case)?);
327+
}
328+
Ok(result)
329+
}
321330
),
322331
// Plain assignment: `x = expr`
323332
rule!(

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

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,3 +1014,69 @@ top_level
10141014
accessor_kind: accessor_kind "set"
10151015
modifier: modifier "protocol"
10161016
name: identifier "P"
1017+
1018+
===
1019+
Enum with comma-separated cases (chained_declaration)
1020+
===
1021+
1022+
enum Suit {
1023+
case clubs, diamonds, hearts, spades
1024+
}
1025+
1026+
---
1027+
1028+
source_file
1029+
statement:
1030+
class_declaration
1031+
body:
1032+
enum_class_body
1033+
member:
1034+
enum_entry
1035+
case:
1036+
enum_case_entry
1037+
name: simple_identifier "clubs"
1038+
enum_case_entry
1039+
name: simple_identifier "diamonds"
1040+
enum_case_entry
1041+
name: simple_identifier "hearts"
1042+
enum_case_entry
1043+
name: simple_identifier "spades"
1044+
declaration_kind: enum
1045+
name: type_identifier "Suit"
1046+
1047+
---
1048+
1049+
top_level
1050+
body:
1051+
block
1052+
stmt:
1053+
class_like_declaration
1054+
member:
1055+
variable_declaration
1056+
modifier: modifier "enum_case"
1057+
pattern:
1058+
name_pattern
1059+
identifier: identifier "clubs"
1060+
variable_declaration
1061+
modifier:
1062+
modifier "chained_declaration"
1063+
modifier "enum_case"
1064+
pattern:
1065+
name_pattern
1066+
identifier: identifier "diamonds"
1067+
variable_declaration
1068+
modifier:
1069+
modifier "chained_declaration"
1070+
modifier "enum_case"
1071+
pattern:
1072+
name_pattern
1073+
identifier: identifier "hearts"
1074+
variable_declaration
1075+
modifier:
1076+
modifier "chained_declaration"
1077+
modifier "enum_case"
1078+
pattern:
1079+
name_pattern
1080+
identifier: identifier "spades"
1081+
modifier: modifier "enum"
1082+
name: identifier "Suit"

0 commit comments

Comments
 (0)