我一直在尝试编写一个 Scala (2.10.0) 编译器插件来分析遍历代码的某些部分。
这是我最初拥有的:
class MyPlugin (val global: Global) extends Plugin {
import global._
val name = "myPlugin"
val components = List[PluginComponent](MyComponent)
private object MyComponent extends PluginComponent {
val global: MyPlugin.this.global.type = MyPlugin.this.global
val runsAfter = List ("refchecks")
val phaseName = "codeAnalysis"
def newPhase (_prev: Phase) = new AnalysisPhase (_prev)
class AnalysisPhase (prev: Phase) extends StdPhase (prev) {
override def name = phaseName
def apply (unit: CompilationUnit) {
codeTraverser traverse unit.body
printLinesToFile(counters.map{case (k,v) => k + "\t" + v},out)
}
def codeTraverser = new ForeachTreeTraverser (tree => /* Analyze tree */)
}
}
}
此代码按预期工作,但我不喜欢它,因为我无法将代码遍历器方法与此对象分离。我想编写一个单独的CodeTraverser
类来对给定的树执行分析。除其他外,这可能会帮助我更好地测试此代码。
主要问题是unit.body
内部的 Tree 类型scala.reflect.internal.Trees
。如果我可以使用scala.reflect.api.Trees#Tree
而不是内部版本,我可以解耦遍历器功能,甚至可以很容易地对其进行测试。
我试图找到一种在两者之间转换的方法,但无济于事。甚至可能吗?从他们的源代码来看,许多事情看起来太相似了,这是不可能的。