Skip to content

Commit b01d328

Browse files
committed
dont rewrite then(&f(&1, ... &1 ...))
1 parent a49a240 commit b01d328

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

lib/style/pipes.ex

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,13 @@ defmodule Styler.Style.Pipes do
145145
# a |> then(&fun/1) |> c => a |> fun() |> c()
146146
defp fix_pipe({:|>, m, [lhs, {:then, _, [{:&, _, [{:/, _, [{fun, m2, _}, _]}]}]}]}), do: {:|>, m, [lhs, {fun, m2, []}]}
147147
# a |> then(&fun(&1, d)) |> c => a |> fun(d) |> c()
148-
defp fix_pipe({:|>, m, [lhs, {:then, _, [{:&, _, [{fun, m2, [{:&, _, _} | args]}]}]}]}),
149-
do: {:|>, m, [lhs, {fun, m2, args}]}
148+
defp fix_pipe({:|>, m, [lhs, {:then, _, [{:&, _, [{fun, m2, [{:&, _, _} | args]}]}]}]} = pipe) do
149+
rewrite = {fun, m2, args}
150+
# if `&1` is referenced more than once, we have to continue using `then`
151+
if rewrite |> Zipper.zip() |> Zipper.any?(&match?({:&, _, _}, &1)),
152+
do: pipe,
153+
else: {:|>, m, [lhs, rewrite]}
154+
end
150155

151156
# Credo.Check.Readability.PipeIntoAnonymousFunctions
152157
# rewrite anonymous function invocation to use `then/2`

lib/zipper.ex

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,12 +381,23 @@ defmodule Styler.Zipper do
381381
"""
382382
@spec find(zipper, direction :: :prev | :next, predicate :: (tree -> any)) :: zipper | nil
383383
def find({tree, _} = zipper, direction \\ :next, predicate)
384-
when direction in [:next, :prev] and is_function(predicate) do
384+
when direction in [:next, :prev] and is_function(predicate, 1) do
385385
if predicate.(tree) do
386386
zipper
387387
else
388388
zipper = if direction == :next, do: next(zipper), else: prev(zipper)
389389
zipper && find(zipper, direction, predicate)
390390
end
391391
end
392+
393+
@doc "Traverses `zipper`, returning true when `fun.(Zipper.node(zipper))` is truthy, or false otherwise"
394+
@spec any?(zipper, (tree -> term)) :: boolean()
395+
def any?({_, _} = zipper, fun) when is_function(fun, 1) do
396+
zipper
397+
|> traverse_while(false, fn {tree, _} = zipper, _ ->
398+
# {nil, nil} optimizes to not go back to the top of the zipper on a hit
399+
if fun.(tree), do: {:halt, {nil, nil}, true}, else: {:cont, zipper, false}
400+
end)
401+
|> elem(1)
402+
end
392403
end

0 commit comments

Comments
 (0)