Metastatic.Adapters.Elixir.MacroExpander
(Metastatic v0.19.0)
View Source
Full macro expansion for the Elixir adapter using ExPanda.
This module takes a surface-level Elixir AST (from Code.string_to_quoted/1)
and produces a fully expanded AST where every macro has been resolved, while
annotating expansion boundaries with the original surface form so that the
FromMeta transformer can reconstruct macros faithfully.
How It Works
- Parse the surface AST via
Code.string_to_quoted/1(done upstream) - Expand the AST fully with
ExPanda.expand/1 - Walk both ASTs in parallel (
annotate/2):- Structural match (same form atom): recurse into children pairwise
- Macro boundary (different form atoms): tag the expanded node with
__original_macro__: surface_nodein its Elixir AST metadata - Leaf/literal match: return expanded as-is
- Return the annotated expanded AST
The __original_macro__ annotation is later propagated by ToMeta into
the MetaAST keyword metadata as :original_macro, and consumed by FromMeta
to restore the original macro call during round-tripping.
Examples
iex> {:ok, surface} = Code.string_to_quoted("unless true, do: :never")
iex> {:ok, annotated} = MacroExpander.expand_and_annotate(surface)
iex> {form, meta, _args} = annotated
iex> form
:case
iex> Keyword.has_key?(meta, :__original_macro__)
true
Summary
Functions
Expand all macros in surface_ast via ExPanda and annotate expansion points.
Expand all macros in a source string and return the annotated AST.
Functions
Expand all macros in surface_ast via ExPanda and annotate expansion points.
Returns {:ok, annotated_ast} where every node that resulted from a macro
expansion carries __original_macro__: original_surface_node in its
Elixir AST metadata keyword list.
Options
:env- customMacro.Envto pass to ExPanda (default: fresh env):file- file path for error messages (default:"nofile")
Examples
iex> {:ok, surface} = Code.string_to_quoted("1 |> to_string()")
iex> {:ok, annotated} = MacroExpander.expand_and_annotate(surface)
iex> match?({{:., _, _}, _, _}, annotated)
true
Expand all macros in a source string and return the annotated AST.
Convenience wrapper that parses + expands + annotates in one step.
Examples
iex> {:ok, annotated} = MacroExpander.expand_and_annotate_string("unless true, do: :never")
iex> {form, meta, _} = annotated
iex> form
:case
iex> is_list(Keyword.get(meta, :__original_macro__))
false