diff options
author | José Valim <jose.valim@plataformatec.com.br> | 2018-04-17 08:52:47 +0200 |
---|---|---|
committer | José Valim <jose.valim@plataformatec.com.br> | 2018-04-17 08:53:21 +0200 |
commit | 718123157c2bc08e0dbaf84efa8679e63143d59f (patch) | |
tree | e5658cee713d3f7b112195a48a95c893d3bd9ad0 | |
parent | be46a1f999392e19aae13773732c3379eb15b22d (diff) | |
download | elixir-718123157c2bc08e0dbaf84efa8679e63143d59f.tar.gz |
Fix formatter for tilde inside bitstrings, closes #7558
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
-rw-r--r-- | lib/elixir/lib/code/formatter.ex | 29 | ||||
-rw-r--r-- | lib/elixir/test/elixir/code_formatter/containers_test.exs | 10 | ||||
-rw-r--r-- | lib/elixir/test/elixir/kernel/expansion_test.exs | 2 |
3 files changed, 27 insertions, 14 deletions
diff --git a/lib/elixir/lib/code/formatter.ex b/lib/elixir/lib/code/formatter.ex index 744198547..96e5a5753 100644 --- a/lib/elixir/lib/code/formatter.ex +++ b/lib/elixir/lib/code/formatter.ex @@ -1351,8 +1351,17 @@ defmodule Code.Formatter do defp bitstring_segment_to_algebra({{:::, _, [segment, spec]}, i}, state, last) do {doc, state} = quoted_to_algebra(segment, :parens_arg, state) {spec, state} = bitstring_spec_to_algebra(spec, state) - doc = concat(concat(doc, "::"), wrap_in_parens_if_inspected_atom(spec)) - {bitstring_wrap_parens(doc, i, last), state} + + spec = wrap_in_parens_if_inspected_atom(spec) + spec = if i == last, do: bitstring_wrap_parens(spec, i, last), else: spec + + doc = + doc + |> bitstring_wrap_parens(i, -1) + |> concat("::") + |> concat(spec) + + {doc, state} end defp bitstring_segment_to_algebra({segment, i}, state, last) do @@ -1370,21 +1379,19 @@ defmodule Code.Formatter do quoted_to_algebra_with_parens_if_operator(spec, :parens_arg, state) end - defp bitstring_wrap_parens(doc, i, last) do - if i == 0 or i == last do - string = format_to_string(doc) + defp bitstring_wrap_parens(doc, i, last) when i == 0 or i == last do + string = format_to_string(doc) - if (i == 0 and String.starts_with?(string, "<<")) or - (i == last and String.ends_with?(string, ">>")) do - wrap_in_parens(doc) - else - doc - end + if (i == 0 and String.starts_with?(string, ["~", "<<"])) or + (i == last and String.ends_with?(string, [">>"])) do + wrap_in_parens(doc) else doc end end + defp bitstring_wrap_parens(doc, _, _), do: doc + ## Literals defp list_to_algebra(meta, args, state) do diff --git a/lib/elixir/test/elixir/code_formatter/containers_test.exs b/lib/elixir/test/elixir/code_formatter/containers_test.exs index 0c3b5fc27..138ae36c2 100644 --- a/lib/elixir/test/elixir/code_formatter/containers_test.exs +++ b/lib/elixir/test/elixir/code_formatter/containers_test.exs @@ -247,13 +247,19 @@ defmodule Code.Formatter.ContainersTest do assert_format "<<1,2,3>>", "<<1, 2, 3>>" end - test "add parens on first and last in case of ambiguity" do + test "add parens on first and last in case of binary ambiguity" do assert_format "<< <<>> >>", "<<(<<>>)>>" assert_format "<< <<>> + <<>> >>", "<<(<<>> + <<>>)>>" assert_format "<< 1 + <<>> >>", "<<(1 + <<>>)>>" assert_format "<< <<>> + 1 >>", "<<(<<>> + 1)>>" assert_format "<< <<>>, <<>>, <<>> >>", "<<(<<>>), <<>>, (<<>>)>>" - assert_format "<< <<>>::1, <<>>::2, <<>>::3 >>", "<<(<<>>::1), <<>>::2, <<>>::3>>" + assert_format "<< <<>>::1, <<>>::2, <<>>::3 >>", "<<(<<>>)::1, <<>>::2, <<>>::3>>" + assert_format "<< <<>>::<<>> >>", "<<(<<>>)::(<<>>)>>" + end + + test "add parens on first in case of operator ambiguity" do + assert_format "<< ~~~1::8 >>", "<<(~~~1)::8>>" + assert_format "<< ~s[foo]::binary >>", "<<(~s[foo])::binary>>" end test "with modifiers" do diff --git a/lib/elixir/test/elixir/kernel/expansion_test.exs b/lib/elixir/test/elixir/kernel/expansion_test.exs index cddbe58e4..0c76ce150 100644 --- a/lib/elixir/test/elixir/kernel/expansion_test.exs +++ b/lib/elixir/test/elixir/kernel/expansion_test.exs @@ -1945,7 +1945,7 @@ defmodule Kernel.ExpansionTest do message = ~r"literal <<>> in bitstring supports only type specifiers" assert_raise CompileError, message, fn -> - expand(quote(do: <<(<<"foo">>::32)>>)) + expand(quote(do: <<(<<"foo">>)::32>>)) end end |