2013-07-22 9 views
6

Ho un un'annotazione personalizzato comeCome elencare tutti i campi con un'annotazione personalizzata utilizzando il riflesso di Scala al runtime?

class MyProperty(val name: String) 
    extends annotation.StaticAnnotation; // or should I extend something else? 

per una determinata classe, come posso elencare tutti i suoi campi che hanno questa annotazione? Sto cercando qualcosa di simile (solo indovinare):

def listProperties[T: ClassTag]: List[(SomeClassRepresentingFields,MyProperty)]; 

risposta

11

Questo può essere fatto con un TypeTag, filtrando attraverso la members del vostro tipo di ingresso:

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 
} 

Poi:

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(""))) 

Questo non ti dà direttamente un MyProperty ma uno universe.Annotation. Ha un metodo scalaArgs che ti dà accesso ai suoi argomenti come alberi se hai bisogno di fare qualcosa con poi.