Repository: adobe/elixir-styler (elixir)

Issue:
ex 1.18 misc deprecations
## Example Input
https://github.com/elixir-lang/elixir/blob/main/CHANGELOG.md#elixir-3

from above, `List.zip => Enum.zip`

not documented there is:
> warning: first..last inside match is deprecated, you must always match on the step: first..last//var or first..last//_ if you want to ignore it



Pull request description:
1.18 hard deprecations
Closes #202 

Patch:
diff --git a/lib/style/deprecations.ex b/lib/style/deprecations.ex
index 6805008..f810e5a 100644
--- a/lib/style/deprecations.ex
+++ b/lib/style/deprecations.ex
@@ -17,6 +17,20 @@ defmodule Styler.Style.Deprecations do
 
   def run({node, meta}, ctx), do: {:cont, {style(node), meta}, ctx}
 
+  # Deprecated in 1.18
+  # rewrite patterns of `first..last = ...` to `first..last//_ = ...`
+  defp style({:=, m, [{:.., _, [_first, _last]} = range, rhs]}), do: {:=, m, [rewrite_range_match(range), rhs]}
+  defp style({:->, m, [[{:.., _, [_first, _last]} = range], rhs]}), do: {:->, m, [[rewrite_range_match(range)], rhs]}
+  defp style({:<-, m, [{:.., _, [_first, _last]} = range, rhs]}), do: {:<-, m, [rewrite_range_match(range), rhs]}
+
+  defp style({def, dm, [{x, xm, params} | rest]}) when def in ~w(def defp)a and is_list(params),
+    do: {def, dm, [{x, xm, Enum.map(params, &rewrite_range_match/1)} | rest]}
+
+  # Deprecated in 1.18
+  # List.zip => Enum.zip
+  defp style({{:., dm_, [{:__aliases__, am, [:List]}, :zip]}, fm, arg}),
+    do: {{:., dm_, [{:__aliases__, am, [:Enum]}, :zip]}, fm, arg}
+
   # Logger.warn => Logger.warning
   # Started to emit warning after Elixir 1.15.0
   defp style({{:., dm, [{:__aliases__, am, [:Logger]}, :warn]}, funm, args}),
@@ -84,6 +98,9 @@ defmodule Styler.Style.Deprecations do
 
   defp style(node), do: node
 
+  defp rewrite_range_match({:.., dm, [first, {_, m, _} = last]}), do: {:"..//", dm, [first, last, {:_, m, nil}]}
+  defp rewrite_range_match(x), do: x
+
   defp add_step_to_date_range?(first, last) do
     with {:ok, f} <- extract_date_value(first),
          {:ok, l} <- extract_date_value(last),


Test patch:
diff --git a/test/style/deprecations_test.exs b/test/style/deprecations_test.exs
index 3d5e8ed..cb9396f 100644
--- a/test/style/deprecations_test.exs
+++ b/test/style/deprecations_test.exs
@@ -33,6 +33,40 @@ defmodule Styler.Style.DeprecationsTest do
     )
   end
 
+  test "matching ranges" do
+    assert_style "first..last = range", "first..last//_ = range"
+    assert_style "^first..^last = range", "^first..^last//_ = range"
+    assert_style "first..last = x = y", "first..last//_ = x = y"
+    assert_style "y = first..last = x", "y = first..last//_ = x"
+
+    assert_style "def foo(x..y), do: :ok", "def foo(x..y//_), do: :ok"
+    assert_style "def foo(a, x..y = z), do: :ok", "def foo(a, x..y//_ = z), do: :ok"
+    assert_style "def foo(%{a: x..y = z}), do: :ok", "def foo(%{a: x..y//_ = z}), do: :ok"
+
+    assert_style "with a..b = c <- :ok, d..e <- :better, do: :ok", "with a..b//_ = c <- :ok, d..e//_ <- :better, do: :ok"
+
+    assert_style(
+      """
+      case x do
+        a..b = c -> :ok
+        d..e -> :better
+      end
+      """,
+      """
+      case x do
+        a..b//_ = c -> :ok
+        d..e//_ -> :better
+      end
+      """
+    )
+  end
+
+  test "List.zip/1" do
+    assert_style "List.zip(foo)", "Enum.zip(foo)"
+    assert_style "foo |> List.zip |> bar", "foo |> Enum.zip() |> bar()"
+    assert_style "foo |> List.zip", "Enum.zip(foo)"
+  end
+
   describe "1.16 deprecations" do
     @describetag skip: Version.match?(System.version(), "< 1.16.0-dev")