diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-07-20 12:46:05 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-07-20 14:39:38 +0200 |
commit | b5f721fb52767d0b839a0ef4614d1bcb039adba1 (patch) | |
tree | 61e650f7dfb8921f08cc4aa647de28a15dcfa368 /src/library | |
parent | e5161f01111c88de4f890c7541a6ff5e7be58916 (diff) | |
download | scala-b5f721fb52767d0b839a0ef4614d1bcb039adba1.tar.gz scala-b5f721fb52767d0b839a0ef4614d1bcb039adba1.tar.bz2 scala-b5f721fb52767d0b839a0ef4614d1bcb039adba1.zip |
SI-5999 a real fix to the packageless problem
After a discussion on a reflection meeting on Jul 17
we concluded that we should split staticModule into
staticModule and staticPackage to remove the ambiguity
between packageless objects and packageless packages
(more in the comments in the body of the commit).
The motivation is verbosely outlined in the comments,
but the bottom line is that Scala allows packages and
packageless objects to have the same name within the same program.
Therefore at times we need to disambiguate, hence the introduction
of the staticPackage method.
As of such staticModule no longer works for packages.
In the same fashion staticPackage doesn't work for modules.
This is done to ensure robustness of reification.
I would like to do the same for getModule in Definitions,
but we have to maintain backward compatibility. That's why I retained
the old behavior, but replaced getModule invocations with getPackage
where appropriate to be in line with staticModule and staticPackage.
Another important thing that follows from the discussion is that
both staticClass and staticModule prefer parent packages over parent objects
in cases of ambiguity. Say, if we have the following snippet of code:
object B { class C } next to package B { class C }
then staticClass("B.C") will never even consider a C inside the object B.
This is how scalac operates, so we decided to be consistent here.
Finally reification logic got changed to distinguish between
staticModule and staticPackage, and to allow for the fact that
staticClass and staticModule prefer parent packages to parent objects.
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/reflect/base/Base.scala | 3 | ||||
-rw-r--r-- | src/library/scala/reflect/base/MirrorOf.scala | 49 |
2 files changed, 51 insertions, 1 deletions
diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala index a4e6256f4d..4457a6cf14 100644 --- a/src/library/scala/reflect/base/Base.scala +++ b/src/library/scala/reflect/base/Base.scala @@ -357,6 +357,9 @@ class Base extends Universe { self => def staticModule(fullName: String): ModuleSymbol = mkStatic[ModuleSymbol](fullName) + def staticPackage(fullName: String): ModuleSymbol = + staticModule(fullName) // this toy universe doesn't care about the distinction between packages and modules + private def mkStatic[S <: Symbol : ClassTag](fullName: String): S = cached(fullName) { val point = fullName lastIndexOf '.' diff --git a/src/library/scala/reflect/base/MirrorOf.scala b/src/library/scala/reflect/base/MirrorOf.scala index d030ace96c..6dc8090eee 100644 --- a/src/library/scala/reflect/base/MirrorOf.scala +++ b/src/library/scala/reflect/base/MirrorOf.scala @@ -25,7 +25,7 @@ abstract class MirrorOf[U <: base.Universe with Singleton] { * scala> res0.fullName * res1: String = scala.collection.immutable.List * - * scala> cm.staticModule("scala") + * scala> cm.staticPackage("scala") * res2: reflect.runtime.universe.ModuleSymbol = package scala * * scala> res2.moduleClass.typeSignature member newTypeName("List") @@ -33,11 +33,58 @@ abstract class MirrorOf[U <: base.Universe with Singleton] { * * scala> res3.fullName * res4: String = scala.List + * + * To be consistent with Scala name resolution rules, in case of ambiguity between + * a package and an object, the object is never been considered. + * + * For example for the following code: + * + * package foo { + * class B + * } + * + * object foo { + * class A + * class B + * } + * + * staticClass("foo.B") will resolve to the symbol corresponding to the class B declared in the package foo, and + * staticClass("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this + * fully qualified class name is written inside any package in a Scala program). + * + * In the example above, to load a symbol that corresponds to the class B declared in the object foo, + * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass. */ def staticClass(fullName: String): U#ClassSymbol /** The symbol corresponding to the globally accessible object with the * given fully qualified name `fullName`. + * + * To be consistent with Scala name resolution rules, in case of ambiguity between + * a package and an object, the object is never been considered. + * + * For example for the following code: + * + * package foo { + * object B + * } + * + * object foo { + * object A + * object B + * } + * + * staticModule("foo.B") will resolve to the symbol corresponding to the object B declared in the package foo, and + * staticModule("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this + * fully qualified class name is written inside any package in a Scala program). + * + * In the example above, to load a symbol that corresponds to the object B declared in the object foo, + * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass. */ def staticModule(fullName: String): U#ModuleSymbol + + /** The symbol corresponding to a package with the + * given fully qualified name `fullName`. + */ + def staticPackage(fullName: String): U#ModuleSymbol } |