Так у меня есть документация аннотацию, которая выглядит следующим образом:Попадая 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
?
Для будущих читателей: я закончил использование аннотаций Java и сочетание отражения Java и Scala. Это было некрасиво, но это сработало. –