指定工具箱解析的 AST 的来源
Specifying the Source of Toolbox-parsed AST
我正在使用 Scala 编译器 API 的工具箱将代码编译成 AST,然后 dissecting/splicing 它们并将它们组合成一棵树。出于调试目的,我正在尝试跟踪哪些节点来自哪些源代码。
示例:
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
// obtain toolbox
val tb = runtimeMirror(this.getClass.getClassLoader).mkToolBox()
// get and parse source code from file
val myCode = scala.io.Source.fromFile("MyCode.scala").mkString
val myTree = tb.parse(myCode)
// get and parse dynamically-generated source code
val genCode = com.example.CodeGenerator.gimmeCode
val genTree = tb.parse(genCode)
// get and parse source code from a string literal
val literalCode = """println("to life, the universe, and everything")"""
val literalTree = tb.parse(literalCode)
// an over-simplified combination of the trees
val frankensteinsTree = q"$myTree;$genTree;$literalTree"
// walk the tree an print the source of each element
val traverser = new Traverser() {
override def traverse(tree: Tree): Unit = {
println("This node originated from " + tree.pos.source)
super.traverse(tree)
}
}
// the root element prints "This node originated from <no source file>"
// the rest print "This node originated from <toolbox>"
traverser.traverse(frankensteinsTree)
在上面的例子中,除了根节点之外的所有节点都显示源是 <toolbox>
。 (根节点表示<no source file>
。)在分解和重新组合它们之前,有没有办法指定tree.pos.source来识别每个节点的实际来源?
你是说
println("Position is: " + "MyCode" + tree.pos.toString.stripPrefix("source-<toolbox>"))
// Position is: MyCode,line-1,offset=7
?
尝试
val p = tree.pos
val pointMessage = if (p.point > p.source.length) "out-of-bounds-" else "offset="
println(
s"source-${p.source.file.canonicalPath},INSERT WHAT YOU WANT,line-${p.line},$pointMessage${p.point}"
) // source-<toolbox>,INSERT WHAT YOU WANT,line-1,offset=7
不,目前(截至 2020-05-28)无法完成。
我正在使用 Scala 编译器 API 的工具箱将代码编译成 AST,然后 dissecting/splicing 它们并将它们组合成一棵树。出于调试目的,我正在尝试跟踪哪些节点来自哪些源代码。
示例:
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
// obtain toolbox
val tb = runtimeMirror(this.getClass.getClassLoader).mkToolBox()
// get and parse source code from file
val myCode = scala.io.Source.fromFile("MyCode.scala").mkString
val myTree = tb.parse(myCode)
// get and parse dynamically-generated source code
val genCode = com.example.CodeGenerator.gimmeCode
val genTree = tb.parse(genCode)
// get and parse source code from a string literal
val literalCode = """println("to life, the universe, and everything")"""
val literalTree = tb.parse(literalCode)
// an over-simplified combination of the trees
val frankensteinsTree = q"$myTree;$genTree;$literalTree"
// walk the tree an print the source of each element
val traverser = new Traverser() {
override def traverse(tree: Tree): Unit = {
println("This node originated from " + tree.pos.source)
super.traverse(tree)
}
}
// the root element prints "This node originated from <no source file>"
// the rest print "This node originated from <toolbox>"
traverser.traverse(frankensteinsTree)
在上面的例子中,除了根节点之外的所有节点都显示源是 <toolbox>
。 (根节点表示<no source file>
。)在分解和重新组合它们之前,有没有办法指定tree.pos.source来识别每个节点的实际来源?
你是说
println("Position is: " + "MyCode" + tree.pos.toString.stripPrefix("source-<toolbox>"))
// Position is: MyCode,line-1,offset=7
?
尝试
val p = tree.pos
val pointMessage = if (p.point > p.source.length) "out-of-bounds-" else "offset="
println(
s"source-${p.source.file.canonicalPath},INSERT WHAT YOU WANT,line-${p.line},$pointMessage${p.point}"
) // source-<toolbox>,INSERT WHAT YOU WANT,line-1,offset=7
不,目前(截至 2020-05-28)无法完成。