summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2003-07-11 09:02:48 +0000
committerpaltherr <paltherr@epfl.ch>2003-07-11 09:02:48 +0000
commitc9f76440265b557f776d67839628ddad8520b7a5 (patch)
tree65aab83a1d3e041db28e29c3b5de8e3c87b79a32 /sources/scalac
parent8b54bfd4f63139f70a9c5306e2256d5db25032e6 (diff)
downloadscala-c9f76440265b557f776d67839628ddad8520b7a5.tar.gz
scala-c9f76440265b557f776d67839628ddad8520b7a5.tar.bz2
scala-c9f76440265b557f776d67839628ddad8520b7a5.zip
- Added method Type.cloneType
- Added method Type.Map.applyParams - Added a boolean "dontClone" to methods Type.Map.map(Symbol) and Type.Map.map(Symbol[])
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/symtab/Type.java108
-rw-r--r--sources/scalac/transformer/LambdaLiftPhase.java8
2 files changed, 94 insertions, 22 deletions
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 72a25d61ec..915ccc8079 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -662,6 +662,28 @@ public class Type implements Modifiers, Kinds, TypeTags {
public abstract Type apply(Type t);
+ /**
+ * This method assumes that all symbols in MethodTypes and
+ * PolyTypes have already been cloned.
+ */
+ public Type applyParams(Type type) {
+ switch (type) {
+
+ case MethodType(Symbol[] vparams, Type result):
+ map(vparams, true);
+ Type result1 = applyParams(result);
+ return result == result1 ? type : MethodType(vparams, result1);
+
+ case PolyType(Symbol[] tparams, Type result):
+ map(tparams, true);
+ Type result1 = applyParams(result);
+ return result == result1 ? type : PolyType(tparams, result1);
+
+ default:
+ return apply(type);
+ }
+ }
+
/** Apply map to all top-level components of this type.
*/
public Type map(Type tp) {
@@ -734,17 +756,26 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
}
- public Symbol map(Symbol sym) {
+ public final Symbol map(Symbol sym) {
+ return map(sym, false);
+ }
+ public Symbol map(Symbol sym, boolean dontClone) {
Type tp = sym.info();
Type tp1 = apply(tp);
- Symbol sym1 = (tp == tp1) ? sym : sym.cloneSymbol().setInfo(tp1);
- if (sym1.kind == TYPE) {
+ if (tp != tp1) {
+ if (!dontClone) sym = sym.cloneSymbol();
+ sym.setInfo(tp1);
+ dontClone = true;
+ }
+ if (sym.kind == TYPE) {
Type lb = sym.loBound();
Type lb1 = apply(lb);
- if (lb != lb1)
- sym1 = sym1.cloneSymbol().setLoBound(lb1);
- }
- return sym1;
+ if (lb != lb1) {
+ if (!dontClone) sym = sym.cloneSymbol();
+ sym.setLoBound(lb1);
+ }
+ }
+ return sym;
}
public Type[] map(Type[] tps) {
@@ -764,11 +795,14 @@ public class Type implements Modifiers, Kinds, TypeTags {
/** Apply map to all elements of this array of symbols,
* preserving recursive references to symbols in the array.
*/
- public Symbol[] map(Symbol[] syms) {
+ public final Symbol[] map(Symbol[] syms) {
+ return map(syms, false);
+ }
+ public Symbol[] map(Symbol[] syms, boolean dontClone) {
Symbol[] syms1 = syms;
for (int i = 0; i < syms.length; i++) {
Symbol sym = syms[i];
- Symbol sym1 = map(sym);
+ Symbol sym1 = map(sym, dontClone);
if (sym != sym1 && syms1 == syms) {
syms1 = new Symbol[syms.length];
System.arraycopy(syms, 0, syms1, 0, i);
@@ -780,11 +814,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
if (syms1[i] == syms[i])
syms1[i] = syms[i].cloneSymbol();
}
- for (int i = 0; i < syms1.length; i++) {
- syms1[i].setInfo(syms1[i].info().subst(syms, syms1));
- if (syms1[i].kind == TYPE)
- syms1[i].setLoBound(syms1[i].loBound().subst(syms, syms1));
- }
+ new SubstSymMap(syms, syms1).map(syms1, true);
}
return syms1;
}
@@ -800,8 +830,8 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
public abstract static class MapOnlyTypes extends Map {
- public Symbol map(Symbol sym) { return sym; }
- public Symbol[] map(Symbol[] syms) { return syms; }
+ public Symbol map(Symbol sym, boolean dontClone) { return sym; }
+ public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; }
public Scope map(Scope s) { return s; }
}
@@ -1224,6 +1254,52 @@ public class Type implements Modifiers, Kinds, TypeTags {
return false;
}
+// Cloning ---------------------------------------------------------------
+
+ /**
+ * Clones a type i.e. returns a new type "as seen from" the new
+ * owner and where all symbols in MethodTypes and PolyTypes have
+ * been cloned.
+ */
+ public Type cloneType(Symbol oldOwner, Symbol newOwner) {
+ Type clone = cloneType0(oldOwner, newOwner);
+ if (oldOwner.isClass())
+ clone = new SubstThisMap(oldOwner, newOwner).applyParams(clone);
+ return clone;
+ }
+
+ private Type cloneType0(Symbol oldOwner, Symbol newOwner) {
+ switch (this) {
+
+ case MethodType(Symbol[] vparams, Type result):
+ Symbol[] clones = new Symbol[vparams.length];
+ for (int i = 0; i < clones.length; i++) {
+ assert vparams[i].owner() == oldOwner : Debug.show(vparams[i]);
+ clones[i] = vparams[i].cloneSymbol(newOwner);
+ }
+ result = result.cloneType0(oldOwner, newOwner);
+ Type clone = Type.MethodType(clones, result);
+ if (vparams.length != 0)
+ clone = new SubstSymMap(vparams, clones).applyParams(clone);
+ return clone;
+
+ case PolyType(Symbol[] tparams, Type result):
+ Symbol[] clones = new Symbol[tparams.length];
+ for (int i = 0; i < clones.length; i++) {
+ assert tparams[i].owner() == oldOwner : Debug.show(tparams[i]);
+ clones[i] = tparams[i].cloneSymbol(newOwner);
+ }
+ result = result.cloneType0(oldOwner, newOwner);
+ Type clone = Type.PolyType(clones, result);
+ if (tparams.length != 0)
+ clone = new SubstSymMap(tparams, clones).applyParams(clone);
+ return clone;
+
+ default:
+ return this;
+ }
+ }
+
// Comparisons ------------------------------------------------------------------
/** Is this type a subtype of that type?
diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java
index 73e26e7986..050cc95515 100644
--- a/sources/scalac/transformer/LambdaLiftPhase.java
+++ b/sources/scalac/transformer/LambdaLiftPhase.java
@@ -73,6 +73,8 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
return transformTypeMap.setOwner(owner).apply(tp);
}
+ /** MapOnlyTypes => All symbols are mapped to themselves.
+ */
private class TransformTypeMap extends Type.MapOnlyTypes {
Symbol owner;
// ArrayList/*<Symbol>*/ excluded = new ArrayList();
@@ -122,12 +124,6 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
}
return map(tp);
}
-
- /** All symbols are mapped to themselves.
- */
- public Scope map(Scope s) { return s; }
- public Symbol map(Symbol s) { return s; }
- public Symbol[] map(Symbol[] ss) { return ss; }
}
private TransformTypeMap transformTypeMap = new TransformTypeMap();