如何获取scala宏来替换方法调用
如何让
scala宏替换方法调用?
我的目标是创建一个名为ToStringAdder的特征.假设我有一个具有此特征的对象x,那么当我调用x.add(any)时,我希望宏实际调用x.add(any,string),其中字符串是AST的字符串表示. (这是因为当’any’是一个函数时,我可以有很好的tostring). >我已经编写了文档中给出的宏 除了Expecty之外,我所看到的所有这些示例都是有效地使用静态方法调用:不使用调用宏的对象. private[this] def recordAllValues(expr: Tree): Tree = expr match { case New(_) => expr // only record after ctor call case Literal(_) => expr // don't record // don't record value of implicit "this" added by compiler; couldn't find a better way to detect implicit "this" than via point case Select(x@This(_),y) if getPosition(expr).point == getPosition(x).point => expr case _ => recordValue(recordSubValues(expr),expr) } 那么我该如何将调用替换为调用宏的对象.我目前的代码如下所示,它是reify调用中需要排序的代码 trait ToStringAdder { def add(param: Any): Any = macro ToStringAdder.toStringAndValueImpl def add(param: Any,toStringBasedOnAST: String): Any ; //This is the actual method I want the above method call to be replaced by } object ToStringAdder { def toStringAndValueImpl(c: Context)(param: c.Expr[Any]): c.Expr[Unit] = { import c.universe._ val paramRep = show(param.tree) val paramRepTree = Literal(Constant(paramRep)) val paramRepExpr = c.Expr[String](paramRepTree) //need to put something here reify { c.someMethodCall("something to represent the method any",param.splice,paramRepExpr.splice ) } } } 解决方法
您可以将ToStringAdder实例的Tree作为c.prefix获取.
试试这个: reify { c.Expr[ToStringAdder](c.prefix.tree).splice.add(param.splice,c.literal(paramRep).splice) } 证明它的工作原理: scala> :paste // Entering paste mode (ctrl-D to finish) import scala.language.experimental.macros import reflect.macros.Context trait ToStringAdder { def add(param: Any): Any = macro ToStringAdder.toStringAndValueImpl def add(param: Any,toStringBasedOnAST: String): Any ; //This is the actual method I want the above method call to be replaced by } object ToStringAdder { def toStringAndValueImpl(c: Context)(param: c.Expr[Any]): c.Expr[Any] = { import c.universe._ val paramRep = show(param.tree) reify { (c.Expr[ToStringAdder](c.prefix.tree)).splice.add(param.splice,c.literal(paramRep).splice) } } } // Exiting paste mode,now interpreting. import scala.language.experimental.macros import reflect.macros.Context defined trait ToStringAdder defined module ToStringAdder scala> class ToStringAdder1 extends ToStringAdder { | def add(param: Any,toStringBasedOnAST: String): Any = s"param: $param ntoStringBasedOnAST: $toStringBasedOnAST" | } defined class ToStringAdder1 scala> new ToStringAdder1().add( (i: Int) => i*2 ) res0: Any = param: <function1> toStringBasedOnAST: ((i: Int) => i.*(2)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |