I have a class hierarchy beginning with these traits:
sealed trait MessageBody
sealed trait MessageKey[T <: MessageBody]
I need to build automatically a list of all direct subclasses of MessageKey
. With searching here and there I came up to this point:
object MessageKey {
private def sealedDescendants[Root: TypeTag] = {
val symbol = typeOf[Root].typeSymbol
val internal = symbol.asInstanceOf[scala.reflect.internal.Symbols#Symbol]
if (internal.isSealed) {
val symbols = internal.sealedDescendants.map(_.asInstanceOf[Symbol]) - symbol
val types = internal.sealedDescendants.filter(_.typeSignature.typeConstructor.baseTypeSeq.length > 3).map(_.typeSignature.typeConstructor.baseTypeSeq(3))
(symbols zip types)
} else {
Set.empty
}
}
// set of all keys (i.e., descendants of MessageKey
private val allClassesAndTypes = sealedDescendants[MessageKey[_ <: MessageBody]]
// map from key-strings to constructors of the MessageKey
private val allObjects = (for ((aKey, aType) <- allClassesAndTypes) yield {
print(aKey+": "+aType)
val ctor = aKey.typeSignature.declaration(ru.nme.CONSTRUCTOR).asMethod
val mirror = ru.runtimeMirror(getClass.getClassLoader)
val cm = mirror.reflectClass(aKey.asClass)
val ctorm = cm.reflectConstructor(ctor)
val keyObj: MessageKey[_ <: MessageBody] = ctorm().asInstanceOf[MessageKey[_ <: MessageBody]]
(keyObj.toString -> ctorm)
}).toMap
}
This code give me objects with type MessageKey[Nothing]
. As you see above, I somehow get to the Type
of each key, but I do not know how to use it.
I would like to do something like
val keyObj: MessageKey[_ <: MessageBody] = ctorm().asInstanceOf[aType]
But, of course, I cannot use aType
there just like that. Any help is appreciated.
Aucun commentaire:
Enregistrer un commentaire