【发布时间】:2013-11-16 11:40:06
【问题描述】:
我正在尝试在 scala 中使用宏注释,其中我的宏注释将采用另一种类型的参数。然后它会使用 scala 反射来查看传入的类型,并根据需要添加一些方法。例如。
trait MyTrait {
def x: Int
def y: Float
}
@MyAnnotation class MyClass //<-- somehow, this annotation should reference MyTrait
class MyAnnotation(val target: Any) extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro MyAnnotationImpl.impl
}
object MyAnnotationImpl {
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
// if I can get a handle on the type MyTrait in here
// then I can call .members on it, etc.
...
}
}
基本上和Using Scala reflection in Scala macros一样,除了使用宏注解。但是,当我尝试使用 TypeTag 模板化我的宏注释时
class MyAnnotation[T](val target: Any) extends StaticAnnotation {
def macroTransform[T](annottees: Any*) = macro MyAnnotationImpl.impl[T]
}
object MyAnnotationImpl {
def impl[T: c.WeakTypeTag](c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
...
}
}
我明白了
[error] /Users/imran/other_projs/learn_macros/macros/src/main/scala/com/imranrashid/oleander/macros/MacrosWithReflection.scala:7: macro annotation has wrong shape:
[error] required: def macroTransform(annottees: Any*) = macro ...
[error] found : def macroTransform[T](annottees: Any*) = macro ...
[error] class MyAnnotation[T](val target: Any) extends StaticAnnotation {
[error] ^
我还尝试将类型作为注释的参数,所以我会像@MyAnnotation(MyTrait) class Foo ... 一样使用它。我可以将名称提取为字符串,例如
val targetTrait = c.prefix.tree match {
case Apply(Select(New(Ident(_)), nme.CONSTRUCTOR), List(Ident(termName))) => termName
}
但是,我不确定我能用那个字符串做什么来取回完整的类型。我也尝试过像@MyAnnotation(typeOf[MyTrait]) class Foo ... 这样的变体,然后在我的宏中的typeOf 上使用c.eval,但这也无法编译。
【问题讨论】: