From 1571ec5f39cacac6433cce0a140ebfb18e2ac314 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 6 Jun 2013 19:20:41 +0200 Subject: Namer redesign. A new design that relies on DefDef local maps, instead of global maps before. --- src/dotty/tools/dotc/typer/Typer.scala | 120 ++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 39 deletions(-) (limited to 'src/dotty/tools/dotc/typer/Typer.scala') diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index dd46a678e..295d0a1b2 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -9,6 +9,7 @@ import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Fla import util.Positions._ import util.SourcePosition import collection.mutable +import annotation.tailrec import language.implicitConversions import desugar.Mode @@ -19,73 +20,82 @@ class Typer extends Namer { import tpd._ - def typedImport(imp: untpd.Import, pt: Type)(implicit ctx: Context): Import = { - val expr1 = typed(imp.expr) - imp.withType(pt).derivedImport(expr1, imp.selectors) - } - def typedModifiers(mods: untpd.Modifiers): Modifiers = ??? - def typedValDef(defn: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = { - val Trees.ValDef(mods, name, tpt, rhs) = defn + def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = { + val Trees.ValDef(mods, name, tpt, rhs) = vdef val mods1 = typedModifiers(mods) val tpt1 = typedType(tpt) val rhs1 = typedExpr(rhs, tpt1.tpe) val pt = if (sym.exists) sym.symRef else NoType - defn.withType(pt).derivedValDef(mods1, name, tpt1, rhs1) + vdef.withType(pt).derivedValDef(mods1, name, tpt1, rhs1) } - def typedDefDef(defn: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = { - val Trees.DefDef(mods, name, tparams, vparamss, tpt, rhs) = defn + def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = { + val Trees.DefDef(mods, name, tparams, vparamss, tpt, rhs) = ddef val mods1 = typedModifiers(mods) val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef]) val vparamss1 = vparamss.mapconserve(_ mapconserve (typed(_).asInstanceOf[ValDef])) val tpt1 = typedType(tpt) val rhs1 = typedExpr(rhs, tpt1.tpe) - defn.withType(sym.symRef).derivedDefDef(mods1, name, tparams1, vparamss1, tpt1, rhs1) + ddef.withType(sym.symRef).derivedDefDef(mods1, name, tparams1, vparamss1, tpt1, rhs1) } - def typedTypeDef(defn: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): TypeDef = { - val Trees.TypeDef(mods, name, tparams, rhs) = defn + def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): TypeDef = { + val Trees.TypeDef(mods, name, tparams, rhs) = tdef val mods1 = typedModifiers(mods) val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef]) val rhs1 = typedType(rhs) - defn.withType(sym.symRef).derivedTypeDef(mods1, name, tparams1, rhs1) + tdef.withType(sym.symRef).derivedTypeDef(mods1, name, tparams1, rhs1) } - def typedClassDef(defn: untpd.ClassDef, cls: ClassSymbol)(implicit ctx: Context) = { - val Trees.ClassDef(mods, name, impl @ Trees.Template(constr, parents, self, body)) = defn + def typedClassDef(cdef: untpd.ClassDef, cls: ClassSymbol)(implicit ctx: Context) = { + val Trees.ClassDef(mods, name, impl @ Template(constr, parents, self, body)) = cdef val mods1 = typedModifiers(mods) - val constr1 = typed(constr) + val constr1 = typed(constr).asInstanceOf[DefDef] val parents1 = parents mapconserve (typed(_)) - val self1 = typed(self) - ??? + val self1 = self.withType(NoType).derivedValDef( + typedModifiers(self.mods), self.name, typed(self.tpt), EmptyTree) + + val localDummy = ctx.newLocalDummy(cls, impl.pos) + val body1 = typedStats(body, localDummy)(inClassContext(cls, self.name)) + val impl1 = impl.withType(localDummy.symRef).derivedTemplate( + constr1, parents1, self1, body1) + + cdef.withType(cls.symRef).derivedClassDef(mods1, name, impl1) + + // todo later: check that + // 1. If class is non-abstract, it is instantiatable: + // - self type is s supertype of own type + // - all type members have consistent bounds + // 2. all private type members have consistent bounds + // 3. Types do not override classes. + // 4. Polymorphic type defs override nothing. } - def typedMemberDef(defn: untpd.MemberDef, sym: Symbol)(implicit ctx: Context) = { - sym.ensureCompleted() - def localContext = ctx.fresh.withOwner(sym) - defn match { - case defn: untpd.ValDef => - typedValDef(defn, sym)(localContext) - case defn: untpd.DefDef => - val typer1 = nestedTyper.remove(sym).get - typer1.typedDefDef(defn, sym)(localContext.withScope(typer1.scope)) - case defn: untpd.TypeDef => - typedTypeDef(defn, sym)(localContext.withNewScope) - case defn: untpd.ClassDef => - typedClassDef(defn, sym.asClass)(localContext) - } + def typedImport(imp: untpd.Import, sym: Symbol)(implicit ctx: Context): Import = { + val expr1 = typed(imp.expr) + imp.withType(sym.symRef).derivedImport(expr1, imp.selectors) } - def typed(tree: untpd.Tree, mode: Mode.Value = Mode.Expr, pt: Type = WildcardType)(implicit ctx: Context): Tree = { - typedTree get tree match { + def typedExpanded(tree: untpd.Tree, mode: Mode.Value = Mode.Expr, pt: Type = WildcardType)(implicit ctx: Context): Tree = { + val sym = symOfTree.remove(tree).getOrElse(NoSymbol) + sym.ensureCompleted() + def localContext = ctx.fresh.withOwner(sym) + typedTree remove tree match { case Some(tree1) => tree1 case none => tree match { - case defn: untpd.MemberDef => - typedMemberDef(defn, symOfTree(defn)) - case imp: untpd.Import => - typedImport(imp, symOfTree(imp).symRef) + case tree: untpd.ValDef => + typedValDef(tree, sym)(localContext) + case tree: untpd.DefDef => + val typer1 = nestedTyper.remove(sym).get + typer1.typedDefDef(tree, sym)(localContext.withTyper(typer1)) + case tree: untpd.TypeDef => + typedTypeDef(tree, sym)(localContext.withNewScope) + case tree: untpd.ClassDef => + typedClassDef(tree, sym.asClass)(localContext) + case tree: untpd.Import => + typedImport(tree, sym) case tree: untpd.TypeTree => if (!tree.isEmpty) typed(tree.original, Mode.Type, pt) else { @@ -98,6 +108,38 @@ class Typer extends Namer { } } + def typed(tree: untpd.Tree, mode: Mode.Value = Mode.Expr, pt: Type = WildcardType)(implicit ctx: Context): Tree = { + val xtree = + tree match { + case tree: untpd.MemberDef => + expandedTree remove tree match { + case Some(xtree) => xtree + case none => tree + } + case _ => tree + } + typedExpanded(xtree, mode, pt) + } + + def typedStats(stats: List[untpd.Tree], exprOwner: Symbol)(implicit ctx: Context): List[tpd.Tree] = { + val buf = new mutable.ListBuffer[Tree] + @tailrec def traverse(stats: List[untpd.Tree])(implicit ctx: Context): List[Tree] = stats match { + case (imp: untpd.Import) :: rest => + val imp1 = typed(imp) + buf += imp1 + traverse(rest)(importContext(imp1.symbol, imp.selectors)) + case (mdef: untpd.MemberDef) :: rest => + buf += typed(mdef) + traverse(rest) + case stat :: rest => + buf += typed(stat)(ctx.fresh.withOwner(exprOwner)) + traverse(rest) + case _ => + buf.toList + } + traverse(stats) + } + def typedExpr(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = typed(tree, Mode.Expr, pt) def typedType(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = -- cgit v1.2.3