Packages

Sibyl is a library which augments the BEAM's default tracing capabilities by hooking into `:telemetry`, `:dbg` (the BEAM's built in tracing and debugging functionality), and `OpenTelemetry`.

Current section

Files

Jump to
sibyl lib sibyl ast.ex
Raw

lib/sibyl/ast.ex

defmodule Sibyl.AST do
@moduledoc """
Utility module for working with ASTs
"""
@type ast() :: term()
@type alias() :: {:__aliases__, term(), [atom()]}
@type unused() :: :__unused__
@doc """
Returns true if the given argument is an Elixir AST node representing a module alias
such as `Enum`.
"""
defguard alias?(ast) when is_tuple(ast) and elem(ast, 0) == :__aliases__
@doc """
Returns true if the given argument is equal to `:__unused__`. Primarily used internally.
"""
defguard unused?(term) when term == :__unused__
@doc """
Returns the `:__unused__` atom.
"""
@spec unused() :: ast()
defmacro unused do
quote do
:__unused__
end
end
# coveralls-ignore-start
# TODO: find a way to unit test this, as we now expect the macro's env to be
# passed in
@doc """
Given an alias AST node, returns the fully resolved alias that said node would expand
to.
For example, given: `{:__aliases, unused(), [Elixir, Enum]}`, returns: `Enum`.
"""
@spec module(alias(), Macro.Env.t()) :: module()
def module({:__aliases__, _metadata, _module_list} = ast, env) do
case Macro.expand(ast, env) do
module when is_atom(module) ->
module
otherwise ->
otherwise = inspect(otherwise)
raise ArgumentError, "expected an alias expanding to a module, got: #{otherwise}"
end
end
end