Spec-Zone.ru › Elixir 1.14

Code.Fragment

Этот модуль предоставляет удобства для анализа фрагментов текстового кода и извлечения доступной информации, когда это возможно.

Большинство функций в этом модуле предоставляют оптимальный вариант и могут быть неточными во всех обстоятельствах. Читайте каждую документацию для получения дополнительной информации.

Этот модуль следует считать экспериментальным.

Краткое описание

Типы

position()

Функции

container_cursor_to_quoted(fragment, opts \\ [])

Принимает строку и возвращает выражение в кавычках с курсором в позиции ближайшего аргумента.

cursor_context(fragment, opts \\ [])

Принимает строку и возвращает контекст курсора.

surround_context(fragment, position, options \\ [])

Принимает строку и возвращает окружающий контекст.

Типы

position()Source

@type position() :: {line :: pos_integer(), column :: pos_integer()}

Функции

container_cursor_to_quoted(fragment, opts \\ [])Source

@spec container_cursor_to_quoted(
  List.Chars.t(),
  keyword()
) ::
  {:ok, Macro.t()}
  | {:error, {location :: keyword(), binary() | {binary(), binary()}, binary()}}

Принимает строку и возвращает выражение в кавычках с курсором в позиции ближайшего аргумента.

Эта функция получает строку с фрагментом кода Elixir, представляющим положение курсора, и преобразует эту строку в AST с включением специального __cursor__() узла на основе положения курсора с контейнером.

