IntelliJ插件中的jar用户可选运行时Java依赖项
任务
我们想为自定义语言创建IntelliJ IDEA插件。已经有一个大型(IntelliJ独立)项目,我们称之为MyLang
,用Scala编写,为定制语言提供解析和类型检查
一个主要的问题是,我们希望插件与MyLang
依赖性的特定来源分离,但是我们曾经或被告知的所有尝试和想法都有缺点
tl;dr:有没有一种方法可以让用户在IntelliJ插件中选择运行时Java依赖项来实现以下目标强>
目标
- 将插件与实际使用的
MyLang
依赖项源分离(因此也与版本分离,至少与非主要版本分离) - 能够让
MyLang
依赖项指向本地JAR和/或编译源目录
其基本原理是让MyLang
的开发人员使用插件测试他们的最新更改。例如,如果一个开发人员改进了MyLang
语言中的类型检查,那么他可能希望立即在IntelliJ中测试它以获得视觉反馈李> - 非关键:能够为每个IntelliJ项目配置
MyLang
依赖项
插件提供了一个自定义项目类型。插件范围的设置并不完美,但可以接受李> - 能够在插件中使用来自
MyLang
的数据结构(即类和函数)李>
尝试/想法
部署具有
MyLang
依赖项的插件- ✅ 1,2,3
- ❌ 四,
- ❌ 插件变得非常大李>
不使用
MyLang
部署插件,让用户选择一个MyLang
构建JAR并使用反射- ✅ 1,2,3
- ❌ 4,尤其是插件中丑陋且不安全的代码李>
- ❌ 只能通过反射通道传递Java或Scala标准API中的基本数据结构李>
根据(稳定的)
MyLang
编译插件,在不使用类加载器的情况下部署并使用类加载器魔术- 选项1:访问[IntelliJ的插件类加载器](https://github.com/JetBrains/intellij-community/blob/b3ce5e06d44058eb119b53ed0d4b7e2ac3e57722/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java
)并使用指向(用户提供的)JAR的URL调用^{
} - ✅ 1,2,4
- ❌ 3(但这并不重要)
- ❌ 其他缺点:
addUrl
被标记为不推荐使用,可能将来会被删除李>
- 选项2:创建自定义parent-last-child-first classloader
- ✅ 1、2、3、4(全部!)李>
- ❌ 拥有IntelliJ的类加载器和新的类加载器对于插件开发者来说是很容易混淆的,并且很容易出错!在将实例从新创建的类加载器的外部传递到内部时,必须非常谨慎。例如,IntelliJ提供的数据结构中的实例(编辑器组件、PSI文件实例等)仅在旧的普通IntelliJ插件类加载器中有效
因此,访问IntelliJ数据结构几乎是不可能的
- 选项1:访问[IntelliJ的插件类加载器](https://github.com/JetBrains/intellij-community/blob/b3ce5e06d44058eb119b53ed0d4b7e2ac3e57722/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java
)并使用指向(用户提供的)JAR的URL调用^{
IntelliJ论坛中有一个(未解决的)讨论,OP需要完全相同的设置:https://intellij-support.jetbrains.com/hc/en-us/community/posts/206121299-classloader-in-plugin
共 (0) 个答案