在Scala宏注释上键入参数

Imr*_*hid 4 reflection scala-macros

我想在Scala中,我的宏注释会采取另一种类型的参数使用宏注解.然后,它会使用Scala的反射来看看式传递,并添加一些方法如appropriate.Eg.

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.
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上,与使用Scala宏中的Scala反射相同,除了使用宏注释.但是,当我尝试使用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] = {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

我明白了

[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]       ^
Run Code Online (Sandbox Code Playgroud)

我也尝试将类型作为我的注释的参数,所以我会像使用它一样@MyAnnotation(MyTrait) class Foo ....我可以用类似的东西将名称提取为String

val targetTrait = c.prefix.tree match {
  case Apply(Select(New(Ident(_)), nme.CONSTRUCTOR), List(Ident(termName))) => termName
}
Run Code Online (Sandbox Code Playgroud)

但是,我不知道我能做什么,而那个String可以取回完整的类型.我也尝试像变体@MyAnnotation(typeOf[MyTrait]) class Foo ...,然后用c.evaltypeOf里面我的宏,但不编译任.

Eug*_*ako 5

在宏天堂2.0.0-SNAPSHOT中,我们有一个非常棘手的方法来访问宏注释的类型参数(当我们有专门的API时,情况将会改善,但是现在很难为scala-reflect引入新功能.jar在宏天堂,所以目前的API有点粗糙).

现在,有必要在注释类上指定type参数,而不是在macroTransform方法上声明任何类型参数.然后,在宏扩展中,访问c.macroApplication并提取与传递的类型参数对应的无类型树.然后,c.typeCheck按照处理宏注释时无法访问父级成员的描述进行操作.