summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala47
-rw-r--r--src/compiler/scala/reflect/internal/FatalError.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Scopes.scala15
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala6
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala56
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala16
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala76
-rw-r--r--src/compiler/scala/reflect/runtime/Loaders.scala22
-rw-r--r--src/compiler/scala/reflect/runtime/Mirror.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/SymbolTable.scala19
-rw-r--r--src/compiler/scala/tools/nsc/CompilerCommand.scala1
-rw-r--r--src/compiler/scala/tools/nsc/MainGenericRunner.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala18
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/util/ShowPickled.scala2
17 files changed, 188 insertions, 104 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 7b07ba9cec..f677b10c32 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -660,38 +660,25 @@ trait Definitions extends reflect.api.StandardDefinitions {
def packageExists(packageName: String): Boolean =
getModuleIfDefined(packageName).isPackage
+ private def getModuleOrClass(path: Name, len: Int): Symbol = {
+ val point = path lastPos('.', len - 1)
+ val owner = if (point > 0) getModuleOrClass(path.toTermName, point) else RootClass
+ val name = path subName (point + 1, len)
+ val sym = owner.info member name
+ val result = if (path.isTermName) sym.suchThat(_ hasFlag MODULE) else sym
+ if (result != NoSymbol) result
+ else {
+ if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug
+ missingHook(owner, name) orElse {
+ throw new MissingRequirementError((if (path.isTermName) "object " else "class ")+path)
+ }
+ }
+ }
+
/** If you're looking for a class, pass a type name.
* If a module, a term name.
*/
- private def getModuleOrClass(path: Name): Symbol = {
- val module = path.isTermName
- val fullname = path.toTermName
- if (fullname == nme.NO_NAME)
- return NoSymbol
-
- var sym: Symbol = RootClass
- var i = 0
- var j = fullname.pos('.', i)
- while (j < fullname.length) {
-// val sym0 = sym //DEBUG
-
- sym = sym.info.member(fullname.subName(i, j))
- // if (sym == NoSymbol)
- // println("no member "+fullname.subName(i, j)+" found in "+sym0+sym0.info.getClass+" "+sym0.info.typeSymbol.info.getClass)
- i = j + 1
- j = fullname.pos('.', i)
- }
- val result =
- if (module) sym.info.member(fullname.subName(i, j)).suchThat(_ hasFlag MODULE)
- else sym.info.member(fullname.subName(i, j).toTypeName)
- if (result == NoSymbol) {
- // println("no member "+fullname.subName(i, j)+" found in "+sym+" "+module)
- if (settings.debug.value)
- { log(sym.info); log(sym.info.members) }//debug
- throw new MissingRequirementError((if (module) "object " else "class ") + fullname)
- }
- result
- }
+ private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)
private def newClass(owner: Symbol, name: TypeName, parents: List[Type]): Symbol = {
val clazz = owner.newClass(NoPosition, name)
@@ -840,7 +827,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
def init() {
if (isInitialized) return
- EmptyPackageClass setInfo ClassInfoType(Nil, new Scope, EmptyPackageClass)
+ EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass)
EmptyPackage setInfo EmptyPackageClass.tpe
RootClass.info.decls enter EmptyPackage
diff --git a/src/compiler/scala/reflect/internal/FatalError.scala b/src/compiler/scala/reflect/internal/FatalError.scala
index edbae19278..c843308480 100644
--- a/src/compiler/scala/reflect/internal/FatalError.scala
+++ b/src/compiler/scala/reflect/internal/FatalError.scala
@@ -3,4 +3,4 @@
* @author Martin Odersky
*/
package scala.reflect.internal
-case class FatalError(msg: String) extends Throwable(msg)
+case class FatalError(msg: String) extends Exception(msg)
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index ae5024a44b..608ec09413 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -316,7 +316,7 @@ trait Names extends api.Names {
def lastIndexOf(ch: Char) = toChars lastIndexOf ch
- /** Return the subname with characters from start to end-1. */
+ /** Return the subname with characters from from to to-1. */
def subName(from: Int, to: Int): Name
/** Replace all occurrences of `from` by `to` in
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala
index 43d429180b..e71d4147ed 100644
--- a/src/compiler/scala/reflect/internal/Scopes.scala
+++ b/src/compiler/scala/reflect/internal/Scopes.scala
@@ -74,13 +74,10 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
}
/** Returns a new scope with the same content as this one. */
- def cloneScope: Scope = {
- val clone = new Scope()
- this.toList foreach (clone enter _)
- clone
- }
+ def cloneScope: Scope = mkScope(this.toList)
- def mkScope: Scope = new Scope()
+ /** Returns a new scope of the same class as this one, with initial elements `decls` */
+ def mkScope(decls: List[Symbol] = Nil): Scope = new Scope(decls)
/** is the scope empty? */
override def isEmpty: Boolean = elems eq null
@@ -302,7 +299,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
override def foreach[U](p: Symbol => U): Unit = toList foreach p
override def filter(p: Symbol => Boolean): Scope =
- if (!(toList forall p)) new Scope(toList filter p) else this
+ if (!(toList forall p)) mkScope(toList filter p) else this
override def mkString(start: String, sep: String, end: String) =
toList.map(_.defString).mkString(start, sep, end)
@@ -311,8 +308,12 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
}
+ /** Create a new scope */
def newScope: Scope = new Scope
+ /** Create new scope for the members of package `pkg` */
+ def newPackageScope(pkgClass: Symbol): Scope = new Scope
+
def newScopeWith(elems: Symbol*) = {
val scope = newScope
elems foreach scope.enter
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index 9ba47c2d8b..0ddfc2df50 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -41,6 +41,12 @@ abstract class SymbolTable extends api.Universe
/** Are we compiling for .NET? */
def forMSIL: Boolean = false
+ /** A last effort if symbol in a select <owner>.<name> is not found.
+ * This is overridden by the reflection compiler to make up a package
+ * when it makes sense (i.e. <owner> is a package and <name> is a term name).
+ */
+ def missingHook(owner: Symbol, name: Name): Symbol = NoSymbol
+
/** A period is an ordinal number for a phase in a run.
* Phases in later runs have higher periods than phases in earlier runs.
* Later phases have higher periods than earlier phases in the same run.
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 9549d4ff94..349fa2bb68 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -1509,6 +1509,9 @@ trait Types extends api.Types { self: SymbolTable =>
new RefinedType0(parents, decls, clazz)
}
+ /** Overridden in reflection compiler */
+ def validateClassInfo(tp: ClassInfoType) {}
+
/** A class representing a class info
*/
case class ClassInfoType(
@@ -1516,6 +1519,7 @@ trait Types extends api.Types { self: SymbolTable =>
override val decls: Scope,
override val typeSymbol: Symbol) extends CompoundType
{
+ validateClassInfo(this)
/** refs indices */
private final val NonExpansive = 0
@@ -3405,7 +3409,7 @@ A type's typeSymbol should never be inspected directly.
val elems = scope.toList
val elems1 = mapOver(elems)
if (elems1 eq elems) scope
- else new Scope(elems1)
+ else scope.mkScope(elems1)
}
/** Map this function over given list of symbols */
@@ -5499,11 +5503,16 @@ A type's typeSymbol should never be inspected directly.
private val lubResults = new mutable.HashMap[(Int, List[Type]), Type]
private val glbResults = new mutable.HashMap[(Int, List[Type]), Type]
- def lub(ts: List[Type]): Type = try {
- lub(ts, lubDepth(ts))
- } finally {
- lubResults.clear()
- glbResults.clear()
+ def lub(ts: List[Type]): Type = ts match {
+ case List() => NothingClass.tpe
+ case List(t) => t
+ case _ =>
+ try {
+ lub(ts, lubDepth(ts))
+ } finally {
+ lubResults.clear()
+ glbResults.clear()
+ }
}
/** The least upper bound wrt <:< of a list of types */
@@ -5631,26 +5640,39 @@ A type's typeSymbol should never be inspected directly.
private var globalGlbDepth = 0
private final val globalGlbLimit = 2
- def glb(ts: List[Type]): Type = try {
- glb(ts, lubDepth(ts))
- } finally {
- lubResults.clear()
- glbResults.clear()
+ /** The greatest lower bound wrt <:< of a list of types */
+ def glb(ts: List[Type]): Type = elimSuper(ts) match {
+ case List() => AnyClass.tpe
+ case List(t) => t
+ case ts0 =>
+ try {
+ glbNorm(ts0, lubDepth(ts0))
+ } finally {
+ lubResults.clear()
+ glbResults.clear()
+ }
}
- /** The greatest lower bound wrt <:< of a list of types */
- private def glb(ts: List[Type], depth: Int): Type = {
- def glb0(ts0: List[Type]): Type = elimSuper(ts0) match {
+ private def glb(ts: List[Type], depth: Int): Type = elimSuper(ts) match {
+ case List() => AnyClass.tpe
+ case List(t) => t
+ case ts0 => glbNorm(ts0, depth)
+ }
+
+ /** The greatest lower bound wrt <:< of a list of types, which have been normalized
+ * wrt elimSuper */
+ private def glbNorm(ts: List[Type], depth: Int): Type = {
+ def glb0(ts0: List[Type]): Type = ts0 match {
case List() => AnyClass.tpe
case List(t) => t
case ts @ PolyType(tparams, _) :: _ =>
val tparams1 = (tparams, matchingBounds(ts, tparams).transpose).zipped map
((tparam, bounds) => tparam.cloneSymbol.setInfo(lub(bounds, depth)))
- PolyType(tparams1, glb0(matchingInstTypes(ts, tparams1)))
+ PolyType(tparams1, glbNorm(matchingInstTypes(ts, tparams1), depth))
case ts @ MethodType(params, _) :: rest =>
- MethodType(params, glb0(matchingRestypes(ts, params map (_.tpe))))
+ MethodType(params, glbNorm(matchingRestypes(ts, params map (_.tpe)), depth))
case ts @ NullaryMethodType(_) :: rest =>
- NullaryMethodType(glb0(matchingRestypes(ts, Nil)))
+ NullaryMethodType(glbNorm(matchingRestypes(ts, Nil), depth))
case ts @ TypeBounds(_, _) :: rest =>
TypeBounds(lub(ts map (_.bounds.lo), depth), glb(ts map (_.bounds.hi), depth))
case ts =>
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index dfae6c50be..335533f1ca 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -38,6 +38,8 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
} catch {
case ex: IOException =>
throw ex
+ case ex: MissingRequirementError =>
+ throw ex
case ex: Throwable =>
/*if (settings.debug.value)*/ ex.printStackTrace()
throw new RuntimeException("error reading Scala signature of "+filename+": "+ex.getMessage())
@@ -815,14 +817,12 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
protected def errorBadSignature(msg: String) =
throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
- protected def errorMissingRequirement(msg: String): Nothing =
- if (debug) errorBadSignature(msg)
- else throw new IOException("class file needed by "+classRoot.name+" is missing.\n"+msg)
-
- protected def errorMissingRequirement(name: Name, owner: Symbol): Nothing =
- errorMissingRequirement(
- "reference " + (if (name.isTypeName) "type " else "value ") +
- name.decode + " of " + owner.tpe.widen + " refers to nonexisting symbol.")
+ protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol =
+ missingHook(owner, name) orElse {
+ throw new MissingRequirementError(
+ "reference " + (if (name.isTypeName) "type " else "value ") +
+ name.decode + " of " + owner.tpe.widen)
+ }
def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that.
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index a01595fad1..35e95b4799 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -16,6 +16,7 @@ import java.lang.reflect.{
WildcardType,
AnnotatedElement
}
+import internal.MissingRequirementError
import internal.pickling.ByteCodecs
import internal.ClassfileConstants._
import internal.pickling.UnPickler
@@ -41,6 +42,14 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
*/
def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = {
def markAbsent(tpe: Type) = List(clazz, module, module.moduleClass) foreach (_ setInfo tpe)
+ def handleError(ex: Exception) = {
+ markAbsent(ErrorType)
+ if (settings.debug.value) ex.printStackTrace()
+ val msg = ex.getMessage()
+ throw new MissingRequirementError(
+ if (msg eq null) "reflection error while loading " + clazz.name
+ else "error while loading " + clazz.name + ", " + msg)
+ }
try {
println("unpickling " + clazz + " " + module) //debug
markAbsent(NoType)
@@ -69,13 +78,10 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
}
}
} catch {
+ case ex: MissingRequirementError =>
+ handleError(ex)
case ex: IOException =>
- markAbsent(ErrorType)
- if (settings.debug.value) ex.printStackTrace()
- val msg = ex.getMessage()
- throw new IOException(
- if (msg eq null) "reflection error while loading " + clazz.name
- else "error while loading " + clazz.name + ", " + msg)
+ handleError(ex)
}
}
@@ -133,9 +139,14 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
val tparams = jclazz.getTypeParameters.toList map createTypeParameter
- val jsuperclazz = jclazz.getGenericSuperclass
- val superclazz = if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz)
- val parents = superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala)
+ val parents = try {
+ parentsLevel += 1
+ val jsuperclazz = jclazz.getGenericSuperclass
+ val superclazz = if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz)
+ superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala)
+ } finally {
+ parentsLevel -= 1
+ }
clazz setInfo polyType(tparams, new ClassInfoType(parents, newScope, clazz))
module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass)
module setInfo module.moduleClass.tpe
@@ -143,17 +154,33 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
def enter(sym: Symbol) =
(if (sym.isStatic) module.moduleClass else clazz).info.decls enter sym
- for (jfield <- jclazz.getDeclaredFields)
- enter(jfieldAsScala(jfield))
+ pendingLoadActions = { () =>
+
+ for (jfield <- jclazz.getDeclaredFields)
+ enter(jfieldAsScala(jfield))
+
+ for (jmeth <- jclazz.getDeclaredMethods)
+ enter(jmethodAsScala(jmeth))
+
+ for (jconstr <- jclazz.getConstructors)
+ enter(jconstrAsScala(jconstr))
- for (jmeth <- jclazz.getDeclaredMethods)
- enter(jmethodAsScala(jmeth))
+ } :: pendingLoadActions
- for (jconstr <- jclazz.getConstructors)
- enter(jconstrAsScala(jconstr))
+ if (parentsLevel == 0) {
+ while (!pendingLoadActions.isEmpty) {
+ val item = pendingLoadActions.head
+ pendingLoadActions = pendingLoadActions.tail
+ item()
+ }
+ }
}
}
+ /** used to avoid cyclies */
+ var parentsLevel = 0
+ var pendingLoadActions: List[() => Unit] = Nil
+
/**
* If Java modifiers `mods` contain STATIC, return the module class
* of the companion module of `clazz`, otherwise the class `clazz` itself.
@@ -252,13 +279,20 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
* The Scala package with given fully qualified name. Unlike `packageNameToScala`,
* this one bypasses the cache.
*/
- private def makeScalaPackage(fullname: String): Symbol = {
+ def makeScalaPackage(fullname: String): Symbol = {
println("make scala pkg "+fullname)
val split = fullname lastIndexOf '.'
val owner = if (split > 0) packageNameToScala(fullname take split) else RootClass
assert(owner.isModuleClass, owner+" when making "+fullname)
- val name = fullname drop (split + 1)
- val pkg = owner.info decl newTermName(name)
+ val name = newTermName(fullname drop (split + 1))
+ var pkg = owner.info decl name
+ if (pkg == NoSymbol) {
+ pkg = owner.newPackage(NoPosition, name)
+ pkg.moduleClass setInfo newPackageType(pkg.moduleClass)
+ pkg setInfo typeRef(pkg.owner.thisType, pkg.moduleClass, Nil)
+ owner.info.decls enter pkg
+ } else if (!pkg.isPackage)
+ throw new ReflectError(pkg+" is not a package")
println(" = "+pkg+"/"+pkg.moduleClass)
pkg.moduleClass
}
@@ -329,7 +363,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
val tparam = owner.newExistential(NoPosition, newTypeName("T$" + tparams.length))
.setInfo(TypeBounds(
lub(jwild.getLowerBounds.toList map typeToScala),
- glb(scala.tools.nsc.util.trace("glb args")(jwild.getUpperBounds.toList) map typeToScala map objToAny)))
+ glb(scala.tools.nsc.util.trace("glb args of "+owner)(jwild.getUpperBounds.toList) map typeToScala map objToAny)))
tparams += tparam
typeRef(NoPrefix, tparam, List())
case _ =>
@@ -428,4 +462,6 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
copyAnnotations(meth, jconstr)
meth
}
-} \ No newline at end of file
+}
+
+class ReflectError(msg: String) extends java.lang.Error(msg) \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala
index d7cdd3c684..f3097e2b6e 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/Loaders.scala
@@ -22,6 +22,7 @@ trait Loaders { self: SymbolTable =>
*/
class TopClassCompleter(clazz: Symbol, module: Symbol) extends LazyType {
def makePackage() {
+ println("wrong guess; making package "+clazz)
val ptpe = newPackageType(module.moduleClass)
for (sym <- List(clazz, module, module.moduleClass)) {
sym setFlag Flags.PACKAGE
@@ -80,7 +81,7 @@ trait Loaders { self: SymbolTable =>
* a TopClassCompleter type. When any of the two symbols is forced via info,
* the TopClassCompleter will sort things out.
*/
- def newPackageType(pkg: Symbol) = new ClassInfoType(List(), new PackageScope(pkg), pkg) {
+ def newPackageType(pkgClass: Symbol) = new ClassInfoType(List(), new PackageScope(pkgClass), pkgClass) {
/*
override def decl(name: Name): Symbol =
(decls lookup name) orElse {
@@ -94,24 +95,31 @@ trait Loaders { self: SymbolTable =>
override def findMember(name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean) =
member(name).filter (m => m.hasAllFlags(requiredFlags) && !m.hasFlag(excludedFlags))
*/
- override def safeToString = pkg.toString
+ override def safeToString = pkgClass.toString
}
- class PackageScope(pkg: Symbol) extends Scope {
+ class PackageScope(pkgClass: Symbol) extends Scope {
override def lookupEntry(name: Name): ScopeEntry = {
val e = super.lookupEntry(name)
if (e != null)
e
else try {
- if (name.isTypeName) jClass.forName(pkg.fullName + "." + name)
- val (clazz, module) = createClassModule(pkg, name.toTypeName, new TopClassCompleter(_, _))
- println("created "+module+"/"+module.moduleClass+" in "+pkg+", scope = "+(this map (_.name)))
+ jClass.forName(pkgClass.fullName + "." + name)
+ val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _))
+ println("created "+module+"/"+module.moduleClass+" in "+pkgClass+", scope = "+(this map (_.name)))
lookupEntry(name)
} catch {
case ex: ClassNotFoundException =>
- println("not found: "+pkg.fullName + "." + name)
+ println("not found : "+pkgClass.fullName + "." + name)
null
}
}
+ override def mkScope(decls: List[Symbol]) = {
+ val result = new PackageScope(pkgClass)
+ decls foreach (result enter)
+ result
+ }
}
+
+ override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass)
}
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
index 508dd0f7df..eea45d787a 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -72,6 +72,7 @@ object Mirror extends Mirror
/** test code; should go to tests once things settle down a bit
*
+ */
object Test extends Mirror with App {
val sym = classToScala(classOf[scala.collection.Iterable[_]])
println(sym)
@@ -80,4 +81,3 @@ object Test extends Mirror with App {
val ms = sym.info.members.toList map (_.initialize)
println("members = "+(ms map (_.defString) mkString ("\n ")))
}
-*/ \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala
index 9e560e0d20..eb4026f7ef 100644
--- a/src/compiler/scala/reflect/runtime/SymbolTable.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolTable.scala
@@ -6,4 +6,21 @@ package runtime
* It can be used either from the reflexive mirror itself (class Universe), or else from
* a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal)
*/
-trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with Loaders
+trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with Loaders {
+
+ /** If `owner` is a package class and `name` is a term name, make a new package
+ * <owner>.<name>, otherwise return NoSymbol
+ */
+ override def missingHook(owner: Symbol, name: Name): Symbol =
+ if (name.isTermName && owner.hasPackageFlag)
+ makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule
+ else {
+ println(name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
+ super.missingHook(owner, name)
+ }
+
+ /** Assert that packages have package scopes */
+ override def validateClassInfo(tp: ClassInfoType) {
+ assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope])
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala
index 50c0816bca..63cb62ee2e 100644
--- a/src/compiler/scala/tools/nsc/CompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala
@@ -5,7 +5,6 @@
package scala.tools.nsc
-import java.io.IOException
import scala.collection.mutable.ListBuffer
import io.File
diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
index d11c91a092..cef13843dc 100644
--- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala
+++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
@@ -5,7 +5,6 @@
package scala.tools.nsc
-import java.io.IOException
import java.net.URL
import scala.tools.util.PathResolver
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index c3fc2732a9..c8c6a71038 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -13,6 +13,7 @@ import scala.compat.Platform.currentTime
import scala.tools.nsc.util.{ ClassPath }
import classfile.ClassfileParser
import reflect.internal.Flags._
+import reflect.internal.MissingRequirementError
import util.Statistics._
import scala.tools.nsc.io.AbstractFile
@@ -105,6 +106,14 @@ abstract class SymbolLoaders {
})
}
override def complete(root: Symbol) : Unit = {
+ def signalError(ex: Exception) {
+ ok = false
+ if (settings.debug.value) ex.printStackTrace()
+ val msg = ex.getMessage()
+ globalError(
+ if (msg eq null) "i/o error while loading " + root.name
+ else "error while loading " + root.name + ", " + msg);
+ }
try {
val start = currentTime
val currentphase = phase
@@ -116,12 +125,9 @@ abstract class SymbolLoaders {
setSource(root.companionSymbol) // module -> class, class -> module
} catch {
case ex: IOException =>
- ok = false
- if (settings.debug.value) ex.printStackTrace()
- val msg = ex.getMessage()
- globalError(
- if (msg eq null) "i/o error while loading " + root.name
- else "error while loading " + root.name + ", " + msg);
+ signalError(ex)
+ case ex: MissingRequirementError =>
+ signalError(ex)
}
initRoot(root)
if (!root.isPackageClass) initRoot(root.companionSymbol)
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index 53016dd748..62946020eb 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -64,7 +64,7 @@ abstract class Flatten extends InfoTransform {
typeRef(sym.toplevelClass.owner.thisType, sym, Nil)
case ClassInfoType(parents, decls, clazz) =>
var parents1 = parents
- val decls1 = new Scope
+ val decls1 = decls.mkScope()
if (clazz.isPackageClass) {
atPhase(phase.next)(decls foreach (decls1 enter _))
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 794f244309..725bf90af3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3668,8 +3668,11 @@ trait Typers extends Modes with Adaptations {
if (name == nme.ERROR && forInteractive)
return makeErrorTree
- if (!qual.tpe.widen.isErroneous)
+ if (!qual.tpe.widen.isErroneous) {
+ val lastTry = missingHook(qual.tpe.typeSymbol, name)
+ if (lastTry != NoSymbol) return typed1(tree setSymbol lastTry, mode, pt)
notAMemberError(tree.pos, qual, name)
+ }
if (forInteractive) makeErrorTree else setError(tree)
} else {
diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala
index 4f9813279f..818b5a06ab 100644
--- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala
+++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala
@@ -7,7 +7,7 @@ package scala.tools
package nsc
package util
-import java.io.{File, FileInputStream, PrintStream, IOException}
+import java.io.{File, FileInputStream, PrintStream}
import java.lang.Long.toHexString
import java.lang.Float.intBitsToFloat
import java.lang.Double.longBitsToDouble