aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Substituters.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-22 18:00:07 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-22 18:00:07 +0100
commit49931062dfa6785bc9a7af6350812e5a7dbc546d (patch)
treeec426579fe152f36456828055a1149a7439a54f8 /src/dotty/tools/dotc/core/Substituters.scala
parent77c862ed65cf6f6d0593e11e91959c4d08a9187b (diff)
downloaddotty-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.scala61
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)
}