2

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.

Jean
  • 21,329
  • 5
  • 46
  • 64
Mahdi
  • 1,778
  • 1
  • 21
  • 35
  • I am starting to think that it is probably not possible in a general setting, because compiler needs to do some stuff based on that generic type, and if we are already at run-time, it is too late. But maybe under some restrictions, this would be possible? – Mahdi Dec 16 '15 at 10:52

0 Answers0