首页 > 解决方案 > IntelliJ 插件中用户可选择的运行时 Java 依赖项

问题描述

任务

我们想为自定义语言创建一个 IntelliJ IDEA 插件。已经有一个大型(独立于 IntelliJ)项目,我们称之为MyLang,用 Scala 编写,为自定义语言提供解析和类型检查。

一个主要问题是我们希望插件与MyLang依赖的特定来源分离,但是我们拥有或被告知的所有尝试和想法都有缺陷。

tl; 博士:有没有办法在 IntelliJ 插件中实现用户可选择的运行时 Java 依赖项来实现以下目标?

目标

  1. 将插件与实际使用的MyLang依赖源解耦(因此也与版本,至少是非主要的)解耦
  2. 能够让MyLang依赖项指向本地 JAR 和/或编译的源目录。

    基本原理是让开发人员MyLang使用插件测试他们的最新更改。例如,如果一位开发人员改进了MyLang语言中的类型检查,那么他可能希望立即在 IntelliJ 中对其进行测试以获得视觉反馈。
  3. 非关键:能够为MyLang每个 IntelliJ 项目配置依赖项。

    该插件提供了一个自定义项目类型。插件范围的设置并不完美,但可以接受。
  4. 能够使用MyLang插件中的数据结构(即类和函数)。

尝试/想法

  1. 部署具有MyLang依赖项的插件

    • ✅ 1, 2, 3
    • ❌ 4
    • ❌ 插件变得非常大。
  2. 部署不带插件的插件MyLang,让用户选择MyLang构建 JAR 并使用反射。

    • ✅ 1, 2, 3
    • ❌ 4,插件中特别丑陋且非类型安全的代码。
    • ❌ 只能通过反射通道传递来自 Java 或 Scala 标准 API 的基本数据结构。
  3. 针对 (stable) 编译插件MyLang,无需部署并使用类加载器魔法

    1. 选项 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. 选项 2:创建自定义的parent-last-child-first 类加载器
      • ✅ 1、2、3、4(全部!)
      • ❌ 拥有 IntelliJ 的类加载器和新的类加载器会让插件开发人员感到困惑,并且很容易出错!必须非常谨慎地将实例从新创建的类加载器外部传递到其内部。例如,来自 IntelliJ 提供的数据结构的实例(编辑器组件、PSIFile 实例……)仅在旧的普通 IntelliJ 插件类加载器中有效。
        因此,访问 IntelliJ 数据结构几乎是不可能的

IntelliJ 论坛中有一个(未解决的)讨论,其中 OP 需要完全相同的设置:https ://intellij-support.jetbrains.com/hc/en-us/community/posts/206121299-classloader-in-plugin

标签: javajardependenciesclassloaderintellij-plugin

解决方案


推荐阅读