aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast/TreeTypeMap.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-10-19 15:32:30 +0200
committerMartin Odersky <odersky@gmail.com>2014-10-26 16:24:01 +0100
commit0f3a903bebdac5eeaa84b2f8fdd0298bd15468f2 (patch)
treebaad7c679295ffa079e11be30f7a8650720a12ad /src/dotty/tools/dotc/ast/TreeTypeMap.scala
parent8b38acbd349a033ba29285397fb54530a25e16e0 (diff)
downloaddotty-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.scala51
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
+ }
+ }
}