Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding method arguments (and types) using Scala 2.10 reflection?

I've learned (from here) to use extractors to obtain Scala metadata. I've also noticed Universe.MethodTypeExtractor:

An extractor class to create and pattern match with syntax MethodType(params, respte) Here, params is a potentially empty list of parameter symbols of the method, and restpe is the result type of the method.

Great! Sounds like what I want!(?)

But how to get a MethodType? (And why is this an extractor for a method "type" (are methods "types"?) as opposed to say, a method "Def" or "Ref"??)

scala> typeOf[List[Int]].member(newTermName("head"))
res2: reflect.runtime.universe.Symbol = method head

scala> res2 match { case MethodType(a, b) => println((a, b)) }
scala.MatchError: method head (of class scala.reflect.internal.Symbols$MethodSymbol) [...]

scala> res2.asType match { case MethodType(a, b) => println((a, b)) }
scala.ScalaReflectionException: method head is not a type [...]

scala> res2.asTerm match { case MethodType(a, b) => println((a, b)) }
scala.MatchError: method head (of class scala.reflect.internal.Symbols$MethodSymbol) [...]

scala> res2.asMethod match { case MethodType(a, b) => println((a, b)) }
scala.MatchError: method head (of class scala.reflect.internal.Symbols$MethodSymbol) [...]

Or am I completely "barking up the wrong tree", so to speak?

like image 973
Tim Avatar asked Oct 12 '12 02:10

Tim


1 Answers

paramss (this is an RC1 name, in M7 it is named params) and returnType are methods of MethodSymbol:

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> typeOf[List[Int]].member(newTermName("head"))
res2: reflect.runtime.universe.Symbol = method head

scala> res2.asMethod.paramss
res4: List[List[reflect.runtime.universe.Symbol]] = List()

scala> res2.asMethod.returnType
res5: reflect.runtime.universe.Type = A

To get a type signature of a method, you should call the typeSignature method defined on Symbol.

Speaking of why methods are types, it's not entirely correct to say so. There are DefDef trees, MethodSymbol symbols and MethodType/NullaryMethodType types - each serving its own purposes within the compiler. Quite soon we'll complete the documentation of the reflection API, so hopefully things will get clearer.

like image 174
Eugene Burmako Avatar answered Oct 22 '22 15:10

Eugene Burmako