我一直在試圖編寫一個分析遍歷代碼的某些部分的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所建議的那樣,問題根源在於有問題的蛋糕(反)模式。 –