Re: how can i reflect the instantiated return type of a generic type's method?

LiangQing <[email protected]> Mon, 14 Mar 2016 11:28:02 +0800
Newsgroups gmane.comp.lang.scala
Message-ID <CAJ2h+mgRscuJBCrRPFP7MJr-d9R9Y8JUN+Cc2-O8uNSyYGNo+Q@mail.gmail.com>
Thanks Daniel.

It solves my problem.

I'm sorry for submitting the question to the wrong mail list.


On Sun, Mar 13, 2016 at 1:12 AM, Daniel Armak <[email protected]> wrote:

> 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.
>

-- 
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.