aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-03-14 16:56:09 +0100
committerMartin Odersky <odersky@gmail.com>2013-03-14 16:56:09 +0100
commit016a60cda879f9c326d3f732fe33ec070f998999 (patch)
tree4ae38c61c39cf0060de3890e26b2f1464334eeb5
parentd2767983aa4aeb9caccfd56273a1ac93e576bb4a (diff)
downloaddotty-016a60cda879f9c326d3f732fe33ec070f998999.tar.gz
dotty-016a60cda879f9c326d3f732fe33ec070f998999.tar.bz2
dotty-016a60cda879f9c326d3f732fe33ec070f998999.zip
Improvements to stub handling.
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala20
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala39
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala4
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala2
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala33
5 files changed, 51 insertions, 47 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 880182614..65c46c701 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -1,8 +1,3 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2012 LAMP/EPFL
- * @author Martin Odersky
- */
-
package dotty.tools
package dotc
package core
@@ -68,8 +63,12 @@ class Definitions(implicit ctx: Context) {
lazy val JavaLangPackageVal = requiredPackage("java.lang")
lazy val ObjectClass = requiredClass("java.lang.Object")
- lazy val AnyRefAlias: TypeSymbol = ctx.newSymbol(
- ScalaPackageClass, tpnme.AnyRef, EmptyFlags, TypeAlias(ObjectClass.typeConstructor)).entered
+ lazy val AnyRefAlias: TypeSymbol = {
+ val anyRef = ctx.newSymbol(
+ ScalaPackageClass, tpnme.AnyRef, EmptyFlags, TypeAlias(ObjectClass.typeConstructor))
+ ScalaPackageClass.preCompleteDecls.openForMutations.enter(anyRef)
+ anyRef
+ }
lazy val AnyClass: ClassSymbol = ctx.newCompleteClassSymbol(
ScalaPackageClass, tpnme.Any, Abstract, Nil).entered
lazy val AnyValClass: ClassSymbol = requiredClass("scala.AnyVal")
@@ -84,7 +83,7 @@ class Definitions(implicit ctx: Context) {
lazy val PredefModule = requiredModule("scala.Predef")
// lazy val FunctionClass: ClassSymbol = requiredClass("scala.Function")
- lazy val SingletonClass: ClassSymbol = requiredClass("scala.Singleton")
+ lazy val SingletonClass: ClassSymbol = requiredClass("dotty.Singleton")
lazy val SeqClass: ClassSymbol = requiredClass("scala.collection.Seq")
lazy val ArrayClass: ClassSymbol = requiredClass("scala.Array")
lazy val uncheckedStableClass: ClassSymbol = requiredClass("scala.annotation.unchecked.uncheckedStable")
@@ -238,16 +237,15 @@ class Definitions(implicit ctx: Context) {
/** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
lazy val syntheticCoreClasses = List(
- AnnotationDefaultAnnot, // #2264
+ AnyRefAlias,
+ SingletonClass,
RepeatedParamClass,
JavaRepeatedParamClass,
ByNameParamClass,
AnyClass,
- AnyRefAlias,
AnyValClass,
NullClass,
NothingClass,
- SingletonClass,
EqualsPatternClass)
private[this] var _isInitialized = false
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index c3486aa0a..a3b48926e 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -140,7 +140,7 @@ object Denotations {
/** The variant of this denotation that's current in the given context. */
def current(implicit ctx: Context): Denotation
- /** Is this denotation different from NoDenotation? */
+ /** Is this denotation different from NoDenotation or an ErrorDenotation? */
def exists: Boolean = true
/** If this denotation does not exist, fallback to alternative */
@@ -170,22 +170,22 @@ object Denotations {
*/
def disambiguate(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation = this match {
case sdenot: SingleDenotation => sdenot
- case mdenot => suchThat(p)
+ case mdenot => suchThat(p) orElse NoQualifyingRef(alternatives)
}
/** Return symbol in this denotation that satisfies the given predicate.
- * Throw a `TypeError` if predicate fails to disambiguate symbol.
- * Return a stubsymbol if no alternative satisfies the predicate.
+ * Return a stubsymbol denotation is a missing ref.
+ * Throw a `TypeError` if predicate fails to disambiguate symbol or no alternative matches.
*/
- def requiredSymbol(p: Symbol => Boolean, name: Name, source: AbstractFile = null)(implicit ctx: Context): Symbol = {
- val sym = disambiguate(p).symbol
- if (sym.exists) sym
- else {
- val firstSym = ((NoSymbol: Symbol) /: alternatives.map(_.symbol)) (_ orElse _)
- val owner = if (firstSym.exists) firstSym.owner else NoSymbol
- ctx.newStubSymbol(owner, name, source)
+ def requiredSymbol(p: Symbol => Boolean, source: AbstractFile = null)(implicit ctx: Context): Symbol =
+ disambiguate(p) match {
+ case MissingRef(ownerd, name) =>
+ ctx.newStubSymbol(ownerd.symbol, name, source)
+ case NoDenotation | _: NoQualifyingRef =>
+ throw new TypeError(s"None of the alternatives of $this satisfies required predicate")
+ case denot =>
+ denot.symbol
}
- }
/** Form a denotation by conjoining with denotation `that` */
def & (that: Denotation)(implicit ctx: Context): Denotation =
@@ -490,11 +490,16 @@ object Denotations {
}
class ErrorDenotation(implicit ctx: Context) extends SingleDenotation {
+ override def exists = false
val symbol = NoSymbol
val info = NoType
validFor = Period.allInRun(ctx.runId)
}
+ case class MissingRef(val owner: SingleDenotation, name: Name)(implicit ctx: Context) extends ErrorDenotation
+
+ case class NoQualifyingRef(alts: List[SingleDenotation])(implicit ctx: Context) extends ErrorDenotation
+
// --------------- PreDenotations -------------------------------------------------
/** A PreDenotation represents a group of single denotations
@@ -556,7 +561,9 @@ object Denotations {
trait DenotationsBase { this: ContextBase =>
- /** The current denotation of the static reference given by path. */
+ /** The current denotation of the static reference given by path,
+ * or a MissingRef or NoQualifyingRef instance, if it does not exist.
+ */
def staticRef(path: Name)(implicit ctx: Context): Denotation = {
def recur(path: Name, len: Int): Denotation = {
val point = path.lastIndexOf('.', len - 1)
@@ -564,15 +571,15 @@ object Denotations {
if (point > 0) recur(path.toTermName, point).disambiguate(_.isParameterless)
else if (path.isTermName) defn.RootClass.denot
else defn.EmptyPackageClass.denot
- if (!owner.exists) NoDenotation
+ if (!owner.exists) owner
else {
val name = path slice (point + 1, len)
val result = owner.info.member(name)
- if (result != NoDenotation) result
+ if (result ne NoDenotation) result
else {
val alt = missingHook(owner.symbol.moduleClass, name)
if (alt.exists) alt.denot
- else result
+ else MissingRef(owner, name)
}
}
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 029b6035b..578fa325b 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -145,7 +145,7 @@ object SymDenotations {
/** The symbols defined in this class when the class is not yet completed.
* @pre: this is a class
*/
- protected final def preCompleteDecls: Scope = _info match {
+ protected[core] final def preCompleteDecls: Scope = _info match {
case cinfo: LazyClassInfo => cinfo.decls
case cinfo: ClassInfo => cinfo.decls
}
@@ -990,7 +990,7 @@ object SymDenotations {
|in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
|It may be completely missing from the current classpath, or the version on
|the classpath might be incompatible with the version used when compiling $src.""".stripMargin)
- if (cctx.debug) (new Throwable).printStackTrace
+ if (cctx.debug) throw new Error()
initializeToDefaults(denot)
}
}
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 41c4c727b..2a8c9cfc5 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -134,7 +134,7 @@ class SymbolLoaders {
def doComplete(root: SymDenotation) {
assert(root is PackageClass, root)
val pre = root.owner.thisType
- root.info = ClassInfo(pre, root.symbol.asClass, Nil, newScope, TermRef(pre, module))
+ root.info = ClassInfo(pre, root.symbol.asClass, Nil, root.preCompleteDecls, TermRef(pre, module))
if (!module.isCompleted)
module.completer.complete(module)
if (!root.isRoot) {
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 57c29f66e..e76de6bdf 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -177,14 +177,19 @@ trait Symbols { this: Context =>
* when attempted to be completed.
*/
def newStubSymbol(owner: Symbol, name: Name, file: AbstractFile = null): Symbol = {
- def stub = new StubInfo()(condensed)
- println(s"creating stub for $name") // !!! DEBUG
- name match {
+ def stubCompleter = new StubInfo()(condensed)
+ val normalizedOwner = if (owner is ModuleVal) owner.moduleClass else owner
+ //println(s"creating stub for ${name.show}, owner = ${normalizedOwner.denot.debugString}, file = $file")
+ //println(s"decls = ${normalizedOwner.preCompleteDecls.toList.map(_.debugString).mkString("\n ")}") // !!! DEBUG
+ //throw new Error()
+ val stub = name match {
case name: TermName =>
- newModuleSymbol(owner, name, EmptyFlags, EmptyFlags, stub, assocFile = file)
+ newModuleSymbol(normalizedOwner, name, EmptyFlags, EmptyFlags, stubCompleter, assocFile = file)
case name: TypeName =>
- newClassSymbol(owner, name, EmptyFlags, stub, assocFile = file)
+ newClassSymbol(normalizedOwner, name, EmptyFlags, stubCompleter, assocFile = file)
}
+ stub.info //!!! DEBUG, force the error for now
+ stub
}
/** Create the local template dummy of given class `cls`. */
@@ -257,20 +262,14 @@ trait Symbols { this: Context =>
// ----- Locating predefined symbols ----------------------------------------
- def requiredPackage(path: PreName): TermSymbol = {
- val pathName = path.toTermName
- base.staticRef(pathName).requiredSymbol(_ is Package, pathName).asTerm
- }
+ def requiredPackage(path: PreName): TermSymbol =
+ base.staticRef(path.toTermName).requiredSymbol(_ is Package).asTerm
- def requiredClass(path: PreName): ClassSymbol = {
- val pathName = path.toTypeName
- base.staticRef(pathName).requiredSymbol(_.isClass, pathName).asClass
- }
+ def requiredClass(path: PreName): ClassSymbol =
+ base.staticRef(path.toTypeName).requiredSymbol(_.isClass).asClass
- def requiredModule(path: PreName): TermSymbol = {
- val pathName = path.toTermName
- base.staticRef(pathName).requiredSymbol(_ is Module, pathName).asTerm
- }
+ def requiredModule(path: PreName): TermSymbol =
+ base.staticRef(path.toTermName).requiredSymbol(_ is Module).asTerm
}
object Symbols {