Re: how can i reflect the instantiated return type of a generic type's method?
Daniel Armak <[email protected]> Sat, 12 Mar 2016 19:12:58 +0200
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CADtYB+m9zSVBo6HtT5BFM2GQmSZ6VO1j9ffNAUi-6CcZoLVi2g@mail.gmail.com> |
BTW Leon, please submit usage questions to the scala-user mailing list. scala-language is for discussing the language itself. Daniel Armak On Sat, Mar 12, 2016 at 6:47 PM, Daniel Armak <[email protected]> wrote: > You need to use Symbol.typeSignatureIn(Type): > > scala> case class Person[T](name: T) > defined class Person > > scala> val tpe = typeOf[Person[String]] > tpe: reflect.runtime.universe.Type = Person[String] > > scala> val method = tpe.members.find(_.name.toString == "name").get.asMethod > method: reflect.runtime.universe.MethodSymbol = value name > > scala> val methodType = method.typeSignatureIn(tpe) > methodType: reflect.runtime.universe.Type = => String > > scala> methodType.resultType > res24: reflect.runtime.universe.Type = String > > > > Daniel Armak > > On Mon, Mar 7, 2016 at 11:09 AM, Leon <[email protected]> wrote: > >> Hi, >> >> I have just write a method to reflect the methods of case class, but meet >> some problem, the code is: >> >> >> case class Name(first: String, last: String) >> case class Person[T](name: T, age: Int) >> case class America(val name: Name, val age: Int) >> >> val m = runtimeMirror(getClass.getClassLoader) >> >> def getFlattenFields(tag: Type, prefix: String = ""): Map[String, >> Method] = { >> val cls = m.runtimeClass(tag) >> tag.members.filter(sym => >> sym.isMethod && sym.asMethod.isGetter && sym.asMethod.isPublic >> ).flatMap { sym => >> val methodSym = sym.asMethod >> val returnType = methodSym.returnType >> * // When reflect generic types, the returnType will be >> something like 'T' but not the* >> * // instantiated return type, how can i get the real return >> type instead of the generic* >> * // type ?* >> Map[String, Method](prefix + methodSym.name.toString -> >> cls.getDeclaredMethod(methodSym.name.toString)) ++ >> (if (returnType.typeSymbol.isClass && >> returnType.typeSymbol.asClass.isCaseClass) { >> getFlattenFields(returnType, prefix + >> methodSym.name.toString + ".") >> } else { >> Map.empty[String, Method] >> }) >> } toMap >> } >> >> println(getFlattenFields(typeOf[Person[Name]])) >> println(getFlattenFields(typeOf[America])) >> >> >> the result of above is: >> >> Map(age -> public int test.Reflect$Person.age(), name -> public >> java.lang.Object test.Reflect$Person.name()) >> Map(age -> public int test.Reflect$America.age(), name -> public >> test.Reflect$Name test.Reflect$America.name(), name.last -> public >> java.lang.String test.Reflect$Name.last(), name.first -> public >> java.lang.String test.Reflect$Name.first()) >> >> the first line of the result is not my expectation, how can i get the >> second line, but using "println(getFlattenFields(typeOf[Person[Name]]))"? >> >> >> Thanks very much >> >> -- >> You received this message because you are subscribed to the Google Groups >> "scala-language" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "scala-language" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.