How to list all fields with a custom annotation using Scala's reflection at runtime?
annotations, reflection, scala, scala-2.10
Solution
This can be done with a `TypeTag`, by filtering through the `members` of your input type:
import reflect.runtime.universe._
def listProperties[T: TypeTag]: List[(TermSymbol, Annotation)] = {
// a field is a Term that is a Var or a Val
val fields = typeOf[T].members.collect{ case s: TermSymbol => s }.
filter(s => s.isVal || s.isVar)
// then only keep the ones with a MyProperty annotation
fields.flatMap(f => f.annotations.find(_.tpe =:= typeOf[MyProperty]).
map((f, _))).toList
}
Then:
scala> class A { @MyProperty("") val a = 1 ; @MyProperty("a") var b = 2 ;
var c: Long = 1L }
defined class A
scala> listProperties[A]
res15: List[(reflect.runtime.universe.TermSymbol, reflect.runtime.universe.Annotation)]
= List((variable b,MyProperty("a")), (value a,MyProperty("")))
This doesn't give you directly a `MyProperty` but a `universe.Annotation`. It has a `scalaArgs` method that gives you access to its arguments as trees if you need to do something with then.
Problem
I have a custom annotation like ``` class MyProperty(val name: String) extends annotation.StaticAnnotation; // or should I extend something else? ``` For a given class, how can I list all its fields that have this annotation? I'm looking for something like (just guessing): ``` def listProperties[T: ClassTag]: List[(SomeClassRepresentingFields,MyProperty)]; ```