Skip to content

Commit

Permalink
Handle variables in patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
reese authored Jan 7, 2024
1 parent 661254f commit 403a0b2
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 15 deletions.
2 changes: 1 addition & 1 deletion fixtures/small/fndptn_actual.rb
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion fixtures/small/fndptn_expected.rb
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
23 changes: 18 additions & 5 deletions librubyfmt/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand All @@ -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::<Vec<_>>(),
);
}
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::<Vec<_>>(),
);
}
format_list_like_thing_items(ps, vals, None, false);
}),
Expand All @@ -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::<Vec<_>>();
vals.insert(0, pattern_splat_as_expr(pre_splat));
vals.push(pattern_splat_as_expr(post_splat));

Expand Down
47 changes: 39 additions & 8 deletions librubyfmt/src/ripper_tree_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u64> {
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<VarRef>, // Container type, e.g. `in Foo["a", "b"]`
pub Option<Vec<Expression>>, // list of values before the first *
pub Option<VarField>, // "*" pattern
pub Option<Vec<Expression>>, // list of values the first *
pub Option<VarRef>, // Container type, e.g. `in Foo["a", "b"]`
pub Option<Vec<ExpressionOrVarField>>, // list of values before the first *
pub Option<VarField>, // "*" pattern
pub Option<Vec<ExpressionOrVarField>>, // list of values the first *
);

def_tag!(fndptn_tag, "fndptn");
#[derive(Deserialize, Debug, Clone)]
pub struct Fndptn(
pub fndptn_tag,
pub Option<VarRef>, // Container type, e.g. `in Foo["a", "b"]`
pub VarField, // leading "*" pattern
pub Vec<Expression>, // inner values
pub VarField, // trailing "*" pattern
pub Option<VarRef>, // Container type, e.g. `in Foo["a", "b"]`
pub VarField, // leading "*" pattern
pub Vec<ExpressionOrVarField>, // inner values
pub VarField, // trailing "*" pattern
);

#[derive(RipperDeserialize, Debug, Clone)]
Expand Down

0 comments on commit 403a0b2

Please sign in to comment.