开发者

Generating Scala code trees from a Scala compiler plugin

开发者 https://www.devze.com 2022-12-20 03:04 出处:网络
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). W

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 wel开发者_C百科l.)

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


This thread looks relevant: Convert Scala AST to source code

Specifically, you can construct Scala AST with the TreeDSL mentioned. http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/compiler/scala/tools/nsc/ast/TreeDSL.html

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号