如何獲得一個scala宏以替換方法調用?如何獲得一個scala宏以替換方法調用
我的目標是創建一個名爲ToStringAdder
的特徵。假設我有一個具有此特徵的對象x
,那麼當我呼叫x.add(any)
時,我希望宏實際調用x.add(any, string)
,其中字符串是AST的字符串表示形式。 (當'any'是一個函數時,這樣我可以有很好的tostring
)。
- 我寫的文檔 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,但。 ..woo ..這很複雜...我懷疑我需要一些重要的時間來加快編譯器的工作速度。
除了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([email protected](_), y) if getPosition(expr).point == getPosition(x).point => expr
case _ => recordValue(recordSubValues(expr), expr)
}
那麼我該如何去取代調用宏的對象的調用。我此刻的代碼如下,它是需要進行排序
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) }
}
}
這是,如果我理解正確的一個非常好的問題。我相信這一點是,如果函數上的toString返回一個唯一的AST,則可以在'Function'上實現一個相等運算符。然後可以做一些很棒的事情,比如不用擔心List中的函數重複 - 只需調用toSet。 – samthebest 2013-12-01 12:45:42