我刚刚完成了Java 6编译器插件的第一个版本,该插件会基于注释自动生成包装器(代理,适配器,委托(delegate),将其命名为您喜欢的东西)。

由于我正在执行Java/Scala混合项目,因此我希望能够在我的Scala代码中使用相同的批注,并获得相同的生成代码(当然,在Scala中除外)。这基本上意味着从头开始。

我想做的是如何在Scala编译器插件内生成代码的方式与在Java编译器插件中生成方法相同,并且还没有找到示例。也就是说,我匹配/查找使用注释的位置,获取带注释的接口(interface)的AST,然后要求API给我一个Stream/Writer,在其中使用String操作输出生成的Scala源代码。

最后一部分是我找不到的。因此,我如何告诉API创建一个新的Scala源文件,并给我一个Stream/Writer/File/Handle,这样我就可以编写它了,完成后,Scala编译器会在在调用插件的同一运行?

我为什么要这样做?首先,由于两个插件的结构相同,因此维护很容易。其次,我想将其开源,并且没有任何方法可以支持任何人想要的每个选项,因此我希望潜在的用户希望使用自己的代码扩展这一代。如果他们只需要做一些printf()而不是学习AST API,这对他们来说将容易得多(这也适用于我)。

最佳答案

简短答案:

做不到

长答案:

可以想象,您可以生成源文件,并将其通过插件中的解析器实例推送。但是,这绝不会对您有任何用处,因为您现在需要解决一个更大的问题:

为了获取所有类型/名称信息以生成delagate/proxy,您必须在带注释的类型的AST经历了namer和typer阶段(不可分割)之后,才使用它。问题在于,任何调用您生成的代码的尝试都将失败类型检查,编译器将引发错误,并且所有其他押注都将关闭。

在有限的情况下,方法合成是可能的,只要您可以以某种方式愚弄typechecker足够长的时间来生成代码,这就是我用Autoproxy 'lite' plugin提出的技巧。即使那样,使用TreeDSL生成代码而不是抽出原始源代码也要好得多。

关于scala - 如何在Scala编译器插件中以文本形式生成新的源代码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7625765/

10-12 22:22
查看更多