From 23969555f5166ad07ec49511f520d0ff6bc97390 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Thu, 16 May 2024 08:48:50 -0600 Subject: [PATCH 1/2] piped version of Keyword/Map.drop => .delete --- lib/style/pipes.ex | 10 ------- lib/style/single_node.ex | 20 ++++++++++--- test/style/pipes_test.exs | 6 ---- test/style/single_node_test.exs | 50 +++++++++++++++++++++++---------- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/lib/style/pipes.ex b/lib/style/pipes.ex index b8a3b02..e836a2d 100644 --- a/lib/style/pipes.ex +++ b/lib/style/pipes.ex @@ -285,16 +285,6 @@ defmodule Styler.Style.Pipes do Style.set_line({:|>, [], [lhs, {new, nm, [mapper]}]}, nm[:line]) end - # lhs |> Map.merge(%{key: value}) => lhs |> Map.put(key, value) - defp fix_pipe({:|>, pm, [lhs, {{:., dm, [{_, _, [mod]} = module, :merge]}, m, [{:%{}, _, [{key, value}]}]}]}) - when mod in [:Map, :Keyword], - do: {:|>, pm, [lhs, {{:., dm, [module, :put]}, m, [key, value]}]} - - # lhs |> Map.merge(key: value) => lhs |> Map.put(:key, value) - defp fix_pipe({:|>, pm, [lhs, {{:., dm, [{_, _, [mod]} = module, :merge]}, m, [[{key, value}]]}]}) - when mod in [:Map, :Keyword], - do: {:|>, pm, [lhs, {{:., dm, [module, :put]}, m, [key, value]}]} - defp fix_pipe(node), do: node defp valid_pipe_start?({op, _, _}) when op in @special_ops, do: true diff --git a/lib/style/single_node.ex b/lib/style/single_node.ex index 4b45085..9aea4a7 100644 --- a/lib/style/single_node.ex +++ b/lib/style/single_node.ex @@ -128,17 +128,29 @@ defmodule Styler.Style.SingleNode do if new_collectable, do: {new_collectable, funm, [enum | rest]}, else: node end - for mod <- [:Map, :Keyword] do + for m <- [:Map, :Keyword] do + # lhs |> Map.merge(%{key: value}) => lhs |> Map.put(key, value) + defp style({:|>, pm, [lhs, {{:., dm, [{_, _, [unquote(m)]} = module, :merge]}, m, [{:%{}, _, [{key, value}]}]}]}), + do: {:|>, pm, [lhs, {{:., dm, [module, :put]}, m, [key, value]}]} + + # lhs |> Map.merge(key: value) => lhs |> Map.put(:key, value) + defp style({:|>, pm, [lhs, {{:., dm, [{_, _, [unquote(m)]} = module, :merge]}, m, [[{key, value}]]}]}), + do: {:|>, pm, [lhs, {{:., dm, [module, :put]}, m, [key, value]}]} + # Map.merge(foo, %{one_key: :bar}) => Map.put(foo, :one_key, :bar) - defp style({{:., dm, [{_, _, [unquote(mod)]} = module, :merge]}, m, [lhs, {:%{}, _, [{key, value}]}]}), + defp style({{:., dm, [{_, _, [unquote(m)]} = module, :merge]}, m, [lhs, {:%{}, _, [{key, value}]}]}), do: {{:., dm, [module, :put]}, m, [lhs, key, value]} # Map.merge(foo, one_key: :bar) => Map.put(foo, :one_key, :bar) - defp style({{:., dm, [{_, _, [unquote(mod)]} = module, :merge]}, m, [lhs, [{key, value}]]}), + defp style({{:., dm, [{_, _, [unquote(m)]} = module, :merge]}, m, [lhs, [{key, value}]]}), do: {{:., dm, [module, :put]}, m, [lhs, key, value]} + # lhs |> Map.drop([key]) => lhs |> Map.delete(key) + defp style({:|>, pm, [lhs, {{:., dm, [{_, _, [unquote(m)]} = module, :drop]}, m, [{:__block__, _, [[key]]}]}]}), + do: {:|>, pm, [lhs, {{:., dm, [module, :delete]}, m, [key]}]} + # Map.drop(foo, [one_key]) => Map.delete(foo, one_key) - defp style({{:., dm, [{_, _, [unquote(mod)]} = module, :drop]}, m, [lhs, {:__block__, _, [[key]]}]}), + defp style({{:., dm, [{_, _, [unquote(m)]} = module, :drop]}, m, [lhs, {:__block__, _, [[key]]}]}), do: {{:., dm, [module, :delete]}, m, [lhs, key]} end diff --git a/test/style/pipes_test.exs b/test/style/pipes_test.exs index cb28cd3..8fbc952 100644 --- a/test/style/pipes_test.exs +++ b/test/style/pipes_test.exs @@ -482,12 +482,6 @@ defmodule Styler.Style.PipesTest do end describe "simple rewrites" do - test "{Keyword/Map}.merge/2 of a single key => *.put/3" do - for module <- ~w(Map Keyword) do - assert_style("foo |> #{module}.merge(%{one_key: :bar}) |> bop()", "foo |> #{module}.put(:one_key, :bar) |> bop()") - end - end - test "rewrites anon fun def ahd invoke to use then" do assert_style("a |> (& &1).()", "then(a, & &1)") assert_style("a |> (& {&1, &2}).(b)", "(&{&1, &2}).(a, b)") diff --git a/test/style/single_node_test.exs b/test/style/single_node_test.exs index 03a7f86..8e012c9 100644 --- a/test/style/single_node_test.exs +++ b/test/style/single_node_test.exs @@ -27,24 +27,44 @@ defmodule Styler.Style.SingleNodeTest do assert_style ~s/"\\"\\"\\"\\" \/>']|})"/, ~s|~s("""" />']\|}\\))| end - test "{Map/Keyword}.merge with a single static key" do - for module <- ~w(Map Keyword) do - assert_style("#{module}.merge(foo, %{one_key: :bar})", "#{module}.put(foo, :one_key, :bar)") - assert_style("#{module}.merge(foo, one_key: :bar)", "#{module}.put(foo, :one_key, :bar)") - # # doesn't rewrite if there's a custom merge strategy - assert_style("#{module}.merge(foo, %{one_key: :bar}, custom_merge_strategy)") - # # doesn't rewrite if > 1 key - assert_style("#{module}.merge(foo, %{a: :b, c: :d})") + describe "{Keyword/Map}.merge/2 of a single key => *.put/3" do + test "in a pipe" do + for module <- ~w(Map Keyword) do + assert_style("foo |> #{module}.merge(%{one_key: :bar}) |> bop()", "foo |> #{module}.put(:one_key, :bar) |> bop()") + end + end + + test "normal call" do + for module <- ~w(Map Keyword) do + assert_style("#{module}.merge(foo, %{one_key: :bar})", "#{module}.put(foo, :one_key, :bar)") + assert_style("#{module}.merge(foo, one_key: :bar)", "#{module}.put(foo, :one_key, :bar)") + # # doesn't rewrite if there's a custom merge strategy + assert_style("#{module}.merge(foo, %{one_key: :bar}, custom_merge_strategy)") + # # doesn't rewrite if > 1 key + assert_style("#{module}.merge(foo, %{a: :b, c: :d})") + end end end - test "{Map/Keyword}.drop with a single key" do - for module <- ~w(Map Keyword) do - assert_style("#{module}.drop(foo, [key])", "#{module}.delete(foo, key)") - assert_style("#{module}.drop(foo, [:key])", "#{module}.delete(foo, :key)") - assert_style("#{module}.drop(foo, [])") - assert_style("#{module}.drop(foo, [a, b])") - assert_style("#{module}.drop(foo, keys)") + describe "{Map/Keyword}.drop with a single key" do + test "in a pipe" do + for module <- ~w(Map Keyword) do + assert_style("foo |> #{module}.drop([key]) |> bar()", "foo |> #{module}.delete(key) |> bar()") + assert_style("foo |> #{module}.drop([:key]) |> bar()", "foo |> #{module}.delete(:key) |> bar()") + assert_style("foo |> #{module}.drop([]) |> bar()") + assert_style("foo |> #{module}.drop([a, b]) |> bar()") + assert_style("foo |> #{module}.drop(keys) |> bar()") + end + end + + test "normal call" do + for module <- ~w(Map Keyword) do + assert_style("#{module}.drop(foo, [key])", "#{module}.delete(foo, key)") + assert_style("#{module}.drop(foo, [:key])", "#{module}.delete(foo, :key)") + assert_style("#{module}.drop(foo, [])") + assert_style("#{module}.drop(foo, [a, b])") + assert_style("#{module}.drop(foo, keys)") + end end end From da99d87d43cc85da1b9bc49e5a4eea8ef0ab4c12 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Thu, 16 May 2024 08:55:04 -0600 Subject: [PATCH 2/2] `lhs |> Enum.reverse() |> Kernel.++(enum)` => `lhs |> Enum.reverse(enum)` --- CHANGELOG.md | 5 +++-- lib/style/pipes.ex | 11 +++++++++++ test/style/pipes_test.exs | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbb9b74..8f9e913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,8 +53,9 @@ See the moduledoc for `Styler.Style.Configs` for more. * `@derive`: move `@derive` before `defstruct|schema|embedded_schema` declarations (fixes compiler warning!) #134 * strings: rewrite double-quoted strings to use `~s` when there's 4+ escaped double-quotes (`"\"\"\"\""` -> `~s("""")`) (`Credo.Check.Readability.StringSigils`) #146 -* `Map.drop(foo, [single_key])` => `Map.delete(foo, single_key)` #161 -* `Keyword.drop(foo, [single_key])` => `Keyword.delete(foo, single_key)` #161 +* `Map.drop(foo, [single_key])` => `Map.delete(foo, single_key)` #161 (also in pipes) +* `Keyword.drop(foo, [single_key])` => `Keyword.delete(foo, single_key)` #161 (also in pipes) +* `lhs |> Enum.reverse() |> Kernel.++(enum)` => `lhs |> Enum.reverse(enum)` ### Fixes diff --git a/lib/style/pipes.ex b/lib/style/pipes.ex index e836a2d..9bc0b54 100644 --- a/lib/style/pipes.ex +++ b/lib/style/pipes.ex @@ -209,6 +209,17 @@ defmodule Styler.Style.Pipes do {:|>, [line: meta[:line]], [lhs, {reverse, [line: meta[:line]], [enum]}]} end + # `lhs |> Enum.reverse() |> Enum.concat(enum)` => `lhs |> Enum.reverse(enum)` + defp fix_pipe( + pipe_chain( + lhs, + {{:., _, [{_, _, [:Enum]}, :reverse]} = reverse, meta, []}, + {{:., _, [{_, _, [:Kernel]}, :++]}, _, [enum]} + ) + ) do + {:|>, [line: meta[:line]], [lhs, {reverse, [line: meta[:line]], [enum]}]} + end + # `lhs |> Enum.filter(filterer) |> Enum.count()` => `lhs |> Enum.count(count)` defp fix_pipe( pipe_chain( diff --git a/test/style/pipes_test.exs b/test/style/pipes_test.exs index 8fbc952..49cfe25 100644 --- a/test/style/pipes_test.exs +++ b/test/style/pipes_test.exs @@ -541,6 +541,25 @@ defmodule Styler.Style.PipesTest do ) end + test "reverse/Kernel.++" do + assert_style("a |> Enum.reverse(bar) |> Kernel.++(foo)") + assert_style("a |> Enum.reverse() |> Kernel.++(foo)", "Enum.reverse(a, foo)") + + assert_style( + """ + a + |> Enum.reverse() + |> Kernel.++([bar, baz]) + |> Enum.sum() + """, + """ + a + |> Enum.reverse([bar, baz]) + |> Enum.sum() + """ + ) + end + test "filter/count" do for enum <- ~w(Enum Stream) do assert_style(