There are a few resources on the web that are instructive in writing Scala compiler plugins that pattern-match against the code, but these don't help in generating code (constructing symbol trees). Where should I start to figure out how to do this? (If there's an easier way than to manually build symbol trees, I'd be interested as well.)
For instance, I'd like write a plugin that replaces some code with a simple AST for this expression, where the variables (extracted from the original program code) could be of any type:
"" + hello + ", " + world + "!"
I realize this may be tricky because of boxing and toString
, e.g. if
hello
were an object and world
were an int, this should really be
something like:
"".+(hello.toString().+(", ".+(new Integer(world).toString().+("!"))))
If you generate the tree before the erasure
compiler phase, you can type hello
and world
with Any
, and call toString
on them.
~: 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))
}
}
you might find something in this project: http://github.com/scala-incubator/autoproxy-plugin
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With