TL;DR: Basically, I\'m looking for the Scala equivalent of the Java:
(MyAnnotation) Thing.getClass().getAnnotations()[0]
D
Without having to depend on scala-compiler, this is my version:
def fetchAnnotations[T <: Annotation](cls : Class[_]) : List[T]= {
import scala.reflect.runtime.universe._
val mirror = runtimeMirror(cls.getClassLoader)
val clsSymbol = mirror.staticClass(cls.getCanonicalName)
val annotations = clsSymbol.annotations
val res = ListBuffer[T]()
for(annt : Annotation <- annotations) {
val anntCls = annt.tree.tpe.typeSymbol.asClass
val classMirror = mirror.reflectClass(anntCls);
val anntType = annt.tree.tpe
val constructor = anntType.decl(termNames.CONSTRUCTOR).asMethod;
val constructorMirror = classMirror.reflectConstructor(constructor);
val instance = annt.tree match {
case Apply(c, args : List[Tree]) =>
val res = args.collect({
case i: Tree =>
i match {
case Literal(Constant(value)) =>
value
}
})
constructorMirror(res: _*).asInstanceOf[T]
}
res+=(instance)
}
res.toList
}
The previous code will only work when the arguments are primitive I suspect.
If we can afford depending on scala-compiler, then we can do something like:
def fetchAnnotations_toolBox[T <: Annotation](cls : Class[_]) : List[T]= {
import scala.reflect.runtime.universe._
val mirror = runtimeMirror(cls.getClassLoader)
val clsSymbol = mirror.staticClass(cls.getCanonicalName)
val annotations = clsSymbol.annotations
val res = ListBuffer[T]()
for(annt : Annotation <- annotations) {
import scala.tools.reflect.ToolBox
val toolbox = mirror.mkToolBox()
val instance = toolbox.eval(toolbox.untypecheck(toolbox.typecheck(annt.tree))).asInstanceOf[T]
res+=(instance)
}
res.toList
}