-
Notifications
You must be signed in to change notification settings - Fork 52
Description
The following example doesn't format corectly:
Constant
.foo
.bar do |
a:,
**
|
endproduces
Constant
.foo
.bar do |
a:,
**
|
endHowever, giving the ** argument a name like **x will format correctly.
The extra newline inserted on line 3 happens because the call to on_line (via format_ident) that happens when there is an identifier present is skipped, and the number of lines traversed exceeds the limit specified in line_difference_requires_newline on the next call to on_line. This causes a fixup newline to be emitted at the location of the last newline, which in this case is the beginning of the .bar send.
It's not obvious to me how to fix this when deserializing from ripper, as it doesn't include line information when the kwrest argument has no identifier:
irb(main):001> Ripper.sexp("foo do |\na:,\n**\n|\n end")
=>
[:program,
[[:method_add_block,
[:method_add_arg, [:fcall, [:@ident, "foo", [1, 0]]], []],
[:do_block,
[:block_var, [:params, nil, nil, nil, nil, [[[:@label, "a:", [2, 0]], false]], [:kwrest_param, nil], nil], false],
[:bodystmt, [[:void_stmt]], nil, nil, nil]]]]]
vs
irb(main):002> Ripper.sexp("foo do |\na:,\n**x\n|\n end")
=>
[:program,
[[:method_add_block,
[:method_add_arg, [:fcall, [:@ident, "foo", [1, 0]]], []],
[:do_block,
[:block_var, [:params, nil, nil, nil, nil, [[[:@label, "a:", [2, 0]], false]], [:kwrest_param, [:@ident, "x", [3, 2]]], nil], false],
[:bodystmt, [[:void_stmt]], nil, nil, nil]]]]]
Without that line information present, I'm not sure the current approach can be fixed. However, we could switch to keeping all params on one line, and spilling one argument per line when we exceed column width, instead of trying to maintain the newline structure from the original program, which would mean we would no longer depend on this information from ripper.