2013-11-14 44 views
0

我需要向应用程序中的某些其他方法添加一个方法。有相当多的人。除了直接的方法之外,是否有任何明智的方法来执行此操作 - 手动将方法调用插入到每个方法中?将一个方法调用插入许多其他方法

+3

见[此答案](http://stackoverflow.com/a/19972102/406435)。您也可以使用[宏注释](http://stackoverflow.com/a/19971700/406435)在编译时自动重写方法。 – senia

回答

4

参见this answerdef macros执行。

实现与macro annotations

import scala.reflect.macros.Context 
import scala.language.experimental.macros 

def wrappedImpl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { 
    import c.universe._ 
    import scala.reflect.internal.Flags._ 

    object DefMods{ 
    def unapply(mods: Modifiers): Option[Modifiers] = { 
     val fs = mods.flags.asInstanceOf[Long] 
     if ((fs & DEFERRED) == 0 && (fs & STABLE) == 0) Some(mods) 
     else None 
    } 
    } 

    def wrap(t: Tree) = t match { 
    case DefDef(DefMods(mods), name, tparams, vparams, tpt, body) if name != nme.CONSTRUCTOR => 
     DefDef(mods, name, tparams, vparams, tpt, 
      q""" 
       println("before") 
       val res = $body 
       println("after") 
       res""") 
    case x => x 
    } 

    def transform(t: Tree) = t match { 
    case ClassDef(mods, name, tparams, Template(parents, self, methods)) => 
     ClassDef(mods, name, tparams, Template(parents, self, methods.map{wrap(_)})) 
    case x => x 
    } 

    c.Expr[Any](Block(annottees.map(_.tree).map(transform(_)).toList, Literal(Constant(())))) 
} 

import scala.annotation.StaticAnnotation 
class wrapped extends StaticAnnotation { 
    def macroTransform(annottees: Any*) = macro wrappedImpl 
} 

你必须使用一个compiler plugin为quasiquotes。

用法:

@wrapped class Test { 
    def test() = println("test") 
} 

scala> new Test().test() 
before 
test 
after 
相关问题