代码之家  ›  专栏  ›  技术社区  ›  xyzzyrz

从scala编译器插件生成scala代码树

  •  7
  • xyzzyrz  · 技术社区  · 15 年前

    有一个 few resources 在web上编写模式与代码匹配的scala编译器插件是有指导意义的,但是这些对生成代码(构建符号树)没有帮助。我应该从哪里开始想怎么做?(如果有比手动构建符号树更简单的方法,我也会感兴趣的。)

    例如,我想为这个表达式编写一个插件,用一个简单的ast替换一些代码,其中变量(从原始程序代码中提取)可以是任何类型:

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

    我知道这可能很棘手因为拳击和 toString ,例如,如果 hello 是一个物体 world 是智力,这真的应该是 类似于:

    "".+(hello.toString().+(", ".+(new Integer(world).toString().+("!"))))
    
    3 回复  |  直到 12 年前
        1
  •  3
  •   retronym    15 年前

    如果在 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
  •  2
  •   BenjaminJackman    15 年前

    你可能会在这个项目中发现一些东西: http://github.com/scala-incubator/autoproxy-plugin