2013-12-20 3 views
3

Так у меня есть документация аннотацию, которая выглядит следующим образом:Попадая Scala 2.10 Значения аннотаций во время выполнения

case class DocProp(name: String = "", dataType: Class[_] = classOf[Object]) 

Идея заключается в том, что по умолчанию мы будем вникать в поле и смотреть на ID и тип возвращаемого значения, но в некоторых случаях это требует переопределения.

Я хочу поставить его на полях моей модели конкретных классов, так что я переобъявить это как type с @field:

type DocProperty = DocProp @field 

, а затем использовать его в следующих различных сценариев:

case class MyModel(
    // 1. use reflection to inspect the property 
    @DocProperty 
    prop1: Int, 

    // 2. override the name 
    @DocProperty(name = "myProp") 
    prop2: String, 

    // 3. override the return type 
    @DocProperty(dataType = classOf[String]) 
    prop3: Option[String], 

    // 4. override everything 
    @DocProperty("myOtherProp", classOf[Number]) 
    prop4: Float, 

    // 5. don't document this one at all 
    hiddenProp: String 
) 

Наконец-то мне удалось проскочить слои runtimeMirrors и еще не перейти к Symbols для значений и связанных с ними аннотаций и вырезать только аннотации DocProp:

// val mc = classOf[MyModel] // passed in 
import scala.reflect.runtime.{universe => ru} 
val mirror = ru.runtimeMirror(mc.getClassLoader) 
val members = mirror.classSymbol(mc).asType.typeSignature.members 

val allProps = (for (m <- members) yield { 
    val a8ns = m.annotations 
    val a8n = a8ns.find(a => a.tpe <:< ru.typeOf[DocProp]) 
    a8n match { 
    case Some(found) => Some((m, found)) 
    case _ => None 
    } 
}).flatten 

Это заставляет меня итератор из (Symbol, Annotation) всего за аннотированное свойство (я по-прежнему нужен символы для отражательных случаев).

Но я сейчас глубоко в чащи reflect.runtime.universe.Trees, и для меня это не очевидно, как выбраться. Как я могу получить от

reflect.runtime.universe.Tree = classOf[java.lang.Number] 

к фактической стоимости Class[Number]? Как я могу получить от

reflect.runtime.universe.Tree = doc.this.DocProp.<init>$default$1 

в пустую строку, или даже 1?

ответ

1

До сих пор нет простого способа достичь этого. Использование ToolBox.eval - обходной путь, который приходит на ум. В нашей JIRA также есть аналогичная проблема, которая рассказывает о получении значений аннотаций Java: https://issues.scala-lang.org/browse/SI-6423.

+1

Для будущих читателей: я закончил использование аннотаций Java и сочетание отражения Java и Scala. Это было некрасиво, но это сработало. –

Смежные вопросы