Контейнер — это любое выражение Elixir, начинающееся с (, {, и [. Это включает вызовы функций, кортежи, списки, карты и так далее. Например, рассмотрим этот код, который будет передан в качестве входных данных:

max(some_value,

Эта функция вернёт эквивалентный AST:

max(some_value, __cursor__())

Другими словами, эта функция способна закрыть любые открытые скобки и вставить позицию курсора. Любое содержимое в позиции курсора, что стоит после запятой или открывающей скобки, отбрасывается. Например, если в качестве входных данных предоставлен:

max(some_value, another_val

Он вернёт тот же AST:

max(some_value, __cursor__())

Аналогично, если предоставлено только это:

max(some_va

Тогда он возвращает:

max(__cursor__())

Также поддерживаются вызовы без скобок, так как мы предполагаем, что скобки являются неявными.

Операторы и анонимные функции не являются контейнерами и, следовательно, будут отброшены. Следующие все вернут тот же AST:

max(some_value,
max(some_value, fn x -> x end
max(some_value, 1 + another_val
max(some_value, 1 |> some_fun() |> another_fun

С другой стороны, кортежи, списки, карты и двоичные данные сохраняют позицию курсора:

max(some_value, [1, 2,

Возвращает следующий AST:

max(some_value, [1, 2, __cursor__()])

Ключевые списки (и блоки do-end) также сохраняются. Следующие:

if(some_value, do:
if(some_value, do: :token
if(some_value, do: 1 + val

Все возвращают:

if(some_value, do: __cursor__())

Возвращаемый этой функцией AST не является безопасным для оценки, но его можно анализировать и расширять.

Примеры

Вызов функции:

iex> Code.Fragment.container_cursor_to_quoted("max(some_value, ")
{:ok, {:max, [line: 1], [{:some_value, [line: 1], nil}, {:__cursor__, [line: 1], []}]}}

Контейнеры (например, список):

iex> Code.Fragment.container_cursor_to_quoted("[some, value")
{:ok, [{:some, [line: 1], nil}, {:__cursor__, [line: 1], []}]}

Для двоичных данных :: сохраняется исключительно как оператор:

iex> Code.Fragment.container_cursor_to_quoted("<<some::integer")
{:ok, {:<<>>, [line: 1], [{:"::", [line: 1], [{:some, [line: 1], nil}, {:__cursor__, [line: 1], []}]}]}}

Параметры

  • :file - имя файла, которое будет сообщено в случае ошибок разбора. По умолчанию "nofile".

  • :line - начальная строка анализируемой строки. По умолчанию 1.

  • :column - начальный столбец анализируемой строки. По умолчанию 1.

  • :columns - при true, прикрепить ключ :column к метаданным в кавычках. По умолчанию false.

  • :token_metadata - при true, включает метаданные, связанные с маркерами, в выражение AST, такие как метаданные для do и end маркеров, для закрывающих маркеров, конца выражений, а также разделителей для сигилов. См. Macro.metadata/0. По умолчанию false.

  • :literal_encoder - функция для кодирования литералов в AST. См. документацию для Code.string_to_quoted/2 для получения дополнительной информации.

cursor_context(fragment, opts \\ [])Source

@spec cursor_context(
  List.Chars.t(),
  keyword()
) ::
  {:alias, charlist()}
  | {:alias, inside_alias, charlist()}
  | {:dot, inside_dot, charlist()}
  | {:dot_arity, inside_dot, charlist()}
  | {:dot_call, inside_dot, charlist()}
  | :expr
  | {:local_or_var, charlist()}
  | {:local_arity, charlist()}
  | {:local_call, charlist()}
  | {:module_attribute, charlist()}
  | {:operator, charlist()}
  | {:operator_arity, charlist()}
  | {:operator_call, charlist()}
  | :none
  | {:sigil, charlist()}
  | {:struct, inside_struct}
  | {:unquoted_atom, charlist()}
when inside_dot:
       {:alias, charlist()}
       | {:alias, inside_alias, charlist()}
       | {:dot, inside_dot, charlist()}
       | {:module_attribute, charlist()}
       | {:unquoted_atom, charlist()}
       | {:var, charlist()},
     inside_alias: {:local_or_var, charlist()} | {:module_attribute, charlist()},
     inside_struct:
       charlist()
       | {:alias, inside_alias, charlist()}
       | {:local_or_var, charlist()}
       | {:module_attribute, charlist()}
       | {:dot, inside_dot, charlist()}

Принимает строку и возвращает контекст курсора.

Эта функция получает строку с фрагментом кода Elixir, представляющим положение курсора, и на основе строки предоставляет контекстную информацию об этом положении. Результат этой функции затем можно использовать для предоставления подсказок, предложений и функциональности автодополнения.

Эта функция предоставляет оптимальный вариант обнаружения и может быть неточной во всех обстоятельствах. См. раздел "Ограничения" ниже.

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

Примеры

iex> Code.Fragment.cursor_context("")
:expr

iex> Code.Fragment.cursor_context("hello_wor")
{:local_or_var, 'hello_wor'}

Возвращаемые значения

  • {:alias, charlist} - контекст является псевдонимом, потенциально вложенным, например, Hello.Wor или HelloWor

  • {:alias, inside_alias, charlist} - контекст является псевдонимом, потенциально вложенным, где inside_alias является выражением {:module_attribute, charlist} или {:local_or_var, charlist} и charlist является статической частью. Примеры __MODULE__.Submodule или @hello.Submodule

  • {:dot, inside_dot, charlist} - контекст является точкой, где inside_dot является либо {:var, charlist}, {:alias, charlist}, {:module_attribute, charlist}, {:unquoted_atom, charlist} или самим dot. Если указана переменная, это может быть удалённый вызов или доступ к полю карты. Примеры Hello.wor, :hello.wor, hello.wor, Hello.nested.wor, hello.nested.wor, и @hello.world. Если charlist пусто, а inside_dot является псевдонимом, то автодополнение может быть либо псевдонимом, либо удалённым вызовом.

  • {:dot_arity, inside_dot, charlist} - контекст - арифметичность точки, где inside_dot является либо {:var, charlist}, {:alias, charlist}, {:module_attribute, charlist}, {:unquoted_atom, charlist} или самим dot. Если указана переменная, это должен быть удалённый арифметичность. Примеры Hello.world/, :hello.world/, hello.world/2, и @hello.world/2

  • {:dot_call, inside_dot, charlist} - контекст - вызов точки. Это означает, что после выражения были добавлены скобки или пробел. где inside_dot является либо {:var, charlist}, {:alias, charlist}, {:module_attribute, charlist}, {:unquoted_atom, charlist} или самим dot. Если указана переменная, это должен быть удалённый вызов. Примеры Hello.world(, :hello.world(, Hello.world, hello.world(, hello.world, и @hello.world(

  • :expr - может быть любым выражением. Автодополнение может предложить псевдоним, локальную или переменную.

  • {:local_or_var, charlist} - контекст - переменная или локальный вызов (импорт или локальный), например, hello_wor

  • {:local_arity, charlist} - контекст - локальный арифметичность (импорт или локальный), например, hello_world/

  • {:local_call, charlist} - контекст - локальный вызов (импорт или локальный), например, hello_world( и hello_world

  • {:module_attribute, charlist} - контекст - атрибут модуля, например, @hello_wor

  • {:operator, charlist} - контекст - оператор, например, + или ==. Обратите внимание, что текстовые операторы, например, when, не отображаются как операторы, а скорее как :local_or_var. @ никогда не является :operator и всегда :module_attribute

  • {:operator_arity, charlist} - контекст - арифметичность оператора, это оператор, за которым следует /, например, +/, not/ или when/

  • {:operator_call, charlist} - контекст - вызов оператора, это оператор, за которым следует пробел, например, left +, not или x when

  • :none - контекст невозможен

  • {:sigil, charlist} - контекст - сигил. Это может быть либо начало сигила, например, ~ или ~s, либо оператор, начинающийся с ~, например, ~> и ~>>

  • {:struct, inside_struct} - контекст - структура, например, %, %UR или %URI. inside_struct может быть либо charlist в случае статического псевдонима, либо выражение {:alias, inside_alias, charlist}, {:module_attribute, charlist}, {:local_or_var, charlist}, {:dot, inside_dot, charlist}

  • {:unquoted_atom, charlist} - контекст - необрамлённый атом. Это может быть любой атом или атом, представляющий модуль

Ограничения

Текущий алгоритм учитывает только последнюю строку входных данных. Это означает, что он также будет отображать предложения внутри строк, heredocs и т. д., что является намеренным, так как это помогает с doctests, ссылками и т. д.

END_OF_DOCUMENT_MARKER

surround_context(fragment, position, options \\ [])Source

@spec surround_context(List.Chars.t(), position(), keyword()) ::
  %{begin: position(), end: position(), context: context} | :none
when context:
       {:alias, charlist()}
       | {:alias, inside_alias, charlist()}
       | {:dot, inside_dot, charlist()}
       | {:local_or_var, charlist()}
       | {:local_arity, charlist()}
       | {:local_call, charlist()}
       | {:module_attribute, charlist()}
       | {:operator, charlist()}
       | {:sigil, charlist()}
       | {:struct, inside_struct}
       | {:unquoted_atom, charlist()}
       | {:keyword, charlist()},
     inside_dot:
       {:alias, charlist()}
       | {:alias, inside_alias, charlist()}
       | {:dot, inside_dot, charlist()}
       | {:module_attribute, charlist()}
       | {:unquoted_atom, charlist()}
       | {:var, charlist()},
     inside_alias: {:local_or_var, charlist()} | {:module_attribute, charlist()},
     inside_struct:
       charlist()
       | {:alias, inside_alias, charlist()}
       | {:local_or_var, charlist()}
       | {:module_attribute, charlist()}
       | {:dot, inside_dot, charlist()}

Принимает строку и возвращает окружающий контекст.

Эта функция получает строку с фрагментом кода Elixir и position. Она возвращает карту, содержащую начало и конец идентификатора вместе с его контекстом, или :none если нет ничего с известным контекстом.

Разница между cursor_context/2 и surround_context/3 заключается в том, что первая предполагает, что выражение во фрагменте кода неполное. Например, do в cursor_context/2 может быть ключевым словом, переменной или локальным вызовом, тогда как surround_context/3 предполагает, что выражение во фрагменте кода полное, поэтому do всегда будет ключевым словом.

position содержит как line, так и column, оба начинаются с индекса 1. Столбец должен предшествовать окружающему выражению. Например, выражение foo, вернёт что-то для столбцов 1, 2 и 3, но не для 4:

foo
^ column 1

foo
 ^ column 2

foo
  ^ column 3

foo
   ^ column 4

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

Подобно cursor_context/2, эта функция также предоставляет определение с наилучшим результатом и может быть неточной во всех случаях. Смотрите раздел "Возвращаемые значения" и "Ограничения" в cursor_context/2 для получения дополнительной информации.

Примеры

iex> Code.Fragment.surround_context("foo", {1, 1})
%{begin: {1, 1}, context: {:local_or_var, 'foo'}, end: {1, 4}}

Отличия от cursor_context/2

Поскольку surround_context/3 работает с полным кодом, она имеет некоторые различия с cursor_context/2:

  • dot_call/dot_arity и operator_call/operator_arity свёрнуты в dot и operator контексты соответственно, так как между ними нет значимых различий

  • С другой стороны, эта функция всё ещё различает local_call/local_arity и local_or_var, так как последнее может быть локальной переменной

  • @ при отсутствии последующего идентификатора возвращается как {:operator, '@'} (в отличие от {:module_attribute, ''} в cursor_context/2

  • Эта функция никогда не возвращает пустые сигилы {:sigil, ''} или пустые структуры {:struct, ''} в качестве контекста

  • Эта функция возвращает ключевые слова как {:keyword, 'do'}

  • Эта функция никогда не возвращает :expr

© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.14.1/Code.Fragment.html

Spec-Zone.ru

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