6
votes

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?

1

1 Answers

4
votes

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.