使用Eclipse构建DSL时,增量编译的最佳方法是什么?

时间:2011-04-22 19:14:56

标签: eclipse-plugin incremental-build incremental-linking incremental-compiler

正如Eclipse文档所建议的那样,我有一个org.eclipse.core.resources.IncrementalProjectBuilder来编译每个源文件,我还有一个org.eclipse.ui.editors.text.TextEditor可以编辑每个源文件。每个源文件都编译到自己的编译单元中,但它可以引用其他(已编译的)源文件中的类型。

这个重要的两个任务是:

  1. 编译(以确保我们使用的类型确实存在)
  2. 自动填充(查找类型,以便我们可以看到它上面存在哪些属性/方法)
  3. 为了实现这一点,我想在内存中存储所有已编译类型的表示(以下称为“类型存储”)。

    我的问题有两个:

    1. 上面的任务1由构建器执行,第二个任务由编辑器执行。因此,他们都可以访问这种类型的商店,我应该创建一个他们都可以访问的静态存储,还是Eclipse提供了一种更简洁的方法来处理这个问题?请注意,在需要时,实例化构建器和编辑器是eclipse,而不是我。

    2. 打开eclipse时,我不想重建整个项目,所以我可以重新填充我的类型存储。到目前为止,我最好的解决方案是将这些数据保存在某处,然后从那里重新填充我的商店(也许在项目打开时)。这是其他增量编译器通常如何做到这一点的吗?我相信Java的方法是使用一个特殊的解析器,从类文件中有效地提取这些数据。

    3. 任何见解都会非常感激。这是我的第一个DSL。

1 个答案:

答案 0 :(得分:2)

这是一个有趣的问题,并没有一个简单的解决方案。我将尝试描述一个潜在的解决方案,并详细描述JDT如何完成增量编译。

首先,关于JDT:

是的,JDT确实读取了类文件的一些信息,但仅适用于没有源代码的库。此信息实际上仅用于编辑帮助(内容辅助,导航等)。

JDT通过在编译时跟踪编译单元之间的依赖关系来计算增量编译。此状态信息存储在磁盘上,并在每次编译后检索和更新。

作为一个更完整的例子,让我们说在完整构建之后,JDT确定A.java依赖于B.java,它依赖于C.java。

如果C.java中存在结构更改(结构更改是可能影响外部文件的更改(例如,添加/删除非私有字段或方法)),则B .java将被重新编译。 A.java将重新编译,因为B.java没有结构变化。

在对JDT的工作原理进行一些澄清之后,这里有一些可能的问题答案:

  1. 是。这必须通过静态可访问的全局对象来完成。 JDT通过JavaCore和JavaModelManager对象完成此操作。如果您不想使用全局单例,那么您可以通过插件的Bundle激活器实例访问您的类型存储。 e4项目确实允许依赖注入,这可能更好(但实际上并不是核心Eclipse API的一部分)。
  2. 我认为坚持文件系统的信息是你最好的选择。确定增量编译依赖关系的唯一真正方法是执行完整构建,因此您需要在某处保留信息。同样,JDT就是这样做的。该信息存储在org.eclipse.core.resources插件中某处的工作区'.metadata目录中。您可以查看org.eclipse.jdt.internal.core.builder.State类以查看实现。
  3. 所以,这可能不是您正在寻找的答案,但我认为这是解决您问题的最有希望的方法。