plymio_ast v0.2.0 Plymio.Ast.Form
Utility Functions for Manipulating Asts (Quoted Forms)
Summary
Functions
maybe_ast_escape/1
escapes (Macro.escape/1
) any value other than a module attribute or an existing ast (i.e. Macro.validate/1
returns :ok
)
Takes a maybe quoted value and returns the realised value
Takes a maybe quoted value, realises it and, if a function, returns
{:ok, function}
. Anything else returns :error
Takes a maybe quoted value, realises it using
maybe_ast_realise_function/1
, and, if {:ok, function}
, returns the
function, else raises a BadFunctionError
exception
Takes a maybe quoted value, realises it and, if a Map
, returns
{:ok, map}
Takes a maybe quoted value, realises it using
maybe_ast_realise_map/1
, and if the result is {:ok, map}
, returns the map,
else raises a BadMapError
exception
Takes a maybe quoted value, realises it and, if a compiled module, returns {:ok, module}
Takes a maybe quoted value, realises it using
maybe_ast_realise_module/1
, and, if {:ok, module}
, returns the
module, else raises a ArgumentError
exception
Takes a maybe quoted value, realises it and, if a tuple, returns {:ok, tuple}
Takes a maybe quoted value, realises it using
maybe_ast_realise_tuple/1
, and if the result is {:ok, tuple}
, returns the tuple,
else raises an ArgumentError
exception
Functions
maybe_ast_escape/1
escapes (Macro.escape/1
) any value other than a module attribute or an existing ast (i.e. Macro.validate/1
returns :ok
)
Examples
iex> 42 |> maybe_ast_escape
42
iex> :two |> maybe_ast_escape
:two
iex> %{a: 1} |> maybe_ast_escape
{:%{}, [], [a: 1]}
iex> %{a: 1} |> Macro.escape |> maybe_ast_escape
{:%{}, [], [a: 1]}
iex> [1, %{b: 2}, {:c, 2, :tre}] |> maybe_ast_escape
[1, {:%{}, [], [b: 2]}, {:{}, [], [:c, 2, :tre]}]
iex> [1, %{b: 2}, {:c, 2, :tre}] |> Macro.escape |> maybe_ast_escape
[1, {:%{}, [], [b: 2]}, {:{}, [], [:c, 2, :tre]}]
Takes a maybe quoted value and returns the realised value.
Realisation in this context means extracting the underlying (“unquoted”) value.
Examples
iex> 1 |> maybe_ast_realise
1
iex> :atom |> maybe_ast_realise
:atom
iex> "string" |> maybe_ast_realise
"string"
iex> [1, :atom, "string"] |> maybe_ast_realise
[1, :atom, "string"]
iex> {:x, 42} |> maybe_ast_realise
{:x, 42}
iex> ast = {:x, 42} |> Macro.escape
...> ast |> maybe_ast_realise
{:x, 42}
iex> %{a: 1, b: 2, c: 3} |> maybe_ast_realise
%{a: 1, b: 2, c: 3}
iex> ast = %{a: 1, b: 2, c: 3} |> Macro.escape
...> ast |> maybe_ast_realise
%{a: 1, b: 2, c: 3}
iex> fun = fn x -> x + 5 end
...> fun = fun |> maybe_ast_realise
...> 42 |> fun.()
47
iex> ast = "fn x -> x + 5 end" |> Code.string_to_quoted!
...> fun = ast |> maybe_ast_realise
...> 42 |> fun.()
47
A map’s keys and values are recursively realised:
iex> ast = %{a: %{a1: 1}, b: %{b21: 21, b22: 22}, c: 3} |> Macro.escape
iex> ast |> maybe_ast_realise
%{a: %{a1: 1}, b: %{b21: 21, b22: 22}, c: 3}
The elements of a tuple are recursively realised:
iex> ast = [{:x, 2, [1,2,3], %{a: %{a1: 1}, b: %{b21: 21, b22: 22}, c: 3}}] |> Macro.escape
iex> ast |> maybe_ast_realise
[{:x, 2, [1,2,3], %{a: %{a1: 1}, b: %{b21: 21, b22: 22}, c: 3}}]
The elements of a list are recursively realised:
iex> ast = [{:x,:y,:z}, [1,2,3], %{a: %{a1: 1}, b: %{b21: 21, b22: 22}, c: 3}] |> Macro.escape
iex> ast |> maybe_ast_realise
[{:x,:y,:z}, [1,2,3], %{a: %{a1: 1}, b: %{b21: 21, b22: 22}, c: 3}]
Takes a maybe quoted value, realises it and, if a function, returns
{:ok, function}
. Anything else returns :error
.
iex> fun = fn x -> x end
...> result = fun |> maybe_ast_realise_function
...> match?({:ok, ^fun}, result)
true
iex> quoted_fun = quote(do: fn x -> x end)
...> {:ok, fun} = quoted_fun |> maybe_ast_realise_function
...> is_function(fun, 1)
true
iex> 42 |> maybe_ast_realise_function
:error
iex> {:x, 42} |> Macro.escape
...> |> maybe_ast_realise_function
:error
Takes a maybe quoted value, realises it using
maybe_ast_realise_function/1
, and, if {:ok, function}
, returns the
function, else raises a BadFunctionError
exception.
iex> fun = fn x -> x end
...> result = fun |> maybe_ast_realise_function!
...> match?(^fun, result)
true
iex> quoted_fun = quote(do: fn x -> x end)
...> fun = quoted_fun |> maybe_ast_realise_function!
...> is_function(fun, 1)
true
iex> 42 |> maybe_ast_realise_function!
** (BadFunctionError) expected a function, got: :error
iex> {:x, 42}
...> |> Macro.escape
...> |> maybe_ast_realise_function!
** (BadFunctionError) expected a function, got: :error
Takes a maybe quoted value, realises it and, if a Map
, returns
{:ok, map}
.
If the realised value is a Keyword
, its is converted to a map and
{:ok, map}
returned.
Anything else returns :error.
The keys and values are recursively realised.
iex> %{a: 1, b: %{b21: 21, b22: 22}, c: 3} |> maybe_ast_realise_map
{:ok, %{a: 1, b: %{b21: 21, b22: 22}, c: 3}}
iex> ast = %{a: 1, b: %{b21: 21, b22: 22}, c: 3} |> Macro.escape
iex> ast |> maybe_ast_realise_map
{:ok, %{a: 1, b: %{b21: 21, b22: 22}, c: 3}}
iex> 42 |> maybe_ast_realise_map
:error
iex> ast = {:x, 42} |> Macro.escape
iex> ast |> maybe_ast_realise_map
:error
Takes a maybe quoted value, realises it using
maybe_ast_realise_map/1
, and if the result is {:ok, map}
, returns the map,
else raises a BadMapError
exception.
iex> %{a: 1, b: %{b21: 21, b22: 22}, c: 3} |> maybe_ast_realise_map!
%{a: 1, b: %{b21: 21, b22: 22}, c: 3}
iex> ast = %{a: 1, b: %{b21: 21, b22: 22}, c: 3} |> Macro.escape
iex> ast |> maybe_ast_realise_map!
%{a: 1, b: %{b21: 21, b22: 22}, c: 3}
iex> 42 |> maybe_ast_realise_map!
** (BadMapError) expected a map, got: :error
iex> ast = {:x, 42} |> Macro.escape
iex> ast |> maybe_ast_realise_map!
** (BadMapError) expected a map, got: :error
Takes a maybe quoted value, realises it and, if a compiled module, returns {:ok, module}
.
Tests whether the module’s __info__
function works to confirm an actual module.
Anything else returns :error
.
iex> mod = (defmodule ABC1, do: nil) |> elem(1)
...> result = mod |> maybe_ast_realise_module
...> match?({:ok, ^mod}, result)
true
iex> mod = (defmodule ABC2, do: nil) |> elem(1)
...> quoted_mod = mod |> Macro.escape
...> result = quoted_mod |> maybe_ast_realise_module
...> match?({:ok, ^mod}, result)
true
iex> 42 |> maybe_ast_realise_module
:error
iex> {:x, 42}
...> |> Macro.escape
...> |> maybe_ast_realise_module
:error
Takes a maybe quoted value, realises it using
maybe_ast_realise_module/1
, and, if {:ok, module}
, returns the
module, else raises a ArgumentError
exception.
iex> mod = (defmodule ABC3, do: nil) |> elem(1)
...> result = mod |> maybe_ast_realise_module!
...> match?(^mod, result)
true
iex> mod = (defmodule ABC, do: nil) |> elem(1)
...> quoted_mod = mod |> Macro.escape
...> result = quoted_mod |> maybe_ast_realise_module!
...> match?(^mod, result)
true
iex> :an_atom_but_not_a_module |> maybe_ast_realise_module!
** (ArgumentError) expected a module, got: :error
iex> 42 |> maybe_ast_realise_module!
** (ArgumentError) expected a module, got: :error
iex> {:x, 42}
...> |> Macro.escape
...> |> maybe_ast_realise_module!
** (ArgumentError) expected a module, got: :error
Takes a maybe quoted value, realises it and, if a tuple, returns {:ok, tuple}
.
Anything else returns :error
.
iex> {:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3} |> maybe_ast_realise_tuple
{:ok, {:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3}}
iex> {:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3}
...> |> Macro.escape
...> |> maybe_ast_realise_tuple
{:ok, {:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3}}
iex> 42 |> maybe_ast_realise_tuple
:error
iex> %{x: 42}
...> |> Macro.escape
...> |> maybe_ast_realise_tuple
:error
Takes a maybe quoted value, realises it using
maybe_ast_realise_tuple/1
, and if the result is {:ok, tuple}
, returns the tuple,
else raises an ArgumentError
exception.
iex> {:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3} |> maybe_ast_realise_tuple!
{:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3}
iex> {:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3}
...> |> Macro.escape
...> |> maybe_ast_realise_tuple!
{:one, 1, %{"two1" => 21, :two2 => 22}, "tre", 3}
iex> 42 |> maybe_ast_realise_tuple!
** (ArgumentError) expected a tuple, got: :error
iex> %{x: 42}
...> |> Macro.escape
...> |> maybe_ast_realise_tuple!
** (ArgumentError) expected a tuple, got: :error