Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating Scala code trees from a Scala compiler plugin

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().+("!"))))
like image 527
Yang Avatar asked Feb 12 '10 04:02

Yang


2 Answers

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))
  }
}
like image 70
retronym Avatar answered Dec 04 '22 09:12

retronym


you might find something in this project: http://github.com/scala-incubator/autoproxy-plugin

like image 35
BenjaminJackman Avatar answered Dec 04 '22 08:12

BenjaminJackman