如何在Scala编译器插件中以文本形式生成新的源代码?

Seb*_*iot 8 compiler-construction plugins scala

我刚刚完成了Java 6编译器插件的第一个版本,它基于注释自动生成包装器(代理,适配器,委托,根据需要调用它).

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

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

最后一部分是我找不到的.那么我如何告诉API创建一个新的Scala源文件,并给我一个Stream/Writer/File/Handle,所以我可以写进去,当我完成后,Scala编译器会编译它,在同一个插件被调用的运行?

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

Kev*_*ght 5

简短回答:

它无法完成

答案很长:

您可以想象生成源文件并通过插件中的解析器实例推送它.但是对你没有任何用处,因为你现在有一个更大的问题需要应对:

为了获取生成delagate/proxy的所有类型/名称信息,在通过命名器和typer阶段(不可分离)之后,你必须选择带注释类型的AST.问题是,任何调用生成的代码的尝试都已经失败了类型检查,编译器将抛出错误,并且任何进一步的投注都会关闭.

在有限的情况下,方法合成可能的,只要你能够以某种方式欺骗类型检查器足够长的时间来生成代码,这就是我使用我的Autoproxy'lite'插件获取的技巧.即便如此,你最好还是TreeDSL在生成代码而不是抽出原始资源.