From c190626eb0a7c6a314429bb4f3c498da989395fc Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 15 Jun 2013 22:01:42 +0200 Subject: Removed ClassDef as a Tree node class. ClassDefs are now TypeDefs that have a Template as rhs. --- src/dotty/tools/dotc/ast/CheckTrees.scala | 3 +- src/dotty/tools/dotc/ast/Desugar.scala | 15 +++++----- src/dotty/tools/dotc/ast/TreeInfo.scala | 1 - src/dotty/tools/dotc/ast/Trees.scala | 33 ++++++++-------------- src/dotty/tools/dotc/ast/TypedTrees.scala | 4 +-- src/dotty/tools/dotc/parsing/Parsers.scala | 4 +-- src/dotty/tools/dotc/printing/RefinedPrinter.scala | 24 +++++++++------- src/dotty/tools/dotc/typer/Namer.scala | 23 ++++++++------- src/dotty/tools/dotc/typer/Typer.scala | 11 ++++---- 9 files changed, 54 insertions(+), 64 deletions(-) (limited to 'src/dotty/tools') diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala index 71bceebf1..4c3413ada 100644 --- a/src/dotty/tools/dotc/ast/CheckTrees.scala +++ b/src/dotty/tools/dotc/ast/CheckTrees.scala @@ -223,9 +223,8 @@ object CheckTrees { check(rhs.tpe <:< tpt.tpe) } case TypeDef(mods, name, tpt) => - check(tpt.tpe.isInstanceOf[TypeBounds]) + check(tpt.isInstanceOf[Template[_]] || tpt.tpe.isInstanceOf[TypeBounds]) case Template(constr, parents, selfType, body) => - case ClassDef(mods, names, impl) => case Import(expr, selectors) => check(expr.isValue) check(expr.tpe.termSymbol.isStable) diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index 390b846f6..2315cb58a 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -80,8 +80,8 @@ object desugar { private val synthetic = Modifiers(Synthetic) - def classDef(cdef: ClassDef)(implicit ctx: Context): Tree = { - val ClassDef( + def classDef(cdef: TypeDef)(implicit ctx: Context): Tree = { + val TypeDef( mods, name, impl @ Template(constr0, parents, self, body)) = cdef val constr1 = defDef(constr0, isPrimaryConstructor = true) @@ -104,7 +104,7 @@ object desugar { val classTypeRef = { val tycon = Ident(cdef.name) - val tparams = cdef.impl.constr.tparams + val tparams = impl.constr.tparams if (tparams.isEmpty) tycon else AppliedTypeTree(tycon, tparams map refOfDef) } @@ -163,7 +163,7 @@ object desugar { } else Nil - val cdef1 = cdef.derivedClassDef(mods, name, + val cdef1 = cdef.derivedTypeDef(mods, name, impl.derivedTemplate(constr, parents, self, constr1.tparams ::: constr1.vparamss.flatten ::: body ::: caseClassMeths)) Thicket.make(cdef1 :: caseCompanions ::: implicitWrappers) @@ -180,15 +180,14 @@ object desugar { val modul = ValDef(mods | ModuleCreationFlags, name, clsRef, New(clsRef, Nil)) val clsSelf = self.derivedValDef(self.mods, self.name, SingletonTypeTree(Ident(name)), self.rhs) val clsTmpl = tmpl.derivedTemplate(constr, parents, clsSelf, body) - val cls = ClassDef(mods.toTypeFlags & AccessFlags | ModuleClassCreationFlags, clsName, clsTmpl) + val cls = TypeDef(mods.toTypeFlags & AccessFlags | ModuleClassCreationFlags, clsName, clsTmpl) Thicket(cls, valDef(modul)) } def memberDef(tree: Tree)(implicit ctx: Context): Tree = tree match { case tree: ValDef => valDef(tree) - case tree: TypeDef => typeDef(tree) + case tree: TypeDef => if (tree.isClassDef) classDef(tree) else typeDef(tree) case tree: DefDef => defDef(tree) - case tree: ClassDef => classDef(tree) case tree: ModuleDef => moduleDef(tree) } @@ -426,7 +425,7 @@ object desugar { Bind(id.name, Typed(Ident(nme.WILDCARD), tpt)).withPos(id.pos) case New(templ: Template) => val x = tpnme.ANON_CLASS - val clsDef = ClassDef(Modifiers(Final), x, templ) + val clsDef = TypeDef(Modifiers(Final), x, templ) Block(clsDef, New(Ident(x), Nil)) case Assign(Apply(fn, args), rhs) => Apply(Select(fn, nme.update), args :+ rhs) diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala index 11d50fc1b..7e9c404eb 100644 --- a/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -37,7 +37,6 @@ abstract class TreeInfo { */ def isIdempotentDef(tree: Tree[Type])(implicit ctx: Context): Boolean = tree match { case EmptyTree - | ClassDef(_, _, _) | TypeDef(_, _, _) | Import(_, _) | DefDef(_, _, _, _, _, _) => diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 7e0ac3bdc..69bc91f5a 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -568,13 +568,23 @@ object Trees { def withName(name: Name) = this.derivedDefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs) } - /** mods type name = rhs or - * mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) + /** mods class name template or + * mods trait name template or + * mods type name = rhs or + * mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) & (lo ne hi) */ case class TypeDef[T >: Untyped](mods: Modifiers[T], name: TypeName, rhs: Tree[T]) extends MemberDef[T] { type ThisTree[T >: Untyped] = TypeDef[T] def withName(name: Name) = this.derivedTypeDef(mods, name.toTypeName, rhs, tparams) + + /** Is this a definition of a class? */ + def isClassDef = rhs.isInstanceOf[Template[_]] + + /** If this a non-class type definition, its type parameters. + * Can be different from Nil only for PolyTypeDefs, which are always + * untyped and get eliminated during desugaring. + */ def tparams: List[untpd.TypeDef] = Nil } @@ -584,13 +594,6 @@ object Trees { type ThisTree[T >: Untyped] = Template[T] } - /** mods class name[tparams] impl */ - case class ClassDef[T >: Untyped](mods: Modifiers[T], name: TypeName, impl: Template[T]) - extends MemberDef[T] { - type ThisTree[T >: Untyped] = ClassDef[T] - def withName(name: Name) = this.derivedClassDef(mods, name.toTypeName, impl) - } - /** import expr.selectors * where a selector is either an untyped `Ident`, `name` or * an untyped `Pair` `name => rename` @@ -727,7 +730,6 @@ object Trees { type DefDef = Trees.DefDef[T] type TypeDef = Trees.TypeDef[T] type Template = Trees.Template[T] - type ClassDef = Trees.ClassDef[T] type Import = Trees.Import[T] type PackageDef = Trees.PackageDef[T] type Annotated = Trees.Annotated[T] @@ -889,10 +891,6 @@ object Trees { case tree: Template[_] if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree case _ => Template(constr, parents, self, body).copyAttr(tree) } - def derivedClassDef(mods: Modifiers[T], name: TypeName, impl: Template[T]): ClassDef[T] = tree match { - case tree: ClassDef[_] if (mods == tree.mods) && (name == tree.name) && (impl eq tree.impl) => tree - case _ => ClassDef(mods, name, impl).copyAttr(tree) - } def derivedImport(expr: Tree[T], selectors: List[Tree[Untyped]]): Import[T] = tree match { case tree: Import[_] if (expr eq tree.expr) && (selectors eq tree.selectors) => tree case _ => Import(expr, selectors).copyAttr(tree) @@ -991,8 +989,6 @@ object Trees { finishTypeDef(tree.derivedTypeDef(mods, name, transform(rhs, c), tree.tparams), tree, c, plugins) case Template(constr, parents, self, body) => finishTemplate(tree.derivedTemplate(transformSub(constr, c), transform(parents, c), transformSub(self, c), transform(body, c)), tree, c, plugins) - case ClassDef(mods, name, impl) => - finishClassDef(tree.derivedClassDef(mods, name, transformSub(impl, c)), tree, c, plugins) case Import(expr, selectors) => finishImport(tree.derivedImport(transform(expr, c), selectors), tree, c, plugins) case PackageDef(pid, stats) => @@ -1059,7 +1055,6 @@ object Trees { def finishDefDef(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree def finishTypeDef(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree def finishTemplate(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree - def finishClassDef(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree def finishImport(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree def finishPackageDef(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree def finishAnnotated(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree @@ -1173,8 +1168,6 @@ object Trees { tree.derivedTypeDef(mods, name, transform(rhs), tree.tparams) case Template(constr, parents, self, body) => tree.derivedTemplate(transformSub(constr), transform(parents), transformSub(self), transformStats(body)) - case ClassDef(mods, name, impl) => - tree.derivedClassDef(mods, name, transformSub(impl)) case Import(expr, selectors) => tree.derivedImport(transform(expr), selectors) case PackageDef(pid, stats) => @@ -1280,8 +1273,6 @@ object Trees { this(x, rhs) case Template(constr, parents, self, body) => this(this(this(this(x, constr), parents), self), body) - case ClassDef(mods, name, impl) => - this(x, impl) case Import(expr, selectors) => this(x, expr) case PackageDef(pid, stats) => diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala index 2f1da6133..5e4f7342d 100644 --- a/src/dotty/tools/dotc/ast/TypedTrees.scala +++ b/src/dotty/tools/dotc/ast/TypedTrees.scala @@ -213,7 +213,7 @@ object tpd extends Trees.Instance[Type] { Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info)) .withType(refType(sym)).checked - def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], constr: DefDef, body: List[Tree])(implicit ctx: Context): ClassDef = { + def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], 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)) @@ -231,7 +231,7 @@ object tpd extends Trees.Instance[Type] { .orElse(ctx.newLocalDummy(cls)) val impl = Trees.Template(constr, parents, selfType, rest) .withType(refType(localDummy)).checked - Trees.ClassDef(Modifiers(cls), cls.name, impl) // !!! todo: revise + Trees.TypeDef(Modifiers(cls), cls.name, impl) // !!! todo: revise .withType(refType(cls)).checked } diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index 4ac74c86e..85d134653 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1740,7 +1740,7 @@ object Parsers { /** ClassDef ::= Id [ClsTypeParamClause] * [ConstrMods] ClsParamClauses TemplateOpt */ - def classDef(mods: Modifiers): ClassDef = atPos(tokenRange) { + def classDef(mods: Modifiers): TypeDef = atPos(tokenRange) { val name = ident().toTypeName val constr = atPos(in.offset) { val tparams = typeParamClauseOpt(ParamOwner.Class) @@ -1749,7 +1749,7 @@ object Parsers { makeConstructor(cmods, tparams, vparamss) } val templ = templateOpt(constr) - ClassDef(mods, name, templ) + TypeDef(mods, name, templ) } /** ConstrMods ::= AccessModifier diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 9df2c053f..dc3956fca 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -25,8 +25,11 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { finally { currentOwner = saved } } - private def ownerIsClass = - currentOwner.isInstanceOf[ClassDef[_]] || currentOwner.isInstanceOf[untpd.ModuleDef] + private def ownerIsClass = currentOwner match { + case owner: TypeDef[_] => owner.isClassDef + case owner: untpd.ModuleDef => true + case _ => false + } override def nameString(name: Name): String = name.decode.toString @@ -216,11 +219,16 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { } case tree @ TypeDef(mods, name, rhs) => atOwner(tree) { - val rhsText = rhs match { - case TypeBoundsTree(_, _) => toText(rhs) - case _ => optText(rhs)(" = " ~ _) + def typeDefText(rhsText: Text) = + modText(mods, "type") ~~ toText(name) ~ tparamsText(tree.tparams) ~ rhsText + rhs match { + case impl: Template => + modText(mods, if (mods is Trait) "trait" else "class") ~~ toText(name) ~ toText(impl) + case rhs: TypeBoundsTree => + typeDefText(toText(rhs)) + case _ => + typeDefText(optText(rhs)(" = " ~ _)) } - modText(mods, "type") ~~ toText(name) ~ tparamsText(tree.tparams) ~ rhsText } case Template(DefDef(mods, _, tparams, vparamss, _, _), parents, self, stats) => val tparamsTxt = tparamsText(tparams) @@ -238,10 +246,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { } provided !self.isEmpty val bodyText = "{" ~~ selfText ~~ toTextGlobal(stats, "\n") ~ "}" prefix ~~ (" extends" provided ownerIsClass) ~~ parentsText ~~ bodyText - case ClassDef(mods, name, impl) => - atOwner(tree) { - modText(mods, if (mods is Trait) "trait" else "class") ~~ toText(name) ~ toText(impl) - } case Import(expr, selectors) => def selectorText(sel: Tree): Text = sel match { case Pair(l, r) => toTextGlobal(l) ~ " => " ~ toTextGlobal(r) diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 18a26e0cf..0b8c1ada2 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -104,7 +104,7 @@ class Namer { typer: Typer => def privateWithinClass(mods: Modifiers) = enclosingClassNamed(mods.privateWithin, mods.pos) val sym = tree match { - case tree: ClassDef => + case tree: TypeDef if tree.isClassDef => ctx.enter(ctx.newClassSymbol( ctx.owner, tree.name, tree.mods.flags, new Completer(tree), privateWithinClass(tree.mods), tree.pos, ctx.source.file)) @@ -166,17 +166,17 @@ class Namer { typer: Typer => * and the real companion, if both exist. */ def mergeCompanionDefs() = { - val caseClassDef = mutable.Map[TypeName, ClassDef]() - for (cdef @ ClassDef(mods, name, _) <- stats) + val caseClassDef = mutable.Map[TypeName, TypeDef]() + for (cdef @ TypeDef(mods, name, _) <- stats) if (mods is Case) caseClassDef(name) = cdef for (mdef @ ModuleDef(_, name, _) <- stats) caseClassDef get name.toTypeName match { case Some(cdef) => - val Thicket((mcls @ ClassDef(_, _, impl)) :: mrest) = expandedTree(mdef) - val Thicket(cls :: (companion: ClassDef) :: crest) = expandedTree(cdef) - val mcls1 = mcls.derivedClassDef(mcls.mods, mcls.name, + val Thicket((mcls @ TypeDef(_, _, impl: Template)) :: mrest) = expandedTree(mdef) + val Thicket(cls :: TypeDef(_, _, compimpl: Template) :: crest) = expandedTree(cdef) + val mcls1 = mcls.derivedTypeDef(mcls.mods, mcls.name, impl.derivedTemplate(impl.constr, impl.parents, impl.self, - companion.impl.body ++ impl.body)) + compimpl.body ++ impl.body)) expandedTree(mdef) = Thicket(mcls1 :: mrest) expandedTree(cdef) = Thicket(cls :: crest) case none => @@ -203,9 +203,8 @@ class Namer { typer: Typer => nestedTyper(sym) = typer1 typer1.defDefSig(tree, sym)(localContext.withTyper(typer1)) case tree: TypeDef => - typeDefSig(tree, sym)(localContext.withNewScope) - case tree: ClassDef => - classDefSig(tree, sym.asClass)(localContext) + if (tree.isClassDef) classDefSig(tree, sym.asClass)(localContext) + else typeDefSig(tree, sym)(localContext.withNewScope) case imp: Import => val expr1 = typedAhead(imp.expr) ImportType(SharedTree(expr1)) @@ -298,7 +297,7 @@ class Namer { typer: Typer => } /** The type signature of a ClassDef with given symbol */ - def classDefSig(cdef: ClassDef, cls: ClassSymbol)(implicit ctx: Context): Type = { + def classDefSig(cdef: TypeDef, cls: ClassSymbol)(implicit ctx: Context): Type = { def parentType(constr: untpd.Tree): Type = { val Trees.Select(Trees.New(tpt), _) = TreeInfo.methPart(constr) @@ -307,7 +306,7 @@ class Namer { typer: Typer => else typedAhead(constr, Mode.Expr).tpe } - val ClassDef(_, _, impl @ Template(_, parents, self, body)) = cdef + val TypeDef(_, _, impl @ Template(_, parents, self, body)) = cdef val decls = newScope val (params, rest) = body span { diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 1b3c2f22b..0d78e070d 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -48,8 +48,8 @@ class Typer extends Namer { tdef.withType(sym.symRef).derivedTypeDef(mods1, name, rhs1) } - def typedClassDef(cdef: untpd.ClassDef, cls: ClassSymbol)(implicit ctx: Context) = { - val Trees.ClassDef(mods, name, impl @ Template(constr, parents, self, body)) = cdef + def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = { + val Trees.TypeDef(mods, name, impl @ Template(constr, parents, self, body)) = cdef val mods1 = typedModifiers(mods) val constr1 = typed(constr).asInstanceOf[DefDef] val parents1 = parents mapconserve (typed(_)) @@ -61,7 +61,7 @@ class Typer extends Namer { val impl1 = impl.withType(localDummy.symRef).derivedTemplate( constr1, parents1, self1, body1) - cdef.withType(cls.symRef).derivedClassDef(mods1, name, impl1) + cdef.withType(cls.symRef).derivedTypeDef(mods1, name, impl1) // todo later: check that // 1. If class is non-abstract, it is instantiatable: @@ -90,9 +90,8 @@ class Typer extends Namer { 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) + if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext) + else typedTypeDef(tree, sym)(localContext.withNewScope) case tree: untpd.Import => typedImport(tree, sym) case tree: untpd.TypeTree => -- cgit v1.2.3