Spec-Zone.ru › Elixir 1.17

Исходный код Macro.Env

Структура, хранящая информацию об окружении во время компиляции.

Текущее окружение можно получить в любое время как __ENV__/0. Внутри макросов, окружение вызывающей функции доступно как __CALLER__/0.

Большинство функций в этом модуле предназначены для низкоуровневых инструментов, которые нуждаются в интеграции с компилятором Elixir, таких как серверы языка и встроенные языки. Для обычного использования в коде Elixir и макросах, необходимо использовать модуль Macro вместо этого. В частности, избегайте прямого изменения структуры Macro.Env и предпочитайте использование высокоуровневых конструкций, таких как import, aliases, и так далее, для создания собственного окружения. Например, для создания пользовательского окружения, можно определить функцию, такую как:

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

Поля структуры

Структура Macro.Env содержит следующие поля:

  • context - контекст среды; он может быть nil (стандартный контекст), :guard (внутри условия) или :match (внутри соответствия)
  • context_modules - список модулей, определенных в текущем контексте
  • file - текущее абсолютное имя файла в виде бинарного
  • function - кортеж в виде {atom, integer}, где первый элемент - имя функции, а второй - её арность; возвращает nil если не находится внутри функции
  • line - текущая строка в виде целого числа
  • module - текущее имя модуля

Следующие поля предназначены только для механизма макрорасширения Elixir и не должны использоваться напрямую:

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

Обзор

Типы

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

Функции

define_alias(env, meta, module, opts \\ [])

Определяет заданный as как псевдоним для module в окружении.

define_import(env, meta, module, opts \\ [])

Определяет заданный module как импортированный в окружении.

define_require(env, meta, module, opts \\ [])

Определяет заданный module как требуемый в окружении.

expand_alias(env, meta, list, opts \\ [])

Расширяет псевдоним, заданный сегментами псевдонима.

expand_import(env, meta, name, arity, opts \\ [])

Расширяет импорт, заданный name и arity.

expand_require(env, meta, module, name, arity, opts \\ [])

Расширяет require, заданный module, name, и arity.

has_var?(env, var)

Проверяет, принадлежит ли переменная окружению.

in_guard?(env)

Возвращает значение, указывающее, находится ли среда компиляции в данный момент внутри условия.

in_match?(env)

Возвращает значение, указывающее, находится ли среда компиляции в данный момент внутри соответствия.

location(env)

Возвращает список ключевых слов, содержащий информацию о файле и строке в качестве ключей.

lookup_alias_as(env, atom)

Возвращает имена любых псевдонимов для данного модуля или атома.

lookup_import(env, name_arity)

Возвращает модули, из которых был импортирован заданный {name, arity}.

prepend_tracer(env, tracer)

Добавляет отслеживатель в начало списка отслеживателей в окружении.

prune_compile_info(env)

Удаляет информацию о компиляции из окружения.

required?(env, module)

Возвращает true если указанный модуль был потребован.

stacktrace(env)

Возвращает стек отслеживания окружения.

to_guard(env)

Возвращает среду в контексте условия.

to_match(env)

Возвращает среду в контексте соответствия.

vars(env)

Возвращает список переменных в текущем окружении.

Типы

context()Исходный код

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

context_modules()Исходный код

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

file()Исходный код

@type file() :: binary()

line()Исходный код

@type line() :: non_neg_integer()

name_arity()Исходный код

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

t()Исходный код

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

variable()Исходный код

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

Функции

define_alias(env, meta, module, opts \\ [])Source

@spec define_alias(t(), Macro.metadata(), module(), keyword()) ::
  {:ok, t()} | {:error, String.t()}

Определяет заданный as как псевдоним для module в среде.

Используется инструментами, которым нужно имитировать компилятор Elixir. Будет выведено соответствующее событие отслеживания компиляции :alias.

Дополнительные параметры

Принимает те же параметры, что и Kernel.SpecialForm.alias/2 плюс:

  • :trace - если установлено в false, отключает трекеры компиляции и лексический трекер. Этот параметр должен использоваться только серверами языков и другими инструментами, которым нужно инспектировать код, не влияя на его компиляцию. Отключение трекера внутри макросов или обычной обработки кода крайне не рекомендуется, так как это мешает компилятору точно отслеживать зависимости

Примеры

iex> env = __ENV__
iex> Macro.Env.expand_alias(env, [], [:Baz])
:error
iex> {:ok, env} = Macro.Env.define_alias(env, [line: 10], Foo.Bar, as: Baz)
iex> Macro.Env.expand_alias(env, [], [:Baz])
{:alias, Foo.Bar}
iex> Macro.Env.expand_alias(env, [], [:Baz, :Bat])
{:alias, Foo.Bar.Bat}

Если параметр :as не задан, псевдоним будет выведен из модуля:

iex> env = __ENV__
iex> {:ok, env} = Macro.Env.define_alias(env, [line: 10], Foo.Bar)
iex> Macro.Env.expand_alias(env, [], [:Bar])
{:alias, Foo.Bar}

