Skip to content

Commit

Permalink
{Keyword|Map}.merge/2 to put/3 rewrites (#96)
Browse files Browse the repository at this point in the history
Closes #90
  • Loading branch information
novaugust authored Dec 7, 2023
1 parent 336a380 commit 13fa7f4
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## main

### Improvements

* Rewrite `{Map|Keyword}.merge(single_key: value)` to use `put/3` instead

## v0.10.5

After being bitten by two of them in a row, Styler's test suite now makes sure that there are no
Expand Down
10 changes: 10 additions & 0 deletions lib/style/pipes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,16 @@ defmodule Styler.Style.Pipes do
else: node
end

for mod <- [:Map, :Keyword] do
# lhs |> Map.merge(%{key: value}) => lhs |> Map.put(key, value)
defp fix_pipe({:|>, pm, [lhs, {{:., dm, [{_, _, [unquote(mod)]} = 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 fix_pipe({:|>, pm, [lhs, {{:., dm, [{_, _, [unquote(mod)]} = module, :merge]}, m, [[{key, value}]]}]}),
do: {:|>, pm, [lhs, {{:., dm, [module, :put]}, m, [key, value]}]}
end

defp fix_pipe(node), do: node

# most of these values were lifted directly from credo's pipe_chain_start.ex
Expand Down
10 changes: 10 additions & 0 deletions lib/style/single_node.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ defmodule Styler.Style.SingleNode do
if Style.empty_map?(collectable), do: {{:., dm, [{:__aliases__, am, [:Map]}, :new]}, funm, [enum | rest]}, else: node
end

for mod <- [:Map, :Keyword] do
# Map.merge(foo, %{one_key: :bar}) => Map.put(foo, :one_key, :bar)
defp style({{:., dm, [{_, _, [unquote(mod)]} = 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}]]}),
do: {{:., dm, [module, :put]}, m, [lhs, key, value]}
end

# Logger.warn => Logger.warning
defp style({{:., dm, [{:__aliases__, am, [:Logger]}, :warn]}, funm, args}),
do: {{:., dm, [{:__aliases__, am, [:Logger]}, :warning]}, funm, args}
Expand Down
1 change: 0 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ defmodule Styler.MixProject do
start_permanent: Mix.env() == :prod,
elixirc_paths: elixirc_paths(Mix.env()),
deps: deps(),
aliases: [test: ["test", "format --check-formatted"]],

## Hex
package: package(),
Expand Down
6 changes: 6 additions & 0 deletions test/style/pipes_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ 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)")
Expand Down
11 changes: 11 additions & 0 deletions test/style/single_node_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ defmodule Styler.Style.SingleNodeTest do
end
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})")
end
end

test "Logger.warn to Logger.warning" do
assert_style("Logger.warn(foo)", "Logger.warning(foo)")
assert_style("Logger.warn(foo, bar)", "Logger.warning(foo, bar)")
Expand Down

0 comments on commit 13fa7f4

Please sign in to comment.