View Source Bunch.Macro (Bunch v1.6.1)

A bunch of helpers for implementing macros.

Summary

Functions

Receives an AST and traverses it expanding all the nodes.

Imitates import functionality by finding and replacing bare function calls (like foo()) in AST with fully-qualified call (like Some.Module.foo())

Imitates import functionality by finding and replacing bare function calls (like foo()) in AST with fully-qualified call (like Some.Module.foo())

Works like Macro.prewalk/2, but allows to skip particular nodes.

Works like Macro.prewalk/3, but allows to skip particular nodes using an accumulator.

Functions

@spec expand_deep(Macro.t(), Macro.Env.t()) :: Macro.t()

Receives an AST and traverses it expanding all the nodes.

This function uses Macro.expand/2 under the hood. Check it out for more information and examples.

@spec inject_call(
  Macro.t(),
  {module(), atom()}
) :: Macro.t()

Imitates import functionality by finding and replacing bare function calls (like foo()) in AST with fully-qualified call (like Some.Module.foo())

Receives AST fragment as first parameter and a pair {Some.Module, :foo} as second

Link to this function

inject_calls(ast, functions)

View Source
@spec inject_calls(Macro.t(), [{module(), atom()}]) :: Macro.t()

Imitates import functionality by finding and replacing bare function calls (like foo()) in AST with fully-qualified call (like Some.Module.foo())

Receives AST fragment as first parameter and list of pairs {Some.Module, :foo} as second

@spec prewalk_while(Macro.t(), (Macro.t() -> {:enter | :skip, Macro.t()})) ::
  Macro.t()

Works like Macro.prewalk/2, but allows to skip particular nodes.

Example

iex> code = quote do fun(1, 2, opts: [key: :val]) end
iex> code |> Bunch.Macro.prewalk_while(fn node ->
...>   if Keyword.keyword?(node) do
...>     {:skip, node ++ [default: 1]}
...>   else
...>     {:enter, node}
...>   end
...> end)
quote do fun(1, 2, opts: [key: :val], default: 1) end
Link to this function

prewalk_while(ast, acc, fun)

View Source
@spec prewalk_while(
  Macro.t(),
  any(),
  (Macro.t(), any() -> {:enter | :skip, Macro.t(), any()})
) :: {Macro.t(), any()}

Works like Macro.prewalk/3, but allows to skip particular nodes using an accumulator.

Example

iex> code = quote do fun(1, 2, opts: [key: :val]) end
iex> code |> Bunch.Macro.prewalk_while(0, fn node, acc ->
...>   if Keyword.keyword?(node) do
...>     {:skip, node ++ [default: 1], acc + 1}
...>   else
...>     {:enter, node, acc}
...>   end
...> end)
{quote do fun(1, 2, opts: [key: :val], default: 1) end, 1}