diff options
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 26 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymbolLoaders.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 29 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 29 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/transform/Erasure.scala | 2 |
8 files changed, 76 insertions, 43 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index ea2682516..4b167baad 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -55,8 +55,11 @@ class Definitions(implicit ctx: Context) { private def newMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol = newSymbol(cls, name.encode, flags | Method, info).entered.asTerm - private def newAliasType(name: TypeName, tpe: Type, flags: FlagSet = EmptyFlags): TypeSymbol = - newSymbol(ScalaPackageClass, name, flags, TypeAlias(tpe)).entered.asType + private def newAliasType(name: TypeName, tpe: Type, flags: FlagSet = EmptyFlags): TypeSymbol = { + val sym = newSymbol(ScalaPackageClass, name, flags, TypeAlias(tpe)) + ScalaPackageClass.preDecls.enter(sym) + sym + } private def newPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int, resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = { diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index bfd150999..272b6f505 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -333,11 +333,11 @@ object Denotations { /** An overloaded denotation consisting of the alternatives of both given denotations. */ case class MultiDenotation(denot1: Denotation, denot2: Denotation) extends Denotation { - final def symbol = unsupported("symbol") - final def info = unsupported("info") + final def symbol = multiHasNot("symbol") + final def info = multiHasNot("info") final def validFor = denot1.validFor & denot2.validFor final def isType = false - def signature(implicit ctx: Context) = unsupported("signature") + def signature(implicit ctx: Context) = multiHasNot("signature") def atSignature(sig: Signature)(implicit ctx: Context): SingleDenotation = denot1.atSignature(sig) orElse denot2.atSignature(sig) def current(implicit ctx: Context): Denotation = @@ -364,6 +364,10 @@ object Denotations { def derivedMultiDenotation(d1: Denotation, d2: Denotation) = if ((d1 eq denot1) && (d2 eq denot2)) this else MultiDenotation(d1, d2) override def toString = alternatives.mkString(" <and> ") + + private def multiHasNot(op: String): Nothing = + throw new UnsupportedOperationException( + s"multi-denotation with alternatives $alternatives does not implement operation $op") } /** A non-overloaded denotation */ diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 91f157e2c..16dab0df8 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -106,7 +106,7 @@ object SymDenotations { if ((this is ModuleClass) && !(this is PackageClass)) tp match { case ClassInfo(_, _, _, _, ost) => - assert(ost.isInstanceOf[TermRef], tp) + assert(ost.isInstanceOf[TermRef] || ost.isInstanceOf[TermSymbol], tp) case _ => } myInfo = tp @@ -162,6 +162,17 @@ object SymDenotations { case _ => info.decls } + /** If this is a package class, the symbols entered in it + * before it is completed. (this is needed to eagerly enter synthetic + * aliases such as AnyRef into a package class without forcing it. + * Right now, I believe the only usage is for the three synthetic aliases + * in Definitions. + */ + final def preDecls(implicit ctx: Context): MutableScope = myInfo match { + case pinfo: SymbolLoaders # PackageLoader => pinfo.preDecls + case _ => decls.asInstanceOf[MutableScope] + } + // ------ Names ---------------------------------------------- /** The name with which the denoting symbol was created */ @@ -451,7 +462,7 @@ object SymDenotations { final def sourceModule: Symbol = myInfo match { case ClassInfo(_, _, _, _, selfType: TermRefBySym) if this is ModuleClass => selfType.fixedSym - case info: ClassCompleterWithDecls => + case info: ModuleClassCompleter => info.sourceModule case _ => NoSymbol @@ -909,7 +920,8 @@ object SymDenotations { case nil => denots } - collect(ownDenots, classParents) + if (name.isConstructorName) ownDenots + else collect(ownDenots, classParents) } else NoDenotation override final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = @@ -1044,20 +1056,24 @@ object SymDenotations { def apply(module: TermSymbol, modcls: ClassSymbol) = this } + /** A base type for completers of module classes that knows about `sourceModule` */ + trait ModuleClassCompleter extends LazyType { + def sourceModule: Symbol + } + /** A lazy type for completing a class that already has a scope with all * declarations in the class. */ class ClassCompleterWithDecls(val decls: Scope, underlying: LazyType = NoCompleter) extends LazyType { def complete(denot: SymDenotation): Unit = underlying.complete(denot) - def sourceModule: Symbol = NoSymbol } /** A lazy type for completing a class that already has a scope with all * declarations in the class. */ class ModuleClassCompleterWithDecls(module: Symbol, decls: Scope, underlying: LazyType = NoCompleter) - extends ClassCompleterWithDecls(decls, underlying) { + extends ClassCompleterWithDecls(decls, underlying) with ModuleClassCompleter { override def sourceModule = module } diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala index dc65b77f4..2fbe147c7 100644 --- a/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -142,13 +142,15 @@ class SymbolLoaders { /** Load contents of a package */ class PackageLoader(override val sourceModule: TermSymbol, classpath: ClassPath)(implicit val cctx: CondensedContext) - extends ClassCompleterWithDecls(newScope) with SymbolLoader { // !!! TODO: ClassCompleter needed? + extends SymbolLoader with ModuleClassCompleter { def description = "package loader " + classpath.name + private[core] val preDecls: MutableScope = newScope + def doComplete(root: SymDenotation) { assert(root is PackageClass, root) val pre = root.owner.thisType - root.info = ClassInfo(pre, root.symbol.asClass, Nil, root.decls, TermRef.withSym(pre, sourceModule)) + root.info = ClassInfo(pre, root.symbol.asClass, Nil, preDecls, TermRef.withSym(pre, sourceModule)) if (!sourceModule.isCompleted) sourceModule.completer.complete(sourceModule) if (!root.isRoot) { @@ -205,7 +207,7 @@ class SymbolLoaders { /** A lazy type that completes itself by calling parameter doComplete. * Any linked modules/classes or module classes are also initialized. */ -trait SymbolLoader extends LazyType { +abstract class SymbolLoader extends LazyType { implicit val cctx: CondensedContext /** Load source or class file for `root`, return */ diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 3e8b13320..f7b079a69 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -92,13 +92,13 @@ trait Symbols { this: Context => flags: FlagSet, parents: List[TypeRef], decls: Scope = newScope, - optSelfType: Type = NoType, + selfInfo: Type = NoType, privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord, assocFile: AbstractFile = null): ClassSymbol = newClassSymbol( owner, name, flags, - ClassInfo(owner.thisType, _, parents, decls, optSelfType), + ClassInfo(owner.thisType, _, parents, decls, selfInfo), privateWithin, coord, assocFile) /** Create a module symbol with associated module class @@ -213,8 +213,8 @@ trait Symbols { this: Context => newConstructor(cls, EmptyFlags, Nil, Nil) /** Create a symbol representing a selftype declaration for class `cls`. */ - def newSelfSym(cls: ClassSymbol, name: TermName = nme.WILDCARD, optSelfType: Type = NoType): TermSymbol = - ctx.newSymbol(cls, name, SelfSymFlags, optSelfType orElse cls.classInfo.selfType, coord = cls.coord) + def newSelfSym(cls: ClassSymbol, name: TermName = nme.WILDCARD, selfInfo: Type = NoType): TermSymbol = + ctx.newSymbol(cls, name, SelfSymFlags, selfInfo orElse cls.classInfo.selfType, coord = cls.coord) /** Create new type parameters with given owner, names, and flags. * @param boundsFn A function that, given type refs to the newly created diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index cf756859f..1bc8f1646 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1774,17 +1774,22 @@ object Types { * These are all normalized to be TypeRefs by moving any refinements * to be member definitions of the class itself. * @param decls The symbols defined directly in this class. - * @param optSelfType The type of `this` in this class, if explicitly given, NoType otherwise. + * @param selfInfo The type of `this` in this class, if explicitly given, + * NoType otherwise. If class is compiled from source, can also + * be a reference to the self symbol containing the type. */ abstract case class ClassInfo( prefix: Type, cls: ClassSymbol, classParents: List[TypeRef], decls: Scope, - optSelfType: Type) extends CachedGroundType with TypeType { + selfInfo: DotClass /* should be: Type | Symbol */) extends CachedGroundType with TypeType { - def selfType(implicit ctx: Context): Type = - if (optSelfType.exists) optSelfType else cls.typeConstructor + def selfType(implicit ctx: Context): Type = selfInfo match { + case NoType => cls.typeConstructor + case self: Symbol => self.info + case tp: Type => tp + } def rebase(tp: Type)(implicit ctx: Context): Type = if ((prefix eq cls.owner.thisType) || !cls.owner.isClass) tp @@ -1812,21 +1817,21 @@ object Types { def derivedClassInfo(prefix: Type)(implicit ctx: Context) = if (prefix eq this.prefix) this - else ClassInfo(prefix, cls, classParents, decls, optSelfType) + else ClassInfo(prefix, cls, classParents, decls, selfInfo) - def derivedClassInfo(prefix: Type, classParents: List[TypeRef], optSelfType: Type)(implicit ctx: Context) = - if ((prefix eq this.prefix) && (classParents eq this.classParents) && (optSelfType eq this.optSelfType)) this - else ClassInfo(prefix, cls, classParents, decls, optSelfType) + def derivedClassInfo(prefix: Type, classParents: List[TypeRef], selfInfo: Type)(implicit ctx: Context) = + if ((prefix eq this.prefix) && (classParents eq this.classParents) && (selfInfo eq this.selfInfo)) this + else ClassInfo(prefix, cls, classParents, decls, selfInfo) override def computeHash = doHash(cls, prefix) } - final class CachedClassInfo(prefix: Type, cls: ClassSymbol, classParents: List[TypeRef], decls: Scope, optSelfType: Type) - extends ClassInfo(prefix, cls, classParents, decls, optSelfType) + final class CachedClassInfo(prefix: Type, cls: ClassSymbol, classParents: List[TypeRef], decls: Scope, selfInfo: DotClass) + extends ClassInfo(prefix, cls, classParents, decls, selfInfo) object ClassInfo { - def apply(prefix: Type, cls: ClassSymbol, classParents: List[TypeRef], decls: Scope, optSelfType: Type = NoType)(implicit ctx: Context) = - unique(new CachedClassInfo(prefix, cls, classParents, decls, optSelfType)) + def apply(prefix: Type, cls: ClassSymbol, classParents: List[TypeRef], decls: Scope, selfInfo: DotClass = NoType)(implicit ctx: Context) = + unique(new CachedClassInfo(prefix, cls, classParents, decls, selfInfo)) } /** Type bounds >: lo <: hi */ diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 23fb79f8f..2b18e2263 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -84,7 +84,7 @@ object UnPickler { tp.derivedPolyType(paramNames, tp.paramBounds, arrayToRepeated(tp.resultType)) } - def setClassInfo(denot: ClassDenotation, info: Type, optSelfType: Type = NoType)(implicit ctx: Context): Unit = { + def setClassInfo(denot: ClassDenotation, info: Type, selfInfo: Type = NoType)(implicit ctx: Context): Unit = { val cls = denot.classSymbol val (tparams, TempClassInfoType(parents, decls, clazz)) = info match { case TempPolyType(tps, cinfo) => (tps, cinfo) @@ -97,9 +97,9 @@ object UnPickler { else denot.enter(tparam, decls) } val ost = - if ((optSelfType eq NoType) && (denot is ModuleClass)) + if ((selfInfo eq NoType) && (denot is ModuleClass)) TermRef.withSym(denot.owner.thisType, denot.sourceModule.asTerm) - else optSelfType + else selfInfo denot.info = ClassInfo(denot.owner.thisType, denot.classSymbol, parentRefs, decls, ost) } } @@ -452,13 +452,14 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: // create a type alias instead cctx.newSymbol(owner, name, flags, localMemberUnpickler, coord = start) else { - def completer(cls: Symbol) = new LocalClassUnpickler(cls) { - override def sourceModule = - if (flags is ModuleClass) - cls.owner.decls.lookup(cls.name.stripModuleClassSuffix.toTermName) - .suchThat(_ is Module).symbol - else NoSymbol - } + def completer(cls: Symbol) = + if (flags is ModuleClass) + new LocalClassUnpickler(cls) with ModuleClassCompleter { + override def sourceModule = + cls.owner.decls.lookup(cls.name.stripModuleClassSuffix.toTermName) + .suchThat(_ is Module).symbol + } + else new LocalClassUnpickler(cls) cctx.newClassSymbol(owner, name.asTypeName, flags, completer, coord = start) } case MODULEsym | VALsym => @@ -491,8 +492,8 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: val tp = at(inforef, readType) denot match { case denot: ClassDenotation => - val optSelfType = if (atEnd) NoType else readTypeRef() - setClassInfo(denot, tp, optSelfType) + val selfInfo = if (atEnd) NoType else readTypeRef() + setClassInfo(denot, tp, selfInfo) case denot => val tp1 = depoly(tp, denot) denot.info = if (tag == ALIASsym) TypeAlias(tp1) else tp1 @@ -529,7 +530,9 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: extends ClassCompleterWithDecls(symScope(cls), localMemberUnpickler) def rootClassUnpickler(start: Coord, cls: Symbol, module: Symbol) = - new ClassCompleterWithDecls(symScope(cls), new AtStartUnpickler(start)) with SymbolLoaders.SecondCompleter { + new ClassCompleterWithDecls(symScope(cls), new AtStartUnpickler(start)) + with ModuleClassCompleter + with SymbolLoaders.SecondCompleter { override def sourceModule = module } diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala index 31679f05e..55a65dd87 100644 --- a/src/dotty/tools/dotc/core/transform/Erasure.scala +++ b/src/dotty/tools/dotc/core/transform/Erasure.scala @@ -57,7 +57,7 @@ object Erasure { tp.paramNames, tp.paramTypes.mapConserve(erasure), resultErasure(tp.resultType)) case tp: PolyType => erasure(tp.resultType) - case tp @ ClassInfo(pre, cls, classParents, decls, optSelfType) => + case tp @ ClassInfo(pre, cls, classParents, decls, _) => val parents: List[TypeRef] = if (cls == defn.ObjectClass || cls.isPrimitiveValueClass) Nil else if (cls == defn.ArrayClass) defn.ObjectClass.typeConstructor :: Nil |