diff --git a/lib/elixir/lib/code/formatter.ex b/lib/elixir/lib/code/formatter.ex index da1cd1b9df..6dd365184c 100644 --- a/lib/elixir/lib/code/formatter.ex +++ b/lib/elixir/lib/code/formatter.ex @@ -506,8 +506,15 @@ defmodule Code.Formatter do # not(left in right) # left not in right - defp quoted_to_algebra({:not, meta, [{:in, _, [left, right]}]}, context, state) do - binary_op_to_algebra(:in, "not in", meta, left, right, context, state) + defp quoted_to_algebra({:not, meta, [{:in, _, [left, right]} = arg]}, context, state) do + %{rename_deprecated_at: since} = state + + # TODO: Remove since check on Elixir v2.0 and the OP arrengement is removed. + if meta[:operator] == :"not in" || (since && Version.match?(since, "~> 1.5")) do + binary_op_to_algebra(:in, "not in", meta, left, right, context, state) + else + unary_op_to_algebra(:not, meta, arg, context, state) + end end defp quoted_to_algebra({:fn, meta, [_ | _] = clauses}, _context, state) do diff --git a/lib/elixir/src/elixir_parser.yrl b/lib/elixir/src/elixir_parser.yrl index c77c5974f0..57c5857d5d 100644 --- a/lib/elixir/src/elixir_parser.yrl +++ b/lib/elixir/src/elixir_parser.yrl @@ -684,13 +684,19 @@ number_value({_, {_, _, Value}, _}) -> %% Operators build_op({_Kind, Location, 'in'}, {UOp, _, [Left]}, Right) when ?rearrange_uop(UOp) -> - %% TODO: Raise on "not left in right" rearrangement on 2.0 + %% TODO: Remove "not left in right" rearrangement on 2.0 elixir_errors:warn(line_from_location(Location), ?file(), "\"not expr1 in expr2\" is deprecated. Use \"expr1 not in expr2\" instead"), {UOp, meta_from_location(Location), [{'in', meta_from_location(Location), [Left, Right]}]}; build_op({_Kind, Location, 'not in'}, Left, Right) -> - {'not', meta_from_location(Location), [{'in', meta_from_location(Location), [Left, Right]}]}; + InMeta = meta_from_location(Location), + NotMeta = + case ?formatter_metadata() of + true -> [{operator, 'not in'} | InMeta]; + false -> InMeta + end, + {'not', NotMeta, [{'in', InMeta, [Left, Right]}]}; build_op({_Kind, Location, Op}, Left, Right) -> {Op, eol_op(Location) ++ meta_from_location(Location), [Left, Right]}. diff --git a/lib/elixir/test/elixir/code_formatter/operators_test.exs b/lib/elixir/test/elixir/code_formatter/operators_test.exs index 356d54be75..ab685b0cb6 100644 --- a/lib/elixir/test/elixir/code_formatter/operators_test.exs +++ b/lib/elixir/test/elixir/code_formatter/operators_test.exs @@ -121,7 +121,10 @@ defmodule Code.Formatter.OperatorsTest do end test "not in" do - assert_format "not(foo in bar)", "foo not in bar" + assert_format "not(foo in bar)", "not (foo in bar)" + assert_format "not(foo in bar)", "foo not in bar", rename_deprecated_at: "1.5.0" + + assert_same "foo not in bar" assert_same "(not foo) in bar" assert_same "(!foo) in bar" end