summaryrefslogtreecommitdiff
path: root/sources/scalac/symtab/Symbol.java
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/symtab/Symbol.java')
-rw-r--r--sources/scalac/symtab/Symbol.java222
1 files changed, 144 insertions, 78 deletions
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 0044beeb2c..585bc5de95 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -119,7 +119,10 @@ public abstract class Symbol implements Modifiers, Kinds {
assert symbol != Symbol.NONE;
assert symbol != Symbol.ERROR;
if (symbol.isModule()) setOwner(symbol.moduleClass(), owner);
- if (symbol.isClass()) setOwner(symbol.constructor(), owner);
+ if (symbol.isClass()) {
+ Symbol[] alts = symbol.allConstructors().alternativeSymbols();
+ for (int i = 0; i < alts.length; i++) setOwner(alts[i], owner);
+ }
symbol.owner = owner;
}
@@ -132,19 +135,22 @@ public abstract class Symbol implements Modifiers, Kinds {
public Symbol setInfo(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 &&
((Type.PolyType)info).result instanceof Type.MethodType
: "illegal type for " + this + ": " + info;
- if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) {
+ //if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) {
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;
}
@@ -173,12 +179,14 @@ public abstract class Symbol implements Modifiers, Kinds {
throw new ApplicationError("setLoBound inapplicable for " + this);
}
-// Symbol classification ----------------------------------------------------
-
- public final boolean isDefined() {
- return !(rawInfoAt(FIRST_ID) instanceof Type.LazyType);
+ /** Add an auxiliary constructor to class; return created symbol.
+ */
+ public Symbol addConstructor() {
+ throw new ApplicationError("addConstructor inapplicable for " + this);
}
+// Symbol classification ----------------------------------------------------
+
/** Does this symbol denote a type? */
public final boolean isType() {
return kind == TYPE || kind == CLASS || kind == ALIAS;
@@ -377,13 +385,13 @@ public abstract class Symbol implements Modifiers, Kinds {
}
/** Is this symbol a constructor? */
- public final boolean isConstructor() {
- return name.isConstrName();
+ public boolean isConstructor() {
+ return false;
}
/** Is this symbol the primary constructor of a type? */
public final boolean isPrimaryConstructor() {
- return isConstructor() && this == primaryConstructorClass().constructor();
+ return isConstructor() && this == primaryConstructorClass().primaryConstructor();
}
public boolean isGenerated() {
@@ -451,8 +459,13 @@ public abstract class Symbol implements Modifiers, Kinds {
return EMPTY_ARRAY;
}
+ /** Get all constructors of class */
+ public Symbol allConstructors() {
+ return NONE;
+ }
+
/** Get primary constructor of class */
- public Symbol constructor() {
+ public Symbol primaryConstructor() {
return NONE;
}
@@ -474,7 +487,7 @@ public abstract class Symbol implements Modifiers, Kinds {
public Symbol classOwner() {
Symbol owner = owner();
Symbol clazz = owner.primaryConstructorClass();
- if (clazz.constructor() == owner) return clazz;
+ if (clazz.primaryConstructor() == owner) return clazz;
else return owner;
}
@@ -501,6 +514,19 @@ public abstract class Symbol implements Modifiers, Kinds {
return this;
}
+ /** Return first alternative if this has a (possibly lazy)
+ * overloaded type, otherwise symbol itself.
+ * Needed only in ClassSymbol.primaryConstructor()
+ */
+ Symbol firstAlternative() {
+ if (infos.info instanceof Type.OverloadedType)
+ return infos.info.alternativeSymbols()[0];
+ else if (infos.info instanceof LazyOverloadedType)
+ return ((LazyOverloadedType) infos.info).sym1.firstAlternative();
+ else
+ return this;
+ }
+
/* If this is a module, return its class.
* Otherwise return the symbol itself.
*/
@@ -508,6 +534,22 @@ public abstract class Symbol implements Modifiers, Kinds {
return this;
}
+ /** if type is a (possibly lazy) overloaded type, return its alternatves
+ * else return array consisting of symbol itself
+ */
+ public Symbol[] alternativeSymbols() {
+ Symbol[] alts = type().alternativeSymbols();
+ if (alts.length == 0) return new Symbol[]{this};
+ else return alts;
+ }
+
+ /** if type is a (possibly lazy) overloaded type, return its alternatves
+ * else return array consisting of type itself
+ */
+ public Type[] alternativeTypes() {
+ return type().alternativeTypes();
+ }
+
/** The symbol accessed by this accessor function.
*/
public Symbol accessed() {
@@ -598,7 +640,7 @@ public abstract class Symbol implements Modifiers, Kinds {
flags &= ~SNDTIME;
} else {
assert !(rawInfoAt(id) instanceof Type.LazyType) : this;
- flags |= INITIALIZED;
+ //flags |= INITIALIZED;
}
//System.out.println("done: " + this.name);//DEBUG
}
@@ -624,8 +666,8 @@ public abstract class Symbol implements Modifiers, Kinds {
/** get info at phase #id, without forcing lazy types.
*/
public Type rawInfoAt(int id) {
- int nextid = infos.limit;
assert infos != TypeIntervalList.EMPTY : this;
+ int nextid = infos.limit;
if (nextid < id) {
PhaseDescriptor curphase = Global.instance.currentPhase;
do {
@@ -868,59 +910,43 @@ public abstract class Symbol implements Modifiers, Kinds {
/** A lazy type which, when forced computed the overloaded type
* of symbols `sym1' and `sym2'. It also checks that this type is well-formed.
*/
- private static class LazyOverloadedType extends Type.LazyType {
+ public static class LazyOverloadedType extends Type.LazyType {
Symbol sym1;
Symbol sym2;
LazyOverloadedType(Symbol sym1, Symbol sym2) {
this.sym1 = sym1;
this.sym2 = sym2;
}
- private Symbol[] alts(Symbol sym) {
- if (sym == null) return Symbol.EMPTY_ARRAY;
- switch (sym.type()) {
- case OverloadedType(Symbol[] alts, _): return alts;
- default: return new Symbol[]{sym};
- }
- }
- private Type[] alttypes(Symbol sym) {
- if (sym == null) return Type.EMPTY_ARRAY;
- switch (sym.type()) {
- case OverloadedType(_, Type[] alttypes): return alttypes;
- default: return new Type[]{sym.type()};
- }
- }
- public void complete(Symbol overloaded) {
- if (sym1 != null) sym1.initialize();
- if (sym2 != null) sym2.initialize();
- Symbol[] alts1 = alts(sym1);
- Symbol[] alts2 = alts(sym2);
+ public Symbol[] alternativeSymbols() {
+ Symbol[] alts1 = sym1.alternativeSymbols();
+ Symbol[] alts2 = sym2.alternativeSymbols();
Symbol[] alts3 = new Symbol[alts1.length + alts2.length];
System.arraycopy(alts1, 0, alts3, 0, alts1.length);
System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length);
+ return alts3;
+ }
+
+ public Type[] alternativeTypes() {
+ Type[] alts1 = sym1.alternativeTypes();
+ Type[] alts2 = sym2.alternativeTypes();
+ Type[] alts3 = new Type[alts1.length + alts2.length];
+ System.arraycopy(alts1, 0, alts3, 0, alts1.length);
+ System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length);
+ return alts3;
+ }
- Type[] alttypes1 = alttypes(sym1);
- Type[] alttypes2 = alttypes(sym2);
- Type[] alttypes3 = new Type[alttypes1.length + alttypes2.length];
- System.arraycopy(alttypes1, 0, alttypes3, 0, alttypes1.length);
- System.arraycopy(alttypes2, 0, alttypes3, alttypes1.length, alttypes2.length);
- overloaded.setInfo(Type.OverloadedType(alts3, alttypes3));
+ public void complete(Symbol overloaded) {
+ overloaded.setInfo(
+ Type.OverloadedType(
+ alternativeSymbols(), alternativeTypes()));
}
+
public String toString() {
return "LazyOverloadedType(" + sym1 + "," + sym2 + ")";
}
}
- /** All the alternatives of this symbol if it's overloaded, the
- * symbol alone otherwise.
- */
- public Symbol[] alternatives() {
- switch (type()) {
- case OverloadedType(Symbol[] alts, _): return alts;
- default: return new Symbol[]{this};
- }
- }
-
/** The symbol which is overridden by this symbol in base class `base'
* `base' must be a superclass of this.owner().
*/
@@ -985,8 +1011,7 @@ public class TermSymbol extends Symbol {
public static TermSymbol newConstructor(Symbol clazz, int flags) {
TermSymbol sym = new TermSymbol(
- clazz.pos, clazz.name.toConstrName(), clazz.owner(),
- flags | FINAL);
+ clazz.pos, clazz.name, clazz.owner(), flags | FINAL);
sym.clazz = clazz;
return sym;
}
@@ -1008,7 +1033,7 @@ public class TermSymbol extends Symbol {
int flags) {
ClassSymbol clazz = new ClassSymbol(
pos, name.toTypeName(), owner, flags | MODUL | FINAL);
- clazz.constructor().setInfo(
+ clazz.primaryConstructor().setInfo(
Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor()));
return newModule(pos, name, owner, flags, clazz);
@@ -1044,6 +1069,11 @@ public class TermSymbol extends Symbol {
else return super.fullName();
}
+ /** Is this symbol a constructor? */
+ public boolean isConstructor() {
+ return name.isTypeName();
+ }
+
/** Return a fresh symbol with the same fields as this one.
*/
public Symbol cloneSymbol(Symbol owner) {
@@ -1129,6 +1159,16 @@ public class TypeSymbol extends Symbol {
return type().unalias().typeParams();
}
+ /** Get all constructors of class */
+ public Symbol allConstructors() {
+ return type().unalias().symbol().allConstructors();
+ }
+
+ /** Get primary constructor of class */
+ public Symbol primaryConstructor() {
+ return type().unalias().symbol().primaryConstructor();
+ }
+
public Type[] closure() {
if (kind == ALIAS) return info().symbol().closure();
int id = currentPhaseId();
@@ -1257,6 +1297,16 @@ public class AbsTypeSymbol extends TypeSymbol {
return Symbol.EMPTY_ARRAY;
}
+ /** Get all constructors of class */
+ public Symbol allConstructors() {
+ return Symbol.NONE;
+ }
+
+ /** Get primary constructor of class */
+ public Symbol primaryConstructor() {
+ return Symbol.NONE;
+ }
+
public Type loBound() {
initialize();
return lobound == null ? Global.instance.definitions.ALL_TYPE : lobound;
@@ -1279,7 +1329,7 @@ public class ClassSymbol extends TypeSymbol {
private Type template;
/** The primary constructor of this type */
- public final Symbol constructor;
+ private Symbol constructor;
/** The module belonging to the class. This means:
* For Java classes, its statics parts.
@@ -1328,27 +1378,38 @@ public class ClassSymbol extends TypeSymbol {
ClassSymbol other = new ClassSymbol(pos, name, owner, flags);
other.module = module;
other.setInfo(info());
- other.constructor.setInfo(
- fixClonedConstrType(
- constructor.info().cloneType(constructor, other.constructor),
- other));
+ other.primaryConstructor().setInfo(
+ fixConstrType(
+ primaryConstructor().info().cloneType(
+ primaryConstructor(), other.primaryConstructor()),
+ other));
+ Symbol[] alts = allConstructors().alternativeSymbols();
+ for (int i = 1; i < alts.length; i++) {
+ Symbol constr = other.addConstructor();
+ constr.setInfo(
+ fixConstrType(
+ alts[i].info().cloneType(alts[i], constr),
+ other));
+ }
other.mangled = mangled;
if (thisSym != this) other.setTypeOfThis(typeOfThis());
return other;
}
- private Type fixClonedConstrType(Type type, Symbol clone) {
+ private Type fixConstrType(Type type, Symbol clone) {
switch (type) {
case MethodType(Symbol[] vparams, Type result):
- result = fixClonedConstrType(result, clone);
+ result = fixConstrType(result, clone);
return new Type.MethodType(vparams, result);
case PolyType(Symbol[] tparams, Type result):
- result = fixClonedConstrType(result, clone);
+ result = fixConstrType(result, clone);
return new Type.PolyType(tparams, result);
case TypeRef(Type pre, Symbol sym, Type[] args):
assert sym == this : Debug.show(sym) + " != " + Debug.show(this);
return new Type.TypeRef(pre, clone, args);
+ case LazyType():
+ return type;
default:
- throw Debug.abort("unexpected constructor type");
+ throw Debug.abort("unexpected constructor type:" + clone + ":" + type);
}
}
@@ -1356,6 +1417,9 @@ public class ClassSymbol extends TypeSymbol {
*/
public void copyTo(Symbol sym) {
super.copyTo(sym);
+ Symbol symconstr = ((ClassSymbol) sym).constructor;
+ constructor.copyTo(symconstr);
+ symconstr.setInfo(fixConstrType(symconstr.rawInfo(), sym));
if (thisSym != this) sym.setTypeOfThis(typeOfThis());
}
@@ -1404,21 +1468,11 @@ public class ClassSymbol extends TypeSymbol {
/** Get type parameters */
public Symbol[] typeParams() {
- // !!! For some Java classes, constructor() returns an
- // Overloaded symbol. This is wrong as constructor() should
- // return the primary constructor. Once this problem is
- // solved, the following switch can be removed.
- Type constrtype = constructor.info();
- switch (constrtype) {
- case OverloadedType(_, _):
- return Symbol.EMPTY_ARRAY;
- default:
- return constrtype.typeParams();
- }
+ return primaryConstructor().info().typeParams();
}
public Symbol[] valueParams() {
- return constructor.info().valueParams();
+ return primaryConstructor().info().valueParams();
}
/** Get type */
@@ -1453,9 +1507,22 @@ public class ClassSymbol extends TypeSymbol {
return this;
}
+ /** add a constructor
+ */
+ public Symbol addConstructor() {
+ Symbol constr = TermSymbol.newConstructor(this, flags & ~MODUL);
+ constructor = constructor.overloadWith(constr);
+ return constr;
+ }
+
/** Get primary constructor */
- public Symbol constructor() {
- return constructor;
+ public Symbol primaryConstructor() {
+ return constructor.firstAlternative();
+ }
+
+ /** Get all constructors */
+ public Symbol allConstructors() {
+ return constructor;
}
/** Return the next enclosing class */
@@ -1479,7 +1546,6 @@ public class ClassSymbol extends TypeSymbol {
public void reset(Type completer) {
super.reset(completer);
- constructor().reset(completer);
module().reset(completer);
template = null;
thisSym = this;
@@ -1520,7 +1586,7 @@ public final class ErrorSymbol extends Symbol {
}
/** Get primary constructor */
- public Symbol constructor() {
+ public Symbol primaryConstructor() {
return TermSymbol.newConstructor(this, 0).setInfo(Type.ErrorType);
}