The newer version of Scala brings us some new features. In this post, Simon Ochsenreither listed many of these new things. One of the most expected, at least for me, is the new Reflection API. In my last project at Caelum, we faced a lot of problems using Java’s Reflection API to discover things that just existed in a Scala class. For example, we needed to know if a method was implicit or not and this information was not clearly pointed at the bytecode. In order to solve this problem, we had to use the scalap library and I can tell, the code is not beautiful.

So my point here is just that, show you how to use the new Reflection API to discover if a method is or not a implicit. The code must be a starting point to do whatever you might need with the rest of the API.

To get started I was looking for a way to get information about the class, such as methods implicitness, existence of companion objects and so on. So I created an Object with an implicit method just to test:

object Pimps{ implicit def pimp(str:String) = new { def test = println("hello") } }

Now I need to get information about this class, all the traits that you must know to work with Scala’s Reflection are at Scala’s github repository, and that was my starting point. The Mirror trait is the entry point of the api, its implementation can be found here. So let’s get started retrieving all the informations about our class. Here is the code:

val aType:Type = Mirror.typeOfInstance(Pimps)

Now we have the Type instance of our class. This object provides informations about your class, for example we can pick all the members. Let me show you the code:

val members:List[Symbol] = aType.members

The Symbol trait is the abstraction of everything that you have in your class, constructors, methods, variables and the class declaration itself. And, at least for me, this was my savior. With an instance of Symbol is possible to get information about the Scala code. For instance, let’s filter all the Symbols that contains an implicit modifier in our Pimps class:

val justImplicits = members.filter(member => member.hasModifier(Modifier.`implicit`))

I think this is a good starting point to test the new API. All the code was tested in REPL with the 2.10 version, milestone 2. Also, there is a gist with the example code. Don’t forget the imports :).

Thanks to @adrianoalmeida7 for kindly reviewing this post.