如何获取 scala 宏来替换方法调用?
我的目标是创建一个名为ToStringAdder
. 假设我有一个x
具有此特征的对象,那么当我调用时,x.add(any)
我希望宏实际调用x.add(any, string)
字符串是 AST 的字符串表示形式的位置。(这样tostring
当'any'是一个函数时我可以很好)。
- 我已经编写了文档 http://docs.scala-lang.org/overviews/macros/overview.html中给出的宏,
- 阅读http://docs.scala-lang.org/sips/pending/self-cleaning-macros.html
- 阅读 PDF http://scalamacros.org/paperstalks/2013-04-22-LetOurPowersCombine.pdf。
- 我查看了https://github.com/retronym/macrocosm/blob/master/src/main/scala/com/github/retronym/macrocosm/Macrocosm.scala中的代码
- 以及https://github.com/pniederw/expecty/tree/master/src/main/scala/org/expecty中的代码 ,但我很遗憾地说我没有完全理解
- 我看过 scaladoc,但是……哇……这很复杂……我怀疑我需要一些重要的时间来了解编译器的工作原理。
除了 Expecty,我看到的所有这些例子都有效地使用了静态方法调用:调用宏的对象没有被使用。Expecty 具有以下方法,它为我提供了有关如何检测“隐式 this”的线索,但我找不到在 reify 调用中引用它的方法。
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 ) }
}
}