所以,让我说我手头有一些事情:
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
}
现在的问题是,在扩展宏之前,typer会运行,并且在应用Context[A]
之前我的apply
不可见
Wat do?
答案 0 :(得分:1)
不是将隐式参数注入参数列表,唯一有效的方法是创建@compileTimeOnly
函数,这些函数将由apply
宏注入替代AST。
@compileTimeOnly
函数的参数列表将被拼接到生成的AST中,生成的AST将被拼接到整个程序中。
必须特别注意修复生成和拼接语法树的符号所有权和类型检查。有关如何正确修复树的更多信息,请参阅macrology201
第1部分第19至30步。
scala-async,sbt和其他人使用这种方法在宏和它们的子节点之间进行协作。