我一直在试图编写一个分析遍历代码的某些部分的Scala(2.10.0)编译器插件。Scala编译器插件解构
这是我本来有:
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
是内部树型scala.reflect.internal.Trees
。如果我可以使用scala.reflect.api.Trees#Tree
而不是内部版本,我可以解耦移植程序的功能,甚至可以非常轻松地进行测试。
我试图找到一种方法来转换两者之间,但无济于事。它甚至有可能吗?从他们的源代码看,很多事情看起来太相似了,这是不可能的。
是的,这将解除耦合器与插件的耦合。虽然正如你和som-snytt所建议的那样,问题根源在于有问题的蛋糕(反)模式。 –