您的原件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
.
所以你应该替换//Manage functions without block
为Block(createPrintln, t)
我猜你的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
}
更新:
super.transform
调用父实现。代码见内部实现。