I’m trying to write an annotation macro which needs to inspect annotations on defs from a certain class. I could not make it work. The expectation is that m.annotations
would return all statically available annotations (where m
is a MethoSymbol
, returned from x.decls
with x
beeing the Type
).
In my tests, m.annotations
never includes my annotation.
The question is whether it is possible to inspect annotations like this. Common sense tells me that it should be possible (meaning the annotation should be available at compile time), but the docs don’t clearly say whether that’s the caseor not.
Here’s the source code:
import scala.annotation.StaticAnnotation
import scala.reflect.macros.whitebox
import scala.language.experimental.macros
class field(name: String) extends scala.annotation.ConstantAnnotation
class BaseClass
class mymacro extends StaticAnnotation {
def macroTransform(annottees: Any*): BaseClass = macro MyMacroImpl.macroImpl
}
class MyMacroImpl(val c: whitebox.Context) {
import c.universe._
def macroImpl(annottees: c.Expr[Any]*): c.Expr[BaseClass] = {
annottees.map(_.tree) match {
case List(classDef: ClassDef) => transformClass(classDef)
}
}
def transformClass(classDef: ClassDef) = {
val ClassDef(mods, className, typeParams, impl) = classDef
val parentTypes = impl.parents.map(tree => c.typecheck(tree, c.TYPEmode))
parentTypes.foreach(t =>
t.tpe.members.foreach(m =>
println("*** " + m.annotations)
)
)
c.Expr(classDef)
}
}
and the test code:
import org.scalatest.matchers.should.Matchers
import org.scalatest.flatspec.AnyFlatSpec
@mymacro
abstract class Test extends BaseClass {
@field(name="foo")
def foo: String
}
class MyTest extends AnyFlatSpec with Matchers {
val x = new Test {
override def foo: String = "foo"
}
}
Cheers,
Răzvan