Skip to content

Commit

Permalink
rewrite all kernel ops inside of |> then
Browse files Browse the repository at this point in the history
  • Loading branch information
novaugust committed Jan 26, 2024
1 parent 7af0397 commit 4fd18d3
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions lib/style/pipes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ defmodule Styler.Style.Pipes do
@collectable ~w(Map Keyword MapSet)a
@enum ~w(Enum Stream)a

# most of these values were lifted directly from credo's pipe_chain_start.ex
@literal ~w(__block__ __aliases__ unquote)a
@value_constructors ~w(% %{} .. ..// <<>> @ {} ^ & fn from)a
@kernel_ops ~w(++ -- && || in - * + / > < <= >= == and or != !== === <>)a
@special_ops ~w(<- ||| &&& <<< >>> <<~ ~>> <~ ~> <~> <|> ^^^ ~~~)a
@special_ops @literal ++ @value_constructors ++ @kernel_ops ++ @special_ops

def run({{:|>, _, _}, _} = zipper, ctx) do
case fix_pipe_start(zipper) do
{{:|>, _, _}, _} = zipper ->
Expand Down Expand Up @@ -143,12 +150,6 @@ defmodule Styler.Style.Pipes do
quote do: {:|>, _, [{:|>, _, [unquote(a), unquote(b)]}, unquote(c)]}
end

# Unary operators needs to be expanded (#128)
defp maybe_wrap_unary({op, meta, []}) when op in ~w(- +)a,
do: {{:., meta, [{:__aliases__, meta, [:Kernel]}, op]}, meta, []}

defp maybe_wrap_unary(lhs), do: lhs

# a |> fun => a |> fun()
defp fix_pipe({:|>, m, [lhs, {fun, m2, nil}]}), do: {:|>, m, [lhs, {fun, m2, []}]}
# a |> then(&fun/1) |> c => a |> fun() |> c()
Expand All @@ -158,9 +159,16 @@ defmodule Styler.Style.Pipes do
rewrite = {fun, m2, args}

# if `&1` is referenced more than once, we have to continue using `then`
if rewrite |> Zipper.zip() |> Zipper.any?(&match?({:&, _, _}, &1)),
do: pipe,
else: {:|>, m, [lhs, maybe_wrap_unary(rewrite)]}
cond do
rewrite |> Zipper.zip() |> Zipper.any?(&match?({:&, _, _}, &1)) ->
pipe

fun in @special_ops ->
if fun in @kernel_ops, do: {:|>, m, [lhs, {{:., m2, [{:__aliases__, m2, [:Kernel]}, fun]}, m2, args}]}, else: pipe

true ->
{:|>, m, [lhs, rewrite]}
end
end

# Credo.Check.Readability.PipeIntoAnonymousFunctions
Expand Down Expand Up @@ -272,14 +280,7 @@ defmodule Styler.Style.Pipes do

defp fix_pipe(node), do: node

# most of these values were lifted directly from credo's pipe_chain_start.ex
@literal ~w(__block__ __aliases__ unquote)a
@value_constructors ~w(% %{} .. ..// <<>> @ {} ^ & fn from)a
@infix_ops ~w(++ -- && || in - * + / > < <= >= == and or != !== ===)a
@binary_ops ~w(<> <- ||| &&& <<< >>> <<~ ~>> <~ ~> <~> <|> ^^^ ~~~)a
@valid_starts @literal ++ @value_constructors ++ @infix_ops ++ @binary_ops

defp valid_pipe_start?({op, _, _}) when op in @valid_starts, do: true
defp valid_pipe_start?({op, _, _}) when op in @special_ops, do: true
# 0-arity Module.function_call()
defp valid_pipe_start?({{:., _, _}, _, []}), do: true
# Exempt ecto's `from`
Expand Down

0 comments on commit 4fd18d3

Please sign in to comment.