aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala7
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala10
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala26
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala8
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala8
-rw-r--r--src/dotty/tools/dotc/core/Types.scala29
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala29
-rw-r--r--src/dotty/tools/dotc/core/transform/Erasure.scala2
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