From 5b63106448275d6cc4bb6822af33247c2521a63c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 14 Feb 2015 18:39:14 +0100 Subject: Make some tree fields lazy Lazy fields are - the rhs field of a ValDef or DefDef - the body field of a Template These can be instantiated with Lazy instances. The scheme is such that lazy fields are completely transparent for users of the Trees API. The only downside is that the parameter used to initialize a potentially lazy field has a weak type (now it's Any, with Dotty it would be a union type of the form `T | Lazy[T]`. Therefore, the parameter cannot be recovered through pattern matching. --- src/dotty/tools/dotc/typer/Namer.scala | 8 ++++---- src/dotty/tools/dotc/typer/Typer.scala | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src/dotty/tools/dotc/typer') diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index c522a5998..4bf194f5e 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -436,9 +436,9 @@ class Namer { typer: Typer => protected implicit val ctx: Context = localContext(cls).setMode(ictx.mode &~ Mode.InSuperCall) - val TypeDef(name, impl @ Template(constr, parents, self, body)) = original + val TypeDef(name, impl @ Template(constr, parents, self, _)) = original - val (params, rest) = body span { + val (params, rest) = impl.body span { case td: TypeDef => td.mods is Param case td: ValDef => td.mods is ParamAccessor case _ => false @@ -496,9 +496,9 @@ class Namer { typer: Typer => index(rest)(inClassContext(selfInfo)) denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo) if (cls is Trait) { - if (body forall isNoInitMember) { + if (impl.body forall isNoInitMember) { cls.setFlag(NoInits) - if (body forall isPureInterfaceMember) + if (impl.body forall isPureInterfaceMember) cls.setFlag(PureInterface) } } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 974a42638..1e93f98f3 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -794,7 +794,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val tpt1 = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else typedAheadType(tree.tpt) val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements) val refineCls = createSymbol(refineClsDef).asClass - val TypeDef(_, Template(_, _, _, refinements1)) = typed(refineClsDef) + val TypeDef(_, impl: Template) = typed(refineClsDef) + val refinements1 = impl.body val seen = mutable.Set[Symbol]() assert(tree.refinements.length == refinements1.length, s"${tree.refinements} != $refinements1") def addRefinement(parent: Type, refinement: Tree): Type = { @@ -866,24 +867,24 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = track("typedValDef") { - val ValDef(name, tpt, rhs) = vdef + val ValDef(name, tpt, _) = vdef addTypedModifiersAnnotations(vdef, sym) val tpt1 = typedType(tpt) - val rhs1 = rhs match { - case Ident(nme.WILDCARD) => rhs withType tpt1.tpe - case _ => typedExpr(rhs, tpt1.tpe) + val rhs1 = vdef.rhs match { + case rhs @ Ident(nme.WILDCARD) => rhs withType tpt1.tpe + case rhs => typedExpr(rhs, tpt1.tpe) } assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym) } def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = track("typedDefDef") { - val DefDef(name, tparams, vparamss, tpt, rhs) = ddef + val DefDef(name, tparams, vparamss, tpt, _) = ddef addTypedModifiersAnnotations(ddef, sym) val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef]) val vparamss1 = vparamss nestedMapconserve (typed(_).asInstanceOf[ValDef]) if (sym is Implicit) checkImplicitParamsNotSingletons(vparamss1) val tpt1 = typedType(tpt) - val rhs1 = typedExpr(rhs, tpt1.tpe) + val rhs1 = typedExpr(ddef.rhs, tpt1.tpe) assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym) //todo: make sure dependent method types do not depend on implicits or by-name params } @@ -896,7 +897,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = track("typedClassDef") { - val TypeDef(name, impl @ Template(constr, parents, self, body)) = cdef + val TypeDef(name, impl @ Template(constr, parents, self, _)) = cdef val superCtx = ctx.superCallContext def typedParent(tree: untpd.Tree): Tree = if (tree.isType) typedType(tree)(superCtx) @@ -913,7 +914,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val parents1 = ensureConstrCall(cls, parentsWithClass)(superCtx) val self1 = typed(self)(ctx.outer).asInstanceOf[ValDef] // outer context where class members are not visible val dummy = localDummy(cls, impl) - val body1 = typedStats(body, dummy)(inClassContext(self1.symbol)) + val body1 = typedStats(impl.body, dummy)(inClassContext(self1.symbol)) checkNoDoubleDefs(cls) val impl1 = cpy.Template(impl)(constr1, parents1, self1, body1) .withType(dummy.nonMemberTermRef) -- cgit v1.2.3