Если невозможно вывести псевдоним, возвращается ошибка:

iex> Macro.Env.define_alias(__ENV__, [line: 10], :an_atom)
{:error,
 "alias cannot be inferred automatically for module: :an_atom, " <>
   "please use the :as option. Implicit aliasing is only supported with Elixir modules"}

define_import(env, meta, module, opts \\ [])Source

@spec define_import(t(), Macro.metadata(), module(), keyword()) ::
  {:ok, t()} | {:error, String.t()}

Определяет заданный module как импортированный в среде.

Предполагается, что module доступен. Используется инструментами, которым нужно имитировать компилятор Elixir. Будет выведено соответствующее событие отслеживания компиляции :import.

Дополнительные параметры

Принимает те же параметры, что и Kernel.SpecialForm.import/2 плюс:

  • :emit_warnings - выводить предупреждения, обнаруженные при определении импортов

  • :trace - если установлено в false, отключает трекеры компиляции и лексический трекер. Этот параметр должен использоваться только серверами языков и другими инструментами, которым нужно инспектировать код, не влияя на его компиляцию. Отключение трекера внутри макросов или обычной обработки кода крайне не рекомендуется, так как это мешает компилятору точно отслеживать зависимости

  • :info_callback - функция, используемая вместо Module.__info__/1. Функция будет вызвана с аргументом :functions или :macros. Она должна вернуть список пар "ключ-значение" {function, arity}. В случае ошибки используется метаданные модуля, основанные на module_info/1.

Примеры

iex> env = __ENV__
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[]
iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], List)
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[{:function, List}]

Принимает те же параметры, что и Kernel.SpecialForm.import/2:

iex> env = __ENV__
iex> Macro.Env.lookup_import(env, {:is_odd, 1})
[]
iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], Integer, only: :macros)
iex> Macro.Env.lookup_import(env, {:is_odd, 1})
[{:macro, Integer}]

Переопределение обратного вызова info

iex> env = __ENV__
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[]
iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], SomeModule, [info_callback: fn :functions -> [{:flatten, 1}]; :macros -> [{:some, 2}]; end])
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[{:function, SomeModule}]
iex> Macro.Env.lookup_import(env, {:some, 2})
[{:macro, SomeModule}]

define_require(env, meta, module, opts \\ [])Source

Определяет заданный module как необходимый в среде.

Не проверяет и не утверждает, что модуль доступен. Используется инструментами, которым нужно имитировать компилятор Elixir. Будет выведено соответствующее событие отслеживания компиляции :require.

Дополнительные параметры

Принимает те же параметры, что и Kernel.SpecialForm.require/2 плюс:

  • :trace - если установлено в false, отключает трекеры компиляции и лексический трекер. Этот параметр должен использоваться только серверами языков и другими инструментами, которым нужно инспектировать код, не влияя на его компиляцию. Отключение трекера внутри макросов или обычной обработки кода крайне не рекомендуется, так как это мешает компилятору точно отслеживать зависимости

Примеры

iex> env = __ENV__
iex> Macro.Env.required?(env, Integer)
false
iex> {:ok, env} = Macro.Env.define_require(env, [line: 10], Integer)
iex> Macro.Env.required?(env, Integer)
true

Если параметр :as задан, также будет определен псевдоним:

iex> env = __ENV__
iex> {:ok, env} = Macro.Env.define_require(env, [line: 10], Foo.Bar, as: Baz)
iex> Macro.Env.expand_alias(env, [], [:Baz])
{:alias, Foo.Bar}

expand_alias(env, meta, list, opts \\ [])Source

@spec expand_alias(t(), keyword(), [atom()], keyword()) :: {:alias, atom()} | :error

Расширяет псевдоним, заданный сегментами псевдонима.

Возвращает {:alias, alias} если сегменты являются списком атомов и псевдоним был найден. В противном случае возвращает :error.

Это расширение может выводить событие отслеживания :alias_expansion , но не :alias_reference.

Параметры

  • :trace - если установлено в false, отключает трекеры компиляции и лексический трекер. Этот параметр должен использоваться только серверами языков и другими инструментами, которым нужно инспектировать код, не влияя на его компиляцию. Отключение трекера внутри макросов или обычной обработки кода крайне не рекомендуется, так как это мешает компилятору точно отслеживать зависимости

Примеры

iex> alias List, as: MyList
iex> Macro.Env.expand_alias(__ENV__, [], [:MyList])
{:alias, List}
iex> Macro.Env.expand_alias(__ENV__, [], [:MyList, :Nested])
{:alias, List.Nested}

Если псевдонима нет или псевдоним начинается с Elixir. (что отключает алиасинг), возвращается :error:

iex> alias List, as: MyList
iex> Macro.Env.expand_alias(__ENV__, [], [:Elixir, MyList])
:error
iex> Macro.Env.expand_alias(__ENV__, [], [:AnotherList])
:error

