From 016a60cda879f9c326d3f732fe33ec070f998999 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 14 Mar 2013 16:56:09 +0100 Subject: Improvements to stub handling. --- src/dotty/tools/dotc/core/Definitions.scala | 20 ++++++------- src/dotty/tools/dotc/core/Denotations.scala | 39 +++++++++++++++----------- src/dotty/tools/dotc/core/SymDenotations.scala | 4 +-- src/dotty/tools/dotc/core/SymbolLoaders.scala | 2 +- src/dotty/tools/dotc/core/Symbols.scala | 33 +++++++++++----------- 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 { -- cgit v1.2.3