From 98160c43002907b2784d1031c476cd46b912e752 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 28 Nov 2013 21:55:31 +0100 Subject: Making substitutions deep type maps that also map parents and self type of a class info. --- src/dotty/tools/dotc/core/Substituters.scala | 18 +++++++------- src/dotty/tools/dotc/core/Types.scala | 35 +++++++++++++++------------- 2 files changed, 28 insertions(+), 25 deletions(-) (limited to 'src/dotty') diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala index 763c3eea7..0df1ea49f 100644 --- a/src/dotty/tools/dotc/core/Substituters.scala +++ b/src/dotty/tools/dotc/core/Substituters.scala @@ -172,39 +172,39 @@ trait Substituters { this: Context => case nil => false } - final class SubstBindingMap(from: BindingType, to: BindingType) extends TypeMap { + final class SubstBindingMap(from: BindingType, to: BindingType) extends DeepTypeMap { def apply(tp: Type) = subst(tp, from, to, this) } - final class Subst1Map(from: Symbol, to: Type) extends TypeMap { + final class Subst1Map(from: Symbol, to: Type) extends DeepTypeMap { def apply(tp: Type) = subst1(tp, from, to, this) } - final class Subst2Map(from1: Symbol, to1: Type, from2: Symbol, to2: Type) extends TypeMap { + final class Subst2Map(from1: Symbol, to1: Type, from2: Symbol, to2: Type) extends DeepTypeMap { def apply(tp: Type) = subst2(tp, from1, to1, from2, to2, this) } - final class SubstMap(from: List[Symbol], to: List[Type]) extends TypeMap { + final class SubstMap(from: List[Symbol], to: List[Type]) extends DeepTypeMap { def apply(tp: Type): Type = subst(tp, from, to, this) } - final class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends TypeMap { + final class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends DeepTypeMap { def apply(tp: Type): Type = substSym(tp, from, to, this) } - final class SubstThisMap(from: ClassSymbol, to: Type) extends TypeMap { + final class SubstThisMap(from: ClassSymbol, to: Type) extends DeepTypeMap { def apply(tp: Type): Type = substThis(tp, from, to, this) } - final class SubstRefinedThisMap(from: RefinedType, to: Type) extends TypeMap { + final class SubstRefinedThisMap(from: RefinedType, to: Type) extends DeepTypeMap { def apply(tp: Type): Type = substThis(tp, from, to, this) } - final class SubstParamMap(from: ParamType, to: Type) extends TypeMap { + final class SubstParamMap(from: ParamType, to: Type) extends DeepTypeMap { def apply(tp: Type) = substParam(tp, from, to, this) } - final class SubstParamsMap(from: BindingType, to: List[Type]) extends TypeMap { + final class SubstParamsMap(from: BindingType, to: List[Type]) extends DeepTypeMap { def apply(tp: Type) = substParams(tp, from, to, this) } } \ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index bfe19c859..8ef7edf24 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1989,11 +1989,6 @@ object Types { abstract class TypeMap(implicit ctx: Context) extends (Type => Type) { thisMap => - /** Unset by default. If set also map parents and self type of a ClassInfo. - * By default, only the prefix is mapped. - */ - def mapClassInfosDeeply = false - def apply(tp: Type): Type /** Map this function over given type */ @@ -2028,17 +2023,8 @@ object Types { tp.derivedTypeBounds(this(lo), this(hi)) } - case tp @ ClassInfo(prefix, _, _, _, _) => - if (mapClassInfosDeeply) { - val prefix1 = this(prefix) - val parents1 = (tp.parents mapConserve this).asInstanceOf[List[TypeRef]] - val self1 = tp.self match { - case self: Type => this(self) - case _ => tp.self - } - tp.derivedClassInfo(prefix1, parents1, self1) - } - else tp.derivedClassInfo(this(prefix)) + case tp: ClassInfo => + mapClassInfo(tp) case tp: TypeVar => val inst = tp.instanceOpt @@ -2076,11 +2062,28 @@ object Types { def mapOver(tree: Tree): Tree = new TreeMapper(this).apply(tree) + /** Can be overridden. By default, only the prefix is mapped. */ + protected def mapClassInfo(tp: ClassInfo): ClassInfo = + tp.derivedClassInfo(this(tp.prefix)) + def andThen(f: Type => Type): TypeMap = new TypeMap { def apply(tp: Type) = f(thisMap(tp)) } } + /** A type map that maps also parents and self type of a ClassInfo */ + abstract class DeepTypeMap(implicit ctx: Context) extends TypeMap { + override def mapClassInfo(tp: ClassInfo) = { + val prefix1 = this(tp.prefix) + val parents1 = (tp.parents mapConserve this).asInstanceOf[List[TypeRef]] + val self1 = tp.self match { + case self: Type => this(self) + case _ => tp.self + } + tp.derivedClassInfo(prefix1, parents1, self1) + } + } + object IdentityTypeMap extends TypeMap()(NoContext) { def apply(tp: Type) = tp } -- cgit v1.2.3