Изменения в Elixir v1.13
Фокус Elixir v1.13 был на инструментах, в основном на инструментах, связанных с форматированием кода, фрагментами кода, рефлексией кода и повторной компиляцией кода. Многие из этих функций напрямую повлияют на разработчиков, работающих над большими базами кода, и обеспечат ощутимые улучшения качества жизни для тех, кто работает с инструментами и средами Elixir, такими как IDE, блокноты и т. д.
Семантическая повторная компиляция
Elixir v1.13 поставляется со многими улучшениями компилятора, поэтому он рекомпилирует ваши файлы реже. В частности:
В расчёт принимается хеш-сумма файлов помимо их размера. Это позволяет избежать повторной компиляции многих файлов при переключении или слиянии веток.
Изменение вашего
mix.exsбольше не будет вызывать полную перекомпиляцию, если вы не измените конфигурации, используемые компилятором Elixir (:elixirc_pathsи:elixirc_options).Изменение файлов конфигурации времени компиляции (
config/config.exsи любого другого файла, импортированного из него) теперь перекомпилирует только те файлы проекта, которые зависят от переконфигурированных приложений, а не всю проект. Однако, если вы измените конфигурацию вашего собственного приложения, весь проект всё равно перекомпилируется.Добавление, обновление или удаление зависимости теперь перекомпилирует только те файлы проекта, которые зависят от изменённой зависимости.
Если ваш проект содержит как файлы Erlang, так и Elixir, изменение файла Erlang теперь перекомпилирует только те файлы Elixir, которые зависят от него.
Вкратце, Elixir перешёл от вызова полной перекомпиляции всякий раз, когда любой из mix.exs, config/config.exs, src/*, и mix.lock изменился в файловой системе к семантической перекомпиляции. Теперь полная перекомпиляция происходит только в следующих случаях:
- вы изменяете параметры компиляции в
mix.exs - вы изменяете конфигурацию текущего проекта в
config/config.exs
mix xref
mix xref — это инструмент, который анализирует взаимосвязи между файлами. Анализируя зависимости между файлами во время компиляции и выполнения, он позволяет разработчикам понимать, какие файлы нужно перекомпилировать при изменении файла.
Elixir v1.13 поставляется со многими улучшениями mix xref, такие как:
mix xref graphтеперь поддерживает установку--labelв «compile-connected», что возвращает все зависимости времени компиляции, которые приводят к дополнительным транзитивным зависимостям.Новый подкоманда
mix xref trace FILEполучает файл и возвращает все зависимости в этом файле, включая строку и то, что вызвало эту зависимость (вызов функции/макроса, псевдоним, структура и т. д.).Все подкоманды
mix xrefподдерживают флаг--fail-above, который позволяет гарантировать, что в вашем проекте не будет более определённого количества циклов компиляции, транзитивных зависимостей времени компиляции и т. д.mix xref graphтеперь поддерживает предоставление нескольких--sinkи--source.
Эти улучшения упрощают понимание влияния перекомпиляции кода на наши базы кода и способы ограничения этого влияния.
Фрагменты кода
Модуль Code получил сопутствующий модуль под названием Code.Fragment, который содержит функции, работающие с неполным кодом, как это часто бывает в редакторах, интерактивных оболочках и т. д. Модуль содержит различные эвристики для анализа исходного кода и возвращения контекстной информации.
Благодаря этим улучшениям, автодополнение IEx получило несколько улучшений качества жизни, таких как автодополнение сигилов, структур и путей. Например, написание ~<TAB> теперь отображает:
iex(1)> ~ ~C (sigil_C) ~D (sigil_D) ~N (sigil_N) ~R (sigil_R) ~S (sigil_S) ~T (sigil_T) ~U (sigil_U) ~W (sigil_W) ~c (sigil_c) ~r (sigil_r) ~s (sigil_s) ~w (sigil_w)
Добавление символа сигила и нажатие клавиши табу отображает доступные разделители:
iex(1)> ~r
" """ ' ''' ( / < [ { |
Аналогично, %<TAB> теперь отображает только доступные структуры (исключая исключения), а не все модули:
iex(1)> %File.St File.Stat File.Stream
После определения структуры вы можете нажать tab для отображения всех доступных полей структуры:
iex(1)> %URI{
authority: fragment: host: path: port:
query: scheme: userinfo:
По мере заполнения поля уже заполненные поля больше не отображаются:
iex(1)> %URI{path: "/example",
authority: fragment: host: port: query:
scheme: userinfo:
В том же духе, SyntaxError и TokenMissingError были улучшены для отображения фрагмента кода, когда это возможно:
$ elixir -e "hello + * world"
** (SyntaxError) nofile:1:9: syntax error before: '*'
|
1 | hello + * world
| ^
Наконец, были добавлены новые трассировщики компиляции, а также ряд функций в Module для извлечения метаданных модуля, которые можно использовать для обогащения предложений в средах программирования.
Расширенное форматирование кода
Задача mix format была дополнена понятием плагинов. Плагины могут обучить форматировщик, как форматировать новые файлы и сигилы с помощью поведения Mix.Tasks.Format.
Например, представьте, что ваш проект использует Markdown двумя различными способами: через пользовательский сигил ~M и через файлы с расширениями .md и .markdown. Пользовательский плагин будет выглядеть следующим образом:
defmodule MixMarkdownFormatter do
@behaviour Mix.Tasks.Format
def features(_opts) do
[sigils: [:M], extensions: [".md", ".markdown"]]
end
def format(contents, opts) do
# logic that formats markdown
end
end
Теперь любое приложение может использовать ваш форматировщик следующим образом:
# .formatter.exs
[
# Define the desired plugins
plugins: [MixMarkdownFormatter],
# Remember to update the inputs list to include the new extensions
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}", "posts/*.{md,markdown}"]
]
Наконец, модуль Code также был дополнен двумя функциями: Code.string_to_quoted_with_comments/2 и Code.quoted_to_algebra/2. Эти функции позволяют получить AST Elixir со всеми исходными комментариями и преобразовать этот AST в отформатированный код. Другими словами, эти функции предоставляют оболочку вокруг форматировщика кода Elixir, поддерживая разработчиков, которые хотят создавать инструменты, непосредственно манипулирующие и настраивающие форматирование исходного кода Elixir.
v1.13.4 (2022-04-07)
Этот релиз был проверен на совместимость с Erlang/OTP 25 RC2.
1. Улучшения
Elixir
- [Код] Разрешить возвращение iodata в функциях форматирования сигилов
- [Код] Передать информацию об открывающем разделителе в функции форматирования сигилов
2. Исправления ошибок
Elixir
- [Ядро] Уточнить унификацию типов для устранения бесконечной петли с рекурсивными переменными
- [Ядро] Добавить зависимости времени компиляции к
require - [Регистр] Заставить
Registryотправлять работать с именованными тройками
3. Устаревшие функции
Mix
- [mix rebar] Устаревший Rebar 2, так как он больше не работает с Erlang/OTP 25
v1.13.3 (2022-02-09)
1. Улучшения
Mix
- [mix format] Передать файл и строку плагинам форматирования
- [mix format] Поддержка вложенных выражений Elixir внутри плагинов форматирования
2. Исправления ошибок
Elixir
- [Код] Исправить дублирование связей, вызывающее ошибки при вычислении
- [Ядро] Убедиться, что подписи, хранящиеся в разделе документации, не содержат новых строк
- [Ядро] Исправить бесконечную петлю при компиляции условий с рекурсивным доступом к карте
- [Макрос] Исправить ошибку в
Macro.to_string/1, когда задан простой псевдонимElixir - [Строка] Исправить ошибку для определённых комбинаций кодовых точек в
String.split_at/2
Mix
- [mix compile] Перекомпилировать файлы проекта при изменении экспортов из зависимостей
- [mix test] Исправить общее покрытие, всегда показывающее красный цвет, даже при значении выше порогового
v1.13.2 (2022-01-13)
1. Улучшения
Mix
- [mix format] Разрешить плагинам также форматировать файлы
.exи.exs - [mix release] Разрешить пропуск проверки режима приложения в спецификации выпуска
- [mix test] Вывести сообщение при провале набора тестов из-за порогового значения покрытия
2. Исправления ошибок
Elixir
- [Код] Не генерировать предупреждения о
Code.Fragment.container_cursor_to_quoted/2 - [Ядро] Исправить сбой при использовании цикла for с
:uniqвнутри другого цикла с:uniq - [Ядро] Убедиться, что
env.context_modulesправильно задано внутри оптимизированногоdefmodule - [Ключевое слово] Устареть недавно добавленное
Keyword.map/2как эквивалентноеKeyword.new/2 - [Карта] Устареть недавно добавленное
Map.map/2как эквивалентноеMap.new/2 - [Протокол] Выводить предупреждение о функциях с нулевой арностью внутри протоколов
v1.13.1 (2021-12-14)
1. Исправления ошибок
Elixir
- [Код] Не отображать фрагменты кода в
SyntaxErrorиTokenMissingError, если строка пустая - [Исключение] Не обвинять
ArgumentErrorв некорректных списках при использованииapply/3 - [Макрос] Установить максимальное значение
line_lengthдляMacro.to_string/1 - [Макрос] Исправить форматирование списков в атрибутах модулей для
Macro.to_string/1 - [Строка] Исправить неправильный подсчёт байтов кодовых точек в
sliceс отрицательными позициями в диапазонах - [Задача] Обеспечить возможность потребления асинхронных потоков из другого процесса, чем тот, который их создал
- [URI] Отменить устаревание
URI.parse/1, так какURI.new/1слишком строг во многих распространённых случаях - [URI] Убедиться, что
URI.new/1возвращает nil для пустых путей
IEx
- [IEx] Убедиться, что флаг
--versionостанавливает IEx
Mix
- [Mix] Сделать консолидацию протоколов частью кэша
Mix.install/2
v1.13.0 (2021-12-03)
1. Улучшения
EEx
- [EEx] Добавить
:parser_optionsк функциям EEx
Elixir
- [Calendar] Добавить
Calendar.year_of_era/3для поддержки календарей, где начало новой эры не совпадает с началом нового года - [CLI] Поддержка
--short-versionв командной строке, которая не запускает виртуальную машину - [Code] Добавить
Code.string_to_quoted_with_comments/2иCode.quoted_to_algebra/2 - [Code] Добавить больше
:token_metadataк псевдонимам и удалённым вызовам при разборе строк - [Code] Добавить модуль
Code.Fragmentдля предоставления информации из фрагментов кода с наилучшим усилием. Модуль в настоящее время предоставляет обновлённыйCode.Fragment.cursor_context/2с поддержкой операторов иCode.Fragment.surround_context/2, который анализирует заданную позицию во фрагменте и находит окружающие разделители - [Code] Разрешить пользовательскую форматирование символов (sigils) для
Code.format_string!/2 - [Code] Добавить
{:on_module, bytecode, :none}отслеживание в трассировщиках компиляции - [Enum] Оптимизировать
Enum.concat/1для списков списков - [Enum] Добавить
Enum.slide/3 - [Exception] Лучшее форматирование исключений Elixir в Erlang
- [Inspect] Разрешить глобальную установку функции inspect по умолчанию с помощью
Inspect.Opts.default_inspect_fun/1 - [IO] Разрешить
:eofкак предел дляIO.getn/2 - [Kernel] Поддержка опции
:sigilsвimport Mod, only: :sigilsи разрешение модификаторов sigils быть также цифрами - [Kernel] Обеспечить согласованное прерывание
get_inи возвращениеnilпри обнаружении значенийnil(ранее Elixir в этом случае вызывал ошибку). Это позволяет пользователю использоватьget_inкак безопасный оператор навигации. - [Kernel] Улучшение времени компиляции путём уменьшения количества копий AST между процессами компилятора
- [Kernel] Выбрасывать исключение при попытке определения модуля с косой чертой в имени
- [Kernel] Выводить предупреждение при использовании
?\, когда нет необходимости в символе экранирования - [Kernel] Отслеживать структуры в типах (typespecs) как зависимости экспорта (export deps) вместо зависимостей времени компиляции (compile-time deps)
- [Kernel] Добавить оператор степени (
**/2) - [Keyword] Добавить
Keyword.validate/2 - [Keyword] Реализовать
Keyword.filter/2иKeyword.map/2 - [List] Добавить
List.keyfind!/3 - [Macro] Добавить
Macro.prewalker/1иMacro.postwalker/1 - [Macro.Env] Добавить следующие рефлексивные функции:
required?/2,lookup_import/2,fetch_alias/2, иfetch_macro_alias/2 - [Map] Реализовать
Map.filter/2иMap.map/2 - [Module] Поддержка
:nillify_clausesвModule.get_definition/3 - [Module] Добавить
Module.attributes_in/1иModule.overridables_in/1 - [OptionParser] Добавить предложения "Вы имели в виду?" к сообщениям об ошибках
OptionParser.ParseError - [Record] Добавить рефлексию записей через
@__records__ - [Task] Добавить
Task.completed/1 - [Task] Добавить
Task.ignore/1для продолжения работы задачи, но игнорирования всех её результатов - [Task] Уменьшить количество копий
Task.async*функций - [URI] Добавить
URI.new/1иURI.new!/1
ExUnit
- [ExUnit] Показать подсказку при сравнении различных, но эквивалентных строк
- [ExUnit.CaptureIO] Добавить
with_io/3для возвращения результата с захваченным вводом/выводом - [ExUnit.CaptureLog] Добавить
with_log/2для возвращения результата с захваченными логами
IEx
- [IEx.Autocomplete] Добавить автодополнение пути всякий раз, когда курсор следует за
"./или"/или"DRIVER:, гдеDRIVER- одиночная буква - [IEx.Autocomplete] Добавить автодополнение для sigils, имён структур и полей структур
- [IEx.Helpers] Разрешить передачу нескольких модулей в
r/1
Logger
- [Logger] Добавить
Logger.put_application_level/2 - [Logger] Выводить все уровни логов в соответствии с Erlang/OTP. Это также означает, что
[warn]теперь отображается как[warning]
Mix
- [Mix] Добавить поддержку переменной среды
MIX_INSTALL_FORCE - [Mix] Поддержка
:configи:system_envвMix.install/2 - [Mix] Добавить
Mix.installed?/0 - [Mix.Shell] Добавить опцию
:defaultкMix.Shell.yes? - [mix archive.install] Выполнить
loadconfigперед созданием архива - [mix compile] Переместить проверку версии Elixir перед компиляцией зависимостей для более ранней обратной связи
- [mix compile.elixir] Не перекомпилировать файлы, если изменилось время их модификации, но содержимое осталось таким же, а файлы .beam всё ещё на диске
- [mix compile.elixir] Не перекомпилировать все источники Elixir при изменении Erlang-модулей, а только зависимые
- [mix compile.elixir] Не перекомпилировать файлы Elixir, если
mix.exsизменяется, вместо этого перекомпилировать только используемые файлы с помощьюMix.Projectили инициировать перекомпиляцию при изменении опции компилятора - [mix compile.elixir] Перекомпилировать только необходимые файлы при добавлении, обновлении или удалении зависимости
- [mix compile.elixir] Перекомпилировать только необходимые файлы при конфигурировании зависимости
- [mix deps] Добавить опцию
:subdirк зависимостям из git - [mix escript.install] Выполнить
loadconfigперед созданием escript - [mix format] Поддерживать
:pluginsвmix format, который может подключаться к пользовательским расширениям и sigils - [mix format] Добавить
Mix.Tasks.Format.formatter_for_file/2 - [mix local.rebar] Больше не поддерживать
sub_dirsв Rebar 2 для облегчения миграции к Rebar 3 - [mix local.rebar] Поддерживать опцию
--if-missingпри установке Rebar - [mix local.rebar] Установить
REBAR_PROFILE=prodпри компиляции зависимостей Rebar - [mix test] Поддерживать
--profile-require=timeдля профилирования времени загрузки самих тестовых файлов - [mix test] Разрешить фильтрацию модулей из покрытия с помощью регулярных выражений
- [mix test] Разрешить настраивать код выхода ExUnit и установить значение по умолчанию в 2
- [mix test] Выходить со статусом 3, если покрытие падает ниже порога
- [mix test] Записывать неудачный манифест при сбое комплекта из-за --warnings-as-errors
- [mix test] Игнорировать
MIX_TEST_PARTITIONпри partition set к 1 - [mix xref] Поддержка нескольких стоков и источников в
mix xref graph - [mix xref] Добавить подкоманду
traceдля вывода зависимостей компиляции между файлами - [mix xref] Добавить опцию
--fail-aboveкmix xref - [mix xref] Добавить
--label compile-connectedкmix xref
2. Исправления ошибок
EEx
- [EEx] Принимать комментарии в EEx между do и первым клаузом
- [EEx] Принимать выражения EEx, где
->следует за символом новой строки
Elixir
- [Application] Разрешить любое выражение в качестве первого аргумента
compile_env - [Application] Выводить предупреждение, если
Application.compile_envилиApplication.compile_env!вызываются без require - [Code] Убедиться, что
:static_atoms_encoderвCode.string_to_quoted/2также применяется к ключам с именем в формате keyword - [Code] Убедиться, что привязки без контекста возвращаются как атомы, а не как
{binding, nil}в операциях eval - [Inspect] Исправить ошибку при инспектировании небинарного битового массива с цветами
- [Kernel] Отклонять двунаправленные символы форматирования в строках и комментариях
- [Kernel] Поддерживать экранирование терминаторов в sigils heredocs верхнего регистра для согласованности
- [Kernel] Выбрасывать исключение, если
__CALLER__или__ENV__или__STACKTRACE__используются в совпадении (match) - [Kernel] Улучшить сообщение об ошибке при некорректном аргументе для
byte_sizeиз конкатенации двоичных данных - [Kernel] Выбрасывать исключение при алиасировании модулей, не являющихся Elixir, без
:as - [Kernel] Разрешить
unquote_splicingвнутри%{...}без скобок - [Kernel] Гарантировать, что ожидание расширения структуры внутри типа (typespec) верно отслеживается как время ожидания в компиляторе
- [Kernel] Правильно распознавать атом
.как ключ списка keyword - [Kernel] Не пропускать переменные из первого генератора в
withиforспециальных формах - [Kernel] Исправить номер столбца в строках с символами NFD
- [Kernel] Исправить ошибку, когда комбинация динамической строки в
quoteсunquoteудалённых вызовов генерировала некорректные метаданные AST - [OptionParser] Проверять типы/модификаторы переключателей на ранней стадии, чтобы предоставить более точную обратную связь
- [Protocol] Добавить
defdelegateв список запрещённых макросов внутри протоколов, так как протоколы не позволяют определять функции - [Protocol] Выводить предупреждение, если
@callback,@macrocallbackи@optional_callbacksопределены внутри протокола - [Protocol] Убедиться, что метаданные протокола детерминированы при объединении
- [Range] Всегда отображать шаг, когда диапазон убывает
- [String] Обновить базу данных Unicode до версии 14.0
- [URI] Декодировать процент только если за ним следуют шестнадцатеричные цифры (в соответствии с https://url.spec.whatwg.org/#percent-decode)
- [Version] Убедиться в правильном приоритете
and/orв требованиях к версии
ExUnit
- [ExUnit] Исправить форматировщик и счётчики из
ExUnit.run/0для учёта всех тестов в модуле в случае, если тест в модулеsetup_allне пройдёт - [ExUnit] Разрешить новые строки в doctests, которые завершаются CRLF
IEx
- [IEx] Исправить потерю
.iex.exsконтекста после сеанса pry - [IEx] Остановите оценщик перед выходом из сервера IEx, чтобы избежать утечек оценщиков
Logger
- [Logger] Вывод ясного сообщения об ошибке для неверной конфигурации
:compile_time_purge_matching - [Logger] Исправлена ошибка, из-за которой Logger не сбрасывал счётчик отбрасывания в некоторых сценариях
Mix
- [mix compile.elixir] Отслеживание транзитивных зависимостей времени выполнения, исходящих из локальных/путевых зависимостей
- [mix compile.elixir] Перекомпиляция файла, если
@external_resourceудалён - [mix compile.elixir] Вывод количества компилируемых файлов на всех циклах компилятора. Это позволит
Compiling N files (.ex)появиться несколько раз при необходимости - [mix deps] Вывод ошибки, если локальная зависимость недоступна во время компиляции
- [mix deps.unlock] Исправление пустого вывода при разблокировании зависимости, которая не заблокирована
- [mix local.install] Не учитывать
MIX_DEPS_PATHдля команд установки - [mix release] Улучшение скриптов выпуска, обеспечивая каскадное выполнение ошибок оболочки (это делается путём избегания экспорта и определения переменных в одном шаге)
- [mix release] Не запускать выпуск, если
RELEASE_COOKIEпусто - [mix release] Разрешение перезапуска релизов, выполняемых в качестве демона
- [mix release] Вывод надлежащего сообщения об ошибке при наличии несериализуемых значений в конфигурациях
- [mix test] Исправление движка покрытия кода для добавления тегов
case,cond, иreceiveветвей, где правая часть является литералом
3. Мягкие устаревания (без вывода предупреждений)
Elixir
- [Code] Параметры среды в
Code.eval_quoted/3иCode.eval_string/3, такие как:aliasesи:tracers, устарели в пользу передачи среды - [IO]
:allвIO.getnустарело в пользу:eof - [URI]
URI.parse/1устарело в пользуURI.new/1иURI.new!/1
Mix
- [mix format]
Mix.Tasks.Format.formatter_opts_for_file/2устарело в пользуMix.Tasks.Format.formatter_for_file/2
4. Жесткие устаревания
Elixir
- [Code]
Code.cursor_context/2устарело, используйтеCode.Fragment.cursor_context/2вместо этого - [Macro]
Macro.to_string/2устарело, используйтеMacro.to_string/1вместо этого - [System]
System.get_pid/0устарело, используйтеSystem.pid/0вместо этого - [Version] Использование
!или!=в требованиях к версии устарело, используйте~>или>=вместо этого
Mix
- [mix escript.build] Опция
:strip_beamустарела в пользу:strip_beams - [Mix]
:exit_codeвMix.raise/2устарело в пользу:exit_status - [Mix.Config]
Mix.Configустарело в пользу модуляConfig
v1.12
Список изменений для выпусков v1.12 можно найти в ветке v1.12.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.13.4/changelog.html