4

マクロ注釈が別の型の引数を取る 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.
    ...
  }
}

基本的には、マクロ注釈を使用する以外は、 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] = {
    ...
  }
}

私は得る

[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 ...使用c.evalしましたtypeOfが、どちらもコンパイルされません。

4

2 に答える 2