Что нового в MPS 2023.2

В MPS 2023.2 улучшена генерация лямбда-выражений BaseLanguage, поддержка JUnit 5, переопределение правил вывода системы типов и многое другое.

Поддержка JUnit 5

JUnit 5

В новой версии MPS тесты генерируются в формате JUnit 5. Для JUnit 4 все еще предоставляется ограниченная поддержка.

  • Любой Java-класс с соответствующей аннотацией можно выполнить как тест.
  • Тесты MPS можно запускать как внутри процесса, так и с порождением нового процесса.
  • Корни существующих тестов генерируются с аннотациями JUP Jupiter API:
    • BTestCase
    • NodeTestCase
    • EditorTestCase
    • MigrationTestCase
    • PatternTest
    • GeneratorTest

Задача Ant для запуска модульных тестов с помощью JUnit 5

Появилась новая задача Ant launchtests с поддержкой следующих элементов:

  • библиотека
  • macro
  • плагин
  • testmodules

Она поддерживает выполнение всех артефактов тестов, кроме JUnit 3, и служит новым целевым объектом для настройки тестов в ходе сборки.

Выполнение тестов из MPS

  • Любой Java-класс с соответствующей аннотацией можно выполнить как тест.
  • Для JUnit 4 предоставляется ограниченная поддержка.
  • Тесты можно запускать как внутри существующего процесса, так и с порождением нового.

API тестовой платформы

API позволяет расширить список типов тестов, доступных в MPS, а также использовать обработчики событий для сеансов тестирования.

Классы, входящие в jetbrains.mps.baseLanguage.unitTest.platform, образуют API тестовой платформы MPS:

TestPlatform Определяет API тестовой платформы MPS.
TestDescriptor Представляет отдельный тест на тестовой платформе MPS.
TestSource Представляет источник теста, например SNode.
TestSession Представляет тестовую сессию.
TestDiscoveryParticipant Позволяет подключиться к процессу обнаружения тестов.
TestSessionListener Дает возможность получать уведомления от сеанса тестирования.

Экспериментальная поддержка пользовательских движков тестирования

Среди прочих функций в JUnit 5 появилась поддержка реализации тестов, выполняемых с помощью пользовательского движка. Типичный пример такого движка — фреймворк тестирования на основе свойств jqwik.

Улучшенная поддержка переопределения правил системы типов
Спонсировано клиентом

Переопределение системы типов

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

Улучшения для BaseLanguage

В одном из предыдущих обновлений в MPS была добавлена расширенная поддержка ссылок на методы и преобразование замыканий в лямбда-выражения Java. В этой версии мы добавили много новых возможностей и исправили ошибки.

Лямбды

Генерация замыканий в виде лямбда-выражений

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

  • если имя переменной конфликтует с внешней переменной — в новой версии появляется предупреждение с предложением переименовать переменную;
  • если целевая версия Java не выше 8;
  • если используются необработанные типы — они плохо работают с лямбда-выражениями Java.

Обычно это повышает качество генерируемого кода, поскольку лямбда-выражения не только удобнее читать, но и вероятность ошибок при их генерации ниже. В то же время MPS допускает использование необработанных типов, которые недопустимы в Java, поскольку выявление таких экземпляров затруднено. В результате там, где используются необработанные типы, при генерации возможны сбои.

Параметры замыканий

Параметры замыканий

Раньше параметры замыканий могли иметь разную форму: ~param, <type> param, param или var param. Добавлять параметры, опуская тип, было неудобно. В новой версии мы отказались от варианта ~param: теперь по умолчанию вставляется простой нетипизированный параметр. Кроме того, если замыкание вводится в вызов функции, то вставляются параметры по умолчанию из ожидаемого типа функции. Наконец, теперь, если в исходном коде тип параметров опущен, в сгенерированных параметрах тип также опускается: это повышает качество компиляции кода.

Потоки

Совместимость с потоками

В MPS широко используются последовательности, однако в некоторых случаях требуется использовать потоки Java. В новой версии улучшен их вывод. Это позволяет решить проблемы с системой типов, вызванные сложными методами, которые могут использоваться API потоков. Мы добавили две операции для стыковки потоков и последовательностей:

  • <stream>.asSequence преобразует последовательность в поток;
  • <sequence>.toStream(parallel=…) выполняет обратное преобразование.

Это позволяет не только выбрать, какой API использовать, но и объединить преимущества последовательностей (повторяемость) и потоков (различные сборщики, больше операторов).

Улучшения работы с коллекциями

В предыдущих версиях уже был добавлен алмазный оператор (new ArrayList<>()) для конструкторов BaseLanguage, но это улучшение не касалось создания коллекций. С выходом этого обновления можно опускать параметры типов из новых коллекций, что упрощает написание кода:

  • тип, выведенный из исходных значений: var myList = new arraylist<> {myInitialValue};
  • тип, выведенный из объявления переменной: map<int, string> myMap = new hashmap<>.

Кроме того, мы улучшили поддержку вариантности в коллекциях. Например, больше нельзя добавить нотацию ? extends Number. Однако система типов больше не препятствует использованию таких связанных типов в тех случаях, когда это допустимо. Тип sequence<> по умолчанию остается ковариантным, поскольку это не вызовет никаких небезопасных последствий: его нельзя вставить в последовательность элементов другого типа. Это может привести к появлению новых ошибок при проверке типов, которые раньше оставались незамеченными. Для их исправления можно использовать либо связанные типы list<? extends node<>>, либо типы последовательности sequence<node<>>.

