Jan Goyvaerts
Jan Goyvaerts

Reputation: 3033

Introspect Scala traits

Consider the example

class FooListener extends Listener {
  @Listen
  def runMeToo = {
    ...
  }
}

trait Listener {

  @Listen
  def runMe = {
    ...
  }
}

I'm writing introspection code to find all methods of a given class (ie FooListener) annotated with a certain annotation (ie @Listen). They'll be invoked under certain circumstances. So I need all their java.lang.Method instances.

It's easy to find those methods in the FooListener class. Easy also to find those of the super classes.

The question is how to find those inherited from the traits ? And the traits of the traits ? Etc...

Upvotes: 1

Views: 916

Answers (2)

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340733

Since traits are translated to interfaces in Java, the following code snippet should work:

val methods = classOf[FooListener].getInterfaces flatMap {intf =>
    intf.getMethods filter {_.getAnnotation(classOf[Listen]) != null}
}

Upvotes: 1

Kim Stebel
Kim Stebel

Reputation: 42047

Methods inherited from a trait are just copied into the class. So you can find them by just listing the methods of the class.

val ms = classOf[FooListener].getMethods()

And then print them with their annotations.

ms.foreach(m => m.getDeclaredAnnotations().foreach(a => println(m + " " + a)))

In my case (annotated with Test), this prints

public void util.FooListener.runMe() @org.junit.Test(expected=class org.junit.Test$None, timeout=0)
public void util.FooListener.runMeToo() @org.junit.Test(expected=class org.junit.Test$None, timeout=0)

Upvotes: 1

Related Questions