我正在尝试制作一个提供最新案例类的类型提供者。
如何拼接类型和默认值(或忽略默认值)?
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
import Flag._
val result = {
annottees.map(_.tree).toList match {
case q"$mods class $name[..$tparams](..$first)(...$rest) extends ..$parents { $self => ..$body }" :: Nil =>
val valType = //TODO
val valDefault = //TODO
val helloVal = q"""val x: $valType = $valDefault"""
q"$mods class $name[..$tparams](..$first, $helloVal)(...$rest) extends ..$parents { $self => ..$body }"
}
}
c.Expr[Any](result)
}
我已经尝试了简单的方法val valType = q"String"
,但是随后出现错误,好像找不到默认值:not enough arguments for method apply
我还尝试了将val定义为剪接typeOf[String]
,并且还尝试了将ValDef
s的列表剪接到我的列表中q"$mods class...
(就像我q"def...
在该站点上的一些类似问题中看到的那样),但是在每种情况下都有一个打字机错误。
有小费吗?非常感谢您的光临。
您可以tq
在的定义中使用插值器valType
来创建类型树。
其余的有点棘手。如果直接定义额外的参数,它似乎就可以正常工作:
q"""
$mods class $name[..$tparams](
..$first,
val x: $valType = $valDefault
)(...$rest) extends ..$parents { $self => ..$body }
"""
但是,当您定义$helloVal
然后插入时,最终没有默认参数标志。您可以这样编写一个助手:
def makeDefault(valDef: ValDef) = valDef match {
case ValDef(mods, name, tpt, rhs) => ValDef(
Modifiers(
mods.flags | DEFAULTPARAM, mods.privateWithin, mods.annotations
),
name, tpt, rhs
)
}
现在,您可以编写以下内容:
val valType = tq"String"
val valDefault = q""""foo""""
val helloVal = makeDefault(q"val x: $valType = $valDefault")
一切都应该按预期工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句