Yan*_*ang 7 compiler-construction plugins code-generation scala
这里有一些 资源是书面的Scala编译器插件对代码模式匹配启发在网络上,但这些并不在生成代码(构建符号树)帮助.我应该在哪里开始弄清楚如何做到这一点?(如果有一种比手动构建符号树更简单的方法,我也会感兴趣.)
例如,我想编写一个插件,用这个表达式的简单AST替换一些代码,其中变量(从原始程序代码中提取)可以是任何类型:
"" + hello + ", " + world + "!"
Run Code Online (Sandbox Code Playgroud)
我意识到这可能是棘手的,因为拳击toString,例如,如果
hello是一个对象,并且world是一个int,这应该是这样的:
"".+(hello.toString().+(", ".+(new Integer(world).toString().+("!"))))
Run Code Online (Sandbox Code Playgroud)
如果您在编译器阶段之前生成树erasure,则可以键入helloand worldwith Any,然后调用toString它们。
~: cat test.scala
object test {
def f(hello: Any, world: Any) = "" + hello + ", " + world + "!"
f("1", "2")
f(1, 1)
}
~: scalac -Xprint:typer test.scala
[[syntax trees at end of typer]]// Scala source: test.scala
package <empty> {
final object test extends java.lang.Object with ScalaObject {
def this(): object test = {
test.super.this();
()
};
def f(hello: Any, world: Any): java.lang.String = "".+(hello).+(", ").+(world).+("!");
test.this.f("1", "2");
test.this.f(1, 1)
}
}
~: scalac -Xprint:erasure test.scala
[[syntax trees at end of erasure]]// Scala source: test.scala
package <empty> {
final class test extends java.lang.Object with ScalaObject {
def this(): object test = {
test.super.this();
()
};
def f(hello: java.lang.Object, world: java.lang.Object): java.lang.String = "".+(hello).+(", ").+(world).+("!");
test.this.f("1", "2");
test.this.f(scala.Int.box(1), scala.Int.box(1))
}
}
Run Code Online (Sandbox Code Playgroud)