[SI-6573] reflection still very non-deterministic Created: 28/Oct/12  Updated: 20/Jul/15

Status: Open
Project: Scala Programming Language
Component/s: Reflection
Affects Version/s: Scala 2.10.0-RC1, Scala 2.11.0-M1
Fix Version/s: Backlog

Type: Bug Priority: Major
Reporter: Paul Phillips Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
 
scala> rootMirror.staticPackage("java.lang").typeSignature.members.size
res0: Int = 16
 
scala> rootMirror.staticPackage("java.lang").typeSignature.members.flatMap(_.typeSignature.members)
res1: Iterable[reflect.runtime.universe.Symbol] = List(value serialVersionUID, constructor StringBuilder, ....)
 
scala> rootMirror.staticPackage("java.lang").typeSignature.members.size
res2: Int = 31



 Comments   
Comment by Eugene Burmako [ 28/Oct/12 ]

Reflection uses classloaders, therefore it cannot exhaustively enumerate members of packages. Any ideas how to defeat that?

Comment by Jason Zaugg [ 28/Oct/12 ]

While it can't enumerate members of packages in general, it can be done if you make some assumptions about the classloader (See, for example, Spring's PathMatchingResourcePatternResolver.)

I don't suggest to offer that functionality out of the box (maintaining and supporting that sort of code is expensive), but you might offer a hook at the point of mirror creation where the caller could provide a package enumerator.

Comment by Chris Hodapp [ 29/Apr/13 ]

Also see Reflections, which is more focused on finding classes.

Comment by Chris Hodapp [ 29/Apr/13 ]

It's worse than you claim: simply being loaded is not enough to make a class show up:

 
package foo
 
import reflect.runtime.universe._
import reflect.runtime.{currentMirror=>cm}
 
class C
 
object Main extends App {
 
	val pkg = cm.staticPackage("foo")
	println(pkg.moduleClass.typeSignature.members)
 
	pkg.moduleClass.typeSignature.member(newTypeName("Main"))
	println(pkg.moduleClass.typeSignature.members)
 
	cm.classLoader.loadClass("foo.C")
	println(pkg.moduleClass.typeSignature.members)
 
	pkg.moduleClass.typeSignature.member(newTypeName("C"))
	println(pkg.moduleClass.typeSignature.members)
 
}

[info] Running foo.Main
Scope{
 
}
Scope{
  object Main;
  class Main extends
}
Scope{
  object Main;
  class Main extends
}
Scope{
  object C;
  class C extends ;
  object Main;
  class Main extends
}

Generated at Mon Jul 16 15:58:36 CEST 2018 using JIRA 7.9.1#79001-sha1:60970b42586a2ec2760ed6cfe825b26961e62b9e.