scala reflection: getDeclaringTrait?
reflection, scala
Solution
In Scala 2.8 you can use the ScalaSigParser to parse the scala specific byte code information.
This will be more stable than the byte code serialization format of scala traits, classes and methods.
import tools.scalap.scalax.rules.scalasig._
import scala.runtime._
val scalaSig = ScalaSigParser.parse(classOf[RichDouble]).get
val richDoubleSymbol = scalaSig.topLevelClasses.head
val methods = richDoubleSymbol.children filter ( _ match {
case m : MethodSymbol => true
case _ => false
})
methods foreach println
richDoubleSymbol.isTrait
ScalaSigParser.parse(classOf[Ordered[Any]]).get.topLevelClasses.head.isTrait
Prints:
scala> methods foreach println
MethodSymbol(x, owner=0, flags=20080004, info=23 ,None)
MethodSymbol(<init>, owner=0, flags=200, info=33 ,None)
[...]
MethodSymbol(isPosInfinity, owner=0, flags=200, info=117 ,None)
MethodSymbol(isNegInfinity, owner=0, flags=200, info=117 ,None)
scala> richDoubleSymbol.isTrait
res1: Boolean = false
scala> ScalaSigParser.parse(classOf[Ordered[Any]]).get.topLevelClasses.head.isTrait
res2: Boolean = true
I suppose following this road you can build a reflection API for Scala.
Problem
When I research a new library, I sometimes find it hard to locate the implementation of a method. In Java, Metho#getDeclaringClass provides the class that declared a given method. So by iterating over Class#getMethods, I can find for each method, the class that declared it. In Scala, traits are converted to Java interfaces and a class that extends a trait will implement the methods of the trait by forwarding them to a companion class defining these methods statically. This means, that Method#getDeclaringClass will return the class, not the trait: ``` scala> trait A { def foo = {println("hi")}} defined trait A scala> class B extends A defined class B scala> classOf[B].getMethods.find(_.getName() == "foo").get.getDeclaringClass res3: java.lang.Class[_] = class B ``` What is the best way to work around this? Meaning, given a class, how can I get a List[(Method, Class)] where each tuple is a method and the trait/class it was declared in?