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

Link to this function

append_argument(zipper, value)

View Source
@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)"
Link to this function

argument_equals?(zipper, index, term)

View Source
@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)
false

See also argument_matches_predicate?/3.

Link to this macro

argument_matches_pattern?(zipper, index, pattern)

View Source (macro)

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]})
true

See also argument_matches_predicate?/3.

Link to this function

argument_matches_predicate?(zipper, index, func)

View Source
@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)
true

See also argument_equals?/3.

Link to this function

function(zipper, atom, arity)

View Source
Link to this function

function?(zipper, name \\ :any, arity \\ :any)

View Source
@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
Link to this function

function_call?(zipper, name, arity \\ :any)

View Source
@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)
false

See also function_call?/1.

Link to this function

get_local_function_call(zipper)

View Source
@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.

Link to this function

get_local_function_call_name(zipper)

View Source
@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
Link to this function

move_to_def(zipper, fun, arity)

View Source
@spec move_to_def(
  Sourceror.Zipper.t(),
  fun :: atom(),
  arity :: integer() | [integer()]
) ::
  {:ok, Sourceror.Zipper.t()} | :error
Link to this function

move_to_defp(zipper, fun, arity)

View Source
@spec move_to_defp(
  Sourceror.Zipper.t(),
  fun :: atom(),
  arity :: integer() | [integer()]
) ::
  {:ok, Sourceror.Zipper.t()} | :error
Link to this function

move_to_function_call(zipper, name, arity, predicate \\ fn _ -> true end)

View Source

Moves 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)
true

See also move_to_function_call_in_current_scope/4.

Link to this function

move_to_function_call_in_current_scope(zipper, name, arity, predicate \\ fn _ -> true end)

View Source

Moves 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)
true

See also move_to_function_call/4.

Link to this function

move_to_nth_argument(zipper, index)

View Source
@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)
true

See also update_nth_argument/3.

Link to this function

update_nth_argument(zipper, index, func)

View Source
@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")
true

See also move_to_nth_argument/2.