6

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?

Community
  • 1
  • 1
Tim
  • 1,615
  • 14
  • 17

1 Answers1

4

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.

Eugene Burmako
  • 13,028
  • 1
  • 46
  • 59
  • Ah. Sorry -- probably should have seen that. Little confused as to when the information is available by a function, and when to use an extractor. Documentation would *certainly* help a lot. Thank you! – Tim Oct 14 '12 at 21:34
  • in 2.11 named paramLists – senz Jul 01 '14 at 11:09
  • How do I get the string of "Scala type" for a method? So, for `def foo(a:List[Int]) = ???`, I need the string `scala.List[scala.Int]`. – Jus12 Aug 15 '16 at 07:05
  • Nevermind, I figured it out. Pasting here. Something like `val y = x.paramss(0)(0); y.typeSignature`. Thanks for the reflection API BTW. Really needed this for a long time. – Jus12 Aug 15 '16 at 07:07