如何在Scala编译器插件中以文本形式生成新的源代码? [英] How do I generate new source code in text form in a Scala compiler plugin?

查看:104
本文介绍了如何在Scala编译器插件中以文本形式生成新的源代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have just finished the first version of a Java 6 compiler plugin, that automatically generates wrappers (proxy, adapter, delegate, call it what you like) based on an annotation.

因为我在做混合Java / Scala项目,我想能够在我的Scala代码中使用相同的注释,并获得相同的生成代码(当然在Scala除外)。这基本上意味着从头开始。

Since I am doing mixed Java/Scala projects, I would like to be able to use the same annotation inside my Scala code, and get the same generated code (except of course in Scala). That basically means starting from scratch.

我想做什么,我还没有找到一个例子,是如何生成的代码里面Scala编译器插件以与Java编译器插件相同的方式。也就是说,我匹配/找到我的注释使用,获取注释接口的AST,然后请求API给我一个Stream / Writer,其中我输出生成的Scala源代码,使用String处理。

What I would like to do, and for which I haven't found an example yet, is how do I generate the code inside a Scala compiler plugin in the same way as in the Java compiler plugin. That is, I match/find where my annotation is used, get the AST for the annotated interface, and then ask the API to give me a Stream/Writer in which I output the generated Scala source code, using String manipulation.

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

That last part is what I could not find. So how do I tell the API to create a new Scala source file, and give me a Stream/Writer/File/Handle, so I can just write in it, and when I'm done, the Scala compiler compiles it, within the same run in which the plugin was invoked?

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

Why would I want to do that? Firstly, because than both plugins have the same structure, so maintenance is easy. Secondly, I want to open source it, and there is just no way to support every option that anyone would want, so I expect potential users to want to extend the generation with their own code. This will be a lot easier for them if they just have to do some printf(), instead of learning the AST API (this also applies to me).

推荐答案

简短答案

无法完成

长回答:

您可以想象生成源文件并通过插件中的解析器实例推送。但不是以任何方式,可能对你有任何用途,因为你现在有一个更大的问题来应对:

You could conceivably generate your source file and push that through a parser instance within your plugin. But not in any way that's likely to be of any use to you, because you'd now have a bigger problem to contend with:

为了抓住所有类型/ name信息生成delagate /代理,你必须在注释类型的AST运行后通过namer和typer阶段(它们是不可分离的)来获取。捕获是,任何尝试调用您生成的代码已经失败类型检查,编译器将抛出一个错误,任何进一步的赌注关闭。

In order to grab all the type/name information for generating the delagate/proxy, you'll have to pick up the annotated type's AST after it has run through both the namer and typer phases (which are inseperable). The catch is that any attempts to call your generated code will already have failed typechecking, the compiler will have thrown an error, and any further bets are off.

方法合成是可能的,在有限的情况下,只要你能以某种方式欺骗typechecker只是足够长的时间来生成你的代码,这是我用 Autoproxy'lite'插件。即使这样,你最好还是使用 TreeDSL 来生成代码,而不是输出原始源。

Method synthesis is possible in limited cases, so long as you can somehow fool the typechecker for just long enough to get your code generated, which is the trick I pulled with my Autoproxy 'lite' plugin. Even then, you're far better off working with TreeDSL to generate code instead of pumping out raw source.

这篇关于如何在Scala编译器插件中以文本形式生成新的源代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