Skip to content

Commit 7181231

Browse files
author
José Valim
committed
Fix formatter for tilde inside bitstrings, closes #7558
Signed-off-by: José Valim <[email protected]>
1 parent be46a1f commit 7181231

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

lib/elixir/lib/code/formatter.ex

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,8 +1351,17 @@ defmodule Code.Formatter do
13511351
defp bitstring_segment_to_algebra({{:::, _, [segment, spec]}, i}, state, last) do
13521352
{doc, state} = quoted_to_algebra(segment, :parens_arg, state)
13531353
{spec, state} = bitstring_spec_to_algebra(spec, state)
1354-
doc = concat(concat(doc, "::"), wrap_in_parens_if_inspected_atom(spec))
1355-
{bitstring_wrap_parens(doc, i, last), state}
1354+
1355+
spec = wrap_in_parens_if_inspected_atom(spec)
1356+
spec = if i == last, do: bitstring_wrap_parens(spec, i, last), else: spec
1357+
1358+
doc =
1359+
doc
1360+
|> bitstring_wrap_parens(i, -1)
1361+
|> concat("::")
1362+
|> concat(spec)
1363+
1364+
{doc, state}
13561365
end
13571366

13581367
defp bitstring_segment_to_algebra({segment, i}, state, last) do
@@ -1370,21 +1379,19 @@ defmodule Code.Formatter do
13701379
quoted_to_algebra_with_parens_if_operator(spec, :parens_arg, state)
13711380
end
13721381

1373-
defp bitstring_wrap_parens(doc, i, last) do
1374-
if i == 0 or i == last do
1375-
string = format_to_string(doc)
1382+
defp bitstring_wrap_parens(doc, i, last) when i == 0 or i == last do
1383+
string = format_to_string(doc)
13761384

1377-
if (i == 0 and String.starts_with?(string, "<<")) or
1378-
(i == last and String.ends_with?(string, ">>")) do
1379-
wrap_in_parens(doc)
1380-
else
1381-
doc
1382-
end
1385+
if (i == 0 and String.starts_with?(string, ["~", "<<"])) or
1386+
(i == last and String.ends_with?(string, [">>"])) do
1387+
wrap_in_parens(doc)
13831388
else
13841389
doc
13851390
end
13861391
end
13871392

1393+
defp bitstring_wrap_parens(doc, _, _), do: doc
1394+
13881395
## Literals
13891396

13901397
defp list_to_algebra(meta, args, state) do

lib/elixir/test/elixir/code_formatter/containers_test.exs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,19 @@ defmodule Code.Formatter.ContainersTest do
247247
assert_format "<<1,2,3>>", "<<1, 2, 3>>"
248248
end
249249

250-
test "add parens on first and last in case of ambiguity" do
250+
test "add parens on first and last in case of binary ambiguity" do
251251
assert_format "<< <<>> >>", "<<(<<>>)>>"
252252
assert_format "<< <<>> + <<>> >>", "<<(<<>> + <<>>)>>"
253253
assert_format "<< 1 + <<>> >>", "<<(1 + <<>>)>>"
254254
assert_format "<< <<>> + 1 >>", "<<(<<>> + 1)>>"
255255
assert_format "<< <<>>, <<>>, <<>> >>", "<<(<<>>), <<>>, (<<>>)>>"
256-
assert_format "<< <<>>::1, <<>>::2, <<>>::3 >>", "<<(<<>>::1), <<>>::2, <<>>::3>>"
256+
assert_format "<< <<>>::1, <<>>::2, <<>>::3 >>", "<<(<<>>)::1, <<>>::2, <<>>::3>>"
257+
assert_format "<< <<>>::<<>> >>", "<<(<<>>)::(<<>>)>>"
258+
end
259+
260+
test "add parens on first in case of operator ambiguity" do
261+
assert_format "<< ~~~1::8 >>", "<<(~~~1)::8>>"
262+
assert_format "<< ~s[foo]::binary >>", "<<(~s[foo])::binary>>"
257263
end
258264

259265
test "with modifiers" do

lib/elixir/test/elixir/kernel/expansion_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1945,7 +1945,7 @@ defmodule Kernel.ExpansionTest do
19451945
message = ~r"literal <<>> in bitstring supports only type specifiers"
19461946

19471947
assert_raise CompileError, message, fn ->
1948-
expand(quote(do: <<(<<"foo">>::32)>>))
1948+
expand(quote(do: <<(<<"foo">>)::32>>))
19491949
end
19501950
end
19511951

0 commit comments

Comments
 (0)