The concept of traversing the owner chain until you hit a package (or, more precisely, a package class) is correct, however the code that you posted has minor stylistic issues. First, there's Symbol.fullName
that concatenates the strings for you. Secondly, magic names necessary for public consumption of the reflection API are usually exposed somewhere in the API.
Here's how I would do what you're trying to do (change newTermName
to TermName
if you're on Scala 2.10.x):
00:08 ~/Projects/Master/sandbox (master)$ cat Test.scala
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
object Test extends App {
def packageName(sym: Symbol) = {
def enclosingPackage(sym: Symbol): Symbol = {
if (sym == NoSymbol) NoSymbol
else if (sym.isPackage) sym
else enclosingPackage(sym.owner)
}
val pkg = enclosingPackage(sym)
if (pkg == cm.EmptyPackageClass) ""
else pkg.fullName
}
println(packageName(typeOf[Test.type].member(TermName("packageName"))))
println(packageName(cm.staticPackage("scala")))
println(packageName(cm.staticClass("scala.collection.immutable.List")))
}
00:08 ~/Projects/Master/sandbox (master)$ sr
scala
scala.collection.immutable