我刚刚完成了Java 6编译器插件的第一个版本,它根据注释自动生成包装器(代理,适配器,委托,根据需要调用它)。
由于我正在进行混合Java / Scala项目,我希望能够在我的Scala代码中使用相同的注释,并获得相同的生成代码(当然,除了Scala)。这基本上意味着从头开始。
我想做什么,而我还没有找到一个例子,我是如何以与Java编译器插件相同的方式在Scala编译器插件中生成代码的。也就是说,我匹配/找到我的注释使用的位置,获取带注释的接口的AST,然后要求API给我一个Stream / Writer,我在其中输出生成的Scala源代码,使用String操作< / em>的
最后一部分是我找不到的。那么我如何告诉API创建一个新的Scala源文件,并给我一个Stream / Writer / File / Handle,所以我可以写进去,当我完成后,Scala编译器会编译它,在调用插件的同一次运行?
为什么我要这样做?首先,因为两个插件都具有相同的结构,所以维护很容易。其次,我想开源它,并且没有办法支持任何人想要的每个选项,所以我希望潜在用户想要用他们自己的代码扩展生成。如果他们只需要做一些printf(),而不是学习AST API(这也适用于我),这对他们来说会容易得多。
答案 0 :(得分:5)
简答:
无法完成
答案很长:
您可以想象生成源文件并通过插件中的解析器实例推送它。但对你来说没有任何可能有用的东西,因为你现在有一个更大的问题需要应对:
为了获取生成delagate / proxy的所有类型/名称信息,在通过命名器和typer阶段(不可分离)之后,你必须选择带注释类型的AST。问题在于,任何调用生成的代码的尝试都已经失败了类型检查,编译器将抛出错误,并且任何进一步的投注都会关闭。
在有限的情况下,方法合成可能,只要你能以某种方式欺骗类型检查器足够长的时间来生成代码,这就是我用Autoproxy 'lite' plugin提取的技巧。 。即便如此,使用TreeDSL
生成代码而不是抽出原始资源会更好。
答案 1 :(得分:1)
Kevin完全正确,但为了完整性,值得一提的是还有另一种选择 - 编写一个生成源代码的编译器插件。这是我在Borachio中采用的方法。这不是一个非常令人满意的解决方案,但它可以起作用。
编辑 - 我只是重新阅读您的问题并意识到您实际上是在询问有关生成源的信息
所以没有直接支持,但它基本上只是打开文件和编写相关的“打印”语句的问题。没有办法在插件AFAIK“内部”调用编译器,但是我编写了一个sbt plugin,它隐藏了调用编译器两次的大部分复杂性。