2011-01-26 18 views
6

Tôi muốn tạo một plugin tạo khuôn mẫu và khi bước đầu tiên chuyển đổi một chuỗi tùy ý thành biểu diễn AST "được biên dịch" (như trình thông dịch scala, tôi đoán). Vì vậy, một plugin trình biên dịch có thể ví dụ như gán someString để "HELLO WORLD":Biên dịch chuỗi thành AST bên trong CompilerPlugin?

@StringAnnotation("""("hello world").toString.toUpperCase""") 
    var someString = "" 

hiện đầu tiên Plugin bắn của tôi làm trong ngắn hạn:

  • runafter phân tích cú pháp
  • tạo ra một đại diện mới chỉ biên dịch và một VirtualFile với nội dung chú thích
  • đơn vị biên dịch và in.body

xem: http://paste.pocoo.org/show/326025/

a) Ngay bây giờ, "object o{val x = 0}" trả về AST, nhưng ví dụ: "var x = 1+ 2" không phải vì nó không phải là tệp .scala hợp lệ. Làm thế nào tôi có thể sửa lỗi này?

b) Chỉ có trình bày một lựa chọn tốt? Thay vào đó tôi có nên ghi đè lên computeInternalPhases với các giai đoạn thích hợp hoặc sử dụng -Ystop: phase?

c) Có thể liên kết môi trường của trình biên dịch bên ngoài với trình biên dịch bên trong hay không, ví dụ:

var x = _ 
    (...) 
    @StringAnnotation("x += 3") 

sẽ hoạt động?

tôi thấy mã sau [1] sử dụng một thông dịch viên và một biến mà làm điều gì đó tương tự:

Interpreter interpreter = new Interpreter(settings); 
    String[] context = { "FOO" }; 
    interpreter.bind("context", "Array[String]", context); 
    interpreter 
    .interpret("de.tutorials.scala2.Test.main(context)"); 
    context[0] = "BAR"; 
    interpreter 
    .interpret("de.tutorials.scala2.Test.main(context)"); 

[1] http://www.tutorials.de/java/320639-beispiel-zur-einbindung-des-scala-interpreters-kompilierte-scala-anwendungen.html#post1653884

nhờ

Hoàn thành Code:

class AnnotationsPI(val global: Global) extends Plugin { 
    import global._ 
    val name = "a_plugins::AnnotationsPI" //a_ to run before namer 
    val description = "AST Trans PI" 
    val components = List[PluginComponent](Component) 

    private object Component extends PluginComponent with Transform with TypingTransformers with TreeDSL { 
    val global: AnnotationsPI.this.global.type = AnnotationsPI.this.global 
    val runsAfter = List[String]("parser"); 
    val phaseName = AnnotationsPI.this.name 

    def newTransformer(unit: CompilationUnit) = { 
     new AnnotationsTransformer(unit) 
    } 

    val SaTpe = "StringAnnotation".toTypeName 

    class AnnotationsTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { 

     /** When using <code>preTransform</code>, each node is 
     * visited before its children. 
     */ 
     def preTransform(tree: Tree): Tree = tree match { 
     case [email protected](Modifiers(_, _, List(Apply(Select(New(Ident(SaTpe)), _), List(Literal(Constant(a))))), _), b, c, d) => //Apply(Select(New(Ident(SaTpe)), /*nme.CONSTRUCTOR*/_), /*List(x)*/x) 
      val str = a.toString 
      val strArr = str.getBytes("UTF-8") 
      import scala.tools.nsc.{ Global, Settings, SubComponent } 
      import scala.tools.nsc.reporters.{ ConsoleReporter, Reporter } 

      val settings = new Settings() 
      val compiler = new Global(settings, new ConsoleReporter(settings)) { 
      override def onlyPresentation = true 
      } 

      val run = new compiler.Run 
      val vfName = "Script.scala" 
      var vfile = new scala.tools.nsc.io.VirtualFile(vfName) 

      val os = vfile.output 
      os.write(strArr, 0, str.size) // void write(byte[] b, int off, int len) 
      os.close 
      new scala.tools.nsc.util.BatchSourceFile(vfName, str) 
      run.compileFiles(vfile :: Nil) 
      for (unit <- run.units) { 
      println("Unit: " + unit) 
      println("Body:\n" + unit.body) 
      } 
      tree 

     case _ => 
      tree 
     } 

     override def transform(tree: Tree): Tree = { 
     super.transform(preTransform(tree)) 
     } 
    } 
    } 

Trả lời

1

Tôi không biết nếu điều này giúp bạn nhiều, nhưng thay vì fiddl ing với thông dịch viên, bạn có thể sử dụng treeFrom (aString) là một phần của dự án tái cấu trúc lại scala (http://scala-refactoring.org/). không trả lời câu hỏi của bạn về các liên kết chéo, mặc dù ...

Các vấn đề liên quan