Генерация деревьев кода Scala из плагина компилятора Scala - PullRequest
7 голосов
/ 12 февраля 2010

В сети есть несколько ресурсов , которые поучительны в написании плагинов компилятора Scala, которые сопоставляются с шаблоном по коду, но они не помогают в создании кода деревья символов). С чего мне начать выяснять, как это сделать? (Если есть более простой способ, чем создавать деревья символов вручную, мне также будет интересно.)

Например, я хотел бы написать плагин, который заменяет некоторый код простым AST для этого выражения, где переменные (извлеченные из исходного программного кода) могут быть любого типа:

"" + hello + ", " + world + "!"

Я понимаю, что это может быть сложно из-за бокса и toString, например. если hello был объектом, а world был целым, это действительно должно быть что-то вроде:

"".+(hello.toString().+(", ".+(new Integer(world).toString().+("!"))))

Ответы [ 3 ]

3 голосов
/ 12 февраля 2010

Если вы генерируете дерево до фазы erasure компилятора, вы можете набрать hello и world с 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))
  }
}
2 голосов
/ 14 февраля 2010

вы можете найти что-то в этом проекте: http://github.com/scala-incubator/autoproxy-plugin

1 голос
/ 03 сентября 2011
...