java - IntelliJ 插件中用户可选择的运行时 Java 依赖项
问题描述
任务
我们想为自定义语言创建一个 IntelliJ IDEA 插件。已经有一个大型(独立于 IntelliJ)项目,我们称之为MyLang
,用 Scala 编写,为自定义语言提供解析和类型检查。
一个主要问题是我们希望插件与MyLang
依赖的特定来源分离,但是我们拥有或被告知的所有尝试和想法都有缺陷。
tl; 博士:有没有办法在 IntelliJ 插件中实现用户可选择的运行时 Java 依赖项来实现以下目标?
目标
- 将插件与实际使用的
MyLang
依赖源解耦(因此也与版本,至少是非主要的)解耦 - 能够让
MyLang
依赖项指向本地 JAR 和/或编译的源目录。
基本原理是让开发人员MyLang
使用插件测试他们的最新更改。例如,如果一位开发人员改进了MyLang
语言中的类型检查,那么他可能希望立即在 IntelliJ 中对其进行测试以获得视觉反馈。 - 非关键:能够为
MyLang
每个 IntelliJ 项目配置依赖项。
该插件提供了一个自定义项目类型。插件范围的设置并不完美,但可以接受。 - 能够使用
MyLang
插件中的数据结构(即类和函数)。
尝试/想法
部署具有
MyLang
依赖项的插件- ✅ 1, 2, 3
- ❌ 4
- ❌ 插件变得非常大。
部署不带插件的插件
MyLang
,让用户选择MyLang
构建 JAR 并使用反射。- ✅ 1, 2, 3
- ❌ 4,插件中特别丑陋且非类型安全的代码。
- ❌ 只能通过反射通道传递来自 Java 或 Scala 标准 API 的基本数据结构。
针对 (stable) 编译插件
MyLang
,无需部署并使用类加载器魔法- 选项 1:访问 [IntelliJ 的插件类加载器]( https://github.com/JetBrains/intellij-community/blob/b3ce5e06d44058eb119b53ed0d4b7e2ac3e57722/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader .java
)并
addUrl
使用(用户提供的)JAR 的 URL 调用- ✅ 1、2、4
- ❌ 3(虽然这不是关键的)
- ❌ 其他缺点:
addUrl
被标记为已弃用,将来可能会被删除。
- 选项 2:创建自定义的parent-last-child-first 类加载器
- ✅ 1、2、3、4(全部!)
- ❌ 拥有 IntelliJ 的类加载器和新的类加载器会让插件开发人员感到困惑,并且很容易出错!必须非常谨慎地将实例从新创建的类加载器外部传递到其内部。例如,来自 IntelliJ 提供的数据结构的实例(编辑器组件、PSIFile 实例……)仅在旧的普通 IntelliJ 插件类加载器中有效。
因此,访问 IntelliJ 数据结构几乎是不可能的
- 选项 1:访问 [IntelliJ 的插件类加载器]( https://github.com/JetBrains/intellij-community/blob/b3ce5e06d44058eb119b53ed0d4b7e2ac3e57722/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader .java
)并
IntelliJ 论坛中有一个(未解决的)讨论,其中 OP 需要完全相同的设置:https ://intellij-support.jetbrains.com/hc/en-us/community/posts/206121299-classloader-in-plugin
解决方案
推荐阅读
- python - Py4JError:调用 .saveAsTable 时发生错误
- javascript - 无法在 nodejs 中将 base64 图像上传到 S3 AWS
- r - 在 r 中选择小的 vif 变量
- python - 如何使用 Discord API 和 Python 请求发送图片
- reactjs - how can you store a component inside an object? React
- css - 格式化 R Shiny / CSS 标签中的所有标签
- react-native - React Native - 使用 react-native-svg-transformer 重复 SVG 背景
- javascript - 如何仅在未使用 Thymeleaf 呈现元素时才包含元素?
- postgresql - 如何使用动态表名进行子查询,其中动态值来自 PostgreSQL 中自己的主查询?
- android - Android EditText Android 中的动画