diff --git a/fixtures/small/fndptn_actual.rb b/fixtures/small/fndptn_actual.rb index 44f1f787..5c00db95 100644 --- a/fixtures/small/fndptn_actual.rb +++ b/fixtures/small/fndptn_actual.rb @@ -1,5 +1,5 @@ case ["I will arise", "and go now", "for always night and day"] -in Lake[*, "I hear lake water lapping", "with low sounds by the shore", *waves] +in Lake[*, "I hear lake water lapping",with_low_sounds_by_the_shore, *waves] <<~YEATS While I stand on the roadway, or on the pavements grey, I hear it in the deep heart's core. diff --git a/fixtures/small/fndptn_expected.rb b/fixtures/small/fndptn_expected.rb index 053bdad2..53d4e78f 100644 --- a/fixtures/small/fndptn_expected.rb +++ b/fixtures/small/fndptn_expected.rb @@ -1,5 +1,5 @@ case ["I will arise", "and go now", "for always night and day"] -in Lake[*, "I hear lake water lapping", "with low sounds by the shore", *waves] +in Lake[*, "I hear lake water lapping", with_low_sounds_by_the_shore, *waves] <<~YEATS While I stand on the roadway, or on the pavements grey, I hear it in the deep heart's core. diff --git a/librubyfmt/src/format.rs b/librubyfmt/src/format.rs index c785b3d9..bc7a5815 100644 --- a/librubyfmt/src/format.rs +++ b/librubyfmt/src/format.rs @@ -3406,10 +3406,10 @@ fn format_pattern(ps: &mut dyn ConcreteParserState, pattern_node: PatternNode) { } } -fn format_aryptn(ps: &mut dyn ConcreteParserState, mut aryptn: Aryptn) { +fn format_aryptn(ps: &mut dyn ConcreteParserState, aryptn: Aryptn) { // Making this `mut` for let Aryptn(_, maybe_collection_name, maybe_pre_star_list, maybe_star, maybe_post_star_list) = - &mut aryptn; + aryptn; if let Some(collection_name) = maybe_collection_name { format_var_ref(ps, collection_name.clone()); } @@ -3418,13 +3418,23 @@ fn format_aryptn(ps: &mut dyn ConcreteParserState, mut aryptn: Aryptn) { Box::new(|ps| { let mut vals = Vec::new(); if let Some(pre_star_list) = maybe_pre_star_list { - vals.append(pre_star_list); + vals.append( + &mut pre_star_list + .into_iter() + .map(|item| item.into_expression()) + .collect::>(), + ); } if let Some(star) = maybe_star { vals.push(pattern_splat_as_expr(star.clone())); } if let Some(post_star_list) = maybe_post_star_list { - vals.append(post_star_list); + vals.append( + &mut post_star_list + .into_iter() + .map(|item| item.into_expression()) + .collect::>(), + ); } format_list_like_thing_items(ps, vals, None, false); }), @@ -3439,7 +3449,10 @@ fn format_fndptn(ps: &mut dyn ConcreteParserState, fndptn: Fndptn) { ps.breakable_of( BreakableDelims::for_array(), Box::new(|ps| { - let mut vals = values.clone(); + let mut vals = values + .into_iter() + .map(|item| item.into_expression()) + .collect::>(); vals.insert(0, pattern_splat_as_expr(pre_splat)); vals.push(pattern_splat_as_expr(post_splat)); diff --git a/librubyfmt/src/ripper_tree_types.rs b/librubyfmt/src/ripper_tree_types.rs index af96ee2f..a5ef810b 100644 --- a/librubyfmt/src/ripper_tree_types.rs +++ b/librubyfmt/src/ripper_tree_types.rs @@ -2386,24 +2386,55 @@ pub enum PatternNode { Fndptn(Fndptn), } +#[derive(RipperDeserialize, Debug, Clone)] +pub enum ExpressionOrVarField { + Expression(Expression), + VarField(VarField), +} + +impl ExpressionOrVarField { + pub fn into_expression(self) -> Expression { + match self { + ExpressionOrVarField::Expression(expr) => expr, + ExpressionOrVarField::VarField(var_field) => { + let start_line = var_field.2.start_line(); + Expression::Ident(Ident::new( + var_field + .1 + .map(|ref_type| ref_type.to_local_string()) + .unwrap_or_else(|| "".to_string()), + LineCol(start_line, 0), + )) + } + } + } + + pub fn start_line(&self) -> Option { + match self { + ExpressionOrVarField::Expression(expr) => expr.start_line(), + ExpressionOrVarField::VarField(var_field) => Some(var_field.2.start_line()), + } + } +} + def_tag!(aryptn_tag, "aryptn"); #[derive(Deserialize, Debug, Clone)] pub struct Aryptn( pub aryptn_tag, - pub Option, // Container type, e.g. `in Foo["a", "b"]` - pub Option>, // list of values before the first * - pub Option, // "*" pattern - pub Option>, // list of values the first * + pub Option, // Container type, e.g. `in Foo["a", "b"]` + pub Option>, // list of values before the first * + pub Option, // "*" pattern + pub Option>, // list of values the first * ); def_tag!(fndptn_tag, "fndptn"); #[derive(Deserialize, Debug, Clone)] pub struct Fndptn( pub fndptn_tag, - pub Option, // Container type, e.g. `in Foo["a", "b"]` - pub VarField, // leading "*" pattern - pub Vec, // inner values - pub VarField, // trailing "*" pattern + pub Option, // Container type, e.g. `in Foo["a", "b"]` + pub VarField, // leading "*" pattern + pub Vec, // inner values + pub VarField, // trailing "*" pattern ); #[derive(RipperDeserialize, Debug, Clone)]