How to list all fields using special annotation using Scala reflection at runtime?

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 of its fields that have this annotation? I am looking for something like (just guessing):

 def listProperties[T: ClassTag]: List[(SomeClassRepresentingFields,MyProperty)]; 
+6
source share
1 answer

This can be done using TypeTag by filtering through the members 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 does not directly give you MyProperty , but universe.Annotation . It has a scalaArgs method that gives you access to its tree-like arguments if you need to do something with it.

+11
source

Source: https://habr.com/ru/post/950006/


All Articles