延迟宏中的隐式解析
Deferring implicit resolution in macros
所以,假设我手头有几件事:
case class M[A](val value: A) {
def apply(as: M[A]*) = macro applyImpl[A]
}
def tpAware(implicit ev: Context[A]): M[A]
val ma: M[X] = ???
我想做:
ma(tpAware)
其中 applyImpl
的定义类似于
def applyVG[A : c.WeakTypeTag, V](c: MacroContext)(vs: c.Expr[M[V]]*): c.Expr[M[A]] = {
import c.universe._
val container = c.prefix.tree.collect {
case a@Apply(n, xs) => xs
}.flatten.apply(1)
val expr = reify {
M {
implicit val ev = Context[A]()
val container = c.Expr[A](container).splice
sequence(c)(vs).splice foreach { c =>
container.add(c.value)
}
container
}
}
expr
}
现在的问题是,打字机在宏展开之前运行,而我的 Context[A]
在应用 apply
之前不可见
做什么?
不是将隐式参数注入参数列表,唯一可行的方法是创建 @compileTimeOnly
函数,该函数将通过 apply
宏在其位置注入替代 AST。
@compileTimeOnly
函数的参数列表将拼接到生成的 AST 中,生成的 AST 将拼接到整个程序中。
必须特别注意修复生成和拼接语法树的符号所有权和类型检查。有关如何正确修复树木的更多信息,请参阅 macrology201
第 1 部分的第 19 步到第 30 步。
这种方法被 scala-async、sbt 和其他人用来在宏和它们的 children 之间进行合作。
所以,假设我手头有几件事:
case class M[A](val value: A) {
def apply(as: M[A]*) = macro applyImpl[A]
}
def tpAware(implicit ev: Context[A]): M[A]
val ma: M[X] = ???
我想做:
ma(tpAware)
其中 applyImpl
的定义类似于
def applyVG[A : c.WeakTypeTag, V](c: MacroContext)(vs: c.Expr[M[V]]*): c.Expr[M[A]] = {
import c.universe._
val container = c.prefix.tree.collect {
case a@Apply(n, xs) => xs
}.flatten.apply(1)
val expr = reify {
M {
implicit val ev = Context[A]()
val container = c.Expr[A](container).splice
sequence(c)(vs).splice foreach { c =>
container.add(c.value)
}
container
}
}
expr
}
现在的问题是,打字机在宏展开之前运行,而我的 Context[A]
在应用 apply
做什么?
不是将隐式参数注入参数列表,唯一可行的方法是创建 @compileTimeOnly
函数,该函数将通过 apply
宏在其位置注入替代 AST。
@compileTimeOnly
函数的参数列表将拼接到生成的 AST 中,生成的 AST 将拼接到整个程序中。
必须特别注意修复生成和拼接语法树的符号所有权和类型检查。有关如何正确修复树木的更多信息,请参阅 macrology201
第 1 部分的第 19 步到第 30 步。
这种方法被 scala-async、sbt 和其他人用来在宏和它们的 children 之间进行合作。