reflection - Getting method's function type from the MethodMirror instance in Scala -


assume have instance of methodmirror created method of object. mirror's fields can access return type , parameters of method. need obtain type method have function.

here toy code example me explain, want achieve. i'm using scala 2.11.6.

import scala.reflect.runtime.universe._  object forstackoverflow {   object obj {     def method(x:string, y:string):int = 0     def expectedrettype():((string, string) => int) = ???   }    def main(args: array[string]) {     val mirror:mirror = runtimemirror(getclass.getclassloader)     val instancemirror = mirror.reflect(obj)      val methodsymbol:methodsymbol = instancemirror.symbol.totype.decl(termname("method")).asmethod     val methodmirror = instancemirror.reflectmethod(methodsymbol)      println(methodmirror.symbol.returntype)     println(methodmirror.symbol.paramlists(0).map { x => x.info.resulttype }.mkstring(", "))      val expectedsymbol:methodsymbol = instancemirror.symbol.totype.decl(termname("expectedrettype")).asmethod     println("i produce 'methodmirror' this: "+expectedsymbol.returntype)   } } 

i want produce type instance methodmirror represent function. example should (string, string) => int. prefer solution doesn't depend on concrete scala's functionx classes.

the method getetaexpandedmethodtype below asked, , handles methods multiple parameter lists.

on other hand not handle generic methods. example def method[t](x: t) = 123, when eta-expanded, creates function of type any => int, getetaexpandedmethodtype report t => int not incorrect not make sense @ (t has no meaning in context).

def getetaexpandedmethodtype(methodsymbol: methodsymbol): type = {   val typ = methodsymbol.typesignature   def paramtype(paramsymbol: symbol): type = {     // todo: handle case paramsymbol denotes type parameter     paramsymbol.typesignaturein(typ)   }    def rec(paramlists: list[list[symbol]]): type = {     paramlists match {       case nil => methodsymbol.returntype       case params :: otherparams =>         val functionclasssymbol = definitions.functionclass(params.length)         appliedtype(functionclasssymbol, params.map(paramtype) :+ rec(otherparams))     }   }   if (methodsymbol.paramlists.isempty) { // no arg method     appliedtype(definitions.functionclass(0), list(methodsymbol.returntype))   } else {     rec(methodsymbol.paramlists)   } } def getetaexpandedmethodtype(methodmirror: methodmirror): type = getetaexpandedmethodtype(methodmirror.symbol) 

repl test:

scala> val mirror: mirror = runtimemirror(getclass.getclassloader) mirror: reflect.runtime.universe.mirror = ...  scala> val instancemirror = mirror.reflect(obj) instancemirror: reflect.runtime.universe.instancemirror = instance mirror obj$@21b6e507  scala> val tpe = instancemirror.symbol.totype tpe: reflect.runtime.universe.type = obj.type  scala> getetaexpandedmethodtype(tpe.decl(termname("method1")).asmethod) res28: reflect.runtime.universe.type = (string, string) => scala.int  scala> getetaexpandedmethodtype(tpe.decl(termname("method2")).asmethod) res29: reflect.runtime.universe.type = () => string  scala> getetaexpandedmethodtype(tpe.decl(termname("method3")).asmethod) res30: reflect.runtime.universe.type = () => scala.long  scala> getetaexpandedmethodtype(tpe.decl(termname("method4")).asmethod) res31: reflect.runtime.universe.type = string => (scala.float => scala.double)  scala> getetaexpandedmethodtype(tpe.decl(termname("method5")).asmethod) res32: reflect.runtime.universe.type = t => scala.int  scala> getetaexpandedmethodtype(tpe.decl(termname("method6")).asmethod) res33: reflect.runtime.universe.type = t => scala.int 

Comments

Popular posts from this blog

dns - How To Use Custom Nameserver On Free Cloudflare? -

qt - Passing a QObject to an Script function with QJSEngine? -

c# - Web API response xml language -