Skip to content

Commit

Permalink
fix: Igniter.Code.Common.with/2 was not properly merging with origina…
Browse files Browse the repository at this point in the history
…l zipper

docs: update typespecs and docs for Igniter.Code.Function
  • Loading branch information
zachdaniel committed Jun 13, 2024
1 parent a04ad64 commit 95b1da8
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 126 deletions.
6 changes: 3 additions & 3 deletions lib/code/common.ex
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@ defmodule Igniter.Code.Common do
`fun` must return {:ok, zipper} or `:error`, which may be positioned at the top of the subtree.
"""
def within(%Zipper{} = zipper, fun) when is_function(fun, 1) do
zipper
def within(%Zipper{} = top_zipper, fun) when is_function(fun, 1) do
top_zipper
|> Zipper.subtree()
|> fun.()
|> case do
Expand All @@ -420,7 +420,7 @@ defmodule Igniter.Code.Common do
{:ok,
zipper
|> Zipper.top()
|> into(zipper)}
|> into(top_zipper)}
end
end

Expand Down
288 changes: 166 additions & 122 deletions lib/code/function.ex
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,54 @@ defmodule Igniter.Code.Function do
end
end

@doc "Updates the `nth` argument of a function call, leaving the zipper at the function call's node."
@spec update_nth_argument(
Zipper.t(),
non_neg_integer(),
(Zipper.t() ->
{:ok, Zipper.t()} | :error)
) ::
{:ok, Zipper.t()} | :error
def update_nth_argument(zipper, index, func) do
if pipeline?(zipper) do
if index == 0 do
zipper
|> Zipper.down()
|> case do
nil ->
:error
Common.within(zipper, fn zipper ->
if pipeline?(zipper) do
if index == 0 do
zipper
|> Zipper.down()
|> case do
nil ->
:error

zipper ->
func.(zipper)
zipper ->
func.(zipper)
end
else
zipper
|> Zipper.down()
|> case do
nil ->
:error

zipper ->
zipper
|> Zipper.rightmost()
|> Zipper.down()
|> case do
nil ->
:error

zipper ->
zipper
|> Common.nth_right(index)
|> case do
:error ->
:error

{:ok, nth} ->
func.(nth)
end
end
end
end
else
zipper
Expand All @@ -148,57 +185,65 @@ defmodule Igniter.Code.Function do

zipper ->
zipper
|> Zipper.rightmost()
|> Zipper.down()
|> Common.nth_right(index)
|> case do
nil ->
:error ->
:error

zipper ->
zipper
|> Common.nth_right(index)
|> case do
:error ->
:error

{:ok, nth} ->
func.(nth)
end
{:ok, nth} ->
func.(nth)
end
end
end
else
zipper
|> Zipper.down()
|> case do
nil ->
:error
end)
end

zipper ->
@doc "Moves to the `nth` argument of a function call."
@spec move_to_nth_argument(
Zipper.t(),
non_neg_integer()
) ::
{:ok, Zipper.t()} | :error
def move_to_nth_argument(zipper, index) do
if function_call?(zipper) do
if pipeline?(zipper) do
if index == 0 do
zipper
|> Common.nth_right(index)
|> Zipper.down()
|> case do
:error ->
nil ->
:error

{:ok, nth} ->
func.(nth)
zipper ->
{:ok, zipper}
end
end
end
end

def move_to_nth_argument(zipper, index) do
if pipeline?(zipper) do
if index == 0 do
zipper
|> Zipper.down()
|> case do
nil ->
:error
else
zipper
|> Zipper.down()
|> case do
nil ->
:error

zipper ->
{:ok, zipper}
zipper ->
zipper
|> Zipper.rightmost()
|> Zipper.down()
|> case do
nil ->
:error

zipper ->
zipper
|> Common.nth_right(index)
|> case do
:error ->
:error

{:ok, nth} ->
{:ok, nth}
end
end
end
end
else
zipper
Expand All @@ -209,114 +254,113 @@ defmodule Igniter.Code.Function do

zipper ->
zipper
|> Zipper.rightmost()
|> Zipper.down()
|> Common.nth_right(index)
|> case do
nil ->
:error ->
:error

zipper ->
zipper
|> Common.nth_right(index)
|> case do
:error ->
:error

{:ok, nth} ->
{:ok, nth}
end
{:ok, nth} ->
{:ok, nth}
end
end
end
else
zipper
|> Zipper.down()
|> case do
nil ->
:error

zipper ->
zipper
|> Common.nth_right(index)
|> case do
:error ->
:error

{:ok, nth} ->
{:ok, nth}
end
end
:error
end
end

@doc "Appends an argument to a function call, leaving the zipper at the function call's node."
@spec append_argument(Zipper.t(), any()) :: {:ok, Zipper.t()} | :error
def append_argument(zipper, value) do
zipper
|> Zipper.append_child(value)
end

def argument_matches_predicate?(zipper, index, func) do
if pipeline?(zipper) do
if index == 0 do
if function_call?(zipper) do
if pipeline?(zipper) do
zipper
|> Zipper.down()
|> case do
nil -> nil
zipper -> func.(zipper)
nil ->
:error

zipper ->
{:ok, Zipper.append_child(zipper, value)}
end
else
{:ok, Zipper.append_child(zipper, value)}
end
else
:error
end
end

@doc "Returns true if the argument at the given index matches the provided predicate"
@spec argument_matches_predicate?(Zipper.t(), non_neg_integer(), (Zipper.t() -> boolean)) ::
boolean()
def argument_matches_predicate?(zipper, index, func) do
if function_call?(zipper) do
if pipeline?(zipper) do
if index == 0 do
zipper
|> Zipper.down()
|> case do
nil -> nil
zipper -> func.(zipper)
end
else
zipper
|> Zipper.down()
|> case do
nil ->
nil

zipper ->
zipper
|> Zipper.rightmost()
|> Zipper.down()
|> case do
nil ->
nil

zipper ->
zipper
|> Common.nth_right(index - 1)
|> case do
:error ->
false

{:ok, zipper} ->
zipper
|> Common.maybe_move_to_block()
|> func.()
end
end
end
end
else
zipper
|> Zipper.down()
|> case do
nil ->
nil
false

zipper ->
zipper
|> Zipper.rightmost()
|> Zipper.down()
|> Common.nth_right(index)
|> case do
nil ->
nil
:error ->
false

zipper ->
{:ok, zipper} ->
zipper
|> Common.nth_right(index - 1)
|> case do
:error ->
false

{:ok, zipper} ->
zipper
|> Common.maybe_move_to_block()
|> func.()
end
|> Common.maybe_move_to_block()
|> func.()
end
end
end
else
zipper
|> Zipper.down()
|> case do
nil ->
false

zipper ->
zipper
|> Common.nth_right(index)
|> case do
:error ->
false

{:ok, zipper} ->
zipper
|> Common.maybe_move_to_block()
|> func.()
end
end
:error
end
end

def pipeline?(zipper) do
defp pipeline?(zipper) do
zipper
|> Zipper.subtree()
|> Zipper.root()
Expand Down
Loading

0 comments on commit 95b1da8

Please sign in to comment.