Skip to content

Commit

Permalink
fix bug for constant pattern and unnamed rest args pattern
Browse files Browse the repository at this point in the history
ref: #325
  • Loading branch information
kzkn committed Sep 1, 2024
1 parent a1dd6c5 commit 68a0214
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 45 deletions.
94 changes: 50 additions & 44 deletions lib/rufo/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3084,46 +3084,75 @@ def visit_array_pattern(node)
_, const_ref, pre_rest, rest, post_rest = node

if const_ref
return visit_constant_pattern(node)
visit const_ref
end

left_paren_token, right_paren_token = if current_token_kind == :on_lparen
%i[on_lparen on_rparen]
elsif current_token_kind == :on_lbracket
%i[on_lbracket on_rbracket]
else
[]
end

# pattern is [*]
if !pre_rest && !post_rest && rest == [:var_field, nil]
consume_token :on_lbracket
if left_paren_token
consume_token left_paren_token
end

skip_space_or_newline
consume_op "*"
skip_space_or_newline
consume_token :on_rbracket

if right_paren_token
consume_token right_paren_token
end
return
end

token_column = current_token_column

has_bracket = current_token_kind == :on_lbracket
if has_bracket
consume_token :on_lbracket
if left_paren_token
consume_token left_paren_token
skip_space
end

write_comma = false
newline = newline?
wrote_comma = false
if pre_rest
visit_literal_elements pre_rest, inside_array: true, token_column: token_column, keep_final_newline: !has_bracket
write_comma = true
end
visit_comma_separated_list pre_rest
skip_space

# pattern like `[a,]` will make `rest` as `[:var_field, nil]`
if rest && ((var_name_node = rest[1]) || current_token_value == "*")
if write_comma
if comma?
check :on_comma
write ","
consume_space
else
next_token
skip_space
wrote_comma = true
end
if newline
skip_space_or_newline
write_line
write_indent
end
end

consume_op "*"
if var_name_node
visit rest
if rest
if wrote_comma
consume_space
end

# pattern like `[a,]` will make `rest` as `[:var_field, nil]`
if (var_name_node = rest[1]) || current_token_value == "*"
consume_op "*"
if var_name_node
visit rest
end
end
elsif wrote_comma && !newline?
# In Ruby 3.3, rest is nil when the code is like `[a,]`. Insert a space after comma at here.
consume_space
end

if post_rest
Expand All @@ -3133,36 +3162,13 @@ def visit_array_pattern(node)
consume_space
next_token

visit_literal_elements post_rest, inside_array: true, token_column: token_column, keep_final_newline: !has_bracket
visit_literal_elements post_rest, inside_array: true, token_column: token_column, keep_final_newline: !left_paren_token
end

skip_space
if has_bracket
consume_token :on_rbracket
end
end

def visit_constant_pattern(node)
# [:aryptn, const_ref, args]
_, const_ref, args = node

visit const_ref

parens = current_token_kind == :on_lparen
if parens
consume_token :on_lparen
else
consume_token :on_lbracket
end

skip_space
visit_comma_separated_list args

skip_space
if parens
consume_token :on_rparen
else
consume_token :on_rbracket
if right_paren_token
consume_token right_paren_token
end
end

Expand Down
144 changes: 143 additions & 1 deletion spec/lib/rufo/formatter_source_specs/pattern_matching.rb.spec
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ end
#~# ORIGINAL alternative pattern

case a
in String | [1, * ]
in String | [1 , * ]
puts x
else
puts "2"
Expand Down Expand Up @@ -199,6 +199,36 @@ in [
a
end

#~# ORIGINAL
case [0]
in [
a, b,
c
]
a
end

#~# EXPECTED
case [0]
in [
a, b,
c
]
a
end

#~# ORIGINAL
case [0]
in [ a , ]
a
end

#~# EXPECTED
case [0]
in [a, ]
a
end

#~# ORIGINAL array pattern (newline after comma)
case [0]
in [ a,
Expand Down Expand Up @@ -796,3 +826,115 @@ case x
in { "a": 1 }
1
end

#~# ORIGINAL issue_325
case "baz"
in Foo[*data] # This splat is what causes the crash
puts "foo"
else
puts "bar"
end

#~# EXPECTED
case "baz"
in Foo[*data] # This splat is what causes the crash
puts "foo"
else
puts "bar"
end

#~# ORIGINAL
case x
in Foo[a, ]
1
end

#~# EXPECTED
case x
in Foo[a, ]
1
end

#~# ORIGINAL
case x
in Foo[ a, * ]
1
end

#~# EXPECTED
case x
in Foo[a, *]
1
end

#~# ORIGINAL
case x
in Foo[ a, *b ]
1
end

#~# EXPECTED
case x
in Foo[a, *b]
1
end

#~# ORIGINAL
case x
in Foo[ *a,b,*c ]
1
end

#~# EXPECTED
case x
in Foo[*a, b, *c]
1
end

#~# ORIGINAL
case x
in Foo[ *,a,* ]
1
end

#~# EXPECTED
case x
in Foo[*, a, *]
1
end

#~# ORIGINAL
case x
in Foo[ a,*b,c ]
1
end

#~# EXPECTED
case x
in Foo[a, *b, c]
1
end

#~# ORIGINAL
case x
in Foo[ * ]
1
end

#~# EXPECTED
case x
in Foo[*]
1
end

#~# ORIGINAL
case x
in Foo( *)
1
end

#~# EXPECTED
case x
in Foo(*)
1
end

0 comments on commit 68a0214

Please sign in to comment.