Scala 2.10 comes with a great reflection API. There are two entry points to it, however: runtime universe and macro context universe.
When using runtime reflection, you should import scala.reflect.runtime.universe. When using reflection inside a macro implementation, you should import universe from the context.
Is it possible to write some code that works in both environments? How should one obtain the universe?
Consider this example:
class MyReflection(val u: scala.reflect.api.Universe) {
import u._
def foo[T: TypeTag] = implicitly[TypeTag[T]].tpe.members // returns MyReflection.u.MemberScope
}
val x = new MyReflection(scala.reflect.runtime.universe)
val members: scala.reflect.runtime.universe.MemberScope = x.foo[String] // BANG! Compiler error
This won't compile because of type mismatch. Same time, it is obvious that both scala.reflect.runtime.universe.MemberScope and MyReflection.u.MemberScope in this example share the same API. Is there a way to abstract over different universes?
Or am I possibly doing something philosophically wrong with trying to export reflection artifacts (MemberScope in this example)?