summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2003-09-01 17:27:13 +0000
committerpaltherr <paltherr@epfl.ch>2003-09-01 17:27:13 +0000
commit860d5686c0af6d6afc5266aded4a269cc5e104b7 (patch)
treebf873b71c86463e0ccfdb269942f89afd4fafa5a /sources
parentcdbd9750f48ad8d3a5a8e3a7d1e4077b7a6988d7 (diff)
downloadscala-860d5686c0af6d6afc5266aded4a269cc5e104b7.tar.gz
scala-860d5686c0af6d6afc5266aded4a269cc5e104b7.tar.bz2
scala-860d5686c0af6d6afc5266aded4a269cc5e104b7.zip
- Replaced field Global.phases by fields Phase....
- Replaced field Global.phases by fields Phase.prev and Phase.next - Reorganized/Cleaned/Documented methods on infos, types and - closures in Symbol Removed method CompilerPhases.remove Add mehods - PhaseDescriptor.addXXXFlag
Diffstat (limited to 'sources')
-rw-r--r--sources/scalac/CompilerPhases.java7
-rw-r--r--sources/scalac/Global.java43
-rw-r--r--sources/scalac/Phase.java15
-rw-r--r--sources/scalac/PhaseDescriptor.java38
-rw-r--r--sources/scalac/symtab/Symbol.java478
-rw-r--r--sources/scalac/transformer/LambdaLift.java14
-rw-r--r--sources/scalac/transformer/LambdaLiftPhase.java7
7 files changed, 345 insertions, 257 deletions
diff --git a/sources/scalac/CompilerPhases.java b/sources/scalac/CompilerPhases.java
index 884ed5f52b..923d436605 100644
--- a/sources/scalac/CompilerPhases.java
+++ b/sources/scalac/CompilerPhases.java
@@ -167,8 +167,6 @@ public class CompilerPhases {
public void freeze() {
PhaseDescriptor[] phases = phases();
PhaseDescriptor.freeze(phases);
- for (int i = 0; i < phases.length; i++)
- if (phases[i].hasSkipFlag()) remove(phases[i]);
}
/** Activates phase "phase" by placing it before phase "where". */
@@ -185,10 +183,5 @@ public class CompilerPhases {
phases.add(index + 1, phase);
}
- /** Deactivates phase "phase". */
- public void remove(PhaseDescriptor phase) {
- phases.remove(phase);
- }
-
//########################################################################
}
diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java
index c9f8452c42..d2d447d298 100644
--- a/sources/scalac/Global.java
+++ b/sources/scalac/Global.java
@@ -107,6 +107,10 @@ public class Global {
*/
public HashMap/*<Symbol,Sourcefile>*/ compiledNow = new HashMap();
+ /** the first phase
+ */
+ private final Phase firstPhase;
+
/** the current phase
*/
public Phase currentPhase;
@@ -122,7 +126,6 @@ public class Global {
/** compilation phases.
*/
public final CompilerPhases PHASE;
- public final Phase[] phases;
/** compilation targets
*/
@@ -197,32 +200,39 @@ public class Global {
this.PHASE = args.phases;
// if (!optimize) PHASE.remove(args.phases.OPTIMIZE);
// TODO: Enable TailCall for other backends when they handle LabelDefs
- if (target != TARGET_JVM) PHASE.remove(args.phases.TAILCALL);
- if (target != TARGET_MSIL) PHASE.remove(args.phases.GENMSIL);
- if (target != TARGET_JVM) PHASE.remove(args.phases.GENJVM);
- if (target != TARGET_JVM_BCEL) PHASE.remove(args.phases.GENJVM_BCEL);
+ if (target != TARGET_JVM) args.phases.TAILCALL.addSkipFlag();
+ if (target != TARGET_MSIL) args.phases.GENMSIL.addSkipFlag();
+ if (target != TARGET_JVM) args.phases.GENJVM.addSkipFlag();
+ if (target != TARGET_JVM_BCEL) args.phases.GENJVM_BCEL.addSkipFlag();
PHASE.freeze();
PhaseDescriptor[] descriptors = PHASE.phases();
- this.phases = new Phase[descriptors.length];
- this.currentPhase = phases[0] = descriptors[0].create(this);
+ this.firstPhase = descriptors[0].create(this);
this.definitions = new Definitions(this);
this.primitives = new Primitives(this);
this.treeGen = new TreeGen(this, make);
+ assert !descriptors[0].hasSkipFlag();
for (int i = 1; i < descriptors.length; i++)
- this.currentPhase = phases[i] = descriptors[i].create(this);
- this.currentPhase = phases[0];
+ if (!descriptors[i].hasSkipFlag()) descriptors[i].create(this);
+ this.currentPhase = firstPhase;
+ }
+
+ /** Returns the first compilation phase. */
+ public Phase getFirstPhase() {
+ return firstPhase;
}
/** Move to next phase
*/
public void nextPhase() {
- currentPhase = phases[currentPhase.id + 1];
+ assert currentPhase.next != null;
+ currentPhase = currentPhase.next;
}
/** Move to previous phase
*/
public void prevPhase() {
- currentPhase = phases[currentPhase.id - 1];
+ assert currentPhase.prev != null;
+ currentPhase = currentPhase.prev;
}
/** the top-level compilation process
@@ -259,9 +269,10 @@ public class Global {
private void compile() {
printer.begin();
+ currentPhase = firstPhase;
// apply successive phases and pray that it works
- for (int i = 0; i < phases.length && reporter.errors() == 0; ++i) {
- currentPhase = phases[i];
+ while (currentPhase.next != null && reporter.errors() == 0) {
+ currentPhase = currentPhase.next;
start();
currentPhase.apply(units);
stop(currentPhase.descriptor.taskDescription());
@@ -295,9 +306,8 @@ public class Global {
*/
public void transformUnit(Unit unit) {
Phase oldCurrentPhase = currentPhase;
- int i = PHASE.REFCHECK.id(); // or PHASE.UNCURRY.id?
- while ((i < oldCurrentPhase.id) && (reporter.errors() == 0)) {
- currentPhase = phases[i];
+ currentPhase = PHASE.ANALYZER.phase().next; // or REFCHECK.next?
+ while ((currentPhase.id < oldCurrentPhase.id) && (reporter.errors() == 0)) {
start();
currentPhase.apply(new Unit[] {unit}); // !!! pb with Analyzer
stop(currentPhase.descriptor.taskDescription());
@@ -307,6 +317,7 @@ public class Global {
currentPhase.graph(this);
if (currentPhase.descriptor.hasCheckFlag())
currentPhase.check(this);
+ currentPhase = currentPhase.next;
}
currentPhase = oldCurrentPhase;
}
diff --git a/sources/scalac/Phase.java b/sources/scalac/Phase.java
index eb0e87f274..d205305c86 100644
--- a/sources/scalac/Phase.java
+++ b/sources/scalac/Phase.java
@@ -50,6 +50,12 @@ public abstract class Phase {
/** The phase identifier */
public final int id;
+ /** The previous phase */
+ public final Phase prev;
+
+ /** The next phase */
+ public Phase next;
+
//########################################################################
// Public Constructors
@@ -58,12 +64,19 @@ public abstract class Phase {
this.global = global;
this.descriptor = descriptor;
this.id = descriptor.id();
- global.currentPhase = global.phases[id] = this;
+ this.prev = global.currentPhase;
+ if (prev != null) prev.next = this;
+ global.currentPhase = this;
}
//########################################################################
// Public Methods
+ /** Does this phase precede the given phase? */
+ public boolean precedes(Phase phase) {
+ return id < phase.id;
+ }
+
/**
* Returns the info of `sym' after the phase. Assumes that `tp' is
* the info of symbol `sym' before this phase.
diff --git a/sources/scalac/PhaseDescriptor.java b/sources/scalac/PhaseDescriptor.java
index 602a329fb6..a57694961b 100644
--- a/sources/scalac/PhaseDescriptor.java
+++ b/sources/scalac/PhaseDescriptor.java
@@ -52,10 +52,10 @@ public final class PhaseDescriptor {
// propagate other flags and freeze remaining phases
PhaseDescriptor last = null;
for (int i = 0; i < phases.length; i++) {
+ phases[i].id = i;
if (phases[i].hasSkipFlag()) continue;
if (last != null) last.flags |= phases[i].flags >>> 16;
phases[i].flags &= 0x0000FFFF;
- phases[i].freeze(last);
last = phases[i];
}
}
@@ -110,12 +110,6 @@ public final class PhaseDescriptor {
return task;
}
- /** Freezes this phase by assigning it an identifier. */
- public void freeze(PhaseDescriptor prev) {
- assert id < 0 : "phase " + name + " already frozen";
- id = prev != null ? prev.id + 1 : 0;
- }
-
/** Creates the object implementing this phase. */
public Phase create(Global global) {
assert id >= 0 : "phase " + name + " not yet frozen";
@@ -154,6 +148,36 @@ public final class PhaseDescriptor {
flags |= flag << (prev ? 16 : 0);
}
+ /** Adds the SKIP flag. */
+ public void addSkipFlag() {
+ flags |= SKIP;
+ }
+
+ /** Adds the CHECK flag. */
+ public void addCheckFlag() {
+ flags |= CHECK;
+ }
+
+ /** Adds the PRINT flag. */
+ public void addPrintFlag() {
+ flags |= PRINT;
+ }
+
+ /** Adds the GRAPH flag. */
+ public void addGraphFlag() {
+ flags |= GRAPH;
+ }
+
+ /** Adds the STOP flag. */
+ public void addStopFlag() {
+ flags |= STOP;
+ }
+
+ /** Adds the LOG flag. */
+ public void addLogFlag() {
+ flags |= LOG;
+ }
+
/** Has this phase the SKIP flag? */
public boolean hasSkipFlag() {
return (flags & SKIP) != 0;
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 58014840aa..a9ee5273ac 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -54,7 +54,7 @@ public abstract class Symbol implements Modifiers, Kinds {
private Symbol owner;
/** The infos of the symbol */
- private TypeIntervalList infos = TypeIntervalList.EMPTY;
+ private TypeIntervalList infos;
// Constructors -----------------------------------------------------------
@@ -128,54 +128,63 @@ public abstract class Symbol implements Modifiers, Kinds {
symbol.owner = owner;
}
- /** Set information, except if symbol is both initialized and locked.
- */
+ /** Set type -- this is an alias for setInfo(Type info) */
+ public final Symbol setType(Type info) { return setInfo(info); }
+
+ /** Set initial information valid from start of current phase. */
public Symbol setInfo(Type info) {
- return setInfoAt(info, currentPhaseId());
+ return setInfoAt(info, Global.instance.currentPhase);
+ }
+
+ /** Set initial information valid from start of first phase. */
+ public final Symbol setFirstInfo(Type info) {
+ return setInfoAt(info, Global.instance.getFirstPhase());
+ }
+
+ /** Set initial information valid from start of given phase. */
+ private final Symbol setInfoAt(Type info, Phase phase) {
+ assert phase != null : this;
+ assert !isConstructor()
+ || info instanceof Type.LazyType
+ || info == Type.NoType
+ || info == Type.ErrorType
+ || info instanceof Type.MethodType
+ || info instanceof Type.OverloadedType
+ || info instanceof Type.PolyType
+ : "illegal type for " + this + ": " + info;
+ if (phase.prev != null) phase = phase.prev;
+ infos = new TypeIntervalList(null, info, phase);
+ if (info instanceof Type.LazyType) flags &= ~INITIALIZED;
+ else flags |= INITIALIZED;
+ return this;
}
- public Symbol setFirstInfo(Type info) {
- return setInfoAt(info, 0);
+ /** Set new information valid from start of next phase */
+ public final Symbol updateInfo(Type info) {
+ return updateInfoAt(info, Global.instance.currentPhase);
}
- private Symbol setInfoAt(Type info, int limit) {
- assert !isConstructor()
- || info instanceof Type.LazyType
- || info == Type.NoType
- || info == Type.ErrorType
- || info instanceof Type.MethodType
- || info instanceof Type.OverloadedType
- || info instanceof Type.PolyType
- : "illegal type for " + this + ": " + info;
- if (infos == TypeIntervalList.EMPTY) {
- infos = new TypeIntervalList(TypeIntervalList.EMPTY);
- }
- infos.limit = limit;
- infos.info = info;
- if (info instanceof Type.LazyType) flags &= ~INITIALIZED;
- else flags |= INITIALIZED;
- return this;
+ /** Set new information valid from start of given phase */
+ private final Symbol updateInfoAt(Type info, Phase phase) {
+ assert infos != null : this;
+ assert !phase.precedes(infos.limit()) :
+ this + " -- " + phase + " -- " + infos.limit();
+ if (infos.limit() == phase) {
+ if (infos.start == phase)
+ infos = infos.prev;
+ else
+ infos.setLimit(infos.limit().prev);
+ }
+ infos = new TypeIntervalList(infos, info, phase);
+ return this;
}
- /** Set type -- this is an alias for setInfo(Type info)
- */
- public Symbol setType(Type info) { return setInfo(info); }
-
/** Set type of `this' in current class
*/
public Symbol setTypeOfThis(Type tp) {
throw new ApplicationError(this + ".setTypeOfThis");
}
- public Symbol updateInfo(Type info) {
- assert infos.limit <= Global.instance.currentPhase.id + 1 : this;
- if (infos.limit > Global.instance.currentPhase.id) infos.limit--;
- infos = new TypeIntervalList(infos);
- infos.limit = Global.instance.currentPhase.id + 1;
- infos.info = info;
- return this;
- }
-
/** Set the low bound of this type variable
*/
public Symbol setLoBound(Type lobound) {
@@ -221,7 +230,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Does this symbol denote a method?
*/
public final boolean isInitializedMethod() {
- if (infos.limit < 0) return false;
+ if (infos == null) return false;
switch (rawInfo()) {
case MethodType(_, _):
case PolyType(_, _):
@@ -536,7 +545,9 @@ public abstract class Symbol implements Modifiers, Kinds {
* Needed in ClassSymbol.primaryConstructor() and in UnPickle.
*/
public Symbol firstAlternative() {
- if (infos.info instanceof Type.OverloadedType)
+ if (infos == null)
+ return this;
+ else if (infos.info instanceof Type.OverloadedType)
return infos.info.alternativeSymbols()[0];
else if (infos.info instanceof LazyOverloadedType)
return ((LazyOverloadedType) infos.info).sym1.firstAlternative();
@@ -591,22 +602,15 @@ public abstract class Symbol implements Modifiers, Kinds {
// Symbol types --------------------------------------------------------------
- /** Was symbol's type updated during phase `id'?
- */
- public boolean isUpdated(int id) {
- return infos.limit >= id;
- }
-
- /** the current phase id, or the id after analysis, whichever is larger.
- */
- static int currentPhaseId() {
- return Global.instance.currentPhase.id;
- }
-
- public int definedPhaseId() {
- TypeIntervalList i = infos;
- while (i.prev != TypeIntervalList.EMPTY) i = i.prev;
- return i.limit;
+ /** Was symbol's type updated during given phase? */
+ public final boolean isUpdatedAt(Phase phase) {
+ TypeIntervalList infos = this.infos;
+ while (infos != null) {
+ if (infos.start == phase) return true;
+ if (infos.limit().precedes(phase)) return false;
+ infos = infos.prev;
+ }
+ return false;
}
/** Is this symbol initialized? */
@@ -616,7 +620,7 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Initialize the symbol */
public final Symbol initialize() {
- info();
+ info();
return this;
}
@@ -630,16 +634,16 @@ public abstract class Symbol implements Modifiers, Kinds {
infos.info.complete(this);
}
- /** Get info; This is:
+ /** Get info at start of current phase; This is:
* for a term symbol, its type
* for a type variable, its bound
* for a type alias, its right-hand side
* for a class symbol, the compound type consisting of
* its baseclasses and members.
*/
- public Type info() {
+ public final Type info() {
//if (isModule()) moduleClass().initialize();
- int id = currentPhaseId();
+ Phase phase = Global.instance.currentPhase;
if ((flags & INITIALIZED) == 0) {
Type info = rawFirstInfo();
assert info != null : this;
@@ -657,84 +661,106 @@ public abstract class Symbol implements Modifiers, Kinds {
Type tp = info();
flags &= ~SNDTIME;
} else {
- assert !(rawInfoAt(id) instanceof Type.LazyType) : this;
+ assert !(rawInfoAt(phase) instanceof Type.LazyType) : this;
//flags |= INITIALIZED;
}
//System.out.println("done: " + this);//DEBUG
}
- return rawInfoAt(id);
+ return rawInfoAt(phase);
+ }
+
+ /** Get info at start of next phase
+ */
+ public final Type nextInfo() {
+ Global.instance.nextPhase();
+ Type info = info();
+ Global.instance.prevPhase();
+ return info;
}
- /** Get info at phase #id
+ /** Get info at start of given phase
*/
- public Type infoAt(int id) {
- info();
- return rawInfoAt(id);
+ protected final Type infoAt(Phase phase) {
+ return initialize().rawInfoAt(phase);
}
- /** Get info at next phase
+ /** Get info at start of current phase, without forcing lazy types.
*/
- public Type nextInfo() {
- Global.instance.nextPhase();
- Type info = info();
- Global.instance.prevPhase();
- return info;
+ public final Type rawInfo() {
+ return rawInfoAt(Global.instance.currentPhase);
}
- /** get info at phase #id, without forcing lazy types.
+ /** Get info at start of next phase, without forcing lazy types.
*/
- private Type rawInfoAt(int id) {
- //if (infos == TypeIntervalList.EMPTY) return Type.NoType;//DEBUG
- assert infos != TypeIntervalList.EMPTY : this;
- int nextid = infos.limit;
- if (nextid < id) {
- Phase curphase = Global.instance.currentPhase;
- do {
- Global.instance.currentPhase = Global.instance.phases[nextid];
- Type newInfo =
- Global.instance.currentPhase.transformInfo(this, infos.info);
- if (newInfo != infos.info) {
- infos = new TypeIntervalList(infos);
- infos.info = newInfo;
- }
- nextid++;
- infos.limit = nextid;
- } while (nextid < id);
- Global.instance.currentPhase = curphase;
+ public final Type rawNextInfo() {
+ Global.instance.nextPhase();
+ Type info = rawInfo();
+ Global.instance.prevPhase();
+ return info;
+ }
+
+ /** Get info at start of given phase, without forcing lazy types.
+ */
+ private final Type rawInfoAt(Phase phase) {
+ //if (infos == null) return Type.NoType;//DEBUG
+ assert infos != null : this;
+ assert phase != null : this;
+ if (infos.limit().precedes(phase)) {
+ while (infos.limit().next != phase) {
+ Global global = phase.global;
+ Phase current = global.currentPhase;
+ Phase next = infos.limit().next;
+ global.currentPhase = next;
+ Type info = next.transformInfo(this, infos.info);
+ global.currentPhase = current;
+ if (info != infos.info) {
+ infos = new TypeIntervalList(infos, info, next);
+ } else {
+ infos.setLimit(next);
+ }
+ }
return infos.info;
} else {
- TypeIntervalList infos1 = infos;
- while (infos1.prev.limit >= id) {
- infos1 = infos1.prev;
- }
- return infos1.info;
+ TypeIntervalList infos = this.infos;
+ while (!infos.start.precedes(phase) && infos.prev != null)
+ infos = infos.prev;
+ return infos.info;
}
}
- public Type rawFirstInfo() {
- TypeIntervalList infos1 = infos;
- while (infos1.prev.limit >= 0) {
- infos1 = infos1.prev;
- }
- return infos1.info;
+ /** Get first defined info, without forcing lazy types.
+ */
+ public final Type rawFirstInfo() {
+ TypeIntervalList infos = this.infos;
+ assert infos != null : this;
+ while (infos.prev != null) infos = infos.prev;
+ return infos.info;
}
- public Type rawInfo() {
- return rawInfoAt(currentPhaseId());
+ /** Get phase that first defined an info, without forcing lazy types.
+ */
+ public final Phase rawFirstInfoStartPhase() {
+ TypeIntervalList infos = this.infos;
+ assert infos != null : this;
+ while (infos.prev != null) infos = infos.prev;
+ return infos.start;
}
- /** The type of a symbol is:
+ /** Get type at start of current phase. The type of a symbol is:
* for a type symbol, the type corresponding to the symbol itself
* for a term symbol, its usual type
*/
public Type type() {
- return info();
+ return info();
}
- /** The type at phase #id
+ /** Get type at start of next phase
*/
- public Type typeAt(int id) {
- return infoAt(id);
+ public final Type nextType() {
+ Global.instance.nextPhase();
+ Type type = type();
+ Global.instance.prevPhase();
+ return type;
}
/** The types of these symbols as an array.
@@ -1053,7 +1079,7 @@ public abstract class Symbol implements Modifiers, Kinds {
public void reset(Type completer) {
this.flags &= SOURCEFLAGS;
this.pos = 0;
- this.infos = TypeIntervalList.EMPTY;
+ this.infos = null;
this.setInfo(completer);
}
@@ -1192,7 +1218,7 @@ public abstract class TypeSymbol extends Symbol {
/** A cache for closures
*/
- private ClosureIntervalList closures = ClosureIntervalList.EMPTY;
+ private ClosureIntervalList closures;
/** The symbol's type template */
private Type template = null;
@@ -1324,101 +1350,91 @@ public abstract class TypeSymbol extends Symbol {
return template;
}
- /** Get type at phase id */
- public Type typeAt(int id) {
- return type();
- }
-
- public Type[] closure() {
- if (kind == ALIAS) return info().symbol().closure();
- int id = currentPhaseId();
- if (closures.limit < id) {
- if (id <= definedPhaseId() || changes(closureAt(id - 1))) {
- closures = new ClosureIntervalList(closures);
- closures.limit = id;
- computeClosure();
- } else {
- closures.limit = id;
- }
- return closures.closure;
- } else {
- ClosureIntervalList closures1 = closures;
- while (closures1.prev.limit >= id) {
- closures1 = closures1.prev;
- }
- return closures1.closure;
- }
+ /**
+ * Get closure at start of current phase. The closure of a symbol
+ * is a list of types which contains the type of the symbol
+ * followed by all its direct and indirect base types, sorted by
+ * isLess().
+ */
+ public final Type[] closure() {
+ if (kind == ALIAS) return info().symbol().closure();
+ if (closures == null) computeClosureAt(rawFirstInfoStartPhase());
+ Phase phase = Global.instance.currentPhase;
+ if (closures.limit().precedes(phase)) {
+ while (closures.limit().next != phase) {
+ Phase limit = closures.limit().next;
+ Type[] closure = closures.closure;
+ for (int i = 0; i < closure.length; i++) {
+ Symbol symbol = closure[i].symbol();
+ if (symbol.infoAt(limit) != symbol.infoAt(limit.next)) {
+ computeClosureAt(limit.next);
+ break;
+ }
+ }
+ closures.setLimit(limit);
+ }
+ return closures.closure;
+ } else {
+ ClosureIntervalList closures = this.closures;
+ while (!closures.start.precedes(phase) && closures.prev != null)
+ closures = closures.prev;
+ return closures.closure;
+ }
}
- //todo: needed?
- private Type[] closureAt(int id) {
- Phase savedPhase = Global.instance.currentPhase;
- Global.instance.currentPhase = Global.instance.phases[id];
- Type[] c = closure();
- Global.instance.currentPhase = savedPhase;
- return c;
- }
+ /** Compute closure at start of given phase. */
+ private final void computeClosureAt(Phase phase) {
+ Phase current = Global.instance.currentPhase;
+ Global.instance.currentPhase = phase;
+ // todo: why can't we do: inclClosure(SymSet.EMPTY, this) ?
+ //System.out.println("computing closure of " + this);//DEBUG
+ Type[] parents = type().parents(); // evals info before use of LOCKED
+ assert (flags & LOCKED) == 0 : Debug.show(this) + " -- " + phase;
+ flags |= LOCKED;
+ SymSet closureClassSet = inclClosure(SymSet.EMPTY, parents);
+ flags &= ~LOCKED;
+ Symbol[] closureClasses = new Symbol[closureClassSet.size() + 1];
+ closureClasses[0] = this;
+ closureClassSet.copyToArray(closureClasses, 1);
+ //System.out.println(ArrayApply.toString(closureClasses));//DEBUG
+ closures = new ClosureIntervalList(closures, Symbol.type(closureClasses), phase.prev == null ? phase : phase.prev);
+ //System.out.println("closure(" + this + ") = " + ArrayApply.toString(closures.closure));//DEBUG
- private boolean changes(Type[] closure) {
- for (int i = 0; i < closure.length; i++) {
- Symbol c = closure[i].symbol();
- if (c.infoAt(Global.instance.currentPhase.id - 1) != c.info())
- return true;
- }
- return false;
- }
- private static Type[] BAD_CLOSURE = new Type[0];
- /** Return the type itself followed by all direct and indirect
- * base types of this type, sorted by isLess().
- */
- private void computeClosure() {
- assert closures.closure != BAD_CLOSURE : this;
- closures.closure = BAD_CLOSURE; // to catch cycles.
- // todo: why can't we do: inclClosure(SymSet.EMPTY, this) ?
- //System.out.println("computing closure of " + this);//DEBUG
- SymSet closureClassSet = inclClosure(SymSet.EMPTY, type().parents());
- Symbol[] closureClasses = new Symbol[closureClassSet.size() + 1];
- closureClasses[0] = this;
- closureClassSet.copyToArray(closureClasses, 1);
- //System.out.println(ArrayApply.toString(closureClasses));//DEBUG
- closures.closure = Symbol.type(closureClasses);
- //System.out.println("closure(" + this + ") = " + ArrayApply.toString(closures.closure));//DEBUG
- adjustType(type());
- //System.out.println("closure(" + this + ") = " + ArrayApply.toString(closures.closure));//DEBUG
+ adjustType(type());
+ //System.out.println("closure(" + this + ") = " + ArrayApply.toString(closures.closure));//DEBUG
+ Global.instance.currentPhase = current;
}
//where
+ private static SymSet inclClosure(SymSet set, Type[] tps) {
+ for (int i = 0; i < tps.length; i++) set = inclClosure(set,tps[i]);
+ return set;
+ }
+ private static SymSet inclClosure(SymSet set, Type tp) {
+ tp = tp.unalias();
+ switch (tp) {
+ case CompoundType(Type[] parents, _):
+ return inclClosure(set, parents);
+ default:
+ return inclClosure(set, tp.symbol());
+ }
+ }
+ private static SymSet inclClosure(SymSet set, Symbol sym) {
+ while (sym.kind == ALIAS) sym = sym.info().symbol();
+ return inclClosure(set.incl(sym), sym.type().parents());
+ }
- private SymSet inclClosure(SymSet set, Type[] tps) {
- for (int i = 0; i < tps.length; i++) {
- Type tp = tps[i].unalias();
- switch (tp) {
- case CompoundType(Type[] parents, _):
- set = inclClosure(set, parents);
- break;
- default:
- set = inclClosure(set, tp.symbol());
- }
- }
- return set;
- }
-
- private SymSet inclClosure(SymSet set, Symbol c) {
- Symbol c1 = c;
- while (c1.kind == ALIAS) c1 = c1.info().symbol();
- return inclClosure(set.incl(c1), c1.type().parents());
- }
-
- void adjustType(Type tp) {
+ private void adjustType(Type tp) {
Type tp1 = tp.unalias();
switch (tp) {
case CompoundType(Type[] parents, _):
break;
default:
- int pos = closurePos(tp1.symbol());
- assert pos >= 0 : this + " " + tp1 + " " + tp1.symbol();
+ Symbol sym = tp1.symbol();
+ int pos = closurePos(sym);
+ assert pos >= 0 : this + " " + tp1 + " " + tp1.symbol() + " " + pos;
closures.closure[pos] = tp1;
}
Type[] parents = tp1.parents();
@@ -1429,7 +1445,7 @@ public abstract class TypeSymbol extends Symbol {
public void reset(Type completer) {
super.reset(completer);
- closures = ClosureIntervalList.EMPTY;
+ closures = null;
tycon = null;
template = null;
}
@@ -1805,34 +1821,68 @@ public class CyclicReference extends Type.Error {
}
}
-/** A class for types indexed by phase numbers.
- */
-class TypeIntervalList {
- int limit;
- Type info;
- TypeIntervalList prev;
- TypeIntervalList(TypeIntervalList prev) {
- this.prev = prev;
+/** A base class for values indexed by phases. */
+abstract class IntervalList {
+
+ // Content of start/limit can't be replaced by (start/limit).next
+ // because during initialization (start/limit).next is not yet
+ // known.
+
+ /** Interval starts at start of phase "start.next" (inclusive) */
+ public final Phase start;
+ /** Interval ends at start of phase "limit.next" (inclusive) */
+ private Phase limit;
+
+ public IntervalList(IntervalList prev, Phase start) {
+ this.start = start;
+ this.limit = start;
+ assert start != null && (prev == null || prev.limit.next == start) :
+ Global.instance.currentPhase + " - " + prev + " - " + start;
}
- static TypeIntervalList EMPTY = new TypeIntervalList(null);
- static {
- EMPTY.limit = -1;
+ public Phase limit() {
+ return limit;
}
-}
-/** A class for closures indexed by phase numbers.
- */
-class ClosureIntervalList {
- int limit;
- Type[] closure;
- ClosureIntervalList prev;
- ClosureIntervalList(ClosureIntervalList prev) {
- this.prev = prev;
+ public void setLimit(Phase phase) {
+ assert phase != null && !phase.precedes(start) : start + " - " + phase;
+ limit = phase;
}
- static ClosureIntervalList EMPTY = new ClosureIntervalList(null);
- static {
- EMPTY.limit = -1;
+
+ public String toString() {
+ return "[" + start + "->" + limit + "]";
}
+
}
+/** A class for types indexed by phases. */
+class TypeIntervalList extends IntervalList {
+
+ /** Previous interval */
+ public final TypeIntervalList prev;
+ /** Info valid during this interval */
+ public final Type info;
+
+ public TypeIntervalList(TypeIntervalList prev, Type info, Phase start) {
+ super(prev, start);
+ this.prev = prev;
+ this.info = info;
+ }
+
+}
+
+/** A class for closures indexed by phases. */
+class ClosureIntervalList extends IntervalList {
+
+ /** Previous interval */
+ public final ClosureIntervalList prev;
+ /** Closure valid during this interval */
+ public final Type[] closure;
+
+ public ClosureIntervalList(ClosureIntervalList prev, Type[] closure, Phase start){
+ super(prev, start);
+ this.prev = prev;
+ this.closure = closure;
+ }
+
+}
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index 6e14e6ff66..5640938030 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -397,7 +397,7 @@ public class LambdaLift extends OwnerTransformer
Tree rhs1 = transform(rhs, sym);
if ((sym.flags & CAPTURED) != 0) {
assert sym.isLocal();
- Type boxedType = sym.typeAt(descr.nextPhase);
+ Type boxedType = sym.nextType();
Type unboxedType = boxedType.typeArgs()[0];
tpe1 = gen.mkType(tpe.pos, boxedType);
rhs1 = gen.New(
@@ -445,7 +445,7 @@ public class LambdaLift extends OwnerTransformer
sym = descr.proxy(sym, currentOwner);
}
Tree tree1 = copy.Ident(tree, sym).setType(
- sym.typeAt(descr.nextPhase));
+ sym.nextType());
if (name != sym.name) ((Ident)tree1).name = sym.name;
if ((sym.flags & CAPTURED) != 0) return gen.Select(tree1, Names.elem);
else return tree1;
@@ -482,7 +482,7 @@ public class LambdaLift extends OwnerTransformer
}
Symbol[] newtparams(Symbol owner) {
- Symbol[] tparams = owner.typeAt(descr.nextPhase).typeParams();
+ Symbol[] tparams = owner.nextType().typeParams();
int nfree = get(free.ftvs, owner).size();
assert nfree == tparams.length - owner.type().typeParams().length
: owner + " " + nfree + " " + tparams.length + " " + owner.type().firstParams().length;
@@ -492,7 +492,7 @@ public class LambdaLift extends OwnerTransformer
}
Symbol[] newparams(Symbol owner) {
- Symbol[] params = owner.typeAt(descr.nextPhase).firstParams();
+ Symbol[] params = owner.nextType().firstParams();
int nfree = get(free.fvs, owner).size();
assert nfree == params.length - owner.type().firstParams().length;
Symbol[] newparams = new Symbol[nfree];
@@ -537,10 +537,10 @@ public class LambdaLift extends OwnerTransformer
sym.updateInfo(
addParams(
addTypeParams(
- sym.infoAt(descr.nextPhase), oldtparams, newtparams),
+ sym.nextInfo(), oldtparams, newtparams),
newparams));
if (global.debug)
- global.log(sym + " has now type " + sym.typeAt(descr.nextPhase));
+ global.log(sym + " has now type " + sym.nextType());
}
} else if (sym.kind == CLASS) {
Symbol constr = sym.primaryConstructor();
@@ -641,7 +641,7 @@ public class LambdaLift extends OwnerTransformer
for (int i = 0; i < fparams.length; i++) {
Symbol farg = descr.proxy(fparams[i], currentOwner);
args1[args.length + i] =
- gen.Ident(pos, farg).setType(farg.typeAt(descr.nextPhase));
+ gen.Ident(pos, farg).setType(farg.nextType());
}
return args1;
} else {
diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java
index e2181c5ccf..c4834e79cb 100644
--- a/sources/scalac/transformer/LambdaLiftPhase.java
+++ b/sources/scalac/transformer/LambdaLiftPhase.java
@@ -17,12 +17,9 @@ import java.util.ArrayList;
public class LambdaLiftPhase extends Phase implements Kinds, Modifiers {
- final int nextPhase;
-
/** Initializes this instance. */
public LambdaLiftPhase(Global global, PhaseDescriptor descriptor) {
super(global, descriptor);
- this.nextPhase = id + 1;
}
/** Applies this phase to the given compilation units. */
@@ -82,7 +79,7 @@ public class LambdaLiftPhase extends Phase implements Kinds, Modifiers {
switch (pre) {
case ThisType(_):
if (sym.kind == CLASS &&
- sym.primaryConstructor().isUpdated(nextPhase)) {
+ sym.primaryConstructor().isUpdatedAt(LambdaLiftPhase.this)) {
Symbol[] tparams = sym.primaryConstructor().nextInfo().typeParams();
int i = tparams.length;
while (i > 0 && (tparams[i-1].flags & SYNTHETIC) != 0)
@@ -138,7 +135,7 @@ public class LambdaLiftPhase extends Phase implements Kinds, Modifiers {
Symbol fowner = LambdaLift.asFunction(o);
if (fowner.isMethod()) {
if (fv.owner() == fowner) return fv;
- Type ft = (fowner.isUpdated(nextPhase)) ? fowner.typeAt(nextPhase)
+ Type ft = (fowner.isUpdatedAt(this)) ? fowner.nextType()
: fowner.type();
Symbol[] ownerparams = fv.isType() ? ft.typeParams()
: ft.firstParams();