你的原Tree
是這樣的:
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> showRaw{ reify { def foo = { true } }.tree }
res0: String = Block(List(DefDef(Modifiers(), newTermName("foo"), List(), List(), TypeTree(), Literal(Constant(true)))), Literal(Constant(())))
無外Block
:
scala> showRaw{ reify { def foo = { true } }.tree match { case Block(List(defdef), _) => defdef } }
res1: String = DefDef(Modifiers(), newTermName("foo"), List(), List(), TypeTree(), Literal(Constant(true)))
所以你rhs
變量不是Block
。
所以,你應該用Block(createPrintln, t)
更換//Manage functions without block
我猜你transform
方法應該返回DefDef
,不Block
。
def addPrintln(t: Tree): Block = t match {
case b :Block => treeCopy.Block(b, createPrintln :: b.stats, b.expr)
case t => Block(createPrintln, t)
}
override def transform(tree: Tree) = tree match {
case defdef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
treeCopy.DefDef(defdef, mods, name, tparams, vparamss, tpt, addPrintln(rhs))
case t => super.transform(t)
}
測試:
scala> def createPrintln = Apply(Select(Ident("System.out"), newTermName("println")), List(Literal(Constant("foo"))))
createPrintln: reflect.runtime.universe.Apply
scala> def addPrintln(t: Tree): Block = t match {
| case b :Block => treeCopy.Block(b, createPrintln :: b.stats, b.expr)
| case t => Block(createPrintln, t)
| }
addPrintln: (t: reflect.runtime.universe.Tree)reflect.runtime.universe.Block
scala> def transform(tree: Tree) = tree match {
| case defdef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
| treeCopy.DefDef(defdef, mods, name, tparams, vparamss, tpt, addPrintln(rhs))
| }
transform: (tree: reflect.runtime.universe.Tree)reflect.runtime.universe.DefDef
scala> val defdef = reify { def foo = { true } }.tree match { case Block(List(defdef), _) => defdef }
defdef: reflect.runtime.universe.Tree = def foo = true
scala> transform(defdef)
res0: reflect.runtime.universe.DefDef =
def foo = {
System.out.println("foo");
true
}
UPD:
super.transform
調用父類的實現。有關代碼,請參見internal implementation。
@senia對於熟悉Scala AST的人來說,這可能是顯而易見的,但對我來說不是,我想了解更多:什麼是'treeCopy'? 'transform'方法覆蓋或實現什麼類或接口? (可以在答案中的代碼更完整或鏈接到相關文檔?) – Suma 2015-05-14 12:09:31