summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-01-25 12:37:51 +0000
committerpaltherr <paltherr@epfl.ch>2004-01-25 12:37:51 +0000
commit2aef35c1c943d8c423ee5113ee1af32ea3dea772 (patch)
tree1933b99b8fec6e80358abdea83bab052c88f74da /sources
parentc8842d2ece2e6a23fd1b660d9a6c9aed8db6843e (diff)
downloadscala-2aef35c1c943d8c423ee5113ee1af32ea3dea772.tar.gz
scala-2aef35c1c943d8c423ee5113ee1af32ea3dea772.tar.bz2
scala-2aef35c1c943d8c423ee5113ee1af32ea3dea772.zip
- Added class ThisTypeMap
Diffstat (limited to 'sources')
-rw-r--r--sources/scalac/symtab/Type.java84
1 files changed, 84 insertions, 0 deletions
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index b4ab232509..3f4281239c 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -9,6 +9,8 @@
package scalac.symtab;
+import java.util.HashMap;
+
import ch.epfl.lamp.util.Position;
import scalac.ApplicationError;
import scalac.util.*;
@@ -1621,6 +1623,88 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
} else return these;
}
+ /**
+ * A map that substitutes ThisTypes of a given class by a given
+ * type. All occurrences of the type parameters of the given class
+ * are replaced by the type arguments extracted from the given
+ * type. Furthermore, the prefixes of the given type are used to
+ * substitute, in the same way, the ThisTypes of the outer classes
+ * of the given class.
+ *
+ * object Foo {
+ * class C[D] { class I[J]; }
+ * val c: C[Int] = new C[Int];
+ * class M[N] extends c.I[N];
+ * }
+ *
+ * In the code above, a ThisTypeMap of class "I" and type
+ * "ThisType(M)", would do the following substitutions:
+ *
+ * - ThisType(I) -> ThisType(M)
+ * - TypeRef(_, J, _) -> TypeRef(_, N, -)
+ * - ThisType(C) -> SingleType(ThisType(Foo), c)
+ * - TypeRef(_, D, _) -> TypeRef(_, Int, _)
+ */
+ private static class ThisTypeMap extends Map {
+ private final HashMap/*<Symbol,Type>*/ subst;
+
+ public ThisTypeMap(Symbol clasz, Type type) {
+ this.subst = new HashMap();
+ initialize(clasz, type);
+ }
+
+ private void initialize(Symbol clasz, Type type) {
+ switch (type) {
+ case ThisType(Symbol symbol):
+ if (symbol == clasz) return;
+ if (symbol.isNone()) return; // !!!
+ }
+ subst.put(clasz, type);
+ Type base = type.baseType(clasz);
+ switch (base) {
+ case TypeRef(Type prefix, Symbol symbol, Type[] args):
+ Symbol[] params = clasz.typeParams();
+ assert symbol == clasz && args.length == params.length:
+ type + "@" + Debug.show(clasz) + " -> " + base;
+ for (int i = 0; i < params.length; i++) {
+ assert params[i].isParameter(): Debug.show(params[i]);
+ subst.put(params[i], args[i]);
+ }
+ initialize(clasz.owner(), prefix);
+ break;
+ default:
+ throw Debug.abort("illegal case",
+ type + "@" + Debug.show(clasz) + " -> " + base);
+ }
+ }
+
+ public Type apply(Type type) {
+ switch (type) {
+ case ThisType(Symbol symbol):
+ Type lookup = (Type)subst.get(symbol);
+ if (lookup == null) break;
+ return lookup;
+ case TypeRef(Type prefix, Symbol symbol, Type[] args):
+ if (!symbol.isParameter()) break;
+ assert args.length == 0: type;
+ Type lookup = (Type)subst.get(symbol);
+ if (lookup == null) break;
+ return lookup;
+ }
+ return map(type);
+ }
+
+ public String toString() {
+ return subst.toString();
+ }
+
+ }
+
+ /** Returns a ThisTypeMap of given class and type. */
+ public static Map getThisTypeMap(Symbol clasz, Type type) {
+ return new ThisTypeMap(clasz, type);
+ }
+
/** A map for substitutions of thistypes.
*/
public static class SubstThisMap extends Map {