2017-03-09 7 views
2
case class FieldName(field: String) extends scala.annotation.StaticAnnotation 
@FieldName("foo") trait Foo 
import scala.reflect.runtime.universe._ 

symbolOf[Foo].annotations.head 
// ann: Annotation = FieldName("type") 

FieldNameオブジェクトとしてアノテーションにアクセスするにはどうすればよいですか?ドキュメントにはtree.children.tailが記載されていますが、タイプはありません。ケースクラス注釈へのアクセス

+0

うん。おっとっと。一定。 – Reactormonk

答えて

3

あなたが本当にFieldName私は考えることができる最善のインスタンスが使用している場合ToolBox.tree.children.tail

scala> case class FieldName(field: String) extends scala.annotation.StaticAnnotation 
defined class FieldName 

scala> @FieldName("foo") trait Foo 
defined trait Foo 

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> val annotation = symbolOf[Foo].annotations.head 
annotation: reflect.runtime.universe.Annotation = FieldName("foo") 

scala> import scala.tools.reflect.ToolBox 
import scala.tools.reflect.ToolBox 

scala> val tb = runtimeMirror(getClass.getClassLoader).mkToolBox() 
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = [email protected] 

scala> tb.eval(tb.untypecheck(annotation.tree)).asInstanceOf[FieldName] 
res10: FieldName = FieldName(foo) 

あなたが実際のインスタンスを作成せずにFieldNameに渡された引数にアクセスすることができます。あなただけのすべてのFieldName注釈をしたいし、その値を抽出する場合

scala> annotation.tree.children.tail.map{ case Literal(Constant(field)) => field } 
res11: List[Any] = List(foo) 

は、あなたがこれを行うことができます。

scala> val fields = symbolOf[Foo].annotations.withFilter( 
    | a => a.tree.tpe <:< typeOf[FieldName] 
    |).flatMap( 
    | a => a.tree.children.tail.map{ case Literal(Constant(field)) => field } 
    |) 
fields: List[Any] = List(foo) 
+0

XYのビットであるかもしれません - タイプによってアクセスすると、間違って他の注釈を捕まえないようにします。実際には正しい注釈であることを確認して値を抽出するだけで十分です。 – Reactormonk

+0

@Reactormonkああ、今何を意味しているのか分かります。 –

+0

複数の注釈がある場合、どのフィールドがどの注釈に属しているかをどのように知ることができますか? – bashan