1
非常简单的宏compat支持的宏注释。Scala宏:ValDef的派生类型签名
def impl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
annottees.map(_.tree) match {
case (classDef @ q"$mods class $tpname[..$tparams] $ctorMods(...$params) extends { ..$earlydefns } with ..$parents { $self => ..$stats }")
:: Nil if mods.hasFlag(Flag.CASE) =>
val name = tpname.toTermName
val typeName = tpname.toTypeName
val res = q"""
$classDef
object $name {
..${doStuff(c)(typeName, name, params.head)}
}
"""
c.Expr[Any](res)
case _ => c.abort(c.enclosingPosition, "Invalid annotation target, this must be a case class")
}
}
因此,所有非常简单直接的乐趣。引起问题的位来自上面的$params
,它们只是List[List[ValDef]]
,即不知何故类型签名会丢失。
def accessors(c: blackbox.Context)(
params: Seq[c.universe.ValDef]
): Iterable[(c.universe.TermName, c.universe.TypeName)] = {
import c.universe._
params.map {
case ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) => {
// tpt.tpe = kaboom, null pointer
name -> TypeName(tpt.tpe.typeSymbol.fullName)
}
}
}
上ValDef
的tpe
回来为null
,所以DEFS不会打字,但我需要的则params的类型签名,以达到我想要的。如何在没有炸毁的情况下获得参数的类型签名?
具有讽刺意味的是,showCode(tpt)
不会产生正确的字符串,所以这可以解决TypeName(tpt.toString)
,但我不知道为什么tpe
不可访问。
你可能想看看在这个问题的答案和尤金Burmako的评论:http://stackoverflow.com/questions/23671379/proper-way-to-pattern-match-the- VALU电子对的一typetree-从-A-valdef合阶宏 –