View Source Sourceror.Code.Function (Sourceror v1.11.0)
Utilities for working with functions.
Summary
Functions
Appends an argument to a function call, leaving the zipper at the function call's node.
Checks if the provided function call (in a Zipper) has an argument that equals
term at index.
Returns true if the argument at the provided index exists and matches the provided pattern
Returns true if the argument at the given index matches the provided predicate.
Returns true if the value is a function literal.
Returns true if the node is a function call.
Returns true if the node is a function call of the given name
Gets the name and arity of a local function call.
Gets the name of a local function call.
Moves to a function call by the given name and arity, matching the given predicate, in the current or lower scope.
Moves to a function call by the given name and arity, matching the given predicate, in the current scope.
Moves to the nth argument of a function call.
Updates the nth argument of a function call, leaving the zipper at the function call's node.
Functions
@spec append_argument(Sourceror.Zipper.t(), any()) :: {:ok, Sourceror.Zipper.t()} | :error
Appends an argument to a function call, leaving the zipper at the function call's node.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2)") |> Sourceror.Zipper.zip()
iex> {:ok, zipper} = Sourceror.Code.Function.append_argument(zipper, 3)
iex> Sourceror.to_string(zipper.node)
"foo(1, 2, 3)"
@spec argument_equals?(Sourceror.Zipper.t(), integer(), any()) :: boolean()
Checks if the provided function call (in a Zipper) has an argument that equals
term at index.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2, 3)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.argument_equals?(zipper, 0, 1)
true
iex> Sourceror.Code.Function.argument_equals?(zipper, 0, 2)
falseSee also argument_matches_predicate?/3.
Returns true if the argument at the provided index exists and matches the provided pattern
Note: to check for argument equality, use argument_equals?/3 instead.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2, 3)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.argument_matches_pattern?(zipper, 1, {:__block__, _, [2]})
trueSee also argument_matches_predicate?/3.
@spec argument_matches_predicate?( Sourceror.Zipper.t(), non_neg_integer(), (Sourceror.Zipper.t() -> boolean()) ) :: boolean()
Returns true if the argument at the given index matches the provided predicate.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2, 3)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.argument_matches_predicate?(zipper, 0, fn z ->
...> match?({:__block__, _, [1]}, z.node)
...> end)
trueSee also argument_equals?/3.
@spec function?( Sourceror.Zipper.t(), name :: :any | :any_named | {module(), atom()} | :anonymous, arity :: :any | non_neg_integer() | [non_neg_integer()] ) :: boolean()
Returns true if the value is a function literal.
Examples:
fn x -> x end&(&1 + &2)&SomeMod.fun/2
To refine the check, you can use name and arity.
Names
:any- matches any function literal, named or not:any_named- matches any named function literal:anonymous- matches any anonymous function literal{module, name}- matches a function literal with the given module and name
Examples
iex> zipper = Sourceror.parse_string!("fn x -> x end") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.function?(zipper, :anonymous, 1)
true
iex> zipper = Sourceror.parse_string!("&(&1 + &2)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.function?(zipper, :anonymous, 2)
true
@spec function_call?(Sourceror.Zipper.t()) :: boolean()
Returns true if the node is a function call.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.function_call?(zipper)
true
iex> zipper = Sourceror.parse_string!("1 + 2") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.function_call?(zipper)
true
@spec function_call?( Sourceror.Zipper.t(), atom() | {module(), atom()}, arity :: integer() | :any | [integer()] ) :: boolean()
Returns true if the node is a function call of the given name
If an atom is provided, it only matches functions in the form of function(name).
If an {module, atom} is provided, it matches functions called on the given module,
taking into account aliases.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.function_call?(zipper, :foo, 2)
true
iex> Sourceror.Code.Function.function_call?(zipper, :bar, 2)
falseSee also function_call?/1.
@spec get_local_function_call(Sourceror.Zipper.t()) :: {:ok, {atom(), non_neg_integer()}} | :error
Gets the name and arity of a local function call.
Returns :error if the node is not a function call or cannot be determined.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.get_local_function_call(zipper)
{:ok, {:foo, 2}}See also get_local_function_call_name/1.
@spec get_local_function_call_name(Sourceror.Zipper.t()) :: {:ok, atom()} | :error
Gets the name of a local function call.
Returns :error if the node is not a function call or cannot be determined.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2)") |> Sourceror.Zipper.zip()
iex> Sourceror.Code.Function.get_local_function_call_name(zipper)
{:ok, :foo}
@spec move_to_def(Sourceror.Zipper.t()) :: {:ok, Sourceror.Zipper.t()} | :error
@spec move_to_def( Sourceror.Zipper.t(), fun :: atom(), arity :: integer() | [integer()] ) :: {:ok, Sourceror.Zipper.t()} | :error
@spec move_to_defp( Sourceror.Zipper.t(), fun :: atom(), arity :: integer() | [integer()] ) :: {:ok, Sourceror.Zipper.t()} | :error
move_to_function_call(zipper, name, arity, predicate \\ fn _ -> true end)
View SourceMoves to a function call by the given name and arity, matching the given predicate, in the current or lower scope.
Examples
iex> zipper = Sourceror.parse_string!("bar = foo(1, 2)") |> Sourceror.Zipper.zip()
iex> {:ok, result} = Sourceror.Code.Function.move_to_function_call(zipper, :foo, 2)
iex> match?({:foo, _, _}, result.node)
trueSee also move_to_function_call_in_current_scope/4.
move_to_function_call_in_current_scope(zipper, name, arity, predicate \\ fn _ -> true end)
View SourceMoves to a function call by the given name and arity, matching the given predicate, in the current scope.
Examples
iex> zipper = Sourceror.parse_string!("bar = 1\nfoo(1, 2)") |> Sourceror.Zipper.zip()
iex> {:ok, result} = Sourceror.Code.Function.move_to_function_call_in_current_scope(zipper, :foo, 2)
iex> match?({:foo, _, _}, result.node)
trueSee also move_to_function_call/4.
@spec move_to_nth_argument( Sourceror.Zipper.t(), non_neg_integer() ) :: {:ok, Sourceror.Zipper.t()} | :error
Moves to the nth argument of a function call.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2, 3)") |> Sourceror.Zipper.zip()
iex> {:ok, result} = Sourceror.Code.Function.move_to_nth_argument(zipper, 1)
iex> match?({:__block__, _, [2]}, result.node)
trueSee also update_nth_argument/3.
@spec update_nth_argument( Sourceror.Zipper.t(), non_neg_integer(), (Sourceror.Zipper.t() -> {:ok, Sourceror.Zipper.t()} | :error) ) :: {:ok, Sourceror.Zipper.t()} | :error
Updates the nth argument of a function call, leaving the zipper at the function call's node.
Examples
iex> zipper = Sourceror.parse_string!("foo(1, 2, 3)") |> Sourceror.Zipper.zip()
iex> {:ok, zipper} = Sourceror.Code.Function.update_nth_argument(zipper, 1, fn z ->
...> {:ok, Sourceror.Code.Common.replace_code(z, "99")}
...> end)
iex> Sourceror.to_string(zipper.node) |> String.contains?("99")
trueSee also move_to_nth_argument/2.