我有内插器xxx
是由宏实现的(我确实拥有代码)并返回XXX。我想在有函数yyy
f: XXX => YYY
代码
class XXXMacro(val c: blackbox.Context) {
import c.universe._
final def xxx(args: c.Expr[Any]*): c.Expr[XXX] = {
val Apply(_, Apply(_, parts) :: Nil) = c.prefix.tree
???
}
}
implicit class XXXInterpolator(sc: StringContext) {
def xxx(args: Any*): XXX = macro XXXMacro.xxx
}
class YYYMacro(val c: blackbox.Context) {
import c.universe._
final def yyy(args: c.Expr[Any]*): c.Expr[YYY] = q"yyy($xxx\"args\")"
}
implicit class YYYInterpolator(sc: StringContext) {
def yyy(args: Any*): YYY = macro XXXMacro.yyy
}
问题是我无法轻易地参数化代码。编译器不允许我执行macro XXXMacro(f).yyy
或macro XXXMacro.yyy(f)
。
另外,当我像将def yyy(args: Any*): YYY = f(new XXXInterpolator(sc).xxx(args))
包裹起来时,上下文在宏中是完全不同的并使它复杂化,因此我无法重用它。有什么办法使它变得更容易吗?
答案 0 :(得分:2)
尝试
class XXXMacro(val c: blackbox.Context) {
import c.universe._
final def xxx(args: c.Expr[Any]*): c.Expr[XXX] = {
val Apply(_, Apply(_, parts) :: Nil) = c.prefix.tree
???
}
final def yyy(args: c.Expr[Any]*): c.Expr[YYY] =
reify {
f(xxx(args: _*).splice)
}
}
implicit class XXXInterpolator(sc: StringContext) {
def xxx(args: Any*): XXX = macro XXXMacro.xxx
}
implicit class YYYInterpolator(sc: StringContext) {
def yyy(args: Any*): YYY = macro XXXMacro.yyy
}
答案 1 :(得分:2)
我不希望XXXMacro依赖YYY。因此,解决方案是为用户trait
和Tree
trait XXXMacroTree {
val c: blackbox.Context
import c.universe._
final def xxxTree(args: c.Expr[Any]*): Tree = ???
final def xxx(args: c.Expr[Any]*): c.Expr[XXX] = c.Expr[XXX](xxxTree(args: _*))
}
class XXXMacro(val c: blackbox.Context) extends XXXMacroTree
implicit class XXXInterpolator(sc: StringContext) {
def xxx(args: Any*): XXX = macro XXXMacro.xxx
}
class YYYMacro(val c: blackbox.Context) extends XXXMacroTree {
import c.universe._
final def yyy(args: c.Expr[Any]*): c.Expr[YYY] = c.Expr[YYY](q"f(${xxxTree(args: _*)}))
}
implicit class YYYInterpolator(sc: StringContext) {
def yyy(args: Any*): YYY = macro YYYMacro.yyy
}