As you can see from your definition of getType
, The typeOf[T]
function doesn't actually care at all about your value obj
. All it does is, at compile time, give you a reified representation of type T
. So if you have trait Foo; trait Bar extends Foo; getType[Foo](new Bar {})
, you will get the type information for Foo
not Bar
. The whole point of reified generics is to preserve the necessary information at compile time.
The solution lies in this answer: You have to use the runtime class of contract
via getClass
and reflect that result.
def getType[T](clazz: Class[T])(implicit rm: ru.Mirror) =
rm.classSymbol(clazz).toType
val symb = getType(contract.getClass)
Consequently your method signature can be simplified to def makeXMLElem(contract: Constract)
.
Example:
import reflect.runtime.{universe => ru}
import ru._
implicit val rm = runtimeMirror(getClass.getClassLoader)
trait Foo; case class Bar(baz: Int) extends Foo
val b: Foo = Bar(33)
b.getClass // Bar!
val symb = getType(b.getClass).declaration(newTermName("baz")).asTerm
val instanceMirror = rm.reflect(b)
val symbMirror = instanceMirror.reflectField(symb)
symbMirror.get // 33 !