quote do
unquote(:foo)() do
"bar"
end
end
becomes
quote do
unquote(:foo) do
"bar"
end
end
Which has different meaning (and AST).
Do you expect that the fix for this will be in the parser or the formatter?
From what i can tell, the parens are present after tokenizing
elixir
[
{:paren_identifier, {1, 1, nil}, :unquote},
{:"(", {1, 8, nil}},
{:atom, {1, 9, nil}, :foo},
{:")", {1, 13, nil}},
{:"(", {1, 14, nil}},
{:")", {1, 15, nil}},
{:do, {1, 17, nil}},
{:eol, {1, 19, 1}},
{:bin_string, {2, 3, nil}, ["bar"]},
{:eol, {2, 8, 1}},
{:end, {3, 1, nil}},
{:eol, {3, 4, 1}}
]
but that information is lost after parsing (which I believe is the correct behavior.)
elixir
{{:unquote, [closing: [line: 1], line: 1],
[{:__block__, [delimiter: ":", line: 1], [:foo]}]},
[
do: [line: 1],
end: [line: 3],
closing: [line: 1],
closing: [line: 1],
line: 1
],
[
[
{{:__block__, [line: 1], [:do]},
{:__block__, [delimiter: "\"", line: 2], ["bar"]}}
]
]}
I'm not sure how this could be fixed without some special rule regarding calls to unquote in the formatter, but that doesn't seem like a robust solution.
What do you think?
It is a bug in the formatter. You don't need a special rule for unquote. The rule should still apply for something like foo(bar)() do ... end (this is not a semantically valid expression but the formatter does not care about it). In a nutshell, the issue is that if we see a function call with only do blocks and without any other parens, such as foo() do ... end, we automatically remove the parens into foo() do ... end. The fix is that we shouldn't remove the parens if the parens are being applied to a function call in itself.
Most helpful comment
It is a bug in the formatter. You don't need a special rule for unquote. The rule should still apply for something like
foo(bar)() do ... end(this is not a semantically valid expression but the formatter does not care about it). In a nutshell, the issue is that if we see a function call with only do blocks and without any other parens, such asfoo() do ... end, we automatically remove the parens intofoo() do ... end. The fix is that we shouldn't remove the parens if the parens are being applied to a function call in itself.