diff options
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 74 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 13 |
3 files changed, 73 insertions, 24 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 334e21ccb..439210af4 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -154,13 +154,13 @@ trait Applications extends Compatibility { self: Typer => /** The arguments re-ordered so that each named argument matches the * same-named formal parameter. */ - val orderedArgs = + lazy val orderedArgs = if (hasNamedArg(args)) reorder(args.asInstanceOf[List[untpd.Tree]]).asInstanceOf[List[Arg]] else args - methType match { + protected def init() = methType match { case methType: MethodType => // apply the result type constraint, unless method type is dependent if (!methType.isDependent) @@ -248,9 +248,9 @@ trait Applications extends Compatibility { self: Typer => def findDefault(cx: Context): Type = { if (cx eq NoContext) NoType else if (cx.scope != cx.outer.scope && - cx.lookup(methRef.name) + cx.denotsNamed(methRef.name) .filterWithPredicate(_.symbol == meth).exists) { - val denot = cx.lookup(getterName).toDenot(NoPrefix) + val denot = cx.denotsNamed(getterName).toDenot(NoPrefix) NamedType(NoPrefix, getterName).withDenot(denot) } else findDefault(cx.outer) } @@ -368,6 +368,7 @@ trait Applications extends Compatibility { self: Typer => def fail(msg: => String) = ok = false def normalizedFun = EmptyTree + init() } /** Subtrait of Application for the cases where arguments are (typed or @@ -403,6 +404,7 @@ trait Applications extends Compatibility { self: Typer => private var typedArgBuf = new mutable.ListBuffer[Tree] private var liftedDefs: mutable.ListBuffer[Tree] = null private var myNormalizedFun: Tree = fun + init() def addArg(arg: Tree, formal: Type): Unit = typedArgBuf += adapt(arg, formal) diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 12c812c22..024577b47 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -12,6 +12,7 @@ import util.Positions._ import util.SourcePosition import collection.mutable import annotation.tailrec +import ErrorReporting._ import language.implicitConversions trait NamerContextOps { this: Context => @@ -24,9 +25,13 @@ trait NamerContextOps { this: Context => sym } - def lookup(name: Name): PreDenotation = - if (isClassDefContext) owner.asClass.membersNamed(name) + def denotsNamed(name: Name): PreDenotation = + if (owner.isClass) owner.asClass.membersNamed(name) else scope.denotsNamed(name) + + def effectiveScope = + if (owner != null && owner.isClass) owner.asClass.decls + else scope } /** This class attaches creates symbols from definitions and imports and gives them @@ -106,25 +111,49 @@ class Namer { typer: Typer => * and store in symOfTree map. */ def createSymbol(tree: Tree)(implicit ctx: Context): Symbol = { + def privateWithinClass(mods: Modifiers) = enclosingClassNamed(mods.privateWithin, mods.pos) - val sym = tree match { + + 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 => - ctx.enter(ctx.newClassSymbol( + recordEnter(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 => - ctx.enter(ctx.newSymbol( + recordEnter(tree, ctx.newSymbol( ctx.owner, tree.name, tree.mods.flags, new Completer(tree), privateWithinClass(tree.mods), tree.pos)) case imp: Import => - ctx.newSymbol( - ctx.owner, nme.IMPORT, Synthetic, new Completer(tree), NoSymbol, tree.pos) + record(imp, ctx.newSymbol( + ctx.owner, nme.IMPORT, Synthetic, new Completer(tree), NoSymbol, tree.pos)) case _ => NoSymbol } - if (sym.exists) symOfTree(tree) = sym - sym } /** All PackageClassInfoTypes come from here. */ @@ -165,6 +194,9 @@ class Namer { typer: Typer => ctx case imp: Import => importContext(createSymbol(imp), imp.selectors) + case mdef: ModuleDef => + createSymbol(expansion(mdef)) + ctx case mdef: MemberDef => expansion(mdef).toList foreach createSymbol ctx @@ -234,12 +266,13 @@ class Namer { typer: Typer => } /** The completer for a symbol defined by a class definition */ - class ClassCompleter(original: TypeDef, override val decls: MutableScope = newScope)(implicit ctx: Context) - extends ClassCompleterWithDecls(decls) { + class ClassCompleter(original: TypeDef, override val sourceModule: Symbol = NoSymbol)(implicit ctx: Context) + extends ClassCompleterWithDecls(newScope) { override def complete(denot: SymDenotation): Unit = { val cls = denot.symbol.asClass def localContext = ctx.fresh.withOwner(cls) - cls.info = classDefSig(original, cls, decls)(localContext) + println(s"completing ${cls.show}, sourceModule = ${sourceModule.show}") + cls.info = classDefSig(original, cls, decls.asInstanceOf[MutableScope])(localContext) } } @@ -248,7 +281,7 @@ class Namer { typer: Typer => typedTree.getOrElseUpdate(tree, typer.typedExpanded(tree, pt)) def typedAheadType(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree = - typedAheadImpl(tree, WildcardType)(ctx retractMode Mode.PatternOrType addMode Mode.Type) + typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType addMode Mode.Type) def typedAheadExpr(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree = typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType) @@ -342,7 +375,7 @@ class Namer { typer: Typer => else typedAheadExpr(constr).tpe } - val TypeDef(_, _, impl @ Template(_, parents, self, body)) = cdef + val TypeDef(_, _, impl @ Template(constr, parents, self, body)) = cdef val (params, rest) = body span { case td: TypeDef => td.mods is Param @@ -350,9 +383,20 @@ class Namer { typer: Typer => case _ => false } enterSyms(params) + def defaultSelfType = + if (cls is Module) TermRef.withSym(ctx.owner.thisType, cls.sourceModule.asTerm) + else NoType + // pre-set info, so that parent types can refer to type params + cls.info = ClassInfo(cls.owner.thisType, cls, Nil, decls, defaultSelfType) val parentTypes = parents map parentType val parentRefs = ctx.normalizeToRefs(parentTypes, cls, decls) - val optSelfType = if (self.tpt.isEmpty) NoType else typedAheadType(self.tpt).tpe + 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) } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index b4e1335f8..6922111f4 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -268,11 +268,11 @@ class Typer extends Namer with Applications with Implicits { } // begin findRef - if (ctx eq NoContext) previous + if (ctx.scope == null) previous else { val outer = ctx.outer - if (ctx.scope ne outer.scope) { - val defDenots = ctx.lookup(name) + if ((ctx.scope ne outer.scope) || (ctx.owner ne outer.owner)) { + val defDenots = ctx.denotsNamed(name) if (defDenots.exists) { val curOwner = ctx.owner val pre = curOwner.thisType @@ -299,6 +299,8 @@ class Typer extends Namer with Applications with Implicits { } // begin typedIdent + def kind = if (name.isTermName) "term" else "type" // !!! DEBUG + println(s"typed ident $kind $name in ${ctx.owner}") if (ctx.mode is Mode.Pattern) { if (name == nme.WILDCARD) return tree.withType(pt) @@ -369,7 +371,7 @@ class Typer extends Namer with Applications with Implicits { case _ => val tpt1 = typedType(tree.tpt) val cls = checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos) - checkInstantiatable(cls, tpt1.pos) + // todo in a later phase: checkInstantiatable(cls, tpt1.pos) cpy.New(tree, tpt1).withType(tpt1.tpe) } @@ -594,7 +596,7 @@ class Typer extends Namer with Applications with Implicits { assert(isFullyDefined(pt)) (EmptyTree, pt) case original: DefDef => - val meth = ctx.lookup(original.name).first + val meth = symbolOfTree(original) assert(meth.exists, meth) (EmptyTree, meth.info.resultType) case original => @@ -815,6 +817,7 @@ class Typer extends Namer with Applications with Implicits { case tree: untpd.Import => typedImport(tree, sym) case tree: untpd.PackageDef => typedPackageDef(tree) case tree: untpd.Annotated => typedAnnotated(tree, pt) + case tree: untpd.TypedSplice => tree.tree case untpd.EmptyTree => tpd.EmptyTree case _ => typed(desugar(tree), pt) } |