Macro.Env — Elixir v1.16.3

Search documentation of Elixir

# View Source Macro.Env (Elixir v1.16.3)

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], warn: false
      alias A.B.C, warn: false
      __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 absolute 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`

# Summary

## Types

context()
context_modules()
file()
line()
name_arity()
t()
variable()

## Functions

fetch_alias(env, atom)

Fetches the alias for the given atom.

fetch_macro_alias(env, atom)

Fetches the macro alias for the given atom.

has_var?(env, var)

Checks if a variable belongs to the environment.

in_guard?(env)

Returns whether the compilation environment is currently inside a guard.

in_match?(env)

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

location(env)

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

lookup_alias_as(env, atom)

Returns the names of any aliases for the given module or atom.

lookup_import(env, name_arity)

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

prepend_tracer(env, tracer)

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

prune_compile_info(env)

Prunes compile information from the environment.

required?(env, module)

Returns `true` if the given module has been required.

stacktrace(env)

Returns the environment stacktrace.

to_match(env)

Returns a `Macro.Env` in the match context.

vars(env)

Returns a list of variables in the current environment.

# Types

Link to this type

# context()

View Source

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

Link to this type

# context_modules()

View Source

    @type context_modules() :: [module()]

Link to this type

# file()

View Source

    @type file() :: binary()

Link to this type

# line()

View Source

    @type line() :: non_neg_integer()

Link to this type

# name_arity()

View Source

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

Link to this type

# t()

View Source

    @type 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()
    }

Link to this type

# variable()

View Source

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

# Functions

Link to this function

# fetch_alias(env, atom)

View Source (since 1.13.0)

    @spec 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(env, atom)

View Source (since 1.13.0)

    @spec 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)

    @spec 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

Link to this function

# in_guard?(env)

View Source

    @spec in_guard?(t()) :: boolean()

Returns whether the compilation environment is currently inside a guard.

Link to this function

# in_match?(env)

View Source

    @spec in_match?(t()) :: boolean()

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

Link to this function

# location(env)

View Source

    @spec location(t()) :: keyword()

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

Link to this function

# lookup_alias_as(env, atom)

View Source (since 1.15.0)

    @spec lookup_alias_as(t(), atom()) :: [atom()]

Returns the names of any aliases for the given module or atom.

## Examples

    iex> alias Foo.Bar
    iex> Bar
    Foo.Bar
    iex> Macro.Env.lookup_alias_as(__ENV__, Foo.Bar)
    [Elixir.Bar]
    iex> alias Foo.Bar, as: Baz
    iex> Baz
    Foo.Bar
    iex> Macro.Env.lookup_alias_as(__ENV__, Foo.Bar)
    [Elixir.Bar, Elixir.Baz]
    iex> Macro.Env.lookup_alias_as(__ENV__, Unknown)
    []

Link to this function

# lookup_import(env, name_arity)

View Source (since 1.13.0)

    @spec 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)

    @spec 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)

    @spec 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?(env, module)

View Source (since 1.13.0)

    @spec 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

Link to this function

# stacktrace(env)

View Source

    @spec stacktrace(t()) :: list()

Returns the environment stacktrace.

Link to this function

# to_match(env)

View Source

    @spec to_match(t()) :: t()

Returns a `Macro.Env` in the match context.

Link to this function

# vars(env)

View Source (since 1.7.0)

    @spec 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.