expand_import(env, meta, name, arity, opts \\ [])Source

@spec expand_import(t(), keyword(), atom(), arity(), keyword()) ::
  {:macro, module(), (Macro.metadata(), args :: [Macro.t()] -> Macro.t())}
  | {:function, module(), atom()}
  | {:error, :not_found | {:conflict, module()} | {:ambiguous, [module()]}}

Расширяет импорт, заданный name и arity.

Если импорт указывает на макрос, возвращается кортеж с модулем и функцией, которая расширяет макрос. Функция ожидает, что метаданные будут присоединены к расширению и аргументы макроса.

Если импорт указывает на функцию, возвращается кортеж с модулем и именем функции.

Если любой импорт найден, будет выведено соответствующее событие отслеживания компиляции.

В противном случае возвращается {:error, reason}.

Параметры

  • :allow_locals - если установлено в false, не пытается захватить локальные макросы, определенные в текущем модуле в env

  • :check_deprecations - если установлено в false, не проверяет устаревшие версии при расширении макросов

  • :trace - если установлено в false, отключает трекеры компиляции и лексический трекер. Этот параметр должен использоваться только серверами языков и другими инструментами, которым нужно инспектировать код, не влияя на его компиляцию. Отключение трекера внутри макросов или обычной обработки кода крайне не рекомендуется, так как это мешает компилятору точно отслеживать зависимости

expand_require(env, meta, module, name, arity, opts \\ [])Source

@spec expand_require(t(), keyword(), module(), atom(), arity(), keyword()) ::
  {:macro, module(), (Macro.metadata(), args :: [Macro.t()] -> Macro.t())}
  | :error

Расширяет require, заданный module, name, и arity.

Если require указывает на макрос, и модуль был загружен, возвращается кортеж с модулем и функцией, которая расширяет макрос. Функция ожидает, что метаданные будут присоединены к расширению и аргументы макроса. Соответствующее событие отслеживания компиляции :remote_macro будет выведено, если макрос найден (заметьте, событие :remote_function не выводится в случаях :error).

В противном случае возвращается :error.

Параметры

  • :check_deprecations - если установлено в false, не проверяет устаревшие версии при расширении макросов

  • :trace - если установлено в false, отключает трекеры компиляции и лексический трекер. Этот параметр должен использоваться только серверами языков и другими инструментами, которым нужно инспектировать код, не влияя на его компиляцию. Отключение трекера внутри макросов или обычной обработки кода крайне не рекомендуется, так как это мешает компилятору точно отслеживать зависимости

has_var?(env, var)Source

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

Проверяет, принадлежит ли переменная среде.

Примеры

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

in_guard?(env)Source

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

Возвращает, находится ли среда компиляции внутри условия.

in_match?(env)Source

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

Возвращает, находится ли среда компиляции внутри условия сопоставления.

location(env)Source

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

Возвращает список ключевых слов, содержащий информацию о файле и строке в качестве ключей.

lookup_alias_as(env, atom)Source

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

Возвращает имена любых псевдонимов для данного модуля или атома.

Примеры

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)
[]

lookup_import(env, name_arity)Source

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

Возвращает модули, из которых был импортирован данный {name, arity}.

Возвращает список кортежей из двух элементов в формате {:function | :macro, module}. Элементы в списке не упорядочены, и порядок не гарантируется.

Использовать только для интроспекции

Эта функция не генерирует события отслеживания компилятора, что может помешать компилятору правильно отслеживать зависимости. Используйте эту функцию для целей рефлексии, но не используйте её для расширения импортов в квалифицированные вызовы. Вместо этого используйте expand_import/5.

Примеры

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}]

prepend_tracer(env, tracer)Source

@spec prepend_tracer(t(), module()) :: t()

Добавляет отслеживатель в начало списка отслеживателей в среде.

Примеры

Macro.Env.prepend_tracer(__ENV__, MyCustomTracer)

prune_compile_info(env)Source

@spec prune_compile_info(t()) :: t()

Удаляет информацию о компиляции из среды.

Это происходит, когда среда захватывается во время компиляции, например, в теле модуля, а затем используется для оценки кода после определения модуля.

required?(env, module)Source

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

Возвращает true, если указанный модуль был загружен.

Примеры

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

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

stacktrace(env)Source

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

Возвращает стек отладки среды.

to_guard(env)Source

@spec to_guard(t()) :: t()

Возвращает среду в контексте условия.

to_match(env)Source

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

Возвращает среду в контексте сопоставления.

vars(env)Source

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

Возвращает список переменных в текущей среде.

Каждая переменная определяется кортежем из двух элементов, где первый элемент — имя переменной как атом, а второй — её контекст, который может быть атомом или целым числом.

Скачать версию ePub

Создано с помощью ExDoc (v0.34.1) для языка программирования Elixir

© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.17.2/Macro.Env.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API