diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TypedTrees.scala | 2 | ||||
-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 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/PlainPrinter.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 92 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/util/Positions.scala | 3 |
14 files changed, 141 insertions, 110 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index 0ce7b3707..9f1fbe446 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -210,16 +210,24 @@ object desugar { flatTree(cdef1 :: companions ::: implicitWrappers) } - /** Expand to: - * <module> val name: name$ = New(name$) - * <module> final class name$ extends parents { self: name.type => body } + /** Expand + * + * object name extends parents { self => body } + * + * to: + * <module> val name: name$ = New(name$) + * <module> final class name$ extends parents { self: name.type => body } */ def moduleDef(mdef: ModuleDef)(implicit ctx: Context): Tree = { val ModuleDef(mods, name, tmpl @ Template(constr, parents, self, body)) = mdef val clsName = name.moduleClassName val clsRef = Ident(clsName) val modul = ValDef(mods | ModuleCreationFlags, name, clsRef, New(clsRef, Nil)) withPos mdef.pos - val clsTmpl = cpy.Template(tmpl, constr, parents, EmptyValDef, body) + val ValDef(selfMods, selfName, selfTpt, selfRhs) = self + if (!selfTpt.isEmpty) ctx.error("object definition may not have a self type", self.pos) + val clsSelf = ValDef(selfMods, selfName, SingletonTypeTree(clsRef), selfRhs) + .withPos(self.pos orElse tmpl.pos.startPos) + val clsTmpl = cpy.Template(tmpl, constr, parents, clsSelf, body) val cls = TypeDef(mods.toTypeFlags & AccessFlags | ModuleClassCreationFlags, clsName, clsTmpl) Thicket(modul, cls) } diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala index 9942728b3..8ac37a104 100644 --- a/src/dotty/tools/dotc/ast/TypedTrees.scala +++ b/src/dotty/tools/dotc/ast/TypedTrees.scala @@ -253,7 +253,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree])(implicit ctx: Context): TypeDef = { val parents = cls.info.parents map (TypeTree(_)) val selfType = - if (cls.classInfo.optSelfType.exists) ValDef(ctx.newSelfSym(cls)) + if (cls.classInfo.selfInfo ne NoType) ValDef(ctx.newSelfSym(cls)) else EmptyValDef def isOwnTypeParamAccessor(stat: Tree) = (stat.symbol is TypeParam) && stat.symbol.owner == cls 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 diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala index fe67f5b89..9e5786126 100644 --- a/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -204,14 +204,14 @@ class PlainPrinter(_ctx: Context) extends Printer { else (if (lo == defn.NothingType) Text() else " >: " ~ toText(lo)) ~ (if (hi == defn.AnyType) Text() else " <: " ~ toText(hi)) - case ClassInfo(pre, cls, cparents, decls, optSelfType) => + case tp @ ClassInfo(pre, cls, cparents, decls, selfInfo) => val preText = toTextLocal(pre) val (tparams, otherDecls) = decls.toList partition treatAsTypeParam val tparamsText = if (tparams.isEmpty) Text() else ("[" ~ dclsText(tparams) ~ "]").close val selfText = - if (optSelfType.exists) - "this: " ~ atPrec(InfixPrec) { toText(optSelfType) } ~ " =>" + if (selfInfo ne NoType) + "this: " ~ atPrec(InfixPrec) { toText(tp.selfType) } ~ " =>" else Text() val parentsText = Text(cparents.map(p => toTextLocal(reconstituteParent(cls, p))), " with ") diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 024577b47..479b29cd8 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -117,35 +117,17 @@ class Namer { typer: Typer => def record(tree: Tree, sym: Symbol): Symbol = { symOfTree(tree) = sym - println(s"entered: $sym in ${ctx.owner} and ${ctx.effectiveScope}") sym } - def recordEnter(tree: Tree, sym: Symbol) = { - if (sym.owner is PackageClass) { - val preExisting = sym.owner.decls.lookup(sym.name) - if (preExisting.defRunId == ctx.runId) - ctx.error(s"${sym.showLocated} is compiled twice", tree.pos) - } - record(tree, ctx.enter(sym)) - } - println(i"creating symbol for $tree") tree match { case tree: TypeDef if tree.isClassDef => - recordEnter(tree, ctx.newClassSymbol( + record(tree, ctx.newClassSymbol( ctx.owner, tree.name, tree.mods.flags, new ClassCompleter(tree), privateWithinClass(tree.mods), tree.pos, ctx.source.file)) - case Thicket((moduleDef: ValDef) :: (modclsDef: TypeDef) :: Nil) => - assert(moduleDef.mods is Module) - val module = ctx.newModuleSymbol( - ctx.owner, moduleDef.name, moduleDef.mods.flags, modclsDef.mods.flags, - (modul, modcls) => new ClassCompleter(modclsDef, modul), - privateWithinClass(moduleDef.mods), modclsDef.pos, ctx.source.file) - recordEnter(modclsDef, module.moduleClass) - recordEnter(moduleDef, module) case tree: MemberDef => - recordEnter(tree, ctx.newSymbol( + record(tree, ctx.newSymbol( ctx.owner, tree.name, tree.mods.flags, new Completer(tree), privateWithinClass(tree.mods), tree.pos)) case imp: Import => @@ -156,6 +138,22 @@ class Namer { typer: Typer => } } + /** If `sym` exists, enter it in effective scope. Check that + * package members are not entered twice in the same run. + */ + def enterSymbol(sym: Symbol)(implicit ctx: Context) = { + if (sym.exists) { + println(s"entered: $sym in ${ctx.owner} and ${ctx.effectiveScope}") + if (sym.owner is PackageClass) { + val preExisting = sym.owner.decls.lookup(sym.name) + if (preExisting.defRunId == ctx.runId) + ctx.error(s"${sym.showLocated} is compiled twice", sym.pos) + } + ctx.enter(sym) + } + sym + } + /** All PackageClassInfoTypes come from here. */ private def createPackageSymbol(pid: RefTree)(implicit ctx: Context): Symbol = { val pkgOwner = pid match { @@ -179,37 +177,35 @@ class Namer { typer: Typer => ctx.fresh.withImportInfo(new ImportInfo(sym, selectors)) /** A new context for the interior of a class */ - def inClassContext(cls: ClassSymbol, selfName: TermName)(implicit ctx: Context): Context = { + def inClassContext(selfInfo: DotClass /* Should be Type | Symbol*/)(implicit ctx: Context): Context = { val localCtx: Context = ctx.fresh.withNewScope - if (selfName != nme.WILDCARD) - localCtx.enter(localCtx.newSelfSym(cls, selfName, cls.thisType)) + selfInfo match { + case sym: Symbol if sym.exists && sym.name != nme.WILDCARD => localCtx.enter(sym) + case _ => + } localCtx } - /** Enter statement */ - def enterSym(stat: Tree)(implicit ctx: Context): Context = stat match { + /** Create top-level symbols for statement and enter them into symbol table */ + def index(stat: Tree)(implicit ctx: Context): Context = stat match { case pcl: PackageDef => val pkg = createPackageSymbol(pcl.pid) - enterSyms(pcl.stats)(ctx.fresh.withOwner(pkg.moduleClass)) + index(pcl.stats)(ctx.fresh.withOwner(pkg.moduleClass)) ctx case imp: Import => importContext(createSymbol(imp), imp.selectors) - case mdef: ModuleDef => - createSymbol(expansion(mdef)) - ctx case mdef: MemberDef => - expansion(mdef).toList foreach createSymbol + expansion(mdef).toList foreach (tree => enterSymbol(createSymbol(tree))) ctx case _ => ctx } - /** Enter all statements in stats. - */ - def enterSyms(stats: List[Tree])(implicit ctx: Context): Context = { + /** Create top-level symbols for statements and enter them into symbol table */ + def index(stats: List[Tree])(implicit ctx: Context): Context = { @tailrec def traverse(stats: List[Tree])(implicit ctx: Context): Context = stats match { case stat :: stats1 => - traverse(stats1)(enterSym(stat)) + traverse(stats1)(index(stat)) case nil => ctx } @@ -266,12 +262,12 @@ class Namer { typer: Typer => } /** The completer for a symbol defined by a class definition */ - class ClassCompleter(original: TypeDef, override val sourceModule: Symbol = NoSymbol)(implicit ctx: Context) + class ClassCompleter(original: TypeDef)(implicit ctx: Context) extends ClassCompleterWithDecls(newScope) { override def complete(denot: SymDenotation): Unit = { val cls = denot.symbol.asClass def localContext = ctx.fresh.withOwner(cls) - println(s"completing ${cls.show}, sourceModule = ${sourceModule.show}") + println(s"completing ${cls.show}") cls.info = classDefSig(original, cls, decls.asInstanceOf[MutableScope])(localContext) } } @@ -288,7 +284,7 @@ class Namer { typer: Typer => /** Enter and typecheck parameter list */ def completeParams(params: List[MemberDef])(implicit ctx: Context) = { - enterSyms(params) + index(params) for (param <- params) typedAheadExpr(param) } @@ -375,29 +371,21 @@ class Namer { typer: Typer => else typedAheadExpr(constr).tpe } - val TypeDef(_, _, impl @ Template(constr, parents, self, body)) = cdef + val TypeDef(_, name, impl @ Template(constr, parents, self, body)) = cdef val (params, rest) = body span { case td: TypeDef => td.mods is Param case td: ValDef => td.mods is ParamAccessor case _ => false } - enterSyms(params) - def defaultSelfType = - if (cls is Module) TermRef.withSym(ctx.owner.thisType, cls.sourceModule.asTerm) - else NoType + index(params) + val selfInfo = if (self.isEmpty) NoType else createSymbol(self) // pre-set info, so that parent types can refer to type params - cls.info = ClassInfo(cls.owner.thisType, cls, Nil, decls, defaultSelfType) + cls.info = ClassInfo(cls.owner.thisType, cls, Nil, decls, selfInfo) val parentTypes = parents map parentType val parentRefs = ctx.normalizeToRefs(parentTypes, cls, decls) - val optSelfType = - if (self.tpt.isEmpty) defaultSelfType - else { - val t = typedAheadType(self.tpt).tpe - if (!t.isError) t else defaultSelfType - } - enterSym(constr) - enterSyms(rest)(inClassContext(cls, self.name)) - ClassInfo(cls.owner.thisType, cls, parentRefs, decls, optSelfType) + index(constr) + index(rest)(inClassContext(selfInfo)) + ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo) } }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 6a36eaaa5..7f2ba2959 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -430,7 +430,7 @@ class Typer extends Namer with Applications with Implicits { } def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context) = { - val exprCtx = enterSyms(tree.stats) + val exprCtx = index(tree.stats) val stats1 = typedStats(tree.stats, ctx.owner) val expr1 = typedExpr(tree.expr, pt)(exprCtx) val result = cpy.Block(tree, stats1, expr1).withType(blockType(stats1, expr1.tpe)) @@ -632,8 +632,7 @@ class Typer extends Namer with Applications with Implicits { def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): RefinedTypeTree = { val tpt1 = typedAheadType(tree.tpt) val refineClsDef = desugar.refinedTypeToClass(tree) - val throwAwayScopeCtx = ctx.fresh.withNewScope - val refineCls = createSymbol(refineClsDef)(throwAwayScopeCtx).asClass + val refineCls = createSymbol(refineClsDef).asClass val TypeDef(_, _, Template(_, _, _, refinements1)) = typed(refineClsDef) assert(tree.refinements.length == refinements1.length, s"${tree.refinements} != $refinements1") def addRefinement(parent: Type, refinement: Tree): Type = { @@ -721,11 +720,9 @@ class Typer extends Namer with Applications with Implicits { val mods1 = typedModifiers(mods) val constr1 = typed(constr).asInstanceOf[DefDef] val parents1 = parents mapconserve (typed(_)) - val self1 = cpy.ValDef(self, typedModifiers(self.mods), self.name, typedType(self.tpt), EmptyTree) - .withType(NoType) - + val self1 = typed(self).asInstanceOf[ValDef] val localDummy = ctx.newLocalDummy(cls, impl.pos) - val body1 = typedStats(body, localDummy)(inClassContext(cls, self.name)) + val body1 = typedStats(body, localDummy)(inClassContext(self1.symbol)) val impl1 = cpy.Template(impl, constr1, parents1, self1, body1) .withType(localDummy.symRef) @@ -931,6 +928,8 @@ class Typer extends Namer with Applications with Implicits { */ def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = { + println(i"adapting $tree of type ${tree.tpe} to $pt") + def adaptOverloaded(ref: TermRef) = { val altDenots = ref.denot.alternatives val alts = altDenots map (alt => diff --git a/src/dotty/tools/dotc/util/Positions.scala b/src/dotty/tools/dotc/util/Positions.scala index 281540321..334a3deb6 100644 --- a/src/dotty/tools/dotc/util/Positions.scala +++ b/src/dotty/tools/dotc/util/Positions.scala @@ -49,6 +49,9 @@ object Positions { def pointDelta = (coords >>> (StartEndBits * 2)).toInt + def orElse(that: Position) = + if (this.exists) this else that + /** The union of two positions. This is the least range that encloses * both positions. It is always a synthetic position. */ |