Настройки конфигурации

Disable Make

Disable Make On Startup

Мы добавили новый параметр Disable Make On Startup в настройках Settings | Project Settings | Make. Если эта опция включена, MPS при запуске не будет собирать все модули проекта. Это удобно, если нужно ускорить запуск в тех случаях, когда первоначальная сборка занимает слишком много времени или велика вероятность ошибки, поскольку для успешной сборки требуется настроить ее вручную.

Изменение библиотеки

Изменение путей к библиотекам и исходному коду в Java-свойствах модуля

На вкладке Java в диалоге свойств модуля добавлен новый параметр Edit. Его непросто найти, но очень удобно использовать. Если нужно изменить набор jar-библиотек модуля, достаточно воспользоваться этим параметром, чтобы не тратить время на удаление и добавление библиотек поодиночке.

Другое

Комментарий TODO

TODO для пользовательских комментариев

Расширение концепта IGenericComment позволяет использовать для концептов, представляющих комментарии на произвольных языках, функцию TODO. Комментарии, представляющие собой объекты TODO, собираются с помощью TODO Finder, отображаются в TODO Viewer, а затем проверяются при коммите.

Аспекты языка: управление действиями Create New

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

Упразднение проверки «Please re-export dependency…»

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

Функции из прежних релизов, профинансированные пользователями

Преимущество сообщества — возможность делиться с другими. Описанные ниже функции были созданы по просьбе платных пользователей MPS, которые и профинансировали их разработку. Теперь эти удобные возможности доступны всем пользователям MPS.

Параллельная проверка моделей

Теперь проверка моделей занимает меньше времени, поскольку эта функция может эффективно использовать параллельное оборудование. В зависимости от настроек в меню Settings | Tools | Model Checker в начале процесса можно запустить сразу несколько потоков.

Повышение производительности при персистентности «file-per-root»

Мы оптимизировали метод FilePerRootDataSource.getStreamByName(), чтобы повысить производительность загрузки данных модели. Если при хранении больших моделей вы следуете принципу «file-per-root», то обязательно заметите разницу.

Диалог поиска

Улучшенная поддержка действия Find text in project

Действие Find text in project было доработано: в новой версии с его помощью можно найти ссылки на именованные узлы, получив больше полезных результатов. Мы добавили панель предварительного просмотра, чтобы результаты можно было посмотреть прямо в диалоге поиска. В отличие от прежних версий, текст, включающий фрагменты HTML, теперь отображается в результатах поиска как простой текст, а не как HTML.

Пропуск миграции зависимостей в задачах Ant

Во время миграции проектов с помощью задач Ant, которые предлагает MPS, могут возникнуть ошибки миграции зависимостей. Мы добавили флаг, позволяющий продолжить миграцию проекта, если такое случилось. Однако по умолчанию миграция проекта по-прежнему прерывается, если обнаружена ошибка миграции зависимости. Чтобы использовать этот флаг, добавьте к задаче Ant migrate параметр haltOnDependencyError="false".

Обновления платформы

Изменение масштаба всей IDE

Теперь в MPS можно увеличивать и уменьшать размер всех элементов интерфейса одновременно. Для этого выберите View | Appearance в главном меню и настройте нужный масштаб. В настройках можно задать сочетания клавиш для вызова этих действий: Settings/Preferences | Keymap | Main Menu | View | Appearance.

Возможность зафиксировать размер окон инструментов

Мы добавили новую опцию, которая позволяет зафиксировать ширину боковых окон инструментов. Вы найдете новый флажок Remember size for each tool window в разделе Settings/Preferences | Appearance & Behavior | Appearance | Tool Windows. Подробнее о том, как эта опция работает в старом и новом интерфейсе, читайте в нашем блоге.

Подсветка синтаксиса в описаниях инспекций

Подсветка синтаксиса в описаниях инспекций

В разделе Settings / Preferences | Editor | Inspections теперь работает подсветка синтаксиса в примерах кода. Так проще понять, что активирует инспекцию, и решить, нужна она вам или нет.

Действие Fill Paragraph для Markdown-файлов

Действие Fill Paragraph для файлов Markdown

Действие Fill Paragraph теперь поддерживается для Markdown-файлов, позволяя разбивать длинные тексты на несколько строк одинаковой длины. Для этого установите курсор внутри абзаца, который нужно отредактировать, и с помощью Find Action (Ctrl+Shift+A) найдите и примените команду Fill Paragraph.

Улучшенное окно Branches

Улучшенное окно Branches

Всплывающее окно Branches стало более удобным. В частности, вам будет проще перемещаться между ветками, потому что теперь они сгруппированы и хранятся в раскрываемых списках.

Автодополнение в диалоге Create New Branch

Автодополнение в окне Create New Branch

В MPS 2023.2 работает автодополнение во всплывающем окне Create New Branch. Как только вы начнете вводить имя новой ветки, IDE предложит подходящие префиксы на основе имен существующих локальных веток.

Руководство по миграции

Перед каждым крупным релизом мы готовим инструкции по миграции с более старых версий MPS, чтобы все прошло гладко. Не забудьте ознакомиться с ними.