Is there a way to get parameter names of a given constructor using scala-macros?
Thanks
Note that the :power
approach in Paul Butcher's answer gives you access to internal APIs, which probably isn't either necessary or desired if you're trying to do this in a macro (or in runtime reflection outside of the REPL, for that matter).
So for example calling isConstructor
on a plain old Symbol
provided by members
in the public Reflection API won't work—you first need to make sure that you have a MethodSymbol
. Similarly with tpe
. You could of course cast to the internal APIs in non-REPL code, but this is dangerous and unnecessary. The following is a better solution:
import scala.reflect.runtime.universe._
class Foo(name: String, i: Int) { def this(name: String) = this(name, 0) }
typeOf[Foo].declaration(nme.CONSTRUCTOR).asTerm.alternatives.collect {
case m: MethodSymbol => m.paramss.map(_.map(_.name))
}
Or just:
typeOf[Foo].declarations.collect {
case m: MethodSymbol if m.isConstructor => m.paramss.map(_.map(_.name))
}
Both of these will give you the following:
List(List(List(name, i)), List(List(name)))
As desired. I've used runtime reflection here to simplify the example, but this will work exactly the same way with the Universe
you get from your Context
in a macro.
This REPL transcript should get you going, I hope:
Welcome to Scala version 2.10.0-RC5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_09).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._, definitions._ also imported **
** Try :help, :vals, power.<tab> **
scala> class Foo(x: Int, y: Float)
defined class Foo
scala> (typeOf[Foo].members find (_.isConstructor)).get.tpe.params map (_.name)
res1: List[$r.intp.global.Symbol#NameType] = List(x, y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With