템플릿 플러그인을 만들고 첫 번째 단계에서 임의의 문자열을 "컴파일 된"AST 표현으로 변환하고 싶습니다. (스칼라 인터프리터는 그렇듯이). 그래서 컴파일러 플러그인 예를 들어 someString을 할당 할 수 있습니다에 "HELLO WORLD"CompilerPlugin에서 AST에 문자열을 컴파일 하시겠습니까?
- runafter 파서
- 는 컴파일러와 VirtualFile을 새로운 표현을 만들어 :
@StringAnnotation("""("hello world").toString.toUpperCase""") var someString = ""
나의 현재 첫 번째 촬영 플러그인은 짧은 않습니다 주석 함량이
- 컴파일 및 인쇄 unit.body
참조 :예 : "object o{val x = 0}"
은 AST를 반환하지만 "var x = 1+ 2"
은 유효한 .scala 파일이 아니기 때문에 유효하지 않습니다. 이 문제를 어떻게 해결할 수 있습니까?
b) 전용 프레젠테이션은 좋은 선택입니까? 대신 적절한 단계로 computeInternalPhases를 재정의하거나 -Ystop : phase를 사용해야합니까?
c) 외부 컴파일러의 환경을 내부 컴파일러의 환경에 바인딩 할 수 있습니까?
var x = _
(...)
@StringAnnotation("x += 3")
?
나는 [1] 비슷한 무언가를 통역 하나 개의 변수를 사용하여 다음과 같은 코드를 발견
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)");
감사
전체 코드 :
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))
}
}
}