Задача
Мы хотели бы создать плагин IntelliJ IDEA для пользовательского языка. Уже существует большой (независимый от IntelliJ) проект, назовем его MyLang
, написанный на Scala, обеспечивающий разбор и проверку типов для пользовательского языка.
Основная проблема заключается в том, что мы хотели бы, чтобы плагин был отделен от определенного источника зависимости MyLang
, но все попытки и идеи, которые у нас были или нам сказали, имеют недостатки.
ТЛ; dr: Есть ли способ иметь выбираемые пользователем зависимости Java во время выполнения в плагине IntelliJ для достижения следующих целей?
Цель
- Отделение плагина от фактического используемого
MyLang
источника зависимостей (и, следовательно, также от версии, по крайней мере, неосновных)
- Возможность указать, что зависимость
MyLang
указывает на локальный каталог JAR и / или каталог скомпилированных источников.
Смысл в том, чтобы позволить разработчикам MyLang
протестировать свои последние изменения с помощью плагина. Например, если один разработчик улучшил проверку типов на языке MyLang
, он мог бы немедленно проверить его в IntelliJ для визуальной обратной связи.
- Некритично: Возможность настройки зависимости
MyLang
для проекта IntelliJ.
Существует специальный тип проекта, который предоставляет плагин. Настройка плагина не идеальна, но приемлема.
- Возможность использовать структуры данных (т.е. классы и функции) из
MyLang
в плагине.
Попытки / Идеи
Развертывание плагина с MyLang
зависимостью
- 1, 2, 3
- ❌ 4
- ❌ Плагин становится очень большим по размеру.
Развернуть плагин без MyLang
, позволить пользователю выбрать JAR-сборку MyLang
и использовать отражение.
- 1, 2, 3
- ❌ 4, особенно некрасивый и нетипичный код в плагине.
- basic Через канал отражения можно передавать только базовые структуры данных из стандартного API Java или Scala.
Скомпилировать плагин против (стабильного) MyLang
, развернуть без использования и использовать classloader magic
- Вариант 1: Получить доступ к [загрузчику классов плагинов IntelliJ] (https://github.com/JetBrains/intellij-community/blob/b3ce5e06d44058eb119b53ed0d4b7e2ac3e57722/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java
) и позвоните
addUrl
с URL-адресом (предоставленным пользователем) JAR
- 1, 2, 4
- 3 (что было некритично)
- ❌ Другой недостаток:
addUrl
помечен как устаревший, возможно, он будет удален в будущем.
- Вариант 2. Создание пользовательского parent-last-child-first-loloader
- 1, 2, 3, 4 (все!)
- ❌ Наличие загрузчика классов IntelliJ и нового на месте сбивает с толку разработчиков плагинов и очень подвержено ошибкам ! Нужно быть очень осторожным в отношении передачи экземпляров извне вновь созданного загрузчика классов внутрь него. Например. экземпляры из структур данных, предоставленных IntelliJ (компоненты редактора, экземпляры PSIFile, ...), действительны только в старом обычном загрузчике классов подключаемого модуля IntelliJ.
Таким образом, доступ к структурам данных IntelliJ становится практически невозможным
На форумах IntelliJ есть одно (неразрешенное) обсуждение, в котором OP требует точно такой же настройки: https://intellij -support.jetbrains.com / hc / en-us / community / posts / 206121299-classloader-in- плагин