diff options
author | Martin Odersky <odersky@gmail.com> | 2013-02-22 18:00:07 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-02-22 18:00:07 +0100 |
commit | 49931062dfa6785bc9a7af6350812e5a7dbc546d (patch) | |
tree | ec426579fe152f36456828055a1149a7439a54f8 /src/dotty/tools/dotc/core/Substituters.scala | |
parent | 77c862ed65cf6f6d0593e11e91959c4d08a9187b (diff) | |
download | dotty-49931062dfa6785bc9a7af6350812e5a7dbc546d.tar.gz dotty-49931062dfa6785bc9a7af6350812e5a7dbc546d.tar.bz2 dotty-49931062dfa6785bc9a7af6350812e5a7dbc546d.zip |
Added substSym method and dropped NoPrefix requirement.
Substituters now work on arbitrary NamedTypes, even if the prefix is different from NoPrefix.
Diffstat (limited to 'src/dotty/tools/dotc/core/Substituters.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Substituters.scala | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala index a63465f2c..33dd14b8e 100644 --- a/src/dotty/tools/dotc/core/Substituters.scala +++ b/src/dotty/tools/dotc/core/Substituters.scala @@ -27,10 +27,8 @@ trait Substituters { this: Context => tp match { case tp: NamedType => val sym = tp.symbol - if (tp.prefix eq NoPrefix) { - if (sym eq from) return to - } - if (sym.isStatic) tp + if (sym eq from) return to + if (sym.isStatic && !from.isStatic) tp else tp.derivedNamedType(subst1(tp.prefix, from, to, map), tp.name) case _: ThisType | _: BoundType | NoPrefix => tp @@ -46,11 +44,9 @@ trait Substituters { this: Context => tp match { case tp: NamedType => val sym = tp.symbol - if (tp.prefix eq NoPrefix) { - if (sym eq from1) return to1 - if (sym eq from2) return to2 - } - if (sym.isStatic) tp + if (sym eq from1) return to1 + if (sym eq from2) return to2 + if (sym.isStatic && !from1.isStatic && !from2.isStatic) tp else tp.derivedNamedType(subst2(tp.prefix, from1, to1, from2, to2, map), tp.name) case _: ThisType | _: BoundType | NoPrefix => tp @@ -66,16 +62,14 @@ trait Substituters { this: Context => tp match { case tp: NamedType => val sym = tp.symbol - if (tp.prefix eq NoPrefix) { - var fs = from - var ts = to - while (fs.nonEmpty) { - if (fs.head eq sym) return ts.head - fs = fs.tail - ts = ts.tail - } + var fs = from + var ts = to + while (fs.nonEmpty) { + if (fs.head eq sym) return ts.head + fs = fs.tail + ts = ts.tail } - if (sym.isStatic) tp + if (sym.isStatic && !existsStatic(from)) tp else tp.derivedNamedType(subst(tp.prefix, from, to, map), tp.name) case _: ThisType | _: BoundType | NoPrefix => tp @@ -87,6 +81,28 @@ trait Substituters { this: Context => } } + final def substSym(tp: Type, from: List[Symbol], to: List[Symbol], map: SubstSymMap): Type = + tp match { + case tp: NamedType => + val sym = tp.symbol + var fs = from + var ts = to + while (fs.nonEmpty) { + if (fs.head eq sym) return NamedType(tp.prefix, ts.head) + fs = fs.tail + ts = ts.tail + } + if (sym.isStatic && !existsStatic(from)) tp + else tp.derivedNamedType(substSym(tp.prefix, from, to, map), tp.name) + case _: ThisType | _: BoundType | NoPrefix => + tp + case tp: RefinedType => + tp.derivedRefinedType(substSym(tp.parent, from, to, map), tp.name, substSym(tp.info, from, to, map)) + case _ => + (if (map != null) map else new SubstSymMap(from, to)) + .mapOver(tp) + } + final def substThis(tp: Type, from: ClassSymbol, to: Type, map: SubstThisMap): Type = tp match { case tp @ ThisType(clazz) => @@ -119,6 +135,11 @@ trait Substituters { this: Context => .mapOver(tp) } + private def existsStatic(syms: List[Symbol]): Boolean = syms match { + case sym :: syms1 => sym.isStatic || existsStatic(syms1) + case nil => false + } + final class SubstBindingMap(from: BindingType, to: BindingType) extends TypeMap { def apply(tp: Type) = subst(tp, from, to, this) } @@ -135,6 +156,10 @@ trait Substituters { this: Context => def apply(tp: Type): Type = subst(tp, from, to, this) } + final class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends TypeMap { + def apply(tp: Type): Type = substSym(tp, from, to, this) + } + final class SubstThisMap(from: ClassSymbol, to: Type) extends TypeMap { def apply(tp: Type): Type = substThis(tp, from, to, this) } |