summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-07-20 12:46:05 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-07-20 14:39:38 +0200
commitb5f721fb52767d0b839a0ef4614d1bcb039adba1 (patch)
tree61e650f7dfb8921f08cc4aa647de28a15dcfa368 /src/library
parente5161f01111c88de4f890c7541a6ff5e7be58916 (diff)
downloadscala-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.scala3
-rw-r--r--src/library/scala/reflect/base/MirrorOf.scala49
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
}