diff options
author | Martin Odersky <odersky@gmail.com> | 2014-10-19 15:32:30 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-10-26 16:24:01 +0100 |
commit | 0f3a903bebdac5eeaa84b2f8fdd0298bd15468f2 (patch) | |
tree | baad7c679295ffa079e11be30f7a8650720a12ad /src/dotty/tools/dotc/ast/TreeTypeMap.scala | |
parent | 8b38acbd349a033ba29285397fb54530a25e16e0 (diff) | |
download | dotty-0f3a903bebdac5eeaa84b2f8fdd0298bd15468f2.tar.gz dotty-0f3a903bebdac5eeaa84b2f8fdd0298bd15468f2.tar.bz2 dotty-0f3a903bebdac5eeaa84b2f8fdd0298bd15468f2.zip |
TreeTypeMap needs to map declarations of mapped classes
... and these mappings have to be part of the applied substitutions.
Without the patch, the postCondition of FirstTransform fails for TreeInfo.scala and others,
because it selects symbols which are not defined in the mapped class.
Unrelated bugfix: JavaArray derives from Object.
Diffstat (limited to 'src/dotty/tools/dotc/ast/TreeTypeMap.scala')
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeTypeMap.scala | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala index 33be848c1..22428edb6 100644 --- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -79,14 +79,25 @@ final class TreeTypeMap( override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = treeMap(tree) match { case impl @ Template(constr, parents, self, body) => - val tmap = withMappedSyms(impl.symbol :: impl.constr.symbol :: Nil) - val parents1 = parents mapconserve transform - val (_, constr1 :: self1 :: Nil) = transformDefs(constr :: self :: Nil) - val body1 = tmap.transformStats(body) - updateDecls(constr :: body, constr1 :: body1) - cpy.Template(impl)( - constr1.asInstanceOf[DefDef], parents1, self1.asInstanceOf[ValDef], body1) - .withType(tmap.mapType(impl.tpe)) + if (oldOwners contains impl.symbol.owner) { + val tmap = withMappedSyms(localSyms(impl :: self :: Nil)) + cpy.Template(impl)( + constr = tmap.transformSub(constr), + parents = parents mapconserve transform, + self = tmap.transformSub(self), + body = body mapconserve tmap.transform + ).withType(tmap.mapType(impl.tpe)) + } + else { + val tmap = withMappedSyms(impl.symbol :: impl.constr.symbol :: Nil) + val parents1 = parents mapconserve transform + val (_, constr1 :: self1 :: Nil) = transformDefs(constr :: self :: Nil) + val body1 = tmap.transformStats(body) + updateDecls(constr :: body, constr1 :: body1) + cpy.Template(impl)( + constr1.asInstanceOf[DefDef], parents1, self1.asInstanceOf[ValDef], body1) + .withType(tmap.mapType(impl.tpe)) + } case tree1 => tree1.withType(mapType(tree1.tpe)) match { case id: Ident if tpd.needsSelect(id.tpe) => @@ -160,8 +171,24 @@ final class TreeTypeMap( * and return a treemap that contains the substitution * between original and mapped symbols. */ - def withMappedSyms(syms: List[Symbol]): TreeTypeMap = { - val mapped = ctx.mapSymbols(syms, this) - withSubstitution(syms, mapped) - } + def withMappedSyms(syms: List[Symbol]): TreeTypeMap = + withMappedSyms(syms, ctx.mapSymbols(syms, this)) + + /** The tree map with the substitution between originals `syms` + * and mapped symbols `mapped`. Also goes into mapped classes + * and substitutes their declarations. + */ + def withMappedSyms(syms: List[Symbol], mapped: List[Symbol]): TreeTypeMap = + if (mapped eq syms) this + else { + val substMap = withSubstitution(syms, mapped) + val mappedClasses = mapped.filter(_.isClass) + (substMap /: mappedClasses) { (tmap, cls) => + val origDcls = cls.decls.toList + val mappedDcls = ctx.mapSymbols(origDcls, tmap) + val tmap1 = tmap.withMappedSyms(origDcls, mappedDcls) + (origDcls, mappedDcls).zipped.foreach(cls.asClass.replace) + tmap1 + } + } } |