Параметры типа в макросах Scala
Я пытаюсь использовать макро-аннотации в 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
внутри моего макроса, но это тоже не компилируется.