Macro.Env (Elixir v1.14.0-dev) View Source

A struct that holds compile time environment information.

The current environment can be accessed at any time as __ENV__/0. Inside macros, the caller environment can be accessed as __CALLER__/0.

An instance of Macro.Env must not be modified by hand. If you need to create a custom environment to pass to Code.eval_quoted/3, use the following trick:

def make_custom_env do
  import SomeModule, only: [some_function: 2]
  alias A.B.C
  __ENV__
end

You may then call make_custom_env() to get a struct with the desired imports and aliases included.

It contains the following fields:

  • context - the context of the environment; it can be nil (default context), :guard (inside a guard) or :match (inside a match)
  • context_modules - a list of modules defined in the current context
  • file - the current file name as a binary
  • function - a tuple as {atom, integer}, where the first element is the function name and the second its arity; returns nil if not inside a function
  • line - the current line as an integer
  • module - the current module name

The following fields are private to Elixir's macro expansion mechanism and must not be accessed directly:

  • aliases
  • functions
  • macro_aliases
  • macros
  • lexical_tracker
  • requires
  • tracers
  • versioned_vars

Link to this section Summary

Functions

Fetches the alias for the given atom.

Fetches the macro alias for the given atom.

Checks if a variable belongs to the environment.

Returns whether the compilation environment is currently inside a guard.

Returns whether the compilation environment is currently inside a match clause.

Returns a keyword list containing the file and line information as keys.

Returns the modules from which the given {name, arity} was imported.

Prepend a tracer to the list of tracers in the environment.

Prunes compile information from the environment.

Returns true if the given module has been required.

Returns the environment stacktrace.

Returns a Macro.Env in the match context.

Returns a list of variables in the current environment.

Link to this section Types

Specs

context() :: :match | :guard | nil

Specs

context_modules() :: [module()]

Specs

file() :: binary()

Specs

line() :: non_neg_integer()

Specs

name_arity() :: {atom(), arity()}

Specs

t() :: %Macro.Env{
  aliases: aliases(),
  context: context(),
  context_modules: context_modules(),
  file: file(),
  function: name_arity() | nil,
  functions: functions(),
  lexical_tracker: lexical_tracker(),
  line: line(),
  macro_aliases: macro_aliases(),
  macros: macros(),
  module: module(),
  requires: requires(),
  tracers: tracers(),
  versioned_vars: versioned_vars()
}

Specs

variable() :: {atom(), atom() | term()}

Link to this section Functions

Link to this function

fetch_alias(map, atom)

View Source (since 1.13.0)

Specs

fetch_alias(t(), atom()) :: {:ok, atom()} | :error

Fetches the alias for the given atom.

Returns {:ok, alias} if the alias exists, :error otherwise.

Examples

iex> alias Foo.Bar, as: Baz
iex> Baz
Foo.Bar
iex> Macro.Env.fetch_alias(__ENV__, :Baz)
{:ok, Foo.Bar}
iex> Macro.Env.fetch_alias(__ENV__, :Unknown)
:error
Link to this function

fetch_macro_alias(map, atom)

View Source (since 1.13.0)

Specs

fetch_macro_alias(t(), atom()) :: {:ok, atom()} | :error

Fetches the macro alias for the given atom.

Returns {:ok, macro_alias} if the alias exists, :error otherwise.

A macro alias is only used inside quoted expansion. See fetch_alias/2 for a more general example.

Link to this function

has_var?(env, var)

View Source (since 1.7.0)

Specs

has_var?(t(), variable()) :: boolean()

Checks if a variable belongs to the environment.

Examples

iex> x = 13
iex> x
13
iex> Macro.Env.has_var?(__ENV__, {:x, nil})
true
iex> Macro.Env.has_var?(__ENV__, {:unknown, nil})
false

Specs

in_guard?(t()) :: boolean()

Returns whether the compilation environment is currently inside a guard.

Specs

in_match?(t()) :: boolean()

Returns whether the compilation environment is currently inside a match clause.

Specs

location(t()) :: keyword()

Returns a keyword list containing the file and line information as keys.

Link to this function

lookup_import(map, pair)

View Source (since 1.13.0)

Specs

lookup_import(t(), name_arity()) :: [{:function | :macro, module()}]

Returns the modules from which the given {name, arity} was imported.

It returns a list of two element tuples in the shape of {:function | :macro, module}. The elements in the list are in no particular order and the order is not guaranteed.

Examples

iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2})
[]
iex> import Tuple, only: [duplicate: 2], warn: false
iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2})
[{:function, Tuple}]
iex> import List, only: [duplicate: 2], warn: false
iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2})
[{:function, List}, {:function, Tuple}]

iex> Macro.Env.lookup_import(__ENV__, {:def, 1})
[{:macro, Kernel}]
Link to this function

prepend_tracer(env, tracer)

View Source (since 1.13.0)

Specs

prepend_tracer(t(), module()) :: t()

Prepend a tracer to the list of tracers in the environment.

Examples

Macro.Env.prepend_tracer(__ENV__, MyCustomTracer)
Link to this function

prune_compile_info(env)

View Source (since 1.14.0)

Specs

prune_compile_info(t()) :: t()

Prunes compile information from the environment.

This happens when the environment is captured at compilation time, for example, in the module body, and then used to evaluate code after the module has been defined.

Link to this function

required?(map, mod)

View Source (since 1.13.0)

Specs

required?(t(), module()) :: boolean()

Returns true if the given module has been required.

Examples

iex> Macro.Env.required?(__ENV__, Integer)
false
iex> require Integer
iex> Macro.Env.required?(__ENV__, Integer)
true

iex> Macro.Env.required?(__ENV__, Kernel)
true

Specs

stacktrace(t()) :: list()

Returns the environment stacktrace.

Specs

to_match(t()) :: t()

Returns a Macro.Env in the match context.

Specs

vars(t()) :: [variable()]

Returns a list of variables in the current environment.

Each variable is identified by a tuple of two elements, where the first element is the variable name as an atom and the second element is its context, which may be an atom or an integer.