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

发布于 2024-11-02 22:21:04 字数 716 浏览 1 评论 0原文

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

这对于两个任务来说很重要:

  1. 编译(以确保我们使用的类型实际存在)
  2. 自动完成(查找类型,以便我们可以看到其中存在哪些属性/方法)

为了完成此任务,我想将所有已编译类型的表示存储在内存中(下面称为我的“类型存储”)。

我的问题有两个:

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

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

任何见解将非常感激。这是我的第一个 DSL。

As suggested by the Eclipse documentation, I have an org.eclipse.core.resources.IncrementalProjectBuilder that compiles each source file and separately I also have a org.eclipse.ui.editors.text.TextEditor that can edit each source file. Each source file is compiled into its own compilation unit, but it can reference types from other (already compiled) source files.

Two tasks for which this is important are:

  1. Compiling (to make sure the types we're using actually exist)
  2. Autocomplete (to look up the type so we can see what properties/methods are present on it)

To accomplish this, I want to store a representation of all the compiled types in memory (referred to below as my "type store").

My question is two fold:

  1. Task one above is performed by the builder and task two by the editor. So that they both have access to this type store, should I create a static store somewhere that they both can have access to, or does Eclipse provide a neater way to deal with this problem? Note that it is eclipse, not me, that instantiates the builders and editors when they are needed.

  2. When opening eclipse, I don't want to have to rebuild the whole project just so I can re-populate my type store. My best solution so far is to persist this data somewhere and then repopulate my store from that (perhaps upon project open). Is this how other incremental compilers typically do this? I believe Java's approach is to use a special parser that efficiently extracts this data from the class files.

Any insights would be really appreciated. This is my first DSL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月苍老的讽刺 2024-11-09 22:21:04

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

首先,了解一下 JDT:

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

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

作为一个更完整的示例,假设在完整构建之后,JDT 确定 A.java 依赖于 B.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 类来查看实现。

因此,这可能不是您正在寻找的答案,但我认为这是解决您的问题最有希望的方法。

This is an interesting question and one that doesn't have a simple solution. I'll try to describe a potential solution and also describe in a little bit more detail how JDT accomplishes incremental compilation.

First, a bit about JDT:

Yes, JDT does read class files for some of its information, but only for libraries that don't have source code. And this information is really only used for editing assistance (content assist, navigation, etc).

JDT computes incremental compilation by keeping track of dependencies between compilation units as they are compiled. This state information is stored on disk and retrieved and updated after each compile.

As a more complete example, let's say that after a full build, JDT determines that A.java depends on B.java, which depends on C.java.

If there is a structural change in C.java (a structural change is a change that can affect outside files (e.g., adding/removing a non-private field or method)), then B.java will be recompiled. A.java will not be recompiled since there was no structural change in B.java.

After this bit of clarification on how JDT works, here are some possible answers to your questions:

  1. Yes. This must be done through statically accessible global objects. JDT does this through the JavaCore and JavaModelManager objects. If you don't want to use global singletons, then you can access to your type store available through your plugin's Bundle activator instance. The e4 project does allow dependency injection, which is probably even better (but is not really a part of the core Eclipse APIs).
  2. I think persisting the information on the file system is your best bet. The only real way to determine incremental compile dependencies is to do a full build, so you need to persist the information somewhere. Again, this is how JDT does it. The information is stored in your workspaces' .metadata directory somewhere in the org.eclipse.core.resources plugin. You can have a look at the org.eclipse.jdt.internal.core.builder.State class to see the implementation.

So, this may not be the answer you are looking for, but I think this is the most promising way to approach your problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文