summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Zenger <mzenger@gmail.com>2003-11-11 13:21:09 +0000
committerMatthias Zenger <mzenger@gmail.com>2003-11-11 13:21:09 +0000
commit2521f5270d8599a6407588cd3ab92143c77bc827 (patch)
tree1c84600ef4c627d56c24f090c6ab3fba3a8f4c76
parent6a5131fc32787d2d4865918a4fb1e480bfc14f8f (diff)
downloadscala-2521f5270d8599a6407588cd3ab92143c77bc827.tar.gz
scala-2521f5270d8599a6407588cd3ab92143c77bc827.tar.bz2
scala-2521f5270d8599a6407588cd3ab92143c77bc827.zip
Added support for | in algebraic patterns;
Added support for reading ConstantValue attributes;
-rw-r--r--sources/scalac/symtab/Type.java4332
-rw-r--r--sources/scalac/symtab/classfile/AttributeParser.java56
-rw-r--r--sources/scalac/symtab/classfile/ConstantPool.java18
-rw-r--r--sources/scalac/transformer/TransMatch.java37
-rw-r--r--sources/scalac/transformer/matching/AlgebraicMatcher.java4
-rw-r--r--sources/scalac/transformer/matching/PatternMatcher.java195
-rw-r--r--sources/scalac/transformer/matching/PatternNode.java13
-rw-r--r--sources/scalac/transformer/matching/PatternNodeCreator.java71
-rw-r--r--sources/scalac/util/AbstractFileReader.java26
9 files changed, 2425 insertions, 2327 deletions
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 2bde3ac1d6..b419a83e7c 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -32,18 +32,18 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* sym represents a valueS
*/
public case SingleType(Type pre, Symbol sym) {
- assert this instanceof ExtSingleType;
+ assert this instanceof ExtSingleType;
}
/** Type for a numeric or string constant.
*/
public case ConstantType(Type base, Object value) {
- if (base.symbol() == Global.instance.definitions.BYTE_CLASS)
- assert value instanceof Byte;
- if (base.symbol() == Global.instance.definitions.CHAR_CLASS)
- assert value instanceof Character;
- if (base.symbol() == Global.instance.definitions.SHORT_CLASS)
- assert value instanceof Short;
+ if (base.symbol() == Global.instance.definitions.BYTE_CLASS)
+ assert value instanceof Byte;
+ if (base.symbol() == Global.instance.definitions.CHAR_CLASS)
+ assert value instanceof Character;
+ if (base.symbol() == Global.instance.definitions.SHORT_CLASS)
+ assert value instanceof Short;
}
/** pre.sym[args]
@@ -51,26 +51,26 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* for example: scala.List[java.lang.String] is coded as
*
* TypeRef(
- * SingleType(ThisType(definitions.ROOT_CLASS), definitions.SCALA),
- * <List>,
- * new Type[]{
- * TypeRef(
- * SingleType(
- * SingleType(ThisType(definitions.ROOT_CLASS), definitions.JAVA),
- * definitions.LANG),
- * definitions.STRING,
- * new Type[]{})}).
+ * SingleType(ThisType(definitions.ROOT_CLASS), definitions.SCALA),
+ * <List>,
+ * new Type[]{
+ * TypeRef(
+ * SingleType(
+ * SingleType(ThisType(definitions.ROOT_CLASS), definitions.JAVA),
+ * definitions.LANG),
+ * definitions.STRING,
+ * new Type[]{})}).
*
*/
public case TypeRef(Type pre, Symbol sym, Type[] args) {
- assert pre.isLegalPrefix() || pre == ErrorType : pre + "#" + sym;
- assert sym.kind == ERROR || sym.isType() : pre + " # " + sym;
+ assert pre.isLegalPrefix() || pre == ErrorType : pre + "#" + sym;
+ assert sym.kind == ERROR || sym.isType() : pre + " # " + sym;
}
/** parts_1 with ... with parts_n { members }
*/
public case CompoundType(Type[] parts, Scope members) {
- assert this instanceof ExtCompoundType;
+ assert this instanceof ExtCompoundType;
}
/** synthetic type of a method def ...(vparams): result = ...
@@ -140,39 +140,39 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
public static final Type[] EMPTY_ARRAY = new Type[0];
public static SingleType singleType(Type pre, Symbol sym) {
- if (pre.isStable() || pre == ErrorType) {
- return new ExtSingleType(pre, sym);
- } else {
- throw new Type.Malformed(pre, sym.nameString() + ".type");
- }
+ if (pre.isStable() || pre == ErrorType) {
+ return new ExtSingleType(pre, sym);
+ } else {
+ throw new Type.Malformed(pre, sym.nameString() + ".type");
+ }
}
public static ConstantType constantType(Object value) {
- return new ConstantType(value2type(value), value);
+ return new ConstantType(value2type(value), value);
}
private static Type value2type(Object value) {
- if (value instanceof Character)
- return Global.instance.definitions.CHAR_TYPE();
- else if (value instanceof Integer)
- return Global.instance.definitions.INT_TYPE();
- else if (value instanceof Long)
- return Global.instance.definitions.LONG_TYPE();
- else if (value instanceof Float)
- return Global.instance.definitions.FLOAT_TYPE();
- else if (value instanceof Double)
- return Global.instance.definitions.DOUBLE_TYPE();
- else if (value instanceof String)
- return Global.instance.definitions.JAVA_STRING_TYPE();
- else if (value instanceof Boolean)
- return Global.instance.definitions.BOOLEAN_TYPE();
- else throw new ApplicationError();
+ if (value instanceof Character)
+ return Global.instance.definitions.CHAR_TYPE();
+ else if (value instanceof Integer)
+ return Global.instance.definitions.INT_TYPE();
+ else if (value instanceof Long)
+ return Global.instance.definitions.LONG_TYPE();
+ else if (value instanceof Float)
+ return Global.instance.definitions.FLOAT_TYPE();
+ else if (value instanceof Double)
+ return Global.instance.definitions.DOUBLE_TYPE();
+ else if (value instanceof String)
+ return Global.instance.definitions.JAVA_STRING_TYPE();
+ else if (value instanceof Boolean)
+ return Global.instance.definitions.BOOLEAN_TYPE();
+ else throw new ApplicationError();
}
public static Type singleTypeMethod(Type pre, Symbol sym) {
Global global = Global.instance;
if (global.currentPhase.id <= global.PHASE.UNCURRY.id())
- return singleType(pre, sym);
+ return singleType(pre, sym);
else if (global.currentPhase.id <= global.PHASE.ERASURE.id())
return sym.type().singleTypeMethod0(pre, sym);
else
@@ -186,75 +186,75 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
case MethodType(Symbol[] args, Type result):
return MethodType(args, result.singleTypeMethod0(pre, sym));
default:
- return singleType(pre, sym);
+ return singleType(pre, sym);
}
}
public static TypeRef appliedType(Type tycon, Type[] args) {
- switch (tycon) {
- case TypeRef(Type pre, Symbol sym, Type[] args1):
- if (args == args1) return (TypeRef)tycon;
- else return TypeRef(pre, sym, args);
- default:
- throw new ApplicationError();
- }
+ switch (tycon) {
+ case TypeRef(Type pre, Symbol sym, Type[] args1):
+ if (args == args1) return (TypeRef)tycon;
+ else return TypeRef(pre, sym, args);
+ default:
+ throw new ApplicationError();
+ }
}
public static CompoundType compoundType(Type[] parts, Scope members,
- Symbol clazz) {
- ExtCompoundType res = new ExtCompoundType(parts, members);
- res.tsym = clazz;
- return res;
+ Symbol clazz) {
+ ExtCompoundType res = new ExtCompoundType(parts, members);
+ res.tsym = clazz;
+ return res;
}
public static CompoundType compoundType(Type[] parts, Scope members) {
- ExtCompoundType res = new ExtCompoundType(parts, members);
- res.tsym = new ClassSymbol(
- Position.FIRSTPOS, Names.COMPOUND_NAME.toTypeName(), Symbol.NONE,
- SYNTHETIC | ABSTRACT);
- res.tsym.setInfo(res);
- res.tsym.primaryConstructor().setInfo(
- Type.MethodType(Symbol.EMPTY_ARRAY, Type.TypeRef(res.tsym.owner().thisType(), res.tsym, Type.EMPTY_ARRAY)));
- return res;
+ ExtCompoundType res = new ExtCompoundType(parts, members);
+ res.tsym = new ClassSymbol(
+ Position.FIRSTPOS, Names.COMPOUND_NAME.toTypeName(), Symbol.NONE,
+ SYNTHETIC | ABSTRACT);
+ res.tsym.setInfo(res);
+ res.tsym.primaryConstructor().setInfo(
+ Type.MethodType(Symbol.EMPTY_ARRAY, Type.TypeRef(res.tsym.owner().thisType(), res.tsym, Type.EMPTY_ARRAY)));
+ return res;
}
public static Type typeRef(Type pre, Symbol sym, Type[] args) {
- if (pre.isLegalPrefix() || pre == ErrorType)
- return TypeRef(pre, sym, args);
- else if (sym.kind == ALIAS && sym.typeParams().length == args.length)
- return sym.info().subst(sym.typeParams(), args)
- .asSeenFrom(pre, sym.owner());
- else
- throw new Type.Malformed(pre, sym.nameString());
+ if (pre.isLegalPrefix() || pre == ErrorType)
+ return TypeRef(pre, sym, args);
+ else if (sym.kind == ALIAS && sym.typeParams().length == args.length)
+ return sym.info().subst(sym.typeParams(), args)
+ .asSeenFrom(pre, sym.owner());
+ else
+ throw new Type.Malformed(pre, sym.nameString());
}
static class ExtSingleType extends SingleType {
- Type tp = null;
- int definedId = -1;
- ExtSingleType(Type pre, Symbol sym) {
- super(pre, sym);
- }
- public Type singleDeref() {
- if (definedId != Global.instance.currentPhase.id) {
- definedId = Global.instance.currentPhase.id;
- tp = pre.memberType(sym).resultType();
- }
- return tp;
- }
+ Type tp = null;
+ int definedId = -1;
+ ExtSingleType(Type pre, Symbol sym) {
+ super(pre, sym);
+ }
+ public Type singleDeref() {
+ if (definedId != Global.instance.currentPhase.id) {
+ definedId = Global.instance.currentPhase.id;
+ tp = pre.memberType(sym).resultType();
+ }
+ return tp;
+ }
}
static class ExtCompoundType extends CompoundType {
- Symbol tsym;
- ExtCompoundType(Type[] parts, Scope members) {
- super(parts, members);
- }
- public Symbol symbol() {
- return tsym;
- }
- void validate() {//debug
- for (Scope.SymbolIterator it = members.iterator(true); it.hasNext(); )
- assert it.next().owner() == tsym;
- }
+ Symbol tsym;
+ ExtCompoundType(Type[] parts, Scope members) {
+ super(parts, members);
+ }
+ public Symbol symbol() {
+ return tsym;
+ }
+ void validate() {//debug
+ for (Scope.SymbolIterator it = members.iterator(true); it.hasNext(); )
+ assert it.next().owner() == tsym;
+ }
}
void validate() {//debug
@@ -268,60 +268,60 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
public Symbol symbol() {
switch (this) {
case ErrorType:
- return Symbol.ERROR;
- case ThisType(Symbol sym):
- return sym;
+ return Symbol.ERROR;
+ case ThisType(Symbol sym):
+ return sym;
case TypeRef(_, Symbol sym, _):
- return sym;
- case SingleType(_, Symbol sym):
- return sym;
- case ConstantType(Type base, _):
- return base.symbol();
- case TypeVar(Type origin, _):
- return origin.symbol();
- case CompoundType(_, _):
- // overridden in ExtCompoundType
- throw new ApplicationError();
+ return sym;
+ case SingleType(_, Symbol sym):
+ return sym;
+ case ConstantType(Type base, _):
+ return base.symbol();
+ case TypeVar(Type origin, _):
+ return origin.symbol();
+ case CompoundType(_, _):
+ // overridden in ExtCompoundType
+ throw new ApplicationError();
default:
- return Symbol.NONE;
- }
+ return Symbol.NONE;
+ }
}
public static Symbol[] symbol(Type[] tps) {
- Symbol[] syms = new Symbol[tps.length];
- for (int i = 0; i < syms.length; i++)
- syms[i] = tps[i].symbol();
- return syms;
+ Symbol[] syms = new Symbol[tps.length];
+ for (int i = 0; i < syms.length; i++)
+ syms[i] = tps[i].symbol();
+ return syms;
}
/** If this is a reference to a type constructor, add its
* type parameters as arguments
*/
public Type withDefaultArgs() {
- switch (this) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if (args.length == 0 && sym.typeParams().length != 0)
- return TypeRef(pre, sym, Symbol.type(sym.typeParams()));
- }
- return this;
+ switch (this) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (args.length == 0 && sym.typeParams().length != 0)
+ return TypeRef(pre, sym, Symbol.type(sym.typeParams()));
+ }
+ return this;
}
/** The upper bound of this type. Returns always a TypeRef whose
* symbol is a class.
*/
public Type bound() {
- switch (unalias()) {
+ switch (unalias()) {
case TypeRef(Type pre, Symbol sym, _):
if (sym.kind == TYPE) return pre.memberInfo(sym).bound();
assert sym.isClass() : Debug.show(sym) + " -- " + this;
return this;
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
return singleDeref().bound();
- case TypeVar(Type origin, Constraint constr):
- if (constr.inst != NoType) return constr.inst.bound();
- else return this;
+ case TypeVar(Type origin, Constraint constr):
+ if (constr.inst != NoType) return constr.inst.bound();
+ else return this;
default:
throw Debug.abort("illegal case", this);
}
@@ -331,197 +331,197 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* otherwise the type itself.
*/
public Type singleDeref() {
- switch (this) {
- case ThisType(Symbol sym):
- return sym.typeOfThis();
- case SingleType(Type pre, Symbol sym):
- // overridden in ExtSingleType
- throw new ApplicationError();
- case ConstantType(Type base, _):
- return base;
- case TypeVar(Type origin, Constraint constr):
- if (constr.inst != NoType) return constr.inst.singleDeref();
- else return this;
- default:
- return this;
- }
+ switch (this) {
+ case ThisType(Symbol sym):
+ return sym.typeOfThis();
+ case SingleType(Type pre, Symbol sym):
+ // overridden in ExtSingleType
+ throw new ApplicationError();
+ case ConstantType(Type base, _):
+ return base;
+ case TypeVar(Type origin, Constraint constr):
+ if (constr.inst != NoType) return constr.inst.singleDeref();
+ else return this;
+ default:
+ return this;
+ }
}
/** If this type is a thistype or singleton type, its underlying object type,
* otherwise the type itself.
*/
public Type widen() {
- Type tp = singleDeref();
- switch (tp) {
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return tp.widen();
- default:
- return tp;
- }
+ Type tp = singleDeref();
+ switch (tp) {
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return tp.widen();
+ default:
+ return tp;
+ }
}
private static Map widenMap = new Map() {
- public Type apply(Type t) {
- return t.widen();
- }
- };
+ public Type apply(Type t) {
+ return t.widen();
+ }
+ };
public static Type[] widen(Type[] tps) {
- return widenMap.map(tps);
+ return widenMap.map(tps);
}
/** The thistype or singleton type corresponding to values of this type.
*/
public Type narrow() {
- switch (unalias()) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym.kind == CLASS) return sym.thisType();
- else return ThisType(sym);
- case CompoundType(_, _):
- return symbol().thisType();
- default:
- return this;
- }
+ switch (unalias()) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (sym.kind == CLASS) return sym.thisType();
+ else return ThisType(sym);
+ case CompoundType(_, _):
+ return symbol().thisType();
+ default:
+ return this;
+ }
}
/** If this type is a constant type, its underlying basetype;
* otherwise the type itself
*/
public Type deconst() {
- switch (this) {
- case ConstantType(Type base, _):
- return base;
- default:
- return this;
- }
+ switch (this) {
+ case ConstantType(Type base, _):
+ return base;
+ default:
+ return this;
+ }
}
/** If this type is a parameterless method, its underlying resulttype;
* otherwise the type itself
*/
public Type derefDef() {
- switch (this) {
- case PolyType(Symbol[] tparams, Type restp):
- if (tparams.length == 0) return restp;
- }
- return this;
+ switch (this) {
+ case PolyType(Symbol[] tparams, Type restp):
+ if (tparams.length == 0) return restp;
+ }
+ return this;
}
/** The lower approximation of this type (which must be a typeref)
*/
public Type loBound() {
- switch (unalias()) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- Type lb = Global.instance.definitions.ALL_TYPE();
- if (sym.kind == TYPE) {
- lb = pre.memberLoBound(sym);
- }
- if (lb.symbol() == Global.instance.definitions.ALL_CLASS &&
- this.symbol() != Global.instance.definitions.ALL_CLASS &&
- this.isSubType(Global.instance.definitions.ANYREF_TYPE())) {
- lb = Global.instance.definitions.ALLREF_TYPE();
- }
- return lb;
- default:
- throw new ApplicationError();
- }
+ switch (unalias()) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ Type lb = Global.instance.definitions.ALL_TYPE();
+ if (sym.kind == TYPE) {
+ lb = pre.memberLoBound(sym);
+ }
+ if (lb.symbol() == Global.instance.definitions.ALL_CLASS &&
+ this.symbol() != Global.instance.definitions.ALL_CLASS &&
+ this.isSubType(Global.instance.definitions.ANYREF_TYPE())) {
+ lb = Global.instance.definitions.ALLREF_TYPE();
+ }
+ return lb;
+ default:
+ throw new ApplicationError();
+ }
}
/** If this is a this-type, named-type, applied type or single-type, its prefix,
* otherwise NoType.
*/
public Type prefix() {
- switch (this) {
- case ThisType(Symbol sym): return sym.owner().thisType();
+ switch (this) {
+ case ThisType(Symbol sym): return sym.owner().thisType();
case TypeRef(Type pre, _, _): return pre;
case SingleType(Type pre, _): return pre;
- case TypeVar(Type origin, Constraint constr):
- if (constr.inst != NoType) return constr.inst.prefix();
- else return NoType;
- default: return NoType;
- }
+ case TypeVar(Type origin, Constraint constr):
+ if (constr.inst != NoType) return constr.inst.prefix();
+ else return NoType;
+ default: return NoType;
+ }
}
/** Get all type arguments of this type.
*/
public Type[] typeArgs() {
- switch (unalias()) {
- case TypeRef(_, _, Type[] args):
- return args;
- default:
- return Type.EMPTY_ARRAY;
- }
+ switch (unalias()) {
+ case TypeRef(_, _, Type[] args):
+ return args;
+ default:
+ return Type.EMPTY_ARRAY;
+ }
}
/** Get type of `this' symbol corresponding to this type, extend
* homomorphically to function types and poly types.
*/
public Type instanceType() {
- switch (unalias()) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym != sym.thisSym())
- return sym.typeOfThis()
- .asSeenFrom(pre, sym.owner())
- .subst(sym.typeParams(), args);
- break;
- case MethodType(Symbol[] params, Type restp):
- Type restp1 = restp.instanceType();
- if (restp1 != restp)
- return MethodType(params, restp1);
- break;
- case PolyType(Symbol[] tparams, Type restp):
- Type restp1 = restp.instanceType();
- if (restp1 != restp)
- return PolyType(tparams, restp1);
- break;
- }
- return this;
+ switch (unalias()) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (sym != sym.thisSym())
+ return sym.typeOfThis()
+ .asSeenFrom(pre, sym.owner())
+ .subst(sym.typeParams(), args);
+ break;
+ case MethodType(Symbol[] params, Type restp):
+ Type restp1 = restp.instanceType();
+ if (restp1 != restp)
+ return MethodType(params, restp1);
+ break;
+ case PolyType(Symbol[] tparams, Type restp):
+ Type restp1 = restp.instanceType();
+ if (restp1 != restp)
+ return PolyType(tparams, restp1);
+ break;
+ }
+ return this;
}
/** Remove all aliases
*/
public Type unalias() {
- Type result = unalias(0);//debug
- //if (this != result) System.out.println(this + " ==> " + result);//DEBUG
- return result;
+ Type result = unalias(0);//debug
+ //if (this != result) System.out.println(this + " ==> " + result);//DEBUG
+ return result;
}
private Type unalias(int n) {
- if (n == 100)
- throw new Type.Error("alias chain too long (recursive type alias?): " + this);
- switch (this) {
+ if (n == 100)
+ throw new Type.Error("alias chain too long (recursive type alias?): " + this);
+ switch (this) {
case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym.kind == ALIAS && sym.typeParams().length == args.length)
- return sym.info().subst(sym.typeParams(), args)
- .asSeenFrom(pre, sym.owner()).unalias(n + 1);
- break;
- case TypeVar(Type origin, Constraint constr):
- if (constr.inst != NoType) return constr.inst.unalias(n + 1);
- else return this;
- }
- return this;
+ if (sym.kind == ALIAS && sym.typeParams().length == args.length)
+ return sym.info().subst(sym.typeParams(), args)
+ .asSeenFrom(pre, sym.owner()).unalias(n + 1);
+ break;
+ case TypeVar(Type origin, Constraint constr):
+ if (constr.inst != NoType) return constr.inst.unalias(n + 1);
+ else return this;
+ }
+ return this;
}
/** The (prefix/argument-adapted) parents of this type.
*/
public Type[] parents() {
- switch (unalias()) {
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return singleDeref().parents();
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym.kind == CLASS) {
- assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args) + " " + sym.primaryConstructor().info();//debug
- return subst(asSeenFrom(sym.info().parents(), pre, sym.owner()),
- sym.typeParams(), args);
- } else {
- return new Type[]{sym.info().asSeenFrom(pre, sym.owner())};
- }
+ switch (unalias()) {
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return singleDeref().parents();
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (sym.kind == CLASS) {
+ assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args) + " " + sym.primaryConstructor().info();//debug
+ return subst(asSeenFrom(sym.info().parents(), pre, sym.owner()),
+ sym.typeParams(), args);
+ } else {
+ return new Type[]{sym.info().asSeenFrom(pre, sym.owner())};
+ }
case CompoundType(Type[] parts, _):
- return parts;
+ return parts;
default:
return Type.EMPTY_ARRAY;
}
@@ -532,16 +532,16 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
*/
public Symbol[] typeParams() {
switch (this) {
- case PolyType(Symbol[] tparams, _):
- return tparams;
+ case PolyType(Symbol[] tparams, _):
+ return tparams;
case MethodType(Symbol[] vparams, _):
return Symbol.EMPTY_ARRAY;
- case TypeRef(_, Symbol sym, Type[] args):
- if (args.length == 0) return sym.typeParams();
- else return Symbol.EMPTY_ARRAY;
+ case TypeRef(_, Symbol sym, Type[] args):
+ if (args.length == 0) return sym.typeParams();
+ else return Symbol.EMPTY_ARRAY;
default:
return Symbol.EMPTY_ARRAY;
- }
+ }
}
/** Get value parameters of method type (a PolyType or MethodType)
@@ -552,14 +552,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
}
private Symbol[] valueParams(boolean ok) {
switch (this) {
- case PolyType(_, Type result):
- return result.valueParams(true);
+ case PolyType(_, Type result):
+ return result.valueParams(true);
case MethodType(Symbol[] vparams, _):
return vparams;
default:
if (ok) return Symbol.EMPTY_ARRAY;
throw Debug.abort("illegal case", this);
- }
+ }
}
/** If this type is a (possibly polymorphic) method type, its result type
@@ -567,38 +567,38 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* otherwise the type itself.
*/
public Type resultType() {
- switch (this) {
- case PolyType(_, Type tpe):
- return tpe.resultType();
- case MethodType(_, Type tpe):
- return tpe.resultType();
- default:
- return this;
- }
+ switch (this) {
+ case PolyType(_, Type tpe):
+ return tpe.resultType();
+ case MethodType(_, Type tpe):
+ return tpe.resultType();
+ default:
+ return this;
+ }
}
/** The number of value parameter sections of this type.
*/
public int paramSectionCount() {
- switch (this) {
- case PolyType(_, Type restpe):
- return restpe.paramSectionCount();
- case MethodType(_, Type restpe):
- return restpe.paramSectionCount() + 1;
- default: return 0;
- }
+ switch (this) {
+ case PolyType(_, Type restpe):
+ return restpe.paramSectionCount();
+ case MethodType(_, Type restpe):
+ return restpe.paramSectionCount() + 1;
+ default: return 0;
+ }
}
/** The first parameter section of this type.
*/
public Symbol[] firstParams() {
- switch (this) {
- case PolyType(_, Type restpe):
- return restpe.firstParams();
- case MethodType(Symbol[] params, _):
- return params;
- default: return Symbol.EMPTY_ARRAY;
- }
+ switch (this) {
+ case PolyType(_, Type restpe):
+ return restpe.firstParams();
+ case MethodType(Symbol[] params, _):
+ return params;
+ default: return Symbol.EMPTY_ARRAY;
+ }
}
/** If this type is overloaded, its alternative types,
@@ -607,10 +607,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
public Type[] alternativeTypes() {
switch (this) {
case OverloadedType(_, Type[] alttypes):
- return alttypes;
- default:
- return new Type[]{this};
- }
+ return alttypes;
+ default:
+ return new Type[]{this};
+ }
}
/** If this type is overloaded, its alternative symbols,
@@ -619,80 +619,80 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
public Symbol[] alternativeSymbols() {
switch (this) {
case OverloadedType(Symbol[] alts, _):
- return alts;
- default:
- return Symbol.EMPTY_ARRAY;
- }
+ return alts;
+ default:
+ return Symbol.EMPTY_ARRAY;
+ }
}
/** If type is a this type of a module class, transform to singletype of
* module.
*/
public Type expandModuleThis() {
- switch (this) {
- case ThisType(Symbol sym):
- if ((sym.flags & MODUL) != 0 && sym.module() != Symbol.NONE) {
- return singleType(
- sym.owner().thisType().expandModuleThis(), sym.module());
- }
- }
- return this;
+ switch (this) {
+ case ThisType(Symbol sym):
+ if ((sym.flags & MODUL) != 0 && sym.module() != Symbol.NONE) {
+ return singleType(
+ sym.owner().thisType().expandModuleThis(), sym.module());
+ }
+ }
+ return this;
}
/** Numeric values
*/
public int intValue() {
- switch (this) {
- case ConstantType(_, Object value):
- return toNumber(value).intValue();
- default:
- throw new ApplicationError();
- }
+ switch (this) {
+ case ConstantType(_, Object value):
+ return toNumber(value).intValue();
+ default:
+ throw new ApplicationError();
+ }
}
public long longValue() {
- switch (this) {
- case ConstantType(_, Object value):
- return toNumber(value).longValue();
- default:
- throw new ApplicationError();
- }
+ switch (this) {
+ case ConstantType(_, Object value):
+ return toNumber(value).longValue();
+ default:
+ throw new ApplicationError();
+ }
}
public float floatValue() {
- switch (this) {
- case ConstantType(_, Object value):
- return toNumber(value).floatValue();
- default:
- throw new ApplicationError();
- }
+ switch (this) {
+ case ConstantType(_, Object value):
+ return toNumber(value).floatValue();
+ default:
+ throw new ApplicationError();
+ }
}
public double doubleValue() {
- switch (this) {
- case ConstantType(_, Object value):
- return toNumber(value).doubleValue();
- default:
- throw new ApplicationError();
- }
+ switch (this) {
+ case ConstantType(_, Object value):
+ return toNumber(value).doubleValue();
+ default:
+ throw new ApplicationError();
+ }
}
public boolean booleanValue() {
- switch (this) {
- case ConstantType(_, Object value):
- return ((Boolean)value).booleanValue();
- default:
- throw new ApplicationError();
- }
+ switch (this) {
+ case ConstantType(_, Object value):
+ return ((Boolean)value).booleanValue();
+ default:
+ throw new ApplicationError();
+ }
}
public String stringValue() {
- switch (this) {
- case ConstantType(_, Object value):
- return value.toString();
- default:
- throw new ApplicationError();
- }
+ switch (this) {
+ case ConstantType(_, Object value):
+ return value.toString();
+ default:
+ throw new ApplicationError();
+ }
}
private static Number toNumber(Object value) {
- return (value instanceof Character)
- ? new Integer(((Character)value).charValue())
- : (Number)value;
+ return (value instanceof Character)
+ ? new Integer(((Character)value).charValue())
+ : (Number)value;
}
// Tests --------------------------------------------------------------------
@@ -700,78 +700,78 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** Is this type a this type or singleton type?
*/
public boolean isStable() {
- switch (unalias()) {
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return true;
- default:
- return false;
- }
+ switch (unalias()) {
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return true;
+ default:
+ return false;
+ }
}
/** Is this type a legal prefix?
*/
public boolean isLegalPrefix() {
- switch (unalias()) {
- case ThisType(_):
- case SingleType(_, _):
- return true;
- case TypeRef(_, Symbol sym, _):
- return sym.kind == CLASS &&
- ((sym.flags & JAVA) != 0 ||
- (sym.flags & (TRAIT | ABSTRACT)) == 0);
- default:
- return false;
- }
+ switch (unalias()) {
+ case ThisType(_):
+ case SingleType(_, _):
+ return true;
+ case TypeRef(_, Symbol sym, _):
+ return sym.kind == CLASS &&
+ ((sym.flags & JAVA) != 0 ||
+ (sym.flags & (TRAIT | ABSTRACT)) == 0);
+ default:
+ return false;
+ }
}
/** Is this type a reference to an object type?
* todo: replace by this.isSubType(global.definitions.ANY_TYPE())?
*/
public boolean isObjectType() {
- switch (unalias()) {
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- case CompoundType(_, _):
- case TypeRef(_, _, _):
- return true;
- default:
- return false;
- }
+ switch (unalias()) {
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ case CompoundType(_, _):
+ case TypeRef(_, _, _):
+ return true;
+ default:
+ return false;
+ }
}
/** Is this type of the form scala.FunctionN[T_1, ..., T_n, +T] or
* scala.Object with scala.FunctionN[T_1, ..., T_n, +T]?
*/
public boolean isFunctionType() {
- switch (this) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- return sym.fullName().startsWith(Names.scala_Function) &&
- args.length > 0;
- case CompoundType(Type[] parents, Scope members):
- return members.isEmpty() &&
- parents.length == 2 &&
- parents[0].symbol().fullName() == Names.scala_Object &&
- parents[1].isFunctionType();
- }
- return false;
+ switch (this) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ return sym.fullName().startsWith(Names.scala_Function) &&
+ args.length > 0;
+ case CompoundType(Type[] parents, Scope members):
+ return members.isEmpty() &&
+ parents.length == 2 &&
+ parents[0].symbol().fullName() == Names.scala_Object &&
+ parents[1].isFunctionType();
+ }
+ return false;
}
/** Is this a polymorphic method type?
*/
public boolean isPolymorphic() {
- return typeParams().length > 0;
+ return typeParams().length > 0;
}
/** Is this a parameterized or polymorphic method type?
*/
public boolean isParameterized() {
- switch (this) {
- case MethodType(_, _): return true;
- default: return isPolymorphic();
- }
+ switch (this) {
+ case MethodType(_, _): return true;
+ default: return isPolymorphic();
+ }
}
// Members and Lookup -------------------------------------------------------
@@ -781,17 +781,17 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
*/
public Scope members() {
switch (this) {
- case ErrorType:
- return new Scope();
- case TypeRef(_, Symbol sym, _):
- return sym.info().members();
- case SingleType(_, _):
- case ConstantType(_, _):
- return singleDeref().members();
- case CompoundType(Type[] basetypes, Scope members):
- return members;
+ case ErrorType:
+ return new Scope();
+ case TypeRef(_, Symbol sym, _):
+ return sym.info().members();
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return singleDeref().members();
+ case CompoundType(Type[] basetypes, Scope members):
+ return members;
default:
- return Scope.EMPTY;
+ return Scope.EMPTY;
}
}
@@ -800,28 +800,28 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
*/
public Symbol lookup(Name name) {
switch (this) {
- case ErrorType:
- return Symbol.ERROR;
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return singleDeref().lookup(name);
- case TypeRef(_, Symbol sym, _):
- return sym.info().lookup(name);
- case CompoundType(Type[] parts, Scope members):
- Symbol sym = members.lookup(name);
- if (sym.kind != NONE) return sym;
- else return lookupNonPrivate(name);
+ case ErrorType:
+ return Symbol.ERROR;
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return singleDeref().lookup(name);
+ case TypeRef(_, Symbol sym, _):
+ return sym.info().lookup(name);
+ case CompoundType(Type[] parts, Scope members):
+ Symbol sym = members.lookup(name);
+ if (sym.kind != NONE) return sym;
+ else return lookupNonPrivate(name);
default:
- return Symbol.NONE;
- }
+ return Symbol.NONE;
+ }
}
/** Lookup non-private symbol with given name among all local and
* inherited members of this type; return Symbol.NONE if not found.
*/
public Symbol lookupNonPrivate(Name name) {
- return lookupNonPrivate(name, 0);
+ return lookupNonPrivate(name, 0);
}
/** Same as before, but with additional parameter `start'.
@@ -830,35 +830,35 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
*/
private Symbol lookupNonPrivate(Name name, int start) {
switch (this) {
- case ErrorType:
- return Symbol.ERROR;
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return singleDeref().lookupNonPrivate(name);
- case TypeRef(_, Symbol sym, _):
- return sym.info().lookupNonPrivate(name, start);
- case CompoundType(Type[] parts, Scope members):
- Symbol sym = members.lookup(name);
- if (sym.kind != NONE && (sym.flags & PRIVATE) == 0)
- return sym;
-
- // search base types in reverse; non-abstract members
- // take precedence over abstract ones.
- int i = parts.length;
- sym = Symbol.NONE;
- while (i > start && (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) {
- i--;
- Symbol sym1 = parts[i].lookupNonPrivate(name, i == 0 ? 0 : 1);
- if (sym1.kind != NONE &&
- (sym1.flags & PRIVATE) == 0 &&
- (sym.kind == NONE || (sym1.flags & DEFERRED) == 0))
- sym = sym1;
- }
- return sym;
+ case ErrorType:
+ return Symbol.ERROR;
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return singleDeref().lookupNonPrivate(name);
+ case TypeRef(_, Symbol sym, _):
+ return sym.info().lookupNonPrivate(name, start);
+ case CompoundType(Type[] parts, Scope members):
+ Symbol sym = members.lookup(name);
+ if (sym.kind != NONE && (sym.flags & PRIVATE) == 0)
+ return sym;
+
+ // search base types in reverse; non-abstract members
+ // take precedence over abstract ones.
+ int i = parts.length;
+ sym = Symbol.NONE;
+ while (i > start && (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) {
+ i--;
+ Symbol sym1 = parts[i].lookupNonPrivate(name, i == 0 ? 0 : 1);
+ if (sym1.kind != NONE &&
+ (sym1.flags & PRIVATE) == 0 &&
+ (sym.kind == NONE || (sym1.flags & DEFERRED) == 0))
+ sym = sym1;
+ }
+ return sym;
default:
- return Symbol.NONE;
- }
+ return Symbol.NONE;
+ }
}
/**
@@ -900,27 +900,27 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
// Set Owner ------------------------------------------------------------------
public Type setOwner(Symbol owner) {
- switch (this) {
- case PolyType(Symbol[] tparams, Type restpe):
- Type restpe1 = restpe.setOwner(owner);
- if (restpe1 == restpe) return this;
- else return Type.PolyType(tparams, restpe1);
- case MethodType(Symbol[] params, Type restpe):
- Symbol[] params1 = params;
- if (params.length > 0 &&
- params[0].owner() != owner && params[0].owner() != Symbol.NONE) {
- params1 = new Symbol[params.length];
- for (int i = 0; i < params.length; i++)
- params1[i] = params[i].cloneSymbol();
- }
- for (int i = 0; i < params.length; i++)
- params1[i].setOwner(owner);
- Type restpe1 = restpe.setOwner(owner);
- if (params1 == params && restpe1 == restpe) return this;
- else return Type.MethodType(params1, restpe1);
- default:
- return this;
- }
+ switch (this) {
+ case PolyType(Symbol[] tparams, Type restpe):
+ Type restpe1 = restpe.setOwner(owner);
+ if (restpe1 == restpe) return this;
+ else return Type.PolyType(tparams, restpe1);
+ case MethodType(Symbol[] params, Type restpe):
+ Symbol[] params1 = params;
+ if (params.length > 0 &&
+ params[0].owner() != owner && params[0].owner() != Symbol.NONE) {
+ params1 = new Symbol[params.length];
+ for (int i = 0; i < params.length; i++)
+ params1[i] = params[i].cloneSymbol();
+ }
+ for (int i = 0; i < params.length; i++)
+ params1[i].setOwner(owner);
+ Type restpe1 = restpe.setOwner(owner);
+ if (params1 == params && restpe1 == restpe) return this;
+ else return Type.MethodType(params1, restpe1);
+ default:
+ return this;
+ }
}
// Maps --------------------------------------------------------------------------
@@ -929,7 +929,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
*/
public abstract static class Map {
- public abstract Type apply(Type t);
+ public abstract Type apply(Type t);
/**
* This method assumes that all symbols in MethodTypes and
@@ -953,153 +953,153 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
}
}
- /** Apply map to all top-level components of this type.
- */
- public Type map(Type tp) {
- switch (tp) {
- case ErrorType:
- case AnyType:
- case NoType:
- case UnboxedType(_):
- case TypeVar(_, _):
- case ThisType(_):
- return tp;
- case TypeRef(Type pre, Symbol sym, Type[] args):
- Type pre1 = apply(pre);
- Type[] args1 = map(args);
- if (pre1 == pre && args1 == args) return tp;
- else return typeRef(pre1, sym, args1);
- case SingleType(Type pre, Symbol sym):
- Type pre1 = apply(pre);
- if (pre1 == pre) return tp;
- else return singleType(pre1, sym);
- case ConstantType(Type base, Object value):
- Type base1 = apply(base);
- if (base1 == base) return tp;
- else return new ConstantType(base1, value);
- case CompoundType(Type[] parts, Scope members):
- Type[] parts1 = map(parts);
- Scope members1 = map(members);
- if (parts1 == parts && members1 == members) {
- return tp;
- } else if (members1 == members && !tp.symbol().isCompoundSym()) {
- return compoundType(parts1, members, tp.symbol());
- } else {
- Scope members2 = new Scope();
- //Type tp1 = compoundType(parts1, members2);
- Type tp1 = (tp.symbol().isCompoundSym()) ? compoundType(parts1, members2)
- : compoundType(parts1, members2, tp.symbol());
- Symbol[] syms1 = members1.elements();
- Symbol[] syms2 = new Symbol[syms1.length];
- for (int i = 0; i < syms2.length; i++) {
- syms2[i] = syms1[i].cloneSymbol(tp1.symbol());
- }
- for (int i = 0; i < syms2.length; i++) {
- syms2[i].setInfo(syms1[i].info().subst(syms1, syms2));
- if (syms2[i].kind == TYPE)
- syms2[i].setLoBound(syms1[i].loBound().subst(syms1, syms2));
- }
- for (int i = 0; i < syms2.length; i++) {
- members2.enter(syms2[i]);
- }
- return tp1;
- }
-
- case MethodType(Symbol[] vparams, Type result):
- Symbol[] vparams1 = map(vparams);
- Type result1 = apply(result);
- if (vparams1 == vparams && result1 == result) return tp;
- else return MethodType(vparams1, result1);
- case PolyType(Symbol[] tparams, Type result):
- Symbol[] tparams1 = map(tparams);
- Type result1 = apply(result);
- if (tparams1 != tparams) result1 = result1.subst(tparams, tparams1);
- if (tparams1 == tparams && result1 == result) return tp;
- else return PolyType(tparams1, result1);
- case OverloadedType(Symbol[] alts, Type[] alttypes):
- Type[] alttypes1 = map(alttypes);
- if (alttypes1 == alttypes) return tp;
- else return OverloadedType(alts, alttypes1);
- case UnboxedArrayType(Type elemtp):
- Type elemtp1 = apply(elemtp);
- if (elemtp1 == elemtp) return tp;
- else return UnboxedArrayType(elemtp1);
- default:
- throw new ApplicationError(tp + " " + tp.symbol());
- }
- }
-
- public final Symbol map(Symbol sym) {
+ /** Apply map to all top-level components of this type.
+ */
+ public Type map(Type tp) {
+ switch (tp) {
+ case ErrorType:
+ case AnyType:
+ case NoType:
+ case UnboxedType(_):
+ case TypeVar(_, _):
+ case ThisType(_):
+ return tp;
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ Type pre1 = apply(pre);
+ Type[] args1 = map(args);
+ if (pre1 == pre && args1 == args) return tp;
+ else return typeRef(pre1, sym, args1);
+ case SingleType(Type pre, Symbol sym):
+ Type pre1 = apply(pre);
+ if (pre1 == pre) return tp;
+ else return singleType(pre1, sym);
+ case ConstantType(Type base, Object value):
+ Type base1 = apply(base);
+ if (base1 == base) return tp;
+ else return new ConstantType(base1, value);
+ case CompoundType(Type[] parts, Scope members):
+ Type[] parts1 = map(parts);
+ Scope members1 = map(members);
+ if (parts1 == parts && members1 == members) {
+ return tp;
+ } else if (members1 == members && !tp.symbol().isCompoundSym()) {
+ return compoundType(parts1, members, tp.symbol());
+ } else {
+ Scope members2 = new Scope();
+ //Type tp1 = compoundType(parts1, members2);
+ Type tp1 = (tp.symbol().isCompoundSym()) ? compoundType(parts1, members2)
+ : compoundType(parts1, members2, tp.symbol());
+ Symbol[] syms1 = members1.elements();
+ Symbol[] syms2 = new Symbol[syms1.length];
+ for (int i = 0; i < syms2.length; i++) {
+ syms2[i] = syms1[i].cloneSymbol(tp1.symbol());
+ }
+ for (int i = 0; i < syms2.length; i++) {
+ syms2[i].setInfo(syms1[i].info().subst(syms1, syms2));
+ if (syms2[i].kind == TYPE)
+ syms2[i].setLoBound(syms1[i].loBound().subst(syms1, syms2));
+ }
+ for (int i = 0; i < syms2.length; i++) {
+ members2.enter(syms2[i]);
+ }
+ return tp1;
+ }
+
+ case MethodType(Symbol[] vparams, Type result):
+ Symbol[] vparams1 = map(vparams);
+ Type result1 = apply(result);
+ if (vparams1 == vparams && result1 == result) return tp;
+ else return MethodType(vparams1, result1);
+ case PolyType(Symbol[] tparams, Type result):
+ Symbol[] tparams1 = map(tparams);
+ Type result1 = apply(result);
+ if (tparams1 != tparams) result1 = result1.subst(tparams, tparams1);
+ if (tparams1 == tparams && result1 == result) return tp;
+ else return PolyType(tparams1, result1);
+ case OverloadedType(Symbol[] alts, Type[] alttypes):
+ Type[] alttypes1 = map(alttypes);
+ if (alttypes1 == alttypes) return tp;
+ else return OverloadedType(alts, alttypes1);
+ case UnboxedArrayType(Type elemtp):
+ Type elemtp1 = apply(elemtp);
+ if (elemtp1 == elemtp) return tp;
+ else return UnboxedArrayType(elemtp1);
+ default:
+ throw new ApplicationError(tp + " " + tp.symbol());
+ }
+ }
+
+ 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);
+ public Symbol map(Symbol sym, boolean dontClone) {
+ Type tp = sym.info();
+ Type tp1 = apply(tp);
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) {
+ if (sym.kind == TYPE) {
+ Type lb = sym.loBound();
+ Type lb1 = apply(lb);
+ if (lb != lb1) {
if (!dontClone) sym = sym.cloneSymbol();
sym.setLoBound(lb1);
}
}
- return sym;
- }
-
- public Type[] map(Type[] tps) {
- Type[] tps1 = tps;
- for (int i = 0; i < tps.length; i++) {
- Type tp = tps[i];
- Type tp1 = apply(tp);
- if (tp1 != tp && tps1 == tps) {
- tps1 = new Type[tps.length];
- System.arraycopy(tps, 0, tps1, 0, i);
- }
- tps1[i] = tp1;
- }
- return tps1;
- }
-
- /** Apply map to all elements of this array of symbols,
- * preserving recursive references to symbols in the array.
- */
- public final Symbol[] map(Symbol[] syms) {
+ return sym;
+ }
+
+ public Type[] map(Type[] tps) {
+ Type[] tps1 = tps;
+ for (int i = 0; i < tps.length; i++) {
+ Type tp = tps[i];
+ Type tp1 = apply(tp);
+ if (tp1 != tp && tps1 == tps) {
+ tps1 = new Type[tps.length];
+ System.arraycopy(tps, 0, tps1, 0, i);
+ }
+ tps1[i] = tp1;
+ }
+ return tps1;
+ }
+
+ /** Apply map to all elements of this array of symbols,
+ * preserving recursive references to symbols in the array.
+ */
+ 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, dontClone);
- if (sym != sym1 && syms1 == syms) {
- syms1 = new Symbol[syms.length];
- System.arraycopy(syms, 0, syms1, 0, i);
- }
- syms1[i] = sym1;
- }
- if (syms1 != syms) {
- for (int i = 0; i < syms1.length; i++) {
- if (syms1[i] == syms[i])
- syms1[i] = syms[i].cloneSymbol();
- }
+ 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, dontClone);
+ if (sym != sym1 && syms1 == syms) {
+ syms1 = new Symbol[syms.length];
+ System.arraycopy(syms, 0, syms1, 0, i);
+ }
+ syms1[i] = sym1;
+ }
+ if (syms1 != syms) {
+ for (int i = 0; i < syms1.length; i++) {
+ if (syms1[i] == syms[i])
+ syms1[i] = syms[i].cloneSymbol();
+ }
new SubstSymMap(syms, syms1).map(syms1, true);
- }
- return syms1;
- }
+ }
+ return syms1;
+ }
- /** Apply map to all elements of this array of this scope.
- */
- public Scope map(Scope s) {
- Symbol[] members = s.elements();
- Symbol[] members1 = map(members);
- if (members == members1) return s;
- else return new Scope(members1);
- }
+ /** Apply map to all elements of this array of this scope.
+ */
+ public Scope map(Scope s) {
+ Symbol[] members = s.elements();
+ Symbol[] members1 = map(members);
+ if (members == members1) return s;
+ else return new Scope(members1);
+ }
}
public abstract static class MapOnlyTypes extends Map {
@@ -1112,9 +1112,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
public Type apply(Type tp) { return tp; }
public Type applyParams(Type tp) { return tp; }
public Type map(Type tp) { return tp; }
- public Symbol map(Symbol sym, boolean dontClone) { return sym; }
+ public Symbol map(Symbol sym, boolean dontClone) { return sym; }
public Type[] map(Type[] tps) { return tps; }
- public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; }
+ public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; }
public Scope map(Scope scope) { return scope; }
};
@@ -1124,103 +1124,103 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* such a type does not exist.
*/
public Type baseType(Symbol clazz) {
- //System.out.println(this + ".baseType(" + clazz + ")");//DEBUG
- switch (this) {
- case ErrorType:
- return ErrorType;
-
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return singleDeref().baseType(clazz);
-
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym == clazz)
- return this;
- else if (sym.kind == TYPE)
- return sym.info()
- .asSeenFrom(pre, sym.owner()).baseType(clazz);
- else if (sym.kind == ALIAS)
- if (sym.typeParams().length == args.length)
- return sym.info().subst(sym.typeParams(), args)
- .asSeenFrom(pre, sym.owner()).baseType(clazz);
- else return Type.NoType;
- else if (clazz.isCompoundSym())
- return NoType;
- else {
- return sym.baseType(clazz)
- .asSeenFrom(pre, sym.owner())
- .subst(sym.typeParams(), args);
- }
-
- case CompoundType(Type[] parts, _):
- for (int i = parts.length - 1; i >= 0; i--) {
- Type result = parts[i].baseType(clazz);
- if (result != NoType) return result;
- }
- break;
-
- case UnboxedArrayType(_):
- if (clazz == Global.instance.definitions.ANY_CLASS ||
- clazz == Global.instance.definitions.ANYREF_CLASS)
- return clazz.type();
- }
- return NoType;
+ //System.out.println(this + ".baseType(" + clazz + ")");//DEBUG
+ switch (this) {
+ case ErrorType:
+ return ErrorType;
+
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return singleDeref().baseType(clazz);
+
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (sym == clazz)
+ return this;
+ else if (sym.kind == TYPE)
+ return sym.info()
+ .asSeenFrom(pre, sym.owner()).baseType(clazz);
+ else if (sym.kind == ALIAS)
+ if (sym.typeParams().length == args.length)
+ return sym.info().subst(sym.typeParams(), args)
+ .asSeenFrom(pre, sym.owner()).baseType(clazz);
+ else return Type.NoType;
+ else if (clazz.isCompoundSym())
+ return NoType;
+ else {
+ return sym.baseType(clazz)
+ .asSeenFrom(pre, sym.owner())
+ .subst(sym.typeParams(), args);
+ }
+
+ case CompoundType(Type[] parts, _):
+ for (int i = parts.length - 1; i >= 0; i--) {
+ Type result = parts[i].baseType(clazz);
+ if (result != NoType) return result;
+ }
+ break;
+
+ case UnboxedArrayType(_):
+ if (clazz == Global.instance.definitions.ANY_CLASS ||
+ clazz == Global.instance.definitions.ANYREF_CLASS)
+ return clazz.type();
+ }
+ return NoType;
}
/** Return overriding instance of `sym' in this type,
* or `sym' itself if none exists.
*/
public Symbol rebind(Symbol sym) {
- if ((sym.flags & (PRIVATE | MODUL)) == 0) {
- Symbol sym1 = lookupNonPrivate(sym.name);
- if (sym1.kind != NONE) {
- if ((sym1.flags & LOCKED) != 0)
- throw new Type.Error("illegal cyclic reference involving " + sym1);
- //System.out.println("rebinding " + sym + " to " + sym1);//DEBUG
- return sym1;
- }
- }
- return sym;
+ if ((sym.flags & (PRIVATE | MODUL)) == 0) {
+ Symbol sym1 = lookupNonPrivate(sym.name);
+ if (sym1.kind != NONE) {
+ if ((sym1.flags & LOCKED) != 0)
+ throw new Type.Error("illegal cyclic reference involving " + sym1);
+ //System.out.println("rebinding " + sym + " to " + sym1);//DEBUG
+ return sym1;
+ }
+ }
+ return sym;
}
/** A map to implement `asSeenFrom'.
*/
static class AsSeenFromMap extends Map {
- private final Type pre;
- private final Symbol clazz;
+ private final Type pre;
+ private final Symbol clazz;
private final boolean local;
- AsSeenFromMap(Type pre, Symbol clazz) {
- this.pre = pre; this.clazz = clazz;
+ AsSeenFromMap(Type pre, Symbol clazz) {
+ this.pre = pre; this.clazz = clazz;
Global global = Global.instance;
this.local =global.PHASE.EXPLICITOUTER.id()<global.currentPhase.id;
- }
-
- public Type apply(Type t) {
- //System.out.println(t + " as seen from " + pre + "," + clazz);//DEBUG
- if (pre == NoType || clazz.kind != CLASS)
- return t;
- switch (t) {
- case ThisType(Symbol sym):
- return t.toPrefix(sym, pre, clazz);
-
- case TypeRef(Type prefix, Symbol sym, Type[] args):
- if (sym.kind == ALIAS && sym.typeParams().length == args.length) {
- return apply(
- sym.info().subst(sym.typeParams(), args)
- .asSeenFrom(prefix, sym.owner()));
- } else if (sym.owner().isPrimaryConstructor()) {
- assert sym.kind == TYPE;
- Type t1 = t.toInstance(sym, pre, clazz);
- //System.out.println(t + ".toInstance(" + pre + "," + clazz + ") = " + t1);//DEBUG
- return t1;
- } else {
- Type prefix1 = apply(prefix);
- Type[] args1 = map(args);
- if (prefix1 == prefix && args1 == args) return t;
- Symbol sym1 = prefix1.rebind(sym);
+ }
+
+ public Type apply(Type t) {
+ //System.out.println(t + " as seen from " + pre + "," + clazz);//DEBUG
+ if (pre == NoType || clazz.kind != CLASS)
+ return t;
+ switch (t) {
+ case ThisType(Symbol sym):
+ return t.toPrefix(sym, pre, clazz);
+
+ case TypeRef(Type prefix, Symbol sym, Type[] args):
+ if (sym.kind == ALIAS && sym.typeParams().length == args.length) {
+ return apply(
+ sym.info().subst(sym.typeParams(), args)
+ .asSeenFrom(prefix, sym.owner()));
+ } else if (sym.owner().isPrimaryConstructor()) {
+ assert sym.kind == TYPE;
+ Type t1 = t.toInstance(sym, pre, clazz);
+ //System.out.println(t + ".toInstance(" + pre + "," + clazz + ") = " + t1);//DEBUG
+ return t1;
+ } else {
+ Type prefix1 = apply(prefix);
+ Type[] args1 = map(args);
+ if (prefix1 == prefix && args1 == args) return t;
+ Symbol sym1 = prefix1.rebind(sym);
if (local && sym != sym1) {
// Here what we should do is remove the outer
// type links of sym from args and then add
@@ -1233,60 +1233,60 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
args1 = asSeenFrom(Symbol.type(sym1.owner().typeParams()), pre, sym1.owner());
if (sym1.isClassType()) prefix1 = localThisType;
}
- Type t1 = typeRef(prefix1, sym1, args1);
+ Type t1 = typeRef(prefix1, sym1, args1);
if (sym1 != sym) t1 = apply(t1.unalias());
return t1;
- }
+ }
- case SingleType(Type prefix, Symbol sym):
- try {
- Type prefix1 = apply(prefix);
- if (prefix1 == prefix) return t;
- else return singleType(prefix1, prefix1.rebind(sym));
- } catch (Type.Malformed ex) {}
- return apply(t.singleDeref());
+ case SingleType(Type prefix, Symbol sym):
+ try {
+ Type prefix1 = apply(prefix);
+ if (prefix1 == prefix) return t;
+ else return singleType(prefix1, prefix1.rebind(sym));
+ } catch (Type.Malformed ex) {}
+ return apply(t.singleDeref());
- default:
- return map(t);
- }
- }
+ default:
+ return map(t);
+ }
+ }
}
//where
Type toInstance(Symbol sym, Type pre, Symbol clazz) {
- if (pre == NoType || clazz.kind != CLASS)
- return this;
- Symbol ownclass = sym.owner().constructorClass();
- if (ownclass == clazz &&
- pre.widen().symbol().isSubClass(ownclass)) {
- switch (pre.baseType(ownclass)) {
- case TypeRef(_, Symbol basesym, Type[] baseargs):
- Symbol[] baseparams = basesym.typeParams();
- for (int i = 0; i < baseparams.length; i++) {
- if (sym == baseparams[i]) return baseargs[i];
- }
- //System.out.println(sym + " " + basesym + " " + ArrayApply.toString(baseparams));//DEBUG
- break;
- case ErrorType:
- return ErrorType;
- }
- throw new ApplicationError(
- this + " in " + ownclass + " cannot be instantiated from " + pre.widen()
- );
- } else {
- return toInstance(sym, pre.baseType(clazz).prefix(), clazz.owner());
- }
- }
-
- Type toPrefix(Symbol sym, Type pre, Symbol clazz) {
- //System.out.println(this + ".toPrefix(" + sym + "," + pre + "," + clazz + ")");//DEBUG
- if (pre == NoType || clazz.kind != CLASS)
- return this;
- else if (sym.isSubClass(clazz) &&
- pre.widen().symbol().isSubClass(sym))
- return pre;
- else
- return toPrefix(sym, pre.baseType(clazz).prefix(), clazz.owner());
- }
+ if (pre == NoType || clazz.kind != CLASS)
+ return this;
+ Symbol ownclass = sym.owner().constructorClass();
+ if (ownclass == clazz &&
+ pre.widen().symbol().isSubClass(ownclass)) {
+ switch (pre.baseType(ownclass)) {
+ case TypeRef(_, Symbol basesym, Type[] baseargs):
+ Symbol[] baseparams = basesym.typeParams();
+ for (int i = 0; i < baseparams.length; i++) {
+ if (sym == baseparams[i]) return baseargs[i];
+ }
+ //System.out.println(sym + " " + basesym + " " + ArrayApply.toString(baseparams));//DEBUG
+ break;
+ case ErrorType:
+ return ErrorType;
+ }
+ throw new ApplicationError(
+ this + " in " + ownclass + " cannot be instantiated from " + pre.widen()
+ );
+ } else {
+ return toInstance(sym, pre.baseType(clazz).prefix(), clazz.owner());
+ }
+ }
+
+ Type toPrefix(Symbol sym, Type pre, Symbol clazz) {
+ //System.out.println(this + ".toPrefix(" + sym + "," + pre + "," + clazz + ")");//DEBUG
+ if (pre == NoType || clazz.kind != CLASS)
+ return this;
+ else if (sym.isSubClass(clazz) &&
+ pre.widen().symbol().isSubClass(sym))
+ return pre;
+ else
+ return toPrefix(sym, pre.baseType(clazz).prefix(), clazz.owner());
+ }
/** This type as seen from prefix `pre' and class `clazz'. This means:
* Replace all thistypes of `clazz' or one of its subclasses by `pre'
@@ -1294,26 +1294,26 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* Proceed analogously for thistypes referring to outer classes.
*/
public Type asSeenFrom(Type pre, Symbol clazz) {
- //System.out.println("computing asseenfrom of " + this + " with " + pre + "," + clazz);//DEBUG
- return new AsSeenFromMap(pre, clazz).apply(this);
+ //System.out.println("computing asseenfrom of " + this + " with " + pre + "," + clazz);//DEBUG
+ return new AsSeenFromMap(pre, clazz).apply(this);
}
/** Types `these' as seen from prefix `pre' and class `clazz'.
*/
public static Type[] asSeenFrom(Type[] these, Type pre, Symbol clazz) {
- return new AsSeenFromMap(pre, clazz).map(these);
+ return new AsSeenFromMap(pre, clazz).map(these);
}
/** The info of `sym', seen as a member of this type.
*/
public Type memberInfo(Symbol sym) {
- return sym.info().asSeenFrom(this, sym.owner());
+ return sym.info().asSeenFrom(this, sym.owner());
}
/** The type of `sym', seen as a member of this type.
*/
public Type memberType(Symbol sym) {
- return sym.type().asSeenFrom(this, sym.owner());
+ return sym.type().asSeenFrom(this, sym.owner());
}
/** The stabilized type of `sym', seen as a member of this type.
@@ -1327,7 +1327,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** The low bound of `sym', seen as a member of this type.
*/
public Type memberLoBound(Symbol sym) {
- return sym.loBound().asSeenFrom(this, sym.owner());
+ return sym.loBound().asSeenFrom(this, sym.owner());
}
// Substitutions ---------------------------------------------------------------
@@ -1335,135 +1335,135 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** A common map superclass for symbol/symbol and type/symbol substitutions.
*/
public static abstract class SubstMap extends Map {
- private Symbol[] from;
-
- SubstMap(Symbol[] from) {
- this.from = from;
- }
-
- public boolean matches(Symbol sym1, Symbol sym2) {
- return sym1 == sym2;
- }
-
- /** Produce replacement type
- * @param i The index in `from' of the symbol to be replaced.
- * @param fromtp The type referring to this symbol.
- */
- protected abstract Type replacement(int i, Type fromtp);
-
- /** Produce new substitution where some symbols are excluded.
- * @param newfrom The new array of from symbols (without excluded syms)
- * @param excluded The array of excluded sysmbols
- */
- protected abstract SubstMap exclude(Symbol[] newfrom, Symbol[] excluded);
-
- public Type apply(Type t) {
- switch (t) {
- case TypeRef(ThisType(_), Symbol sym, Type[] args):
- for (int i = 0; i < from.length; i++) {
- if (matches(sym, from[i])) return replacement(i, t);
- }
- break;
- case SingleType(ThisType(_), Symbol sym):
- for (int i = 0; i < from.length; i++) {
- if (matches(sym, from[i])) return replacement(i, t);
- }
- break;
- case PolyType(Symbol[] tparams, Type result):
- Symbol[] from1 = excludeSyms(from, tparams, from);
- if (from1 != from) {
- SubstMap f = exclude(from1, tparams);
- Symbol[] tparams1 = f.map(tparams);
- Type result1 = f.apply(result);
- if (tparams1 != tparams)
- result1 = result1.subst(tparams, tparams1);
- if (tparams1 == tparams && result1 == result) return t;
- else return PolyType(tparams1, result1);
- }
- }
- return map(t);
- }
- //where
- private boolean contains1(Symbol[] syms, Symbol sym) {
- int i = 0;
- while (i < syms.length && syms[i] != sym) i++;
- return i < syms.length;
- }
-
- private int nCommon(Symbol[] from, Symbol[] tparams) {
- int cnt = 0;
- for (int i = 0; i < from.length; i++) {
- if (contains1(tparams, from[i])) cnt++;
- }
- return cnt;
- }
-
- private Symbol[] excludeSyms(Symbol[] from, Symbol[] tparams, Symbol[] syms) {
- int n = nCommon(from, tparams);
- if (n == 0) {
- return syms;
- } else {
- Symbol[] syms1 = new Symbol[syms.length - n];
- int j = 0;
- for (int i = 0; i < from.length; i++) {
- if (!contains1(tparams, from[i])) syms1[j++] = syms[i];
- }
- return syms1;
- }
- }
-
- private Type[] excludeTypes(Symbol[] from, Symbol[] tparams, Type[] types) {
- int n = nCommon(from, tparams);
- if (n == 0) {
- return types;
- } else {
- Type[] types1 = new Type[types.length - n];
- int j = 0;
- for (int i = 0; i < from.length; i++) {
- if (!contains1(tparams, from[i])) types1[j++] = types[i];
- }
- return types1;
- }
- }
+ private Symbol[] from;
+
+ SubstMap(Symbol[] from) {
+ this.from = from;
+ }
+
+ public boolean matches(Symbol sym1, Symbol sym2) {
+ return sym1 == sym2;
+ }
+
+ /** Produce replacement type
+ * @param i The index in `from' of the symbol to be replaced.
+ * @param fromtp The type referring to this symbol.
+ */
+ protected abstract Type replacement(int i, Type fromtp);
+
+ /** Produce new substitution where some symbols are excluded.
+ * @param newfrom The new array of from symbols (without excluded syms)
+ * @param excluded The array of excluded sysmbols
+ */
+ protected abstract SubstMap exclude(Symbol[] newfrom, Symbol[] excluded);
+
+ public Type apply(Type t) {
+ switch (t) {
+ case TypeRef(ThisType(_), Symbol sym, Type[] args):
+ for (int i = 0; i < from.length; i++) {
+ if (matches(sym, from[i])) return replacement(i, t);
+ }
+ break;
+ case SingleType(ThisType(_), Symbol sym):
+ for (int i = 0; i < from.length; i++) {
+ if (matches(sym, from[i])) return replacement(i, t);
+ }
+ break;
+ case PolyType(Symbol[] tparams, Type result):
+ Symbol[] from1 = excludeSyms(from, tparams, from);
+ if (from1 != from) {
+ SubstMap f = exclude(from1, tparams);
+ Symbol[] tparams1 = f.map(tparams);
+ Type result1 = f.apply(result);
+ if (tparams1 != tparams)
+ result1 = result1.subst(tparams, tparams1);
+ if (tparams1 == tparams && result1 == result) return t;
+ else return PolyType(tparams1, result1);
+ }
+ }
+ return map(t);
+ }
+ //where
+ private boolean contains1(Symbol[] syms, Symbol sym) {
+ int i = 0;
+ while (i < syms.length && syms[i] != sym) i++;
+ return i < syms.length;
+ }
+
+ private int nCommon(Symbol[] from, Symbol[] tparams) {
+ int cnt = 0;
+ for (int i = 0; i < from.length; i++) {
+ if (contains1(tparams, from[i])) cnt++;
+ }
+ return cnt;
+ }
+
+ private Symbol[] excludeSyms(Symbol[] from, Symbol[] tparams, Symbol[] syms) {
+ int n = nCommon(from, tparams);
+ if (n == 0) {
+ return syms;
+ } else {
+ Symbol[] syms1 = new Symbol[syms.length - n];
+ int j = 0;
+ for (int i = 0; i < from.length; i++) {
+ if (!contains1(tparams, from[i])) syms1[j++] = syms[i];
+ }
+ return syms1;
+ }
+ }
+
+ private Type[] excludeTypes(Symbol[] from, Symbol[] tparams, Type[] types) {
+ int n = nCommon(from, tparams);
+ if (n == 0) {
+ return types;
+ } else {
+ Type[] types1 = new Type[types.length - n];
+ int j = 0;
+ for (int i = 0; i < from.length; i++) {
+ if (!contains1(tparams, from[i])) types1[j++] = types[i];
+ }
+ return types1;
+ }
+ }
}
/** A map for symbol/symbol substitutions
*/
public static class SubstSymMap extends SubstMap {
- Symbol[] to;
- protected SubstSymMap(Symbol[] from, Symbol[] to) {
- super(from);
- this.to = to;
- }
- protected Type replacement(int i, Type fromtp) {
- switch (fromtp) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- return typeRef(pre, to[i], args);
- case SingleType(Type pre, Symbol sym):
- return singleType(pre, to[i]);
- default:
- throw new ApplicationError();
- }
- }
- protected SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) {
- return new SubstSymMap(newfrom, excludeSyms(from, excluded, to));
- }
+ Symbol[] to;
+ protected SubstSymMap(Symbol[] from, Symbol[] to) {
+ super(from);
+ this.to = to;
+ }
+ protected Type replacement(int i, Type fromtp) {
+ switch (fromtp) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ return typeRef(pre, to[i], args);
+ case SingleType(Type pre, Symbol sym):
+ return singleType(pre, to[i]);
+ default:
+ throw new ApplicationError();
+ }
+ }
+ protected SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) {
+ return new SubstSymMap(newfrom, excludeSyms(from, excluded, to));
+ }
}
/** A map for type/symbol substitutions
*/
public static class SubstTypeMap extends SubstMap {
- Type[] to;
- protected SubstTypeMap(Symbol[] from, Type[] to) {
- super(from);
- this.to = to;
- }
- protected Type replacement(int i, Type fromtp) {
- return to[i];
- }
- protected SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) {
- return new SubstTypeMap(newfrom, excludeTypes(from, excluded, to));
- }
+ Type[] to;
+ protected SubstTypeMap(Symbol[] from, Type[] to) {
+ super(from);
+ this.to = to;
+ }
+ protected Type replacement(int i, Type fromtp) {
+ return to[i];
+ }
+ protected SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) {
+ return new SubstTypeMap(newfrom, excludeTypes(from, excluded, to));
+ }
}
@@ -1525,111 +1525,111 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** Substitute symbols `to' for occurrences of symbols `from' in this type.
*/
public Type subst(Symbol[] from, Symbol[] to) {
- if (to.length != 0 && from != to) {//!!!
- assert from.length == to.length
- : this + ": " + from.length + " != " + to.length;
- return new SubstSymMap(from, to).apply(this);
- } else return this;
+ if (to.length != 0 && from != to) {//!!!
+ assert from.length == to.length
+ : this + ": " + from.length + " != " + to.length;
+ return new SubstSymMap(from, to).apply(this);
+ } else return this;
}
/** Substitute symbols `to' for occurrences of symbols `from' in these types.
*/
public static Type[] subst(Type[] these, Symbol[] from, Symbol[] to) {
- if (these.length != 0 && to.length != 0 && from != to) {
- assert from.length == to.length;
- return new SubstSymMap(from, to).map(these);
- } else return these;
+ if (these.length != 0 && to.length != 0 && from != to) {
+ assert from.length == to.length;
+ return new SubstSymMap(from, to).map(these);
+ } else return these;
}
/** Substitute types `to' for occurrences of symbols `from' in this type.
*/
public Type subst(Symbol[] from, Type[] to) {
- if (to.length != 0) {
- assert from.length == to.length
- : this + ": " + Debug.show(from) + " <> " + ArrayApply.toString(to);
- return new SubstTypeMap(from, to).apply(this);
- } else return this;
+ if (to.length != 0) {
+ assert from.length == to.length
+ : this + ": " + Debug.show(from) + " <> " + ArrayApply.toString(to);
+ return new SubstTypeMap(from, to).apply(this);
+ } else return this;
}
/** Substitute types `to' for occurrences of symbols `from' in these types.
*/
public static Type[] subst(Type[] these, Symbol[] from, Type[] to) {
- if (these.length != 0 && to.length != 0) {
- assert from.length == to.length;
- return new SubstTypeMap(from, to).map(these);
- } else return these;
+ if (these.length != 0 && to.length != 0) {
+ assert from.length == to.length;
+ return new SubstTypeMap(from, to).map(these);
+ } else return these;
}
/** A map for substitutions of thistypes.
*/
public static class SubstThisMap extends Map {
- Symbol from;
- Type to;
- public SubstThisMap(Symbol from, Type to) {
- this.from = from;
- this.to = to;
- }
+ Symbol from;
+ Type to;
+ public SubstThisMap(Symbol from, Type to) {
+ this.from = from;
+ this.to = to;
+ }
public SubstThisMap(Symbol oldSym, Symbol newSym) {
this(oldSym, newSym.thisType());
}
- public Type apply(Type t) {
- switch (t) {
- case ThisType(Symbol sym):
- if (sym == from) return to;
- else return t;
- default:
- return map(t);
- }
- }
+ public Type apply(Type t) {
+ switch (t) {
+ case ThisType(Symbol sym):
+ if (sym == from) return to;
+ else return t;
+ default:
+ return map(t);
+ }
+ }
}
public Type substThis(Symbol from, Type to) {
- return new SubstThisMap(from, to).apply(this);
+ return new SubstThisMap(from, to).apply(this);
}
public static Type[] substThis(Type[] these, Symbol from, Type to) {
- return new SubstThisMap(from, to).map(these);
+ return new SubstThisMap(from, to).map(these);
}
static class ContainsMap extends Map {
- boolean result = false;
- Symbol sym;
- ContainsMap(Symbol sym) {
- this.sym = sym;
- }
- public Type apply(Type t) {
- if (!result) {
- switch (t) {
- case TypeRef(Type pre, Symbol sym1, Type[] args):
- if (sym == sym1) result = true;
- else { map(pre); map(args); }
- break;
- case SingleType(Type pre, Symbol sym1):
- map(pre);
- if (sym == sym1) result = true;
- break;
- default:
- map(t);
- }
- }
- return t;
- }
+ boolean result = false;
+ Symbol sym;
+ ContainsMap(Symbol sym) {
+ this.sym = sym;
+ }
+ public Type apply(Type t) {
+ if (!result) {
+ switch (t) {
+ case TypeRef(Type pre, Symbol sym1, Type[] args):
+ if (sym == sym1) result = true;
+ else { map(pre); map(args); }
+ break;
+ case SingleType(Type pre, Symbol sym1):
+ map(pre);
+ if (sym == sym1) result = true;
+ break;
+ default:
+ map(t);
+ }
+ }
+ return t;
+ }
}
/** Does this type contain symbol `sym'?
*/
public boolean contains(Symbol sym) {
- ContainsMap f = new ContainsMap(sym);
- f.apply(this);
- return f.result;
+ ContainsMap f = new ContainsMap(sym);
+ f.apply(this);
+ return f.result;
}
/** Does this type contain any of the symbols `syms'?
*/
public boolean containsSome(Symbol[] syms) {
- for (int i = 0; i < syms.length; i++)
- if (contains(syms[i])) return true;
- return false;
+ for (int i = 0; i < syms.length; i++)
+ if (contains(syms[i])) return true;
+ return false;
}
// Cloning ---------------------------------------------------------------
@@ -1772,513 +1772,513 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** Is this type a subtype of that type?
*/
public boolean isSubType(Type that) {
- if (explainSwitch) {
- for (int i = 0; i < indent; i++) System.out.print(" ");
- System.out.println(this + " < " + that + "?");
- indent++;
- }
- boolean result = isSubType0(that);
- if (explainSwitch) {
- indent--;
- for (int i = 0; i < indent; i++) System.out.print(" ");
- System.out.println(result);
- }
- return result;
+ if (explainSwitch) {
+ for (int i = 0; i < indent; i++) System.out.print(" ");
+ System.out.println(this + " < " + that + "?");
+ indent++;
+ }
+ boolean result = isSubType0(that);
+ if (explainSwitch) {
+ indent--;
+ for (int i = 0; i < indent; i++) System.out.print(" ");
+ System.out.println(result);
+ }
+ return result;
}
public boolean isSubType0(Type that) {
- if (this == that) return true;
-
- switch (this) {
- case ErrorType:
- case AnyType:
- return true;
- }
-
- switch (that) {
- case ErrorType:
- case AnyType:
- return true;
-
- case NoType:
- return false;
-
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- switch (this) {
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return this.isSameAs(that);
- }
- break;
-
- case TypeRef(Type pre1, Symbol sym1, Type[] args1):
- switch (this) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if (pre.isSubType(pre1) &&
- (sym == sym1 || sym == pre.rebind(sym1)) &&
- isSubArgs(args, args1, sym.typeParams())
- ||
- sym.kind == TYPE && pre.memberInfo(sym).isSubType(that))
- return true;
- break;
- }
- if (sym1.kind == CLASS) {
- Type base = this.baseType(sym1);
- if (this != base && base.isSubType(that))
- return true;
- }
- break;
-
- case CompoundType(Type[] parts1, Scope members1):
- int i = 0;
- while (i < parts1.length && isSubType(parts1[i])) i++;
- if (i == parts1.length && specializes(members1))
- return true;
- break;
-
- case MethodType(Symbol[] ps1, Type res1):
- switch (this) {
- case MethodType(Symbol[] ps, Type res):
- if (ps.length != ps1.length) return false;
- for (int i = 0; i < ps.length; i++) {
- Symbol p1 = ps1[i];
- Symbol p = ps[i];
- if (!p1.type().isSameAs(p.type()) ||
- (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED)))
- return false;
- }
- return res.isSubType(res1);
- }
- break;
-
- case PolyType(Symbol[] ps1, Type res1):
- switch (this) {
- case PolyType(Symbol[] ps, Type res):
- if (ps.length != ps1.length) return false;
- for (int i = 0; i < ps.length; i++)
- if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) ||
- !ps[i].loBound().isSameAs(ps1[i].loBound().subst(ps1, ps)))
- return false;
- return res.isSubType(res1.subst(ps1, ps));
- }
- break;
-
- case OverloadedType(Symbol[] alts1, Type[] alttypes1):
- for (int i = 0; i < alttypes1.length; i++) {
- if (!isSubType(alttypes1[i]))
- return false;
- }
- return true;
-
- case UnboxedType(int tag1):
- switch (this) {
- case UnboxedType(int tag):
- return tag == tag1 ||
+ if (this == that) return true;
+
+ switch (this) {
+ case ErrorType:
+ case AnyType:
+ return true;
+ }
+
+ switch (that) {
+ case ErrorType:
+ case AnyType:
+ return true;
+
+ case NoType:
+ return false;
+
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ switch (this) {
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return this.isSameAs(that);
+ }
+ break;
+
+ case TypeRef(Type pre1, Symbol sym1, Type[] args1):
+ switch (this) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (pre.isSubType(pre1) &&
+ (sym == sym1 || sym == pre.rebind(sym1)) &&
+ isSubArgs(args, args1, sym.typeParams())
+ ||
+ sym.kind == TYPE && pre.memberInfo(sym).isSubType(that))
+ return true;
+ break;
+ }
+ if (sym1.kind == CLASS) {
+ Type base = this.baseType(sym1);
+ if (this != base && base.isSubType(that))
+ return true;
+ }
+ break;
+
+ case CompoundType(Type[] parts1, Scope members1):
+ int i = 0;
+ while (i < parts1.length && isSubType(parts1[i])) i++;
+ if (i == parts1.length && specializes(members1))
+ return true;
+ break;
+
+ case MethodType(Symbol[] ps1, Type res1):
+ switch (this) {
+ case MethodType(Symbol[] ps, Type res):
+ if (ps.length != ps1.length) return false;
+ for (int i = 0; i < ps.length; i++) {
+ Symbol p1 = ps1[i];
+ Symbol p = ps[i];
+ if (!p1.type().isSameAs(p.type()) ||
+ (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED)))
+ return false;
+ }
+ return res.isSubType(res1);
+ }
+ break;
+
+ case PolyType(Symbol[] ps1, Type res1):
+ switch (this) {
+ case PolyType(Symbol[] ps, Type res):
+ if (ps.length != ps1.length) return false;
+ for (int i = 0; i < ps.length; i++)
+ if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) ||
+ !ps[i].loBound().isSameAs(ps1[i].loBound().subst(ps1, ps)))
+ return false;
+ return res.isSubType(res1.subst(ps1, ps));
+ }
+ break;
+
+ case OverloadedType(Symbol[] alts1, Type[] alttypes1):
+ for (int i = 0; i < alttypes1.length; i++) {
+ if (!isSubType(alttypes1[i]))
+ return false;
+ }
+ return true;
+
+ case UnboxedType(int tag1):
+ switch (this) {
+ case UnboxedType(int tag):
+ return tag == tag1 ||
(tag < tag1 && tag1 <= DOUBLE && tag1 != CHAR);
- }
- break;
-
- case UnboxedArrayType(UnboxedType(int tag1)):
- switch (this) {
- case UnboxedArrayType(UnboxedType(int tag)):
- return tag1 == tag;
- }
- break;
-
- case UnboxedArrayType(Type elemtp1):
- switch (this) {
- case UnboxedArrayType(Type elemtp):
- return elemtp.isSubType(elemtp1);
- }
- break;
-
- case TypeVar(Type origin, Constraint constr):
- //todo: should we test for equality with origin?
- if (constr.inst != NoType) {
- return this.isSubType(constr.inst);
- } else {
- constr.lobounds = new List(this, constr.lobounds);
- return true;
- }
-
- default:
- throw new ApplicationError(this + " <: " + that);
- }
-
- switch (this) {
- case NoType:
- return false;
- case ThisType(_):
- case SingleType(_, _):
- if (this.singleDeref().isSubType(that)) return true;
- break;
- case ConstantType(_, Object value):
- if (this.singleDeref().isSubType(that)) return true;
- break;
- case TypeVar(Type origin, Constraint constr):
- if (constr.inst != NoType) {
- return constr.inst.isSubType(that);
- } else {
- constr.hibounds = new List(that, constr.hibounds);
- return true;
- }
-
- case TypeRef(_, Symbol sym, Type[] args):
- switch (that) {
- case TypeRef(Type pre1, Symbol sym1, _):
- if (sym1.kind == TYPE && this.isSubType(that.loBound()))
- return true;
- }
- if (sym.kind == ALIAS && sym.typeParams().length == args.length)
- return this.unalias().isSubType(that);
- else if (sym == Global.instance.definitions.ALL_CLASS)
- return that.isSubType(Global.instance.definitions.ANY_TYPE());
- else if (sym == Global.instance.definitions.ALLREF_CLASS)
- return
- that.symbol() == Global.instance.definitions.ANY_CLASS ||
- (that.symbol() != Global.instance.definitions.ALL_CLASS &&
- that.isSubType(Global.instance.definitions.ANYREF_TYPE()));
- break;
-
- case OverloadedType(Symbol[] alts, Type[] alttypes):
- for (int i = 0; i < alttypes.length; i++) {
- if (alttypes[i].isSubType(that)) return true;
- }
- break;
-
- case CompoundType(Type[] parts, Scope members):
- int i = 0;
- while (i < parts.length) {
- if (parts[i].isSubType(that)) return true;
- i++;
- }
- break;
-
- case UnboxedArrayType(_):
+ }
+ break;
+
+ case UnboxedArrayType(UnboxedType(int tag1)):
+ switch (this) {
+ case UnboxedArrayType(UnboxedType(int tag)):
+ return tag1 == tag;
+ }
+ break;
+
+ case UnboxedArrayType(Type elemtp1):
+ switch (this) {
+ case UnboxedArrayType(Type elemtp):
+ return elemtp.isSubType(elemtp1);
+ }
+ break;
+
+ case TypeVar(Type origin, Constraint constr):
+ //todo: should we test for equality with origin?
+ if (constr.inst != NoType) {
+ return this.isSubType(constr.inst);
+ } else {
+ constr.lobounds = new List(this, constr.lobounds);
+ return true;
+ }
+
+ default:
+ throw new ApplicationError(this + " <: " + that);
+ }
+
+ switch (this) {
+ case NoType:
+ return false;
+ case ThisType(_):
+ case SingleType(_, _):
+ if (this.singleDeref().isSubType(that)) return true;
+ break;
+ case ConstantType(_, Object value):
+ if (this.singleDeref().isSubType(that)) return true;
+ break;
+ case TypeVar(Type origin, Constraint constr):
+ if (constr.inst != NoType) {
+ return constr.inst.isSubType(that);
+ } else {
+ constr.hibounds = new List(that, constr.hibounds);
+ return true;
+ }
+
+ case TypeRef(_, Symbol sym, Type[] args):
+ switch (that) {
+ case TypeRef(Type pre1, Symbol sym1, _):
+ if (sym1.kind == TYPE && this.isSubType(that.loBound()))
+ return true;
+ }
+ if (sym.kind == ALIAS && sym.typeParams().length == args.length)
+ return this.unalias().isSubType(that);
+ else if (sym == Global.instance.definitions.ALL_CLASS)
+ return that.isSubType(Global.instance.definitions.ANY_TYPE());
+ else if (sym == Global.instance.definitions.ALLREF_CLASS)
+ return
+ that.symbol() == Global.instance.definitions.ANY_CLASS ||
+ (that.symbol() != Global.instance.definitions.ALL_CLASS &&
+ that.isSubType(Global.instance.definitions.ANYREF_TYPE()));
+ break;
+
+ case OverloadedType(Symbol[] alts, Type[] alttypes):
+ for (int i = 0; i < alttypes.length; i++) {
+ if (alttypes[i].isSubType(that)) return true;
+ }
+ break;
+
+ case CompoundType(Type[] parts, Scope members):
+ int i = 0;
+ while (i < parts.length) {
+ if (parts[i].isSubType(that)) return true;
+ i++;
+ }
+ break;
+
+ case UnboxedArrayType(_):
if (Global.instance.definitions.JAVA_OBJECT_TYPE().isSubType(that))
return true;
// !!! we should probably also test for Clonable, Serializable, ...
- }
+ }
- switch (that) {
- case TypeRef(_, Symbol sym1, Type[] args):
- if (sym1.kind == ALIAS && sym1.typeParams().length == args.length)
- return this.isSubType(that.unalias());
- break;
- }
+ switch (that) {
+ case TypeRef(_, Symbol sym1, Type[] args):
+ if (sym1.kind == ALIAS && sym1.typeParams().length == args.length)
+ return this.isSubType(that.unalias());
+ break;
+ }
- return false;
+ return false;
}
/** Are types `these' subtypes of corresponding types `those'?
*/
public static boolean isSubType(Type[] these, Type[] those) {
- if (these.length != those.length) return false;
- for (int i = 0; i < these.length; i++) {
- if (!these[i].isSubType(those[i])) return false;
- }
- return true;
+ if (these.length != those.length) return false;
+ for (int i = 0; i < these.length; i++) {
+ if (!these[i].isSubType(those[i])) return false;
+ }
+ return true;
}
/** Are types `these' arguments types conforming to corresponding types `those'?
*/
static boolean isSubArgs(Type[] these, Type[] those, Symbol[] tparams) {
- if (these.length != those.length) return false;
- for (int i = 0; i < these.length; i++) {
- if ((tparams[i].flags & COVARIANT) != 0) {
- if (!these[i].isSubType(those[i])) return false;
- } else if ((tparams[i].flags & CONTRAVARIANT) != 0) {
- //System.out.println("contra: " + these[i] + " " + those[i] + " " + those[i].isSubType(these[i]));//DEBUG
- if (!those[i].isSubType(these[i])) return false;
- } else {
- if (!these[i].isSameAs(those[i])) return false;
- }
- }
- return true;
+ if (these.length != those.length) return false;
+ for (int i = 0; i < these.length; i++) {
+ if ((tparams[i].flags & COVARIANT) != 0) {
+ if (!these[i].isSubType(those[i])) return false;
+ } else if ((tparams[i].flags & CONTRAVARIANT) != 0) {
+ //System.out.println("contra: " + these[i] + " " + those[i] + " " + those[i].isSubType(these[i]));//DEBUG
+ if (!those[i].isSubType(these[i])) return false;
+ } else {
+ if (!these[i].isSameAs(those[i])) return false;
+ }
+ }
+ return true;
}
public static boolean isSubSet(Type[] alts, Type[] alts1) {
- for (int i = 0; i < alts.length; i++) {
- int j = 0;
- while (j < alts1.length && !alts1[j].isSameAs(alts[i])) j++;
- if (j == alts1.length) return false;
- }
- return true;
+ for (int i = 0; i < alts.length; i++) {
+ int j = 0;
+ while (j < alts1.length && !alts1[j].isSameAs(alts[i])) j++;
+ if (j == alts1.length) return false;
+ }
+ return true;
}
/** Does this type implement all symbols in scope `s' with same or stronger types?
*/
public boolean specializes(Scope s) {
- for (Scope.SymbolIterator it = s.iterator(true); it.hasNext();) {
- if (!specializes(it.next())) return false;
- }
- return true;
+ for (Scope.SymbolIterator it = s.iterator(true); it.hasNext();) {
+ if (!specializes(it.next())) return false;
+ }
+ return true;
}
/** Does this type implement symbol `sym1' with same or stronger type?
*/
public boolean specializes(Symbol sym1) {
- if (explainSwitch) {
- for (int i = 0; i < indent; i++) System.out.print(" ");
- System.out.println(this + " specializes " + sym1 + "?");
- indent++;
- }
- boolean result = specializes0(sym1);
- if (explainSwitch) {
- indent--;
- for (int i = 0; i < indent; i++) System.out.print(" ");
- System.out.println(result);
- }
- return result;
+ if (explainSwitch) {
+ for (int i = 0; i < indent; i++) System.out.print(" ");
+ System.out.println(this + " specializes " + sym1 + "?");
+ indent++;
+ }
+ boolean result = specializes0(sym1);
+ if (explainSwitch) {
+ indent--;
+ for (int i = 0; i < indent; i++) System.out.print(" ");
+ System.out.println(result);
+ }
+ return result;
}
private boolean specializes0(Symbol sym1) {
- Type self = narrow();
- Symbol[] tparams = symbol().typeParams();
- Type[] targs = typeArgs();
- Symbol sym = lookup(sym1.name);
- return
- sym.kind != NONE &&
- (sym == sym1
- ||
- (sym.kind == sym1.kind || sym1.kind == TYPE) &&
- self.memberInfo(sym).subst(tparams, targs)
- .isSubType(sym1.info().substThis(sym1.owner(), self)) &&
- sym1.loBound().substThis(sym1.owner(), self)
- .isSubType(self.memberLoBound(sym).subst(tparams, targs))
- ||
- (sym.kind == TYPE && sym1.kind == ALIAS &&
- sym1.info().unalias().isSameAs(sym.type())));
+ Type self = narrow();
+ Symbol[] tparams = symbol().typeParams();
+ Type[] targs = typeArgs();
+ Symbol sym = lookup(sym1.name);
+ return
+ sym.kind != NONE &&
+ (sym == sym1
+ ||
+ (sym.kind == sym1.kind || sym1.kind == TYPE) &&
+ self.memberInfo(sym).subst(tparams, targs)
+ .isSubType(sym1.info().substThis(sym1.owner(), self)) &&
+ sym1.loBound().substThis(sym1.owner(), self)
+ .isSubType(self.memberLoBound(sym).subst(tparams, targs))
+ ||
+ (sym.kind == TYPE && sym1.kind == ALIAS &&
+ sym1.info().unalias().isSameAs(sym.type())));
}
/** Is this type the same as that type?
*/
public boolean isSameAs(Type that) {
- if (explainSwitch) {
- for (int i = 0; i < indent; i++) System.out.print(" ");
- System.out.println(this + " = " + that + "?");
- indent++;
- }
- boolean result = isSameAs0(that);
- if (explainSwitch) {
- indent--;
- for (int i = 0; i < indent; i++) System.out.print(" ");
- System.out.println(result);
- }
- return result;
+ if (explainSwitch) {
+ for (int i = 0; i < indent; i++) System.out.print(" ");
+ System.out.println(this + " = " + that + "?");
+ indent++;
+ }
+ boolean result = isSameAs0(that);
+ if (explainSwitch) {
+ indent--;
+ for (int i = 0; i < indent; i++) System.out.print(" ");
+ System.out.println(result);
+ }
+ return result;
}
public boolean isSameAs0(Type that) {
- if (this == that) return true;
-
- switch (this) {
- case ErrorType:
- case AnyType:
- return true;
-
- case ThisType(Symbol sym):
- switch (that) {
- case ThisType(Symbol sym1):
- return sym == sym1;
- case SingleType(Type pre1, Symbol sym1):
- return sym1.isModule()
- && sym == sym1.moduleClass()
- && sym.owner().thisType().isSameAs(pre1)
- ||
- deAlias(that) != that &&
- this.isSameAs(deAlias(that));
- }
- break;
-
- case SingleType(Type pre, Symbol sym):
- switch (that) {
- case SingleType(Type pre1, Symbol sym1):
- return sym == sym1 && pre.isSameAs(pre1)
- ||
- (deAlias(this) != this || deAlias(that) != that) &&
+ if (this == that) return true;
+
+ switch (this) {
+ case ErrorType:
+ case AnyType:
+ return true;
+
+ case ThisType(Symbol sym):
+ switch (that) {
+ case ThisType(Symbol sym1):
+ return sym == sym1;
+ case SingleType(Type pre1, Symbol sym1):
+ return sym1.isModule()
+ && sym == sym1.moduleClass()
+ && sym.owner().thisType().isSameAs(pre1)
+ ||
+ deAlias(that) != that &&
+ this.isSameAs(deAlias(that));
+ }
+ break;
+
+ case SingleType(Type pre, Symbol sym):
+ switch (that) {
+ case SingleType(Type pre1, Symbol sym1):
+ return sym == sym1 && pre.isSameAs(pre1)
+ ||
+ (deAlias(this) != this || deAlias(that) != that) &&
deAlias(this).isSameAs(deAlias(that));
- case ThisType(Symbol sym1):
- return sym.isModule()
- && sym.moduleClass() == sym1
- && pre.isSameAs(sym1.owner().thisType())
- ||
- deAlias(this) != this &&
- deAlias(this).isSameAs(that);
- }
- break;
-
- case ConstantType(Type base, Object value):
- switch (that) {
- case ConstantType(Type base1, Object value1):
- return base.isSameAs(base1) && value.equals(value1);
- }
- break;
-
- case TypeRef(Type pre, Symbol sym, Type[] args):
- switch (that) {
- case TypeRef(Type pre1, Symbol sym1, Type[] args1):
- if (sym == sym1 && pre.isSameAs(pre1) && isSameAs(args, args1))
- return true;
- }
- break;
-
- case CompoundType(Type[] parts, Scope members):
- switch (that) {
- case CompoundType(Type[] parts1, Scope members1):
- if (parts.length != parts1.length) return false;
- for (int i = 0; i < parts.length; i++)
- if (!parts[i].isSameAs(parts1[i])) return false;
- return isSameAs(members, members1);
- }
- break;
-
- case MethodType(Symbol[] ps, Type res):
- switch (that) {
- case MethodType(Symbol[] ps1, Type res1):
- if (ps.length != ps1.length) return false;
- for (int i = 0; i < ps.length; i++) {
- Symbol p1 = ps1[i];
- Symbol p = ps[i];
- if (!p1.type().isSameAs(p.type()) ||
- (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED)))
- return false;
- }
- return res.isSameAs(res1);
- }
- break;
-
- case PolyType(Symbol[] ps, Type res):
- switch (that) {
- case PolyType(Symbol[] ps1, Type res1):
- if (ps.length != ps1.length) return false;
- for (int i = 0; i < ps.length; i++)
- if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) ||
- !ps1[i].loBound().subst(ps1, ps).isSameAs(ps[i].loBound()))
- return false;
- return res.isSameAs(res1.subst(ps1, ps));
- }
- break;
-
- case OverloadedType(Symbol[] alts, Type[] alttypes):
- switch (that) {
- case OverloadedType(Symbol[] alts1, Type[] alttypes1):
- return isSubSet(alttypes1, alttypes)
- && isSubSet(alttypes, alttypes1);
- }
- break;
-
- case UnboxedType(int kind):
- switch (that) {
- case UnboxedType(int kind1):
- return kind == kind1;
- }
- break;
-
- case UnboxedArrayType(Type elemtp):
- switch (that) {
- case UnboxedArrayType(Type elemtp1):
- return elemtp.isSameAs(elemtp1);
- }
- break;
- }
-
- switch (that) {
- case ErrorType:
- case AnyType:
- return true;
- case NoType:
- return false;
- case TypeVar(Type origin, Constraint constr):
- if (constr.inst != NoType) return constr.inst.isSameAs(this);
- else return constr.instantiate(this.any2typevar());
- }
-
- switch (this) {
- case NoType:
- return false;
- case TypeRef(_, Symbol sym, Type[] args):
- if (sym.kind == ALIAS && sym.typeParams().length == args.length)
- return this.unalias().isSameAs(that);
- break;
- case TypeVar(Type origin, Constraint constr):
- if (constr.inst != NoType) return constr.inst.isSameAs(that);
- else return constr.instantiate(that.any2typevar());
- }
-
- switch (that) {
- case TypeRef(_, Symbol sym, Type[] args):
- if (sym.kind == ALIAS && sym.typeParams().length == args.length)
- return this.isSameAs(that.unalias());
- }
-
- return false;
+ case ThisType(Symbol sym1):
+ return sym.isModule()
+ && sym.moduleClass() == sym1
+ && pre.isSameAs(sym1.owner().thisType())
+ ||
+ deAlias(this) != this &&
+ deAlias(this).isSameAs(that);
+ }
+ break;
+
+ case ConstantType(Type base, Object value):
+ switch (that) {
+ case ConstantType(Type base1, Object value1):
+ return base.isSameAs(base1) && value.equals(value1);
+ }
+ break;
+
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ switch (that) {
+ case TypeRef(Type pre1, Symbol sym1, Type[] args1):
+ if (sym == sym1 && pre.isSameAs(pre1) && isSameAs(args, args1))
+ return true;
+ }
+ break;
+
+ case CompoundType(Type[] parts, Scope members):
+ switch (that) {
+ case CompoundType(Type[] parts1, Scope members1):
+ if (parts.length != parts1.length) return false;
+ for (int i = 0; i < parts.length; i++)
+ if (!parts[i].isSameAs(parts1[i])) return false;
+ return isSameAs(members, members1);
+ }
+ break;
+
+ case MethodType(Symbol[] ps, Type res):
+ switch (that) {
+ case MethodType(Symbol[] ps1, Type res1):
+ if (ps.length != ps1.length) return false;
+ for (int i = 0; i < ps.length; i++) {
+ Symbol p1 = ps1[i];
+ Symbol p = ps[i];
+ if (!p1.type().isSameAs(p.type()) ||
+ (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED)))
+ return false;
+ }
+ return res.isSameAs(res1);
+ }
+ break;
+
+ case PolyType(Symbol[] ps, Type res):
+ switch (that) {
+ case PolyType(Symbol[] ps1, Type res1):
+ if (ps.length != ps1.length) return false;
+ for (int i = 0; i < ps.length; i++)
+ if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) ||
+ !ps1[i].loBound().subst(ps1, ps).isSameAs(ps[i].loBound()))
+ return false;
+ return res.isSameAs(res1.subst(ps1, ps));
+ }
+ break;
+
+ case OverloadedType(Symbol[] alts, Type[] alttypes):
+ switch (that) {
+ case OverloadedType(Symbol[] alts1, Type[] alttypes1):
+ return isSubSet(alttypes1, alttypes)
+ && isSubSet(alttypes, alttypes1);
+ }
+ break;
+
+ case UnboxedType(int kind):
+ switch (that) {
+ case UnboxedType(int kind1):
+ return kind == kind1;
+ }
+ break;
+
+ case UnboxedArrayType(Type elemtp):
+ switch (that) {
+ case UnboxedArrayType(Type elemtp1):
+ return elemtp.isSameAs(elemtp1);
+ }
+ break;
+ }
+
+ switch (that) {
+ case ErrorType:
+ case AnyType:
+ return true;
+ case NoType:
+ return false;
+ case TypeVar(Type origin, Constraint constr):
+ if (constr.inst != NoType) return constr.inst.isSameAs(this);
+ else return constr.instantiate(this.any2typevar());
+ }
+
+ switch (this) {
+ case NoType:
+ return false;
+ case TypeRef(_, Symbol sym, Type[] args):
+ if (sym.kind == ALIAS && sym.typeParams().length == args.length)
+ return this.unalias().isSameAs(that);
+ break;
+ case TypeVar(Type origin, Constraint constr):
+ if (constr.inst != NoType) return constr.inst.isSameAs(that);
+ else return constr.instantiate(that.any2typevar());
+ }
+
+ switch (that) {
+ case TypeRef(_, Symbol sym, Type[] args):
+ if (sym.kind == ALIAS && sym.typeParams().length == args.length)
+ return this.isSameAs(that.unalias());
+ }
+
+ return false;
}
//where
Type deAlias(Type tp) {
- switch (tp) {
- case SingleType(_, _):
- Type tp1 = tp.singleDeref();
- if (tp1.isStable()) return deAlias(tp1);
- }
- return tp;
- }
+ switch (tp) {
+ case SingleType(_, _):
+ Type tp1 = tp.singleDeref();
+ if (tp1.isStable()) return deAlias(tp1);
+ }
+ return tp;
+ }
/** Are types `these' the same as corresponding types `those'?
*/
public static boolean isSameAs(Type[] these, Type[] those) {
- if (these.length != those.length) return false;
- for (int i = 0; i < these.length; i++) {
- if (!these[i].isSameAs(those[i])) return false;
- }
- return true;
+ if (these.length != those.length) return false;
+ for (int i = 0; i < these.length; i++) {
+ if (!these[i].isSameAs(those[i])) return false;
+ }
+ return true;
}
/** Do scopes `s1' and `s2' define he same symbols with the same kinds and infos?
*/
public boolean isSameAs(Scope s1, Scope s2) {
- return isSubScope(s1, s2) && isSubScope(s2, s1);
+ return isSubScope(s1, s2) && isSubScope(s2, s1);
}
/** Does scope `s1' define all symbols of scope `s2' with the same kinds and infos?
*/
private boolean isSubScope(Scope s1, Scope s2) {
- for (Scope.SymbolIterator it = s2.iterator(); it.hasNext(); ) {
- Symbol sym2 = it.next();
- Symbol sym1 = s1.lookup(sym2.name);
- if (sym1.kind != sym2.kind ||
- !sym1.info().isSameAs(
- sym2.info().substThis(
- sym2.owner(), sym1.owner().thisType())) ||
- !sym1.loBound().isSameAs(
- sym2.loBound().substThis(
- sym2.owner(), sym1.owner().thisType())))
- return false;
- }
- return true;
+ for (Scope.SymbolIterator it = s2.iterator(); it.hasNext(); ) {
+ Symbol sym2 = it.next();
+ Symbol sym1 = s1.lookup(sym2.name);
+ if (sym1.kind != sym2.kind ||
+ !sym1.info().isSameAs(
+ sym2.info().substThis(
+ sym2.owner(), sym1.owner().thisType())) ||
+ !sym1.loBound().isSameAs(
+ sym2.loBound().substThis(
+ sym2.owner(), sym1.owner().thisType())))
+ return false;
+ }
+ return true;
}
boolean isSameAsAll(Type[] tps) {
- int i = 1;
- while (i < tps.length && isSameAs(tps[i])) i++;
- return i == tps.length;
+ int i = 1;
+ while (i < tps.length && isSameAs(tps[i])) i++;
+ return i == tps.length;
}
/** Map every occurrence of AnyType to a fresh type variable.
*/
public static Map any2typevarMap = new Map() {
- public Type apply(Type t) { return t.any2typevar(); }
+ public Type apply(Type t) { return t.any2typevar(); }
};
public Type any2typevar() {
- switch (this) {
- case AnyType:
- return TypeVar(this, new Constraint());
- default:
- return any2typevarMap.map(this);
- }
+ switch (this) {
+ case AnyType:
+ return TypeVar(this, new Constraint());
+ default:
+ return any2typevarMap.map(this);
+ }
}
// Closures and Least Upper Bounds ---------------------------------------------------
@@ -2287,17 +2287,17 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* its direct and indirect (pre-) base types, sorted by Symbol.isLess().
*/
public Type[] closure() {
- switch (this.widen().unalias()) {
+ switch (this.widen().unalias()) {
case TypeRef(Type pre, Symbol sym, Type[] args):
- return subst(
- asSeenFrom(sym.closure(), pre, sym.owner()),
- sym.typeParams(), args);
+ return subst(
+ asSeenFrom(sym.closure(), pre, sym.owner()),
+ sym.typeParams(), args);
- case CompoundType(Type[] parts, Scope members):
- Type[][] closures = new Type[parts.length][];
- for (int i = 0; i < parts.length; i++)
- closures[i] = parts[i].closure();
- return union(closures);
+ case CompoundType(Type[] parts, Scope members):
+ Type[][] closures = new Type[parts.length][];
+ for (int i = 0; i < parts.length; i++)
+ closures[i] = parts[i].closure();
+ return union(closures);
default:
return new Type[]{this};
@@ -2309,92 +2309,92 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* is a subtype of the former.
*/
static private Type[] union(Type[][] closures) {
- if (closures.length == 1) return closures[0]; // fast special case
- int[] index = new int[closures.length];
- int totalsize = 0;
- for (int i = 0; i < index.length; i++) {
- index[i] = 0;
- totalsize = totalsize + closures[i].length;
- }
- Type[] res = new Type[totalsize];
- int j = 0;
-
- while (true) {
- // find minimal element
- Type min = null;
- for (int i = 0; i < index.length; i++) {
- if (index[i] < closures[i].length) {
- Type cltype = closures[i][index[i]];
- if (min == null ||
- cltype.symbol().isLess(min.symbol()) ||
- cltype.symbol() == min.symbol()) {
- min = cltype;
- }
- }
- }
- if (min == null) break;
-
- res[j] = min;
- j = j + 1;
-
- // bump all indices that start with minimal element
- for (int i = 0; i < index.length; i++) {
- if (index[i] < closures[i].length &&
- closures[i][index[i]].symbol() == min.symbol())
- index[i] = index[i] + 1;
- }
- }
- Type[] result = new Type[j];
- System.arraycopy(res, 0, result, 0, j);
- return result;
+ if (closures.length == 1) return closures[0]; // fast special case
+ int[] index = new int[closures.length];
+ int totalsize = 0;
+ for (int i = 0; i < index.length; i++) {
+ index[i] = 0;
+ totalsize = totalsize + closures[i].length;
+ }
+ Type[] res = new Type[totalsize];
+ int j = 0;
+
+ while (true) {
+ // find minimal element
+ Type min = null;
+ for (int i = 0; i < index.length; i++) {
+ if (index[i] < closures[i].length) {
+ Type cltype = closures[i][index[i]];
+ if (min == null ||
+ cltype.symbol().isLess(min.symbol()) ||
+ cltype.symbol() == min.symbol()) {
+ min = cltype;
+ }
+ }
+ }
+ if (min == null) break;
+
+ res[j] = min;
+ j = j + 1;
+
+ // bump all indices that start with minimal element
+ for (int i = 0; i < index.length; i++) {
+ if (index[i] < closures[i].length &&
+ closures[i][index[i]].symbol() == min.symbol())
+ index[i] = index[i] + 1;
+ }
+ }
+ Type[] result = new Type[j];
+ System.arraycopy(res, 0, result, 0, j);
+ return result;
}
/** return intersection of non-empty array of closures
*/
static private Type[] intersection(Type[][] closures) {
- if (closures.length == 1) return closures[0]; // fast special case
- int[] index = new int[closures.length];
- Type[] mintypes = new Type[closures.length];
- int minsize = Integer.MAX_VALUE;
- for (int i = 0; i < index.length; i++) {
- index[i] = 0;
- if (closures[i].length < minsize) minsize = closures[i].length;
- }
- Type[] res = new Type[minsize];
- int j = 0;
-
- L:
- while (true) {
- // find minimal element
- Symbol minsym = null;
- for (int i = 0; i < index.length; i++) {
- if (index[i] == closures[i].length) break L;
- Symbol clsym = closures[i][index[i]].symbol();
- if (minsym == null || clsym.isLess(minsym)) minsym = clsym;
- }
-
- boolean agree = true;
- // bump all indices that start with minimal element
- for (int i = 0; i < index.length; i++) {
- Type cltype = closures[i][index[i]];
- if (cltype.symbol() == minsym) {
- mintypes[i] = cltype;
- index[i] = index[i] + 1;
- } else {
- agree = false;
- }
- }
- if (agree) {
- Type mintype = argLub(mintypes);
- if (mintype.symbol().kind == CLASS) {
- res[j] = mintype;
- j = j + 1;
- }
- }
- }
- Type[] result = new Type[j];
- System.arraycopy(res, 0, result, 0, j);
- return result;
+ if (closures.length == 1) return closures[0]; // fast special case
+ int[] index = new int[closures.length];
+ Type[] mintypes = new Type[closures.length];
+ int minsize = Integer.MAX_VALUE;
+ for (int i = 0; i < index.length; i++) {
+ index[i] = 0;
+ if (closures[i].length < minsize) minsize = closures[i].length;
+ }
+ Type[] res = new Type[minsize];
+ int j = 0;
+
+ L:
+ while (true) {
+ // find minimal element
+ Symbol minsym = null;
+ for (int i = 0; i < index.length; i++) {
+ if (index[i] == closures[i].length) break L;
+ Symbol clsym = closures[i][index[i]].symbol();
+ if (minsym == null || clsym.isLess(minsym)) minsym = clsym;
+ }
+
+ boolean agree = true;
+ // bump all indices that start with minimal element
+ for (int i = 0; i < index.length; i++) {
+ Type cltype = closures[i][index[i]];
+ if (cltype.symbol() == minsym) {
+ mintypes[i] = cltype;
+ index[i] = index[i] + 1;
+ } else {
+ agree = false;
+ }
+ }
+ if (agree) {
+ Type mintype = argLub(mintypes);
+ if (mintype.symbol().kind == CLASS) {
+ res[j] = mintype;
+ j = j + 1;
+ }
+ }
+ }
+ Type[] result = new Type[j];
+ System.arraycopy(res, 0, result, 0, j);
+ return result;
}
/** same as lub, but all types are instances of the same class,
@@ -2402,575 +2402,575 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
*/
//todo: catch lubs not within bounds.
static Type argLub(Type[] tps) {
- tps = elimRedundant(tps, true);
- if (tps.length == 1) return tps[0];
-
- Type pre = tps[0].prefix();
- Symbol sym = tps[0].symbol();
- Symbol[] tparams = sym.typeParams();
- Type[] args = new Type[tparams.length];
- Type[][] argss = new Type[args.length][tps.length];
- for (int i = 0; i < tps.length; i++) {
- switch (tps[i]) {
- case TypeRef(Type pre1, Symbol sym1, Type[] args1):
- assert sym == sym1;
- assert args1.length == args.length;
- if (!pre.isSameAs(pre1)) return NoType;
- for (int j = 0; j < args1.length; j++)
- argss[j][i] = args1[j];
- break;
- case ErrorType:
- return ErrorType;
- default:
- assert false : tps[i];
- }
- }
- for (int j = 0; j < args.length; j++) {
- if ((tparams[j].flags & COVARIANT) != 0)
- args[j] = lub(argss[j]);
- else if ((tparams[j].flags & CONTRAVARIANT) != 0)
- args[j] = glb(argss[j]);
- else return NoType;
- }
- return typeRef(pre, sym, args);
+ tps = elimRedundant(tps, true);
+ if (tps.length == 1) return tps[0];
+
+ Type pre = tps[0].prefix();
+ Symbol sym = tps[0].symbol();
+ Symbol[] tparams = sym.typeParams();
+ Type[] args = new Type[tparams.length];
+ Type[][] argss = new Type[args.length][tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case TypeRef(Type pre1, Symbol sym1, Type[] args1):
+ assert sym == sym1;
+ assert args1.length == args.length;
+ if (!pre.isSameAs(pre1)) return NoType;
+ for (int j = 0; j < args1.length; j++)
+ argss[j][i] = args1[j];
+ break;
+ case ErrorType:
+ return ErrorType;
+ default:
+ assert false : tps[i];
+ }
+ }
+ for (int j = 0; j < args.length; j++) {
+ if ((tparams[j].flags & COVARIANT) != 0)
+ args[j] = lub(argss[j]);
+ else if ((tparams[j].flags & CONTRAVARIANT) != 0)
+ args[j] = glb(argss[j]);
+ else return NoType;
+ }
+ return typeRef(pre, sym, args);
}
/** The frontier of a closure C is the minimal set of types such that
* the union of the closures of these types equals C.
*/
static private Type[] frontier(Type[] closure) {
- Type[] front = new Type[closure.length];
- int j = 0;
- for (int i = 0; i < closure.length; i++) {
- int k = 0;
- Type tp = closure[i];
- while (k < j && !front[k].symbol().isSubClass(tp.symbol()))
- k++;
- if (k == j) {
- front[j] = tp;
- j++;
- }
- }
- Type[] result = new Type[j];
- System.arraycopy(front, 0, result, 0, j);
- return result;
+ Type[] front = new Type[closure.length];
+ int j = 0;
+ for (int i = 0; i < closure.length; i++) {
+ int k = 0;
+ Type tp = closure[i];
+ while (k < j && !front[k].symbol().isSubClass(tp.symbol()))
+ k++;
+ if (k == j) {
+ front[j] = tp;
+ j++;
+ }
+ }
+ Type[] result = new Type[j];
+ System.arraycopy(front, 0, result, 0, j);
+ return result;
}
/** remove types that are subtypes of some other type.
*/
static private Type[] elimRedundant(Type[] tps, boolean elimLower) {
- Type.List tl = Type.List.EMPTY;
- int nredundant = 0;
- boolean[] redundant = new boolean[tps.length];
- for (int i = 0; i < tps.length; i++) {
- switch (tps[i]) {
- case ErrorType:
- return new Type[]{ErrorType};
- case MethodType(_, _):
- case PolyType(_, _):
- case OverloadedType(_, _):
- return new Type[]{NoType};
- default:
- assert tps[i].isObjectType(): tps[i];
- for (int j = 0; j < i && !redundant[i]; j++) {
- if (!redundant[j]) {
- if (tps[i].isSubType(tps[j])) {
- redundant[elimLower ? i : j] = true;
- nredundant++;
- } else if (tps[j].isSubType(tps[i])) {
- redundant[elimLower ? j : i] = true;
- nredundant++;
- }
- }
- }
- }
- }
-
- if (nredundant != 0) {
- Type[] tps1 = new Type[tps.length - nredundant];
- int n = 0;
- for (int i = 0; i < tps.length; i++) {
- if (!redundant[i]) tps1[n++] = tps[i];
- }
- return tps1;
- } else {
- return tps;
- }
+ Type.List tl = Type.List.EMPTY;
+ int nredundant = 0;
+ boolean[] redundant = new boolean[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case ErrorType:
+ return new Type[]{ErrorType};
+ case MethodType(_, _):
+ case PolyType(_, _):
+ case OverloadedType(_, _):
+ return new Type[]{NoType};
+ default:
+ assert tps[i].isObjectType(): tps[i];
+ for (int j = 0; j < i && !redundant[i]; j++) {
+ if (!redundant[j]) {
+ if (tps[i].isSubType(tps[j])) {
+ redundant[elimLower ? i : j] = true;
+ nredundant++;
+ } else if (tps[j].isSubType(tps[i])) {
+ redundant[elimLower ? j : i] = true;
+ nredundant++;
+ }
+ }
+ }
+ }
+ }
+
+ if (nredundant != 0) {
+ Type[] tps1 = new Type[tps.length - nredundant];
+ int n = 0;
+ for (int i = 0; i < tps.length; i++) {
+ if (!redundant[i]) tps1[n++] = tps[i];
+ }
+ return tps1;
+ } else {
+ return tps;
+ }
}
/** Return the least upper bound of non-empty array of types `tps'.
*/
public static Type lub(Type[] tps) {
- //System.out.println("lub" + ArrayApply.toString(tps));//DEBUG
-
- if (tps.length == 0) return Global.instance.definitions.ALL_TYPE();
-
- //If all types are method types with same parameters,
- //compute lub of their result types.
- switch (tps[0]) {
- case PolyType(Symbol[] tparams, _):
- return polyLub(tps, tparams);
- case MethodType(Symbol[] vparams, _):
- return methodLub(tps, vparams);
- }
-
- // remove types that are subtypes of some other type.
- tps = elimRedundant(tps, true);
- if (tps.length == 1) return tps[0];
-
- // intersect closures and build frontier.
- Type[][] closures = new Type[tps.length][];
- for (int i = 0; i < tps.length; i++) {
- closures[i] = tps[i].closure();
- }
- Type[] allBaseTypes = intersection(closures);
- Type[] leastBaseTypes = frontier(allBaseTypes);
- assert leastBaseTypes.length > 0 : ArrayApply.toString(tps);
-
- // add refinements where necessary
- Scope members = new Scope();
- Type lubType = compoundType(leastBaseTypes, members);
- Type lubThisType = lubType.narrow();
- //System.out.println("lubtype = " + lubType);//DEBUG
-
- Symbol[] rsyms = new Symbol[tps.length];
- Type[] rtps = new Type[tps.length];
- Type[] rlbs = new Type[tps.length];
- for (int i = 0; i < allBaseTypes.length; i++) {
- for (Scope.SymbolIterator it = allBaseTypes[i].members().iterator();
- it.hasNext(); ) {
- Symbol sym = it.next();
- Name name = sym.name;
- if ((sym.flags & PRIVATE) == 0 && lubType.lookup(name) == sym) {
- Type symType = memberTp(lubThisType, sym);
- Type symLoBound = lubThisType.memberLoBound(sym);
- int j = 0;
- while (j < tps.length) {
- rsyms[j] = tps[j].lookupNonPrivate(name);
- if (rsyms[j] == sym) break;
- rtps[j] = memberTp(tps[j], rsyms[j])
- .substThis(tps[j].symbol(), lubThisType);
- rlbs[j] = tps[j].memberLoBound(rsyms[j])
- .substThis(tps[j].symbol(), lubThisType);
- if (rtps[j].isSameAs(symType) &&
- rlbs[j].isSameAs(symLoBound)) break;
- j++;
- }
- if (j == tps.length) {
- Symbol lubSym = lub(rsyms, rtps, rlbs, lubType.symbol());
- if (lubSym.kind != NONE &&
- !(lubSym.kind == sym.kind &&
- lubSym.info().isSameAs(symType) &&
- lubSym.loBound().isSameAs(symType)))
- members.enter(lubSym);
- }
- }
- }
- }
- //System.out.print("lub "); System.out.print(ArrayApply.toString(tps)); System.out.println(" = " + lubType);//DEBUG
- if (leastBaseTypes.length == 1 && members.isEmpty())
- return leastBaseTypes[0];
- else return lubType;
+ //System.out.println("lub" + ArrayApply.toString(tps));//DEBUG
+
+ if (tps.length == 0) return Global.instance.definitions.ALL_TYPE();
+
+ //If all types are method types with same parameters,
+ //compute lub of their result types.
+ switch (tps[0]) {
+ case PolyType(Symbol[] tparams, _):
+ return polyLub(tps, tparams);
+ case MethodType(Symbol[] vparams, _):
+ return methodLub(tps, vparams);
+ }
+
+ // remove types that are subtypes of some other type.
+ tps = elimRedundant(tps, true);
+ if (tps.length == 1) return tps[0];
+
+ // intersect closures and build frontier.
+ Type[][] closures = new Type[tps.length][];
+ for (int i = 0; i < tps.length; i++) {
+ closures[i] = tps[i].closure();
+ }
+ Type[] allBaseTypes = intersection(closures);
+ Type[] leastBaseTypes = frontier(allBaseTypes);
+ assert leastBaseTypes.length > 0 : ArrayApply.toString(tps);
+
+ // add refinements where necessary
+ Scope members = new Scope();
+ Type lubType = compoundType(leastBaseTypes, members);
+ Type lubThisType = lubType.narrow();
+ //System.out.println("lubtype = " + lubType);//DEBUG
+
+ Symbol[] rsyms = new Symbol[tps.length];
+ Type[] rtps = new Type[tps.length];
+ Type[] rlbs = new Type[tps.length];
+ for (int i = 0; i < allBaseTypes.length; i++) {
+ for (Scope.SymbolIterator it = allBaseTypes[i].members().iterator();
+ it.hasNext(); ) {
+ Symbol sym = it.next();
+ Name name = sym.name;
+ if ((sym.flags & PRIVATE) == 0 && lubType.lookup(name) == sym) {
+ Type symType = memberTp(lubThisType, sym);
+ Type symLoBound = lubThisType.memberLoBound(sym);
+ int j = 0;
+ while (j < tps.length) {
+ rsyms[j] = tps[j].lookupNonPrivate(name);
+ if (rsyms[j] == sym) break;
+ rtps[j] = memberTp(tps[j], rsyms[j])
+ .substThis(tps[j].symbol(), lubThisType);
+ rlbs[j] = tps[j].memberLoBound(rsyms[j])
+ .substThis(tps[j].symbol(), lubThisType);
+ if (rtps[j].isSameAs(symType) &&
+ rlbs[j].isSameAs(symLoBound)) break;
+ j++;
+ }
+ if (j == tps.length) {
+ Symbol lubSym = lub(rsyms, rtps, rlbs, lubType.symbol());
+ if (lubSym.kind != NONE &&
+ !(lubSym.kind == sym.kind &&
+ lubSym.info().isSameAs(symType) &&
+ lubSym.loBound().isSameAs(symType)))
+ members.enter(lubSym);
+ }
+ }
+ }
+ }
+ //System.out.print("lub "); System.out.print(ArrayApply.toString(tps)); System.out.println(" = " + lubType);//DEBUG
+ if (leastBaseTypes.length == 1 && members.isEmpty())
+ return leastBaseTypes[0];
+ else return lubType;
}
//where
- private static Type memberTp(Type base, Symbol sym) {
- return sym.kind == CLASS ? base.memberType(sym) : base.memberInfo(sym);
- }
+ private static Type memberTp(Type base, Symbol sym) {
+ return sym.kind == CLASS ? base.memberType(sym) : base.memberInfo(sym);
+ }
private static Type polyLub(Type[] tps, Symbol[] tparams0) {
- Type[][] hiboundss = new Type[tparams0.length][tps.length];
- Type[][] loboundss = new Type[tparams0.length][tps.length];
- Type[] restps = new Type[tps.length];
- for (int i = 0; i < tps.length; i++) {
- switch (tps[i]) {
- case PolyType(Symbol[] tparams, Type restp):
- if (tparams.length == tparams0.length) {
- for (int j = 0; j < tparams0.length; j++) {
- hiboundss[j][i] = tparams[j].info()
- .subst(tparams, tparams0);
- loboundss[j][i] = tparams[j].loBound()
- .subst(tparams, tparams0);
- }
- restps[i] = restp.subst(tparams, tparams0);
- } else {
- return Type.NoType;
- }
- break;
- default:
- return Type.NoType;
- }
- }
- Type[] hibounds = new Type[tparams0.length];
- Type[] lobounds = new Type[tparams0.length];
- for (int j = 0; j < tparams0.length; j++) {
- hibounds[j] = glb(hiboundss[j]);
- lobounds[j] = lub(loboundss[j]);
- }
- Symbol[] tparams = new Symbol[tparams0.length];
- for (int j = 0; j < tparams.length; j++) {
- tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE)
- .setInfo(hibounds[j].subst(tparams0, tparams))
- .setLoBound(lobounds[j].subst(tparams0, tparams));
- }
- return Type.PolyType(tparams, lub(restps).subst(tparams0, tparams));
+ Type[][] hiboundss = new Type[tparams0.length][tps.length];
+ Type[][] loboundss = new Type[tparams0.length][tps.length];
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case PolyType(Symbol[] tparams, Type restp):
+ if (tparams.length == tparams0.length) {
+ for (int j = 0; j < tparams0.length; j++) {
+ hiboundss[j][i] = tparams[j].info()
+ .subst(tparams, tparams0);
+ loboundss[j][i] = tparams[j].loBound()
+ .subst(tparams, tparams0);
+ }
+ restps[i] = restp.subst(tparams, tparams0);
+ } else {
+ return Type.NoType;
+ }
+ break;
+ default:
+ return Type.NoType;
+ }
+ }
+ Type[] hibounds = new Type[tparams0.length];
+ Type[] lobounds = new Type[tparams0.length];
+ for (int j = 0; j < tparams0.length; j++) {
+ hibounds[j] = glb(hiboundss[j]);
+ lobounds[j] = lub(loboundss[j]);
+ }
+ Symbol[] tparams = new Symbol[tparams0.length];
+ for (int j = 0; j < tparams.length; j++) {
+ tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE)
+ .setInfo(hibounds[j].subst(tparams0, tparams))
+ .setLoBound(lobounds[j].subst(tparams0, tparams));
+ }
+ return Type.PolyType(tparams, lub(restps).subst(tparams0, tparams));
}
private static Type methodLub(Type[] tps, Symbol[] vparams0) {
- Type[] restps = new Type[tps.length];
- for (int i = 0; i < tps.length; i++) {
- switch (tps[i]) {
- case MethodType(Symbol[] vparams, Type restp):
- if (vparams.length != vparams0.length)
- return Type.NoType;
- for (int j = 0; j < vparams.length; j++)
- if (!vparams[j].type().isSameAs(vparams0[j].type()) ||
- (vparams[j].flags & (DEF | REPEATED)) !=
- (vparams0[j].flags & (DEF | REPEATED)))
- return Type.NoType;
- restps[i] = restp;
- }
- }
- Symbol[] vparams = new Symbol[vparams0.length];
- for (int j = 0; j < vparams.length; j++) {
- vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE);
- }
- return Type.MethodType(vparams, lub(restps));
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case MethodType(Symbol[] vparams, Type restp):
+ if (vparams.length != vparams0.length)
+ return Type.NoType;
+ for (int j = 0; j < vparams.length; j++)
+ if (!vparams[j].type().isSameAs(vparams0[j].type()) ||
+ (vparams[j].flags & (DEF | REPEATED)) !=
+ (vparams0[j].flags & (DEF | REPEATED)))
+ return Type.NoType;
+ restps[i] = restp;
+ }
+ }
+ Symbol[] vparams = new Symbol[vparams0.length];
+ for (int j = 0; j < vparams.length; j++) {
+ vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE);
+ }
+ return Type.MethodType(vparams, lub(restps));
}
private static Symbol lub(Symbol[] syms, Type[] tps, Type[] lbs, Symbol owner) {
- //System.out.println("lub" + ArrayApply.toString(syms));//DEBUG
- int lubKind = syms[0].kind;
- for (int i = 1; i < syms.length; i++) {
- Symbol sym = syms[i];
- if (sym.kind == ERROR) return Symbol.NONE;
- if (sym.isType() && sym.kind != lubKind) lubKind = TYPE;
- }
- if (lubKind == syms[0].kind && tps[0].isSameAsAll(tps)) {
- return syms[0].cloneSymbol();
- }
-
- Type lubType = lub(tps);
- if (lubType == Type.NoType) return Symbol.NONE;
- Symbol lubSym;
- switch (lubKind) {
- case VAL:
- lubSym = new TermSymbol(syms[0].pos, syms[0].name, owner, 0);
- break;
- case TYPE: case ALIAS: case CLASS:
- lubSym = new AbsTypeSymbol(syms[0].pos, syms[0].name, owner, 0);
- lubSym.setLoBound(glb(lbs));
- break;
- default:
- throw new ApplicationError();
- }
- lubSym.setInfo(lubType.setOwner(lubSym));
- return lubSym;
+ //System.out.println("lub" + ArrayApply.toString(syms));//DEBUG
+ int lubKind = syms[0].kind;
+ for (int i = 1; i < syms.length; i++) {
+ Symbol sym = syms[i];
+ if (sym.kind == ERROR) return Symbol.NONE;
+ if (sym.isType() && sym.kind != lubKind) lubKind = TYPE;
+ }
+ if (lubKind == syms[0].kind && tps[0].isSameAsAll(tps)) {
+ return syms[0].cloneSymbol();
+ }
+
+ Type lubType = lub(tps);
+ if (lubType == Type.NoType) return Symbol.NONE;
+ Symbol lubSym;
+ switch (lubKind) {
+ case VAL:
+ lubSym = new TermSymbol(syms[0].pos, syms[0].name, owner, 0);
+ break;
+ case TYPE: case ALIAS: case CLASS:
+ lubSym = new AbsTypeSymbol(syms[0].pos, syms[0].name, owner, 0);
+ lubSym.setLoBound(glb(lbs));
+ break;
+ default:
+ throw new ApplicationError();
+ }
+ lubSym.setInfo(lubType.setOwner(lubSym));
+ return lubSym;
}
public static Type glb(Type[] tps) {
- if (tps.length == 0) return Global.instance.definitions.ANY_TYPE();
-
- // step one: eliminate redunandant types; return if one one is left
- tps = elimRedundant(tps, false);
- if (tps.length == 1) return tps[0];
-
- // step two: build arrays of all typerefs and all refinements
- Type.List treftl = Type.List.EMPTY;
- Type.List comptl = Type.List.EMPTY;
- for (int i = 0; i < tps.length; i++) {
- switch (tps[i]) {
- case TypeRef(_, _, _):
- treftl = new Type.List(tps[i], treftl);
- break;
- case CompoundType(Type[] parents, Scope members):
- if (!members.isEmpty())
- comptl = new Type.List(tps[i], comptl);
- for (int j = 0; j < parents.length; j++)
- treftl = new Type.List(parents[j], treftl);
- break;
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return Global.instance.definitions.ALL_TYPE();
- }
- }
-
- CompoundType glbType = compoundType(Type.EMPTY_ARRAY, new Scope());
- Type glbThisType = glbType.narrow();
-
- // step 3: compute glb of all refinements.
- Scope members = Scope.EMPTY;
- if (comptl != List.EMPTY) {
- Type[] comptypes = comptl.toArrayReverse();
- Scope[] refinements = new Scope[comptypes.length];
- for (int i = 0; i < comptypes.length; i++)
- refinements[i] = comptypes[i].members();
- if (!setGlb(glbType.members, refinements, glbThisType)) {
- // refinements don't have lower bound, so approximate
- // by AllRef
- glbType.members = Scope.EMPTY;
- treftl = new Type.List(
- Global.instance.definitions.ALLREF_TYPE(), treftl);
- }
- }
-
- // eliminate redudant typerefs
- Type[] treftypes = elimRedundant(treftl.toArrayReverse(), false);
- if (treftypes.length != 1 || !glbType.members.isEmpty()) {
- // step 4: replace all abstract types by their lower bounds.
- boolean hasAbstract = false;
- for (int i = 0; i < treftypes.length; i++) {
- if (treftypes[i].unalias().symbol().kind == TYPE)
- hasAbstract = true;
- }
- if (hasAbstract) {
- treftl = Type.List.EMPTY;
- for (int i = 0; i < treftypes.length; i++) {
- if (treftypes[i].unalias().symbol().kind == TYPE)
- treftl = new Type.List(treftypes[i].loBound(), treftl);
- else
- treftl = new Type.List(treftypes[i], treftl);
- }
- treftypes = elimRedundant(treftl.toArrayReverse(), false);
- }
- }
-
- if (treftypes.length != 1) {
- // step 5: if there are conflicting instantiations of same
- // class, replace them by lub/glb of arguments or lower bound.
- Type lb = NoType;
- for (int i = 0;
- i < treftypes.length &&
- lb.symbol() != Global.instance.definitions.ALL_CLASS;
- i++) {
- for (int j = 0; j < i; j++) {
- if (treftypes[j].symbol() == treftypes[i].symbol())
- lb = argGlb(treftypes[j], treftypes[i]);
- }
- }
- if (lb != NoType) return lb;
- }
-
- if (treftypes.length == 1 && glbType.members.isEmpty()) {
- return treftypes[0];
- } else {
- glbType.parts = treftypes;
- return glbType;
- }
+ if (tps.length == 0) return Global.instance.definitions.ANY_TYPE();
+
+ // step one: eliminate redunandant types; return if one one is left
+ tps = elimRedundant(tps, false);
+ if (tps.length == 1) return tps[0];
+
+ // step two: build arrays of all typerefs and all refinements
+ Type.List treftl = Type.List.EMPTY;
+ Type.List comptl = Type.List.EMPTY;
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case TypeRef(_, _, _):
+ treftl = new Type.List(tps[i], treftl);
+ break;
+ case CompoundType(Type[] parents, Scope members):
+ if (!members.isEmpty())
+ comptl = new Type.List(tps[i], comptl);
+ for (int j = 0; j < parents.length; j++)
+ treftl = new Type.List(parents[j], treftl);
+ break;
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return Global.instance.definitions.ALL_TYPE();
+ }
+ }
+
+ CompoundType glbType = compoundType(Type.EMPTY_ARRAY, new Scope());
+ Type glbThisType = glbType.narrow();
+
+ // step 3: compute glb of all refinements.
+ Scope members = Scope.EMPTY;
+ if (comptl != List.EMPTY) {
+ Type[] comptypes = comptl.toArrayReverse();
+ Scope[] refinements = new Scope[comptypes.length];
+ for (int i = 0; i < comptypes.length; i++)
+ refinements[i] = comptypes[i].members();
+ if (!setGlb(glbType.members, refinements, glbThisType)) {
+ // refinements don't have lower bound, so approximate
+ // by AllRef
+ glbType.members = Scope.EMPTY;
+ treftl = new Type.List(
+ Global.instance.definitions.ALLREF_TYPE(), treftl);
+ }
+ }
+
+ // eliminate redudant typerefs
+ Type[] treftypes = elimRedundant(treftl.toArrayReverse(), false);
+ if (treftypes.length != 1 || !glbType.members.isEmpty()) {
+ // step 4: replace all abstract types by their lower bounds.
+ boolean hasAbstract = false;
+ for (int i = 0; i < treftypes.length; i++) {
+ if (treftypes[i].unalias().symbol().kind == TYPE)
+ hasAbstract = true;
+ }
+ if (hasAbstract) {
+ treftl = Type.List.EMPTY;
+ for (int i = 0; i < treftypes.length; i++) {
+ if (treftypes[i].unalias().symbol().kind == TYPE)
+ treftl = new Type.List(treftypes[i].loBound(), treftl);
+ else
+ treftl = new Type.List(treftypes[i], treftl);
+ }
+ treftypes = elimRedundant(treftl.toArrayReverse(), false);
+ }
+ }
+
+ if (treftypes.length != 1) {
+ // step 5: if there are conflicting instantiations of same
+ // class, replace them by lub/glb of arguments or lower bound.
+ Type lb = NoType;
+ for (int i = 0;
+ i < treftypes.length &&
+ lb.symbol() != Global.instance.definitions.ALL_CLASS;
+ i++) {
+ for (int j = 0; j < i; j++) {
+ if (treftypes[j].symbol() == treftypes[i].symbol())
+ lb = argGlb(treftypes[j], treftypes[i]);
+ }
+ }
+ if (lb != NoType) return lb;
+ }
+
+ if (treftypes.length == 1 && glbType.members.isEmpty()) {
+ return treftypes[0];
+ } else {
+ glbType.parts = treftypes;
+ return glbType;
+ }
}
private static Type argGlb(Type tp1, Type tp2) {
- switch (tp1) {
- case TypeRef(Type pre1, Symbol sym1, Type[] args1):
- switch (tp2) {
- case TypeRef(Type pre2, Symbol sym2, Type[] args2):
- assert sym1 == sym2;
- if (pre1.isSameAs(pre2)) {
- Symbol[] tparams = sym1.typeParams();
- Type[] args = new Type[tparams.length];
- for (int i = 0; i < tparams.length; i++) {
- if (args1[i].isSameAs(args2[i]))
- args[i] = args1[i];
- else if ((tparams[i].flags & COVARIANT) != 0)
- args[i]= lub(new Type[]{args1[i], args2[i]});
- else if ((tparams[i].flags & CONTRAVARIANT) != 0)
- args[i]= glb(new Type[]{args1[i], args2[i]});
- else
- return glb(new Type[]{tp1.loBound(), tp2.loBound()});
- }
- return typeRef(pre1, sym1, args);
- }
- }
- }
- return glb(new Type[]{tp1.loBound(), tp2.loBound()});
+ switch (tp1) {
+ case TypeRef(Type pre1, Symbol sym1, Type[] args1):
+ switch (tp2) {
+ case TypeRef(Type pre2, Symbol sym2, Type[] args2):
+ assert sym1 == sym2;
+ if (pre1.isSameAs(pre2)) {
+ Symbol[] tparams = sym1.typeParams();
+ Type[] args = new Type[tparams.length];
+ for (int i = 0; i < tparams.length; i++) {
+ if (args1[i].isSameAs(args2[i]))
+ args[i] = args1[i];
+ else if ((tparams[i].flags & COVARIANT) != 0)
+ args[i]= lub(new Type[]{args1[i], args2[i]});
+ else if ((tparams[i].flags & CONTRAVARIANT) != 0)
+ args[i]= glb(new Type[]{args1[i], args2[i]});
+ else
+ return glb(new Type[]{tp1.loBound(), tp2.loBound()});
+ }
+ return typeRef(pre1, sym1, args);
+ }
+ }
+ }
+ return glb(new Type[]{tp1.loBound(), tp2.loBound()});
}
/** Set scope `result' to glb of scopes `ss'. Return true iff succeeded.
*/
private static boolean setGlb(Scope result, Scope[] ss, Type glbThisType) {
- for (int i = 0; i < ss.length; i++)
- for (Scope.SymbolIterator it = ss[i].iterator(); it.hasNext(); )
- if (!addMember(result, it.next(), glbThisType)) return false;
- return true;
+ for (int i = 0; i < ss.length; i++)
+ for (Scope.SymbolIterator it = ss[i].iterator(); it.hasNext(); )
+ if (!addMember(result, it.next(), glbThisType)) return false;
+ return true;
}
/** Add member `sym' to scope `s'. If`s' has already a member with same name,
* overwrite its info/low bound to form glb of both symbols.
*/
private static boolean addMember(Scope s, Symbol sym, Type glbThisType) {
- Type syminfo = sym.info().substThis(sym.owner(), glbThisType);
- Type symlb = sym.loBound().substThis(sym.owner(), glbThisType);
- Scope.Entry e = s.lookupEntry(sym.name);
- if (e == Scope.Entry.NONE) {
- Symbol sym1 = sym.cloneSymbol(glbThisType.symbol());
- sym1.setInfo(syminfo);
- if (sym1.kind == TYPE) sym1.setLoBound(symlb);
- s.enter(sym1);
- } else {
- Type einfo = e.sym.info();
- if (einfo.isSameAs(syminfo)) {
- } else if (einfo.isSubType(syminfo) && sym.kind != ALIAS) {
- } else if (syminfo.isSubType(einfo) && e.sym.kind != ALIAS) {
- e.sym.setInfo(syminfo);
- } else if (sym.kind == VAL && e.sym.kind == VAL ||
- sym.kind == TYPE && e.sym.kind == TYPE) {
- e.sym.setInfo(glb(new Type[]{einfo, syminfo}).setOwner(e.sym));
- } else {
- return false;
- }
- if (e.sym.kind == TYPE && sym.kind == TYPE) {
- Type elb = e.sym.loBound();
- if (elb.isSameAs(symlb)) {
- } else if (symlb.isSubType(elb)) {
- } else if (elb.isSubType(symlb)) {
- e.sym.setLoBound(symlb);
- } else {
- e.sym.setLoBound(lub(new Type[]{elb, symlb}));
- }
- }
- }
- return true;
+ Type syminfo = sym.info().substThis(sym.owner(), glbThisType);
+ Type symlb = sym.loBound().substThis(sym.owner(), glbThisType);
+ Scope.Entry e = s.lookupEntry(sym.name);
+ if (e == Scope.Entry.NONE) {
+ Symbol sym1 = sym.cloneSymbol(glbThisType.symbol());
+ sym1.setInfo(syminfo);
+ if (sym1.kind == TYPE) sym1.setLoBound(symlb);
+ s.enter(sym1);
+ } else {
+ Type einfo = e.sym.info();
+ if (einfo.isSameAs(syminfo)) {
+ } else if (einfo.isSubType(syminfo) && sym.kind != ALIAS) {
+ } else if (syminfo.isSubType(einfo) && e.sym.kind != ALIAS) {
+ e.sym.setInfo(syminfo);
+ } else if (sym.kind == VAL && e.sym.kind == VAL ||
+ sym.kind == TYPE && e.sym.kind == TYPE) {
+ e.sym.setInfo(glb(new Type[]{einfo, syminfo}).setOwner(e.sym));
+ } else {
+ return false;
+ }
+ if (e.sym.kind == TYPE && sym.kind == TYPE) {
+ Type elb = e.sym.loBound();
+ if (elb.isSameAs(symlb)) {
+ } else if (symlb.isSubType(elb)) {
+ } else if (elb.isSubType(symlb)) {
+ e.sym.setLoBound(symlb);
+ } else {
+ e.sym.setLoBound(lub(new Type[]{elb, symlb}));
+ }
+ }
+ }
+ return true;
}
private static Type polyGlb(Type[] tps, Symbol[] tparams0) {
- Type[][] hiboundss = new Type[tparams0.length][tps.length];
- Type[][] loboundss = new Type[tparams0.length][tps.length];
- Type[] restps = new Type[tps.length];
- for (int i = 0; i < tps.length; i++) {
- switch (tps[i]) {
- case PolyType(Symbol[] tparams, Type restp):
- if (tparams.length == tparams0.length) {
- for (int j = 0; j < tparams0.length; j++) {
- hiboundss[j][i] = tparams[j].info()
- .subst(tparams, tparams0);
- loboundss[j][i] = tparams[j].loBound()
- .subst(tparams, tparams0);
- }
- restps[i] = restp.subst(tparams, tparams0);
- } else {
- return Type.NoType;
- }
- break;
- default:
- return Type.NoType;
- }
- }
- Type[] hibounds = new Type[tparams0.length];
- Type[] lobounds = new Type[tparams0.length];
- for (int j = 0; j < tparams0.length; j++) {
- hibounds[j] = lub(hiboundss[j]);
- lobounds[j] = glb(loboundss[j]);
- }
- Symbol[] tparams = new Symbol[tparams0.length];
- for (int j = 0; j < tparams.length; j++) {
- tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE)
- .setInfo(hibounds[j].subst(tparams0, tparams))
- .setLoBound(lobounds[j].subst(tparams0, tparams));
- }
- return Type.PolyType(tparams, glb(restps).subst(tparams0, tparams));
+ Type[][] hiboundss = new Type[tparams0.length][tps.length];
+ Type[][] loboundss = new Type[tparams0.length][tps.length];
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case PolyType(Symbol[] tparams, Type restp):
+ if (tparams.length == tparams0.length) {
+ for (int j = 0; j < tparams0.length; j++) {
+ hiboundss[j][i] = tparams[j].info()
+ .subst(tparams, tparams0);
+ loboundss[j][i] = tparams[j].loBound()
+ .subst(tparams, tparams0);
+ }
+ restps[i] = restp.subst(tparams, tparams0);
+ } else {
+ return Type.NoType;
+ }
+ break;
+ default:
+ return Type.NoType;
+ }
+ }
+ Type[] hibounds = new Type[tparams0.length];
+ Type[] lobounds = new Type[tparams0.length];
+ for (int j = 0; j < tparams0.length; j++) {
+ hibounds[j] = lub(hiboundss[j]);
+ lobounds[j] = glb(loboundss[j]);
+ }
+ Symbol[] tparams = new Symbol[tparams0.length];
+ for (int j = 0; j < tparams.length; j++) {
+ tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE)
+ .setInfo(hibounds[j].subst(tparams0, tparams))
+ .setLoBound(lobounds[j].subst(tparams0, tparams));
+ }
+ return Type.PolyType(tparams, glb(restps).subst(tparams0, tparams));
}
private static Type methodGlb(Type[] tps, Symbol[] vparams0) {
- Type[] restps = new Type[tps.length];
- for (int i = 0; i < tps.length; i++) {
- switch (tps[i]) {
- case MethodType(Symbol[] vparams, Type restp):
- if (vparams.length != vparams0.length)
- return Type.NoType;
- for (int j = 0; j < vparams.length; j++)
- if (!vparams[i].type().isSameAs(vparams0[i].type()) ||
- (vparams[i].flags & (DEF | REPEATED)) !=
- (vparams0[i].flags & (DEF | REPEATED)))
- return Type.NoType;
- restps[i] = restp;
- }
- }
- Symbol[] vparams = new Symbol[vparams0.length];
- for (int j = 0; j < vparams.length; j++) {
- vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE);
- }
- return Type.MethodType(vparams, glb(restps));
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case MethodType(Symbol[] vparams, Type restp):
+ if (vparams.length != vparams0.length)
+ return Type.NoType;
+ for (int j = 0; j < vparams.length; j++)
+ if (!vparams[i].type().isSameAs(vparams0[i].type()) ||
+ (vparams[i].flags & (DEF | REPEATED)) !=
+ (vparams0[i].flags & (DEF | REPEATED)))
+ return Type.NoType;
+ restps[i] = restp;
+ }
+ }
+ Symbol[] vparams = new Symbol[vparams0.length];
+ for (int j = 0; j < vparams.length; j++) {
+ vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE);
+ }
+ return Type.MethodType(vparams, glb(restps));
}
// Erasure --------------------------------------------------------------------------
public static Map erasureMap = new MapOnlyTypes() {
- public Type apply(Type t) { return t.erasure(); }
+ public Type apply(Type t) { return t.erasure(); }
};
private static final Type[] unboxedType =
- new Type[LastUnboxedTag + 1 - FirstUnboxedTag];
+ new Type[LastUnboxedTag + 1 - FirstUnboxedTag];
private static final Type[] unboxedArrayType =
- new Type[LastUnboxedTag + 1 - FirstUnboxedTag];
+ new Type[LastUnboxedTag + 1 - FirstUnboxedTag];
private static final Name[] unboxedName =
- new Name[LastUnboxedTag + 1 - FirstUnboxedTag];
+ new Name[LastUnboxedTag + 1 - FirstUnboxedTag];
private static final Name[] boxedName =
- new Name[LastUnboxedTag + 1 - FirstUnboxedTag];
+ new Name[LastUnboxedTag + 1 - FirstUnboxedTag];
private static final Name[] boxedFullName =
- new Name[LastUnboxedTag + 1 - FirstUnboxedTag];
+ new Name[LastUnboxedTag + 1 - FirstUnboxedTag];
private static void mkStdClassType(int kind, String unboxedstr, String boxedstr) {
- unboxedType[kind - FirstUnboxedTag] = UnboxedType(kind);
- unboxedArrayType[kind - FirstUnboxedTag] = UnboxedArrayType(unboxedType(kind));
- unboxedName[kind - FirstUnboxedTag] = Name.fromString(unboxedstr);
- boxedName[kind - FirstUnboxedTag] = Name.fromString(boxedstr);
- boxedFullName[kind - FirstUnboxedTag] = Name.fromString("scala." + boxedstr);
+ unboxedType[kind - FirstUnboxedTag] = UnboxedType(kind);
+ unboxedArrayType[kind - FirstUnboxedTag] = UnboxedArrayType(unboxedType(kind));
+ unboxedName[kind - FirstUnboxedTag] = Name.fromString(unboxedstr);
+ boxedName[kind - FirstUnboxedTag] = Name.fromString(boxedstr);
+ boxedFullName[kind - FirstUnboxedTag] = Name.fromString("scala." + boxedstr);
}
static {
- mkStdClassType(BYTE, "byte", "Byte");
- mkStdClassType(SHORT, "short", "Short");
- mkStdClassType(CHAR, "char", "Char");
- mkStdClassType(INT, "int", "Int");
- mkStdClassType(LONG, "long", "Long");
- mkStdClassType(FLOAT, "float", "Float");
- mkStdClassType(DOUBLE, "double", "Double");
- mkStdClassType(BOOLEAN, "boolean", "Boolean");
- mkStdClassType(UNIT, "void", "Unit");
+ mkStdClassType(BYTE, "byte", "Byte");
+ mkStdClassType(SHORT, "short", "Short");
+ mkStdClassType(CHAR, "char", "Char");
+ mkStdClassType(INT, "int", "Int");
+ mkStdClassType(LONG, "long", "Long");
+ mkStdClassType(FLOAT, "float", "Float");
+ mkStdClassType(DOUBLE, "double", "Double");
+ mkStdClassType(BOOLEAN, "boolean", "Boolean");
+ mkStdClassType(UNIT, "void", "Unit");
}
/** Return unboxed type of given kind.
*/
public static Type unboxedType(int kind) {
- return unboxedType[kind - FirstUnboxedTag];
+ return unboxedType[kind - FirstUnboxedTag];
}
/** Return unboxed array type of given element kind.
*/
public static Type unboxedArrayType(int kind) {
- return unboxedArrayType[kind - FirstUnboxedTag];
+ return unboxedArrayType[kind - FirstUnboxedTag];
}
/** Return the name of unboxed type of given kind.
*/
public static Name unboxedName(int kind) {
- return unboxedName[kind - FirstUnboxedTag];
+ return unboxedName[kind - FirstUnboxedTag];
}
/** Return the name of boxed type of given kind.
*/
public static Name boxedName(int kind) {
- return boxedName[kind - FirstUnboxedTag];
+ return boxedName[kind - FirstUnboxedTag];
}
/** Return the full name of boxed type of given kind.
*/
public static Name boxedFullName(int kind) {
- return boxedFullName[kind - FirstUnboxedTag];
+ return boxedFullName[kind - FirstUnboxedTag];
}
/** If type is boxed, return its unboxed equivalent; otherwise return the type
* itself.
*/
public Type unbox() {
- switch (this) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if ((sym.flags & MODUL) == 0) {
- Name fullname = sym.fullName();
- if (fullname == Names.scala_Array && args.length == 1) {
+ switch (this) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if ((sym.flags & MODUL) == 0) {
+ Name fullname = sym.fullName();
+ if (fullname == Names.scala_Array && args.length == 1) {
Type item = args[0].unalias();
Type bound = item.upperBound();
- // todo: check with Philippe if this is what we want.
+ // todo: check with Philippe if this is what we want.
if (item.symbol().isClass() ||
(bound.symbol() != Global.instance.definitions.ANY_CLASS &&
bound.symbol() != Global.instance.definitions.ANYVAL_CLASS))
@@ -2981,72 +2981,72 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
for (int i = 0; i < boxedFullName.length; i++) {
if (boxedFullName[i] == fullname) return unboxedType[i];
}
- }
- }
- return this;
+ }
+ }
+ return this;
}
//where
- private Type upperBound() {
- switch (this) {
- case TypeRef(Type pre, Symbol sym, Type[] args):
- if (sym.kind == ALIAS && sym.typeParams().length == args.length
- || sym.kind == TYPE)
- return pre.memberInfo(sym).upperBound();
- }
- return this;
- }
+ private Type upperBound() {
+ switch (this) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ if (sym.kind == ALIAS && sym.typeParams().length == args.length
+ || sym.kind == TYPE)
+ return pre.memberInfo(sym).upperBound();
+ }
+ return this;
+ }
/** Return the erasure of this type.
*/
public Type erasure() {
- switch (this) {
- case ThisType(_):
- case SingleType(_, _):
- case ConstantType(_, _):
- return singleDeref().erasure();
- case TypeRef(Type pre, Symbol sym, Type[] args):
- switch (sym.kind) {
- case ALIAS: case TYPE:
- return sym.info().asSeenFrom(pre, sym.owner()).erasure();
-
- case CLASS:
+ switch (this) {
+ case ThisType(_):
+ case SingleType(_, _):
+ case ConstantType(_, _):
+ return singleDeref().erasure();
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ switch (sym.kind) {
+ case ALIAS: case TYPE:
+ return sym.info().asSeenFrom(pre, sym.owner()).erasure();
+
+ case CLASS:
if (sym == Global.instance.definitions.UNIT_CLASS) return this;
- Name fullname = sym.fullName();
- if (fullname == Names.java_lang_Object ||
- fullname == Names.scala_AnyRef ||
- fullname == Names.scala_AnyVal ||
- fullname == Names.scala_All ||
- fullname == Names.scala_AllRef)
- return TypeRef(localThisType, Global.instance.definitions.ANY_CLASS, EMPTY_ARRAY);
- else {
- Type this1 = unbox();
- if (this1 != this) return this1;
+ Name fullname = sym.fullName();
+ if (fullname == Names.java_lang_Object ||
+ fullname == Names.scala_AnyRef ||
+ fullname == Names.scala_AnyVal ||
+ fullname == Names.scala_All ||
+ fullname == Names.scala_AllRef)
+ return TypeRef(localThisType, Global.instance.definitions.ANY_CLASS, EMPTY_ARRAY);
+ else {
+ Type this1 = unbox();
+ if (this1 != this) return this1;
else return TypeRef(localThisType, sym, EMPTY_ARRAY);
- }
-
- default: throw new ApplicationError(sym + " has wrong kind: " + sym.kind);
- }
- case CompoundType(Type[] parents, _):
- if (parents.length > 0) return parents[0].erasure();
- else return this;
- case MethodType(Symbol[] params, Type tp):
- Symbol[] params1 = erasureMap.map(params);
- Type tp1 = tp.fullErasure();
- switch (tp1) {
- case MethodType(Symbol[] params2, Type tp2):
- Symbol[] newparams = new Symbol[params1.length + params2.length];
- System.arraycopy(params1, 0, newparams, 0, params1.length);
- System.arraycopy(params2, 0, newparams, params1.length, params2.length);
- return MethodType(newparams, tp2);
- default:
- if (params1 == params && tp1 == tp) return this;
- else return MethodType(params1, tp1);
- }
- case PolyType(_, Type result):
- return result.erasure();
- default:
- return erasureMap.map(this);
- }
+ }
+
+ default: throw new ApplicationError(sym + " has wrong kind: " + sym.kind);
+ }
+ case CompoundType(Type[] parents, _):
+ if (parents.length > 0) return parents[0].erasure();
+ else return this;
+ case MethodType(Symbol[] params, Type tp):
+ Symbol[] params1 = erasureMap.map(params);
+ Type tp1 = tp.fullErasure();
+ switch (tp1) {
+ case MethodType(Symbol[] params2, Type tp2):
+ Symbol[] newparams = new Symbol[params1.length + params2.length];
+ System.arraycopy(params1, 0, newparams, 0, params1.length);
+ System.arraycopy(params2, 0, newparams, params1.length, params2.length);
+ return MethodType(newparams, tp2);
+ default:
+ if (params1 == params && tp1 == tp) return this;
+ else return MethodType(params1, tp1);
+ }
+ case PolyType(_, Type result):
+ return result.erasure();
+ default:
+ return erasureMap.map(this);
+ }
}
/** Return the full erasure of the type. Full erasure is the same
@@ -3067,164 +3067,164 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
}
public String toLongString() {
- String str = toString();
- if (str.endsWith(".type")) return str + " (with underlying type " + widen() + ")";
- else return str;
+ String str = toString();
+ if (str.endsWith(".type")) return str + " (with underlying type " + widen() + ")";
+ else return str;
}
public int hashCode() {
- switch (this) {
- case ErrorType:
- return ERROR;
- case NoType:
- return NOtpe;
- case ThisType(Symbol sym):
- return THIStpe
- ^ (sym.hashCode() * 41);
- case TypeRef(Type pre, Symbol sym, Type[] args):
- return TYPEREFtpe
- ^ (pre.hashCode() * 41)
- ^ (sym.hashCode() * (41*41))
+ switch (this) {
+ case ErrorType:
+ return ERROR;
+ case NoType:
+ return NOtpe;
+ case ThisType(Symbol sym):
+ return THIStpe
+ ^ (sym.hashCode() * 41);
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ return TYPEREFtpe
+ ^ (pre.hashCode() * 41)
+ ^ (sym.hashCode() * (41*41))
^ (hashCode(args) * (41*41*41));
- case SingleType(Type pre, Symbol sym):
- return SINGLEtpe
- ^ (pre.hashCode() * 41)
- ^ (sym.hashCode() * (41*41));
- case ConstantType(Type base, Object value):
- return CONSTANTtpe
- ^ (base.hashCode() * 41)
- ^ (value.hashCode() * (41*41));
- case CompoundType(Type[] parts, Scope members):
- return symbol().hashCode();
- //return COMPOUNDtpe
- // ^ (hashCode(parts) * 41)
- // ^ (members.hashCode() * (41 * 41));
- case MethodType(Symbol[] vparams, Type result):
- int h = METHODtpe;
- for (int i = 0; i < vparams.length; i++)
- h = (h << 4) ^ (vparams[i].flags & SOURCEFLAGS);
- return h
- ^ (hashCode(Symbol.type(vparams)) * 41)
- ^ (result.hashCode() * (41 * 41));
- case PolyType(Symbol[] tparams, Type result):
- return POLYtpe
- ^ (hashCode(tparams) * 41)
- ^ (result.hashCode() * (41 * 41));
- case OverloadedType(Symbol[] alts, Type[] alttypes):
- return OVERLOADEDtpe
- ^ (hashCode(alts) * 41)
- ^ (hashCode(alttypes) * (41 * 41));
- case UnboxedType(int kind):
- return UNBOXEDtpe
- ^ (kind * 41);
- case UnboxedArrayType(Type elemtp):
- return UNBOXEDARRAYtpe
- ^ (elemtp.hashCode() * 41);
- default:
- throw new ApplicationError();
- }
+ case SingleType(Type pre, Symbol sym):
+ return SINGLEtpe
+ ^ (pre.hashCode() * 41)
+ ^ (sym.hashCode() * (41*41));
+ case ConstantType(Type base, Object value):
+ return CONSTANTtpe
+ ^ (base.hashCode() * 41)
+ ^ (value.hashCode() * (41*41));
+ case CompoundType(Type[] parts, Scope members):
+ return symbol().hashCode();
+ //return COMPOUNDtpe
+ // ^ (hashCode(parts) * 41)
+ // ^ (members.hashCode() * (41 * 41));
+ case MethodType(Symbol[] vparams, Type result):
+ int h = METHODtpe;
+ for (int i = 0; i < vparams.length; i++)
+ h = (h << 4) ^ (vparams[i].flags & SOURCEFLAGS);
+ return h
+ ^ (hashCode(Symbol.type(vparams)) * 41)
+ ^ (result.hashCode() * (41 * 41));
+ case PolyType(Symbol[] tparams, Type result):
+ return POLYtpe
+ ^ (hashCode(tparams) * 41)
+ ^ (result.hashCode() * (41 * 41));
+ case OverloadedType(Symbol[] alts, Type[] alttypes):
+ return OVERLOADEDtpe
+ ^ (hashCode(alts) * 41)
+ ^ (hashCode(alttypes) * (41 * 41));
+ case UnboxedType(int kind):
+ return UNBOXEDtpe
+ ^ (kind * 41);
+ case UnboxedArrayType(Type elemtp):
+ return UNBOXEDARRAYtpe
+ ^ (elemtp.hashCode() * 41);
+ default:
+ throw new ApplicationError();
+ }
}
public static int hashCode(Object[] elems) {
- int h = 0;
- for (int i = 0; i < elems.length; i++)
- h = h * 41 + elems[i].hashCode();
- return h;
+ int h = 0;
+ for (int i = 0; i < elems.length; i++)
+ h = h * 41 + elems[i].hashCode();
+ return h;
}
// todo: change in relation to needs.
public boolean equals(Object other) {
- if (this == other) {
- return true;
- } else if (other instanceof Type) {
- Type that = (Type) other;
- switch (this) {
- case ErrorType:
- return that == ErrorType;
- case NoType:
- return that == NoType;
- case ThisType(Symbol sym):
- switch (that) {
- case ThisType(Symbol sym1):
- return sym == sym1;
- default: return false;
- }
- case TypeRef(Type pre, Symbol sym, Type[] args):
- switch (that) {
- case TypeRef(Type pre1, Symbol sym1, Type[] args1):
- return pre.equals(pre1) && sym == sym1 && equals(args, args1);
- default: return false;
- }
- case SingleType(Type pre, Symbol sym):
- switch (that) {
- case SingleType(Type pre1, Symbol sym1):
- return pre.equals(pre1) && sym == sym1;
- default: return false;
- }
- case ConstantType(Type base, Object value):
- switch (that) {
- case ConstantType(Type base1, Object value1):
- return base.equals(base1) && value.equals(value1);
- default: return false;
- }
- case CompoundType(Type[] parts, Scope members):
- switch (that) {
- case CompoundType(Type[] parts1, Scope members1):
- return this.symbol() == that.symbol();
- //return parts.equals(parts1) && members.equals(members1);
- default: return false;
- }
- case MethodType(Symbol[] vparams, Type result):
- switch (that) {
- case MethodType(Symbol[] vparams1, Type result1):
- if (vparams.length != vparams1.length)
- return false;
- for (int i = 0; i < vparams.length; i++)
- if ((vparams[i].flags & SOURCEFLAGS) !=
- (vparams1[i].flags & SOURCEFLAGS))
- return false;
- return
- equals(Symbol.type(vparams), Symbol.type(vparams1)) &&
- result.equals(result1);
- default: return false;
- }
- case PolyType(Symbol[] tparams, Type result):
- switch (that) {
- case PolyType(Symbol[] tparams1, Type result1):
- return equals(tparams, tparams1) && result.equals(result1);
- default: return false;
- }
- case OverloadedType(Symbol[] alts, Type[] alttypes):
- switch (that) {
- case OverloadedType(Symbol[] alts1, Type[] alttypes1):
- return equals(alts, alts1) && equals(alttypes, alttypes1);
- default: return false;
- }
- case UnboxedType(int kind):
- switch (that) {
- case UnboxedType(int kind1):
- return kind == kind1;
- default: return false;
- }
- case UnboxedArrayType(Type elemtp):
- switch (that) {
- case UnboxedArrayType(Type elemtp1):
- return elemtp.equals(elemtp1);
- default: return false;
- }
- default:
- }
- }
- return false;
+ if (this == other) {
+ return true;
+ } else if (other instanceof Type) {
+ Type that = (Type) other;
+ switch (this) {
+ case ErrorType:
+ return that == ErrorType;
+ case NoType:
+ return that == NoType;
+ case ThisType(Symbol sym):
+ switch (that) {
+ case ThisType(Symbol sym1):
+ return sym == sym1;
+ default: return false;
+ }
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ switch (that) {
+ case TypeRef(Type pre1, Symbol sym1, Type[] args1):
+ return pre.equals(pre1) && sym == sym1 && equals(args, args1);
+ default: return false;
+ }
+ case SingleType(Type pre, Symbol sym):
+ switch (that) {
+ case SingleType(Type pre1, Symbol sym1):
+ return pre.equals(pre1) && sym == sym1;
+ default: return false;
+ }
+ case ConstantType(Type base, Object value):
+ switch (that) {
+ case ConstantType(Type base1, Object value1):
+ return base.equals(base1) && value.equals(value1);
+ default: return false;
+ }
+ case CompoundType(Type[] parts, Scope members):
+ switch (that) {
+ case CompoundType(Type[] parts1, Scope members1):
+ return this.symbol() == that.symbol();
+ //return parts.equals(parts1) && members.equals(members1);
+ default: return false;
+ }
+ case MethodType(Symbol[] vparams, Type result):
+ switch (that) {
+ case MethodType(Symbol[] vparams1, Type result1):
+ if (vparams.length != vparams1.length)
+ return false;
+ for (int i = 0; i < vparams.length; i++)
+ if ((vparams[i].flags & SOURCEFLAGS) !=
+ (vparams1[i].flags & SOURCEFLAGS))
+ return false;
+ return
+ equals(Symbol.type(vparams), Symbol.type(vparams1)) &&
+ result.equals(result1);
+ default: return false;
+ }
+ case PolyType(Symbol[] tparams, Type result):
+ switch (that) {
+ case PolyType(Symbol[] tparams1, Type result1):
+ return equals(tparams, tparams1) && result.equals(result1);
+ default: return false;
+ }
+ case OverloadedType(Symbol[] alts, Type[] alttypes):
+ switch (that) {
+ case OverloadedType(Symbol[] alts1, Type[] alttypes1):
+ return equals(alts, alts1) && equals(alttypes, alttypes1);
+ default: return false;
+ }
+ case UnboxedType(int kind):
+ switch (that) {
+ case UnboxedType(int kind1):
+ return kind == kind1;
+ default: return false;
+ }
+ case UnboxedArrayType(Type elemtp):
+ switch (that) {
+ case UnboxedArrayType(Type elemtp1):
+ return elemtp.equals(elemtp1);
+ default: return false;
+ }
+ default:
+ }
+ }
+ return false;
}
public static boolean equals(Object[] elems1, Object[] elems2) {
- if (elems1.length != elems2.length) return false;
- for (int i = 0; i < elems1.length; i++) {
- if (!elems1[i].equals(elems2[i])) return false;
- }
- return true;
+ if (elems1.length != elems2.length) return false;
+ for (int i = 0; i < elems1.length; i++) {
+ if (!elems1[i].equals(elems2[i])) return false;
+ }
+ return true;
}
// Type.List class -----------------------------------------------------------------
@@ -3232,42 +3232,42 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** A class for lists of types.
*/
public static class List {
- public Type head;
- public List tail;
- public List(Type head, List tail) {
- this.head = head; this.tail = tail;
- }
- public int length() {
- return (this == EMPTY) ? 0 : 1 + tail.length();
- }
- public Type[] toArray() {
- Type[] ts = new Type[length()];
- copyToArray(ts, 0, 1);
- return ts;
- }
- public void copyToArray(Type[] ts, int start, int delta) {
- if (this != EMPTY) {
- ts[start] = head;
- tail.copyToArray(ts, start+delta, delta);
- }
- }
- public Type[] toArrayReverse() {
- Type[] ts = new Type[length()];
- copyToArray(ts, ts.length - 1, -1);
- return ts;
- }
-
- public String toString() {
- if (this == EMPTY) return "List()";
- else return head + "::" + tail;
- }
-
- public static List EMPTY = new List(null, null);
-
- public static List append(List l, Type tp) {
- return (l == EMPTY) ? new List(tp, EMPTY)
- : new List(l.head, append(l.tail, tp));
- }
+ public Type head;
+ public List tail;
+ public List(Type head, List tail) {
+ this.head = head; this.tail = tail;
+ }
+ public int length() {
+ return (this == EMPTY) ? 0 : 1 + tail.length();
+ }
+ public Type[] toArray() {
+ Type[] ts = new Type[length()];
+ copyToArray(ts, 0, 1);
+ return ts;
+ }
+ public void copyToArray(Type[] ts, int start, int delta) {
+ if (this != EMPTY) {
+ ts[start] = head;
+ tail.copyToArray(ts, start+delta, delta);
+ }
+ }
+ public Type[] toArrayReverse() {
+ Type[] ts = new Type[length()];
+ copyToArray(ts, ts.length - 1, -1);
+ return ts;
+ }
+
+ public String toString() {
+ if (this == EMPTY) return "List()";
+ else return head + "::" + tail;
+ }
+
+ public static List EMPTY = new List(null, null);
+
+ public static List append(List l, Type tp) {
+ return (l == EMPTY) ? new List(tp, EMPTY)
+ : new List(l.head, append(l.tail, tp));
+ }
}
// Type.Constraint class -------------------------------------------------------
@@ -3276,20 +3276,20 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* of type variables.
*/
public static class Constraint {
- public List lobounds = List.EMPTY;
- public List hibounds = List.EMPTY;
- public Type inst = NoType;
-
- public boolean instantiate(Type tp) {
- for (List l = lobounds; l != List.EMPTY; l = l.tail) {
- if (!l.head.isSubType(tp)) return false;
- }
- for (List l = hibounds; l != List.EMPTY; l = l.tail) {
- if (!tp.isSubType(l.head)) return false;
- }
- inst = tp;
- return true;
- }
+ public List lobounds = List.EMPTY;
+ public List hibounds = List.EMPTY;
+ public Type inst = NoType;
+
+ public boolean instantiate(Type tp) {
+ for (List l = lobounds; l != List.EMPTY; l = l.tail) {
+ if (!l.head.isSubType(tp)) return false;
+ }
+ for (List l = hibounds; l != List.EMPTY; l = l.tail) {
+ if (!tp.isSubType(l.head)) return false;
+ }
+ inst = tp;
+ return true;
+ }
}
// Type.Error class --------------------------------------------------------------
@@ -3297,34 +3297,34 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
/** A class for throwing type errors
*/
public static class Error extends java.lang.Error {
- public String msg;
- public Error(String msg) {
- super(msg);
- this.msg = msg;
- }
+ public String msg;
+ public Error(String msg) {
+ super(msg);
+ this.msg = msg;
+ }
}
public static class Malformed extends Error {
- public Malformed(Type pre, String tp) {
- super("malformed type: " + pre + "#" + tp);
- }
+ public Malformed(Type pre, String tp) {
+ super("malformed type: " + pre + "#" + tp);
+ }
}
/** A class for throwing type errors
*/
public static class VarianceError extends Error {
- public VarianceError(String msg) {
- super(msg);
- }
+ public VarianceError(String msg) {
+ super(msg);
+ }
}
public static void explainTypes(Type found, Type required) {
- if (Global.instance.explaintypes) {
- boolean s = explainSwitch;
- explainSwitch = true;
- found.isSubType(required);
- explainSwitch = s;
- }
+ if (Global.instance.explaintypes) {
+ boolean s = explainSwitch;
+ explainSwitch = true;
+ found.isSubType(required);
+ explainSwitch = s;
+ }
}
}
diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java
index 7de745ee1f..3e1ac9da20 100644
--- a/sources/scalac/symtab/classfile/AttributeParser.java
+++ b/sources/scalac/symtab/classfile/AttributeParser.java
@@ -34,6 +34,8 @@ public class AttributeParser implements ClassfileConstants {
this.parser = parser;
}
+ /** convert an attribute name into an attribute id
+ */
public int nameToId(Name name) {
if (name == SOURCEFILE_N)
return SOURCEFILE_ATTR;
@@ -62,6 +64,9 @@ public class AttributeParser implements ClassfileConstants {
return BAD_ATTR;
}
+ /** read all attributes associated with symbol 'sym' which are
+ * contained in 'attrs'.
+ */
public Symbol readAttributes(Symbol def, Type type, int attrs) {
char nattr = in.nextChar();
for (int i = 0; i < nattr; i++) {
@@ -79,6 +84,8 @@ public class AttributeParser implements ClassfileConstants {
return def;
}
+ /** read a single attribute 'attr' for symbol 'sym' with type 'type'.
+ */
public void readAttribute(Symbol sym, Type type, int attr, int attrLen) {
switch (attr) {
// class attributes
@@ -93,9 +100,9 @@ public class AttributeParser implements ClassfileConstants {
Name name = (Name)pool.readPool(in.nextChar());
int flags = in.nextChar();
if (name != null) {
- inner.owner(outer);
- inner.mangled(name);
- inner.flags = flags;
+ // inner.owner(outer);
+ // inner.mangled(name);
+ // inner.flags = flags;
}
} */
in.skip(attrLen);
@@ -126,9 +133,9 @@ public class AttributeParser implements ClassfileConstants {
sym.flags |= Modifiers.DEPRECATED;
return;
case CONSTANT_VALUE_ATTR:
- // Type ctype = (Type)reader.readPool(in.nextChar());
- // def.type = types.coerce(ctype, def.type);
- in.skip(attrLen);
+ Object constVal = pool.readPool(in.nextChar());
+ //System.out.println(sym.owner() + "." + sym + ": " + constVal + " of type " + constantType(type, constVal));
+ sym.setFirstInfo(constantType(type, constVal));
return;
case META_ATTR:
//System.out.println("parsing meta data for " + sym);
@@ -152,10 +159,45 @@ public class AttributeParser implements ClassfileConstants {
}
}
+ /** return the constant type for the given constant.
+ */
+ Type constantType(Type base, Object value) {
+ if (base.symbol() == parser.global.definitions.BYTE_CLASS)
+ value = new Byte(((Number)value).byteValue());
+ if (base.symbol() == parser.global.definitions.CHAR_CLASS)
+ value = new Character((char)((Number)value).intValue());
+ if (base.symbol() == parser.global.definitions.SHORT_CLASS)
+ value = new Short(((Number)value).shortValue());
+ return Type.ConstantType(base, value);
+ }
+
+ /** return the type of a given constant.
+ */
+ Type typeOfValue(Object value) {
+ if (value instanceof Character)
+ return parser.make.charType();
+ else if (value instanceof Integer)
+ return parser.make.intType();
+ else if (value instanceof Long)
+ return parser.make.longType();
+ else if (value instanceof Float)
+ return parser.make.floatType();
+ else if (value instanceof Double)
+ return parser.make.doubleType();
+ else if (value instanceof String)
+ return parser.global.definitions.JAVA_STRING_CLASS.typeConstructor();
+ else if (value instanceof Boolean)
+ return parser.make.booleanType();
+ else
+ throw new ApplicationError("unknown constant type");
+ }
+
Scope tvars = new Scope();
+ /** a parser class for parsing meta type information in classfiles
+ * generated by pico.
+ */
class MetaParser {
-
Symbol owner;
StringTokenizer scanner;
Type defaultType;
diff --git a/sources/scalac/symtab/classfile/ConstantPool.java b/sources/scalac/symtab/classfile/ConstantPool.java
index 4260b9e6ad..a4113ed9e7 100644
--- a/sources/scalac/symtab/classfile/ConstantPool.java
+++ b/sources/scalac/symtab/classfile/ConstantPool.java
@@ -97,14 +97,11 @@ public class ConstantPool implements ClassfileConstants {
case CONSTANT_UTF8:
poolObj[i] = Name.fromAscii(in.buf, index + 3, in.getChar(index + 1));
break;
-
case CONSTANT_UNICODE:
throw new RuntimeException("can't read unicode strings in classfiles");
-
case CONSTANT_CLASS:
poolObj[i] = classOrType(readExternal(in.getChar(index + 1)));
break;
-
case CONSTANT_FIELDREF: {
//Symbol owner = (Symbol)readPool(in.getChar(index + 1));
//NameAndType nt = (NameAndType)readPool(in.getChar(index + 3));
@@ -112,7 +109,6 @@ public class ConstantPool implements ClassfileConstants {
// .type(sigparser.sigToType(Name.names, nt.sig.index, nt.sig.length()));
throw new RuntimeException("can't read constant_fieldrefs in classfiles");
}
-
case CONSTANT_METHODREF:
case CONSTANT_INTFMETHODREF: {
//Symbol owner = (Symbol)readPool(in.getChar(index + 1));
@@ -121,19 +117,25 @@ public class ConstantPool implements ClassfileConstants {
// .type(sigparser.sigToType(Name.names, nt.sig.index, nt.sig.length()));
throw new RuntimeException("can't read constant_methodrefs in classfiles");
}
-
case CONSTANT_NAMEANDTYPE:
poolObj[i] = new NameAndType((Name)readPool(in.getChar(index + 1)),
readExternal(in.getChar(index + 3)));
break;
-
case CONSTANT_STRING:
+ poolObj[i] = ((Name)readPool(in.getChar(index + 1))).toString();
+ break;
case CONSTANT_INTEGER:
+ poolObj[i] = new Integer(in.getInt(index + 1));
+ break;
case CONSTANT_FLOAT:
+ poolObj[i] = new Float(in.getFloat(index + 1));
+ break;
case CONSTANT_LONG:
+ poolObj[i] = new Long(in.getLong(index + 1));
+ break;
case CONSTANT_DOUBLE:
- throw new RuntimeException("can't read constants in classfiles");
-
+ poolObj[i] = new Double(in.getDouble(index + 1));
+ break;
default:
throw new RuntimeException("bad constant pool tag: " + in.byteAt(index));
}
diff --git a/sources/scalac/transformer/TransMatch.java b/sources/scalac/transformer/TransMatch.java
index 4cea1d9770..5942f28b94 100644
--- a/sources/scalac/transformer/TransMatch.java
+++ b/sources/scalac/transformer/TransMatch.java
@@ -91,25 +91,24 @@ public class TransMatch extends OwnerTransformer {
int i = 0;
while (i < cases.length) {
containsReg = TestRegTraverser.apply(cases[i]) || containsReg;
- Set nilvars = TestRegTraverser.getNilVariables();
- if(!nilvars.isEmpty()) {
- //System.err.println("nilvars present");
- Tree[] newBody = new Tree[ nilvars.size() + 1 ];
- int j=0;
- for( Iterator it = nilvars.iterator(); it.hasNext(); ) {
- Symbol v = (Symbol) it.next();
- newBody[ j++ ] = unit.global.treeGen.ValDef(v,
- unit.global.treeGen.Nil(cases[i].pos));
- }
- newBody[ newBody.length - 1 ] = cases[i].body;
- cases[i].body = unit.global.treeGen.mkBlock( newBody );
- }
- i++;
- }
-
+ Set nilvars = TestRegTraverser.getNilVariables();
+ if(!nilvars.isEmpty()) {
+ //System.err.println("nilvars present");
+ Tree[] newBody = new Tree[ nilvars.size() + 1 ];
+ int j=0;
+ for( Iterator it = nilvars.iterator(); it.hasNext(); ) {
+ Symbol v = (Symbol) it.next();
+ newBody[ j++ ] = unit.global.treeGen.ValDef(v,
+ unit.global.treeGen.Nil(cases[i].pos));
+ }
+ newBody[ newBody.length - 1 ] = cases[i].body;
+ cases[i].body = unit.global.treeGen.mkBlock( newBody );
+ }
+ i++;
+ }
if (containsReg) {
- AlgebraicMatcher am = new AlgebraicMatcher( unit );
- Matcher matcher = new Matcher( currentOwner, root, restpe );
+ AlgebraicMatcher am = new AlgebraicMatcher( unit );
+ Matcher matcher = new Matcher( currentOwner, root, restpe );
am.construct( matcher, cases );
return matcher.tree;
} else {
@@ -117,7 +116,7 @@ public class TransMatch extends OwnerTransformer {
currentOwner, restpe);
pm.enter(cases);
if (global.log()) {
- global.log("internal pattern matching structure");
+ global.log("internal pattern matching structure");
pm.print();
}
return pm.toTree();
diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java
index 9bcddb3e11..4708dd6258 100644
--- a/sources/scalac/transformer/matching/AlgebraicMatcher.java
+++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java
@@ -53,6 +53,10 @@ public class AlgebraicMatcher extends PatternMatcher {
for( int i = 0; i < cases.length; i++ ) {
enter( cases[ i ] );//(CaseDef) cases[i], i);
}
+ if (unit.global.log()) {
+ unit.global.log("internal pattern matching structure");
+ print();
+ }
_m.tree = toTree();
}
diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java
index 99a921e2e4..793cc83a7e 100644
--- a/sources/scalac/transformer/matching/PatternMatcher.java
+++ b/sources/scalac/transformer/matching/PatternMatcher.java
@@ -52,7 +52,7 @@ public class PatternMatcher extends PatternTool {
public PatternMatcher(Unit unit, Tree selector,
Symbol owner, Type resultType) {
super(unit);
- initialize(selector, owner, resultType, true);
+ initialize(selector, owner, resultType, true);
}
/** constructor, used in subclass ALgebraicMatcher
@@ -75,10 +75,10 @@ public class PatternMatcher extends PatternTool {
owner,
Modifiers.MUTABLE);
this.resultVar.setType(resultType);
- this.owner = owner;
+ this.owner = owner;
this.selector = selector;
this.optimize &= (unit.global.target == Global.TARGET_JVM);
- this.doBinding = doBinding;
+ this.doBinding = doBinding;
}
/** pretty printer
@@ -160,8 +160,18 @@ public class PatternMatcher extends PatternTool {
if (patNode.or != null)
print(patNode.or, ind);
break;
- case Body(_, _, Tree[] stats):
- System.out.println(indent + "BODY(" + stats.length + ")");
+ case AltPat(Header header):
+ System.out.println(indent + "-- ALTERNATIVES:");
+ print(header, indent + " * ");
+ print(patNode.and, indent + " * -> ");
+ if (patNode.or != null)
+ print(patNode.or, indent);
+ break;
+ case Body(_, Tree[] guards, Tree[] stats):
+ if ((guards.length == 0) && (stats.length == 0))
+ System.out.println(indent + "true");
+ else
+ System.out.println(indent + "BODY(" + stats.length + ")");
break;
}
}
@@ -187,9 +197,8 @@ public class PatternMatcher extends PatternTool {
target.and = mk.Body(caseDef.pos, env.boundVars(), guard, body);
else if (target.and instanceof Body)
updateBody((Body)target.and, env.boundVars(), guard, body);
- else {
+ else
unit.error(pat.pos, "duplicate case");
- }
}
}
@@ -274,82 +283,81 @@ public class PatternMatcher extends PatternTool {
}
protected boolean isSeqApply( Tree.Apply tree ) {
- return (tree.args.length == 1 &&
- (tree.type.symbol().flags & Modifiers.CASE) == 0);
+ return (tree.args.length == 1 &&
+ (tree.type.symbol().flags & Modifiers.CASE) == 0);
}
protected PatternNode patternNode(Tree tree, Header header, CaseEnv env) {
switch (tree) {
- case Bind(Name name, Typed( Ident( Names.PATTERN_WILDCARD ), Tree tpe)): // little opt. for x@_:Type
- if(header.type.isSubType(tpe.type)) {
- PatternNode node = mk.DefaultPat(tree.pos, tpe.type);
- env.newBoundVar( tree.symbol(), tree.type, header.selector );
- return node;
- } else {
- ConstrPat node = mk.ConstrPat(tree.pos, tpe.type);
- env.newBoundVar( tree.symbol(), tree.type, gen.Ident(tree.pos, node.casted));
- return node;
- }
- case Bind(Name name, Ident( Names.PATTERN_WILDCARD )): // little opt. for x@_
- PatternNode node = mk.DefaultPat(tree.pos, header.type);
- if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD))
- env.newBoundVar(tree.symbol(),tree.type, header.selector);
- return node;
-
- case Bind(Name name, Tree pat):
- PatternNode node = patternNode(pat, header, env);
- if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD))
- env.newBoundVar( tree.symbol(),
- tree.type,
- header.selector);
+ case Bind(Name name, Typed( Ident( Names.PATTERN_WILDCARD ), Tree tpe)): // little opt. for x@_:Type
+ if(header.type.isSubType(tpe.type)) {
+ PatternNode node = mk.DefaultPat(tree.pos, tpe.type);
+ env.newBoundVar( tree.symbol(), tree.type, header.selector );
+ return node;
+ } else {
+ ConstrPat node = mk.ConstrPat(tree.pos, tpe.type);
+ env.newBoundVar( tree.symbol(), tree.type, gen.Ident(tree.pos, node.casted));
+ return node;
+ }
+ case Bind(Name name, Ident( Names.PATTERN_WILDCARD )): // little opt. for x@_
+ PatternNode node = mk.DefaultPat(tree.pos, header.type);
+ if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD))
+ env.newBoundVar(tree.symbol(),tree.type, header.selector);
+ return node;
+
+ case Bind(Name name, Tree pat):
+ PatternNode node = patternNode(pat, header, env);
+ if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD))
+ env.newBoundVar( tree.symbol(),
+ tree.type,
+ header.selector);
+ return node;
+ case Apply(Tree fn, Tree[] args): // pattern with args
+ if(isSeqApply((Apply)tree)) {
+ if (!delegateSequenceMatching) {
+ switch (args[0]) {
+ case Sequence(Tree[] ts):
+ return mk.SequencePat( tree.pos, tree.type, ts.length );
+ }
+ } else {
+ PatternNode res = mk.ConstrPat(tree.pos, tree.type);
+ res.and = mk.Header(tree.pos, header.type, header.selector);
+ res.and.and = mk.SeqContainerPat( tree.pos, tree.type, args[ 0 ] );
+ return res;
+ }
+ } else if ((fn.symbol() != null) && fn.symbol().isStable())
+ return mk.VariablePat(tree.pos, tree);
+ return mk.ConstrPat(tree.pos, tree.type);
+ case Typed(Ident ident, Tree tpe): // variable pattern
+ boolean doTest = header.type.isSubType(tpe.type);
+ PatternNode node = doTest ?
+ mk.DefaultPat(tree.pos, tpe.type)
+ : mk.ConstrPat(tree.pos, tpe.type);
+ if ((env != null) && (ident.symbol() != defs.PATTERN_WILDCARD))
+ switch (node) {
+ case ConstrPat(Symbol casted):
+ env.newBoundVar(
+ ((Tree.Typed)tree).expr.symbol(),
+ tpe.type,
+ gen.Ident(tree.pos, casted));
+ break;
+ default:
+ env.newBoundVar(
+ ((Tree.Typed)tree).expr.symbol(),
+ tpe.type,
+ doTest ? header.selector : gen.Ident(tree.pos, ((ConstrPat) node).casted));
+ }
return node;
- case Apply(Tree fn, Tree[] args): // pattern with args
- if( isSeqApply((Apply) tree ) ) {
- if ( !delegateSequenceMatching ) {
- switch (args[0]) {
- case Sequence(Tree[] ts):
- return mk.SequencePat( tree.pos, tree.type, ts.length );
- }
- } else {
- PatternNode res = mk.ConstrPat(tree.pos, tree.type);
- res.and = mk.Header(tree.pos, header.type, header.selector);
- res.and.and = mk.SeqContainerPat( tree.pos, tree.type, args[ 0 ] );
- return res;
- }
- }
- return mk.ConstrPat(tree.pos, tree.type);
-
- case Typed(Ident ident, Tree tpe): // variable pattern
- boolean doTest = header.type.isSubType(tpe.type);
- PatternNode node = doTest ?
- mk.DefaultPat(tree.pos, tpe.type)
- : mk.ConstrPat(tree.pos, tpe.type);
- if ((env != null) && (ident.symbol() != defs.PATTERN_WILDCARD))
- switch (node) {
- case ConstrPat(Symbol casted):
- env.newBoundVar(
- ((Tree.Typed)tree).expr.symbol(),
- tpe.type,
- gen.Ident(tree.pos, casted));
- break;
- default:
- env.newBoundVar(
- ((Tree.Typed)tree).expr.symbol(),
- tpe.type,
- doTest ? header.selector : gen.Ident(tree.pos, ((ConstrPat) node).casted));
- }
- return node;
- case Ident(Name name): // pattern without args or variable
- if (tree.symbol() == defs.PATTERN_WILDCARD)
+ case Ident(Name name): // pattern without args or variable
+ if (tree.symbol() == defs.PATTERN_WILDCARD)
return mk.DefaultPat(tree.pos, header.type);
else if (tree.symbol().isPrimaryConstructor()) {
- assert false; // this may not happen ?? ----------------- Burak
- return mk.ConstrPat(tree.pos, tree.type);
+ assert false; // this may not happen ?? ----------------- Burak
+ return mk.ConstrPat(tree.pos, tree.type);
} else if (name.isVariable()) {// should be Bind ------------ Burak
- assert false;
+ assert false;
if (env != null)
- env.newBoundVar(
- tree.symbol(),
+ env.newBoundVar(tree.symbol(),
tree.type,
header.selector);
return mk.DefaultPat(tree.pos, header.type);
@@ -368,17 +376,19 @@ public class PatternMatcher extends PatternTool {
} else {
return mk.SeqContainerPat(tree.pos, tree.type, tree);
}
- case Alternative(Tree[] ts): // CAN THIS WORK ?
- assert ts.length > 0;
- PatternNode res = patternNode( ts[ 0 ], header, env );
- for (int i = 1; i < ts.length; i++) {
- res.or = patternNode(ts[i], header, env);
- res = res.or ;
+ case Alternative(Tree[] ts):
+ assert ts.length > 1;
+ PatternNode subroot = mk.ConstrPat(header.pos, header.type);
+ subroot.and = mk.Header(header.pos, header.type, header.selector.duplicate());
+ CaseEnv subenv = new CaseEnv(owner, unit);
+ for (int i = 0; i < ts.length; i++) {
+ PatternNode target = enter1(ts[i], -1, subroot, subroot.symbol(), subenv);
+ target.and = mk.Body(tree.pos);
}
- return res;
+ return mk.AltPat(tree.pos, (Header)subroot.and);
default:
new scalac.ast.printer.TextTreePrinter().print(tree).flush();
- throw new ApplicationError("unit "+unit+" tree"+tree);
+ throw new ApplicationError("unit = " + unit + "; tree = "+tree);
}
}
@@ -603,7 +613,13 @@ public class PatternMatcher extends PatternTool {
PatternNode patNode = root.and;
while (patNode != null) {
PatternNode node = patNode;
- while ((node = node.or) != null)
+ while ((node = node.or) != null) {
+ switch (node) {
+ case ConstantPat(_):
+ break;
+ default:
+ return false;
+ }
switch (node.and) {
case Body(ValDef[][] bound, Tree[] guard, _):
if ((guard.length > 1) ||
@@ -614,6 +630,7 @@ public class PatternMatcher extends PatternTool {
default:
return false;
}
+ }
patNode = patNode.next();
}
return true;
@@ -828,7 +845,12 @@ public class PatternMatcher extends PatternTool {
node = next;
break;
case Body(ValDef[][] bound, Tree[] guard, Tree[] body):
- if (!doBinding) bound = new ValDef[][] { new ValDef[] {} };
+ if ((bound.length == 0) &&
+ (guard.length == 0) &&
+ (body.length == 0)) {
+ return gen.mkBooleanLit(node.pos, true); // cf.Or(res, gen.mkBooleanLit(node.pos, true));
+ } else if (!doBinding)
+ bound = new ValDef[][]{new ValDef[]{}};
for (int i = guard.length - 1; i >= 0; i--) {
Tree[] ts = new Tree[bound[i].length + 1];
System.arraycopy(bound[i], 0, ts, 0, bound[i].length);
@@ -986,6 +1008,11 @@ public class PatternMatcher extends PatternTool {
cf.Equals(selector.duplicate(), tree),
toTree(node.and),
toTree(node.or, selector.duplicate()));
+ case AltPat(Header header):
+ return gen.If(
+ toTree(header),
+ toTree(node.and),
+ toTree(node.or, selector.duplicate()));
default:
throw new ApplicationError();
}
diff --git a/sources/scalac/transformer/matching/PatternNode.java b/sources/scalac/transformer/matching/PatternNode.java
index 3cd583c5d8..03e73fda97 100644
--- a/sources/scalac/transformer/matching/PatternNode.java
+++ b/sources/scalac/transformer/matching/PatternNode.java
@@ -14,9 +14,9 @@ import scalac.ast.*;
import scalac.symtab.*;
import scalac.typechecker.*;
-/** intermediary data structure for algebraic matching
- */
+/** Intermediate data structure for algebraic matcher
+ */
public class PatternNode {
public int pos = Position.FIRSTPOS;
public Type type;
@@ -27,11 +27,11 @@ public class PatternNode {
public case Body(Tree.ValDef[][] bound, Tree[] guard, Tree[] body);
public case DefaultPat();
public case ConstrPat(Symbol casted);
- public case SequencePat(Symbol casted, int len); // only used in PatternMatcher
- public case SeqContainerPat(Symbol casted, Tree seqpat); // in AlgebraicMatcher
public case ConstantPat(Object value);
public case VariablePat(Tree tree);
-
+ public case AltPat(Header subheader);
+ public case SequencePat(Symbol casted, int len); // only used in PatternMatcher
+ public case SeqContainerPat(Symbol casted, Tree seqpat); // in AlgebraicMatcher
public PatternNode dup() {
PatternNode res;
@@ -60,6 +60,9 @@ public class PatternNode {
case VariablePat(Tree tree):
res = VariablePat(tree);
break;
+ case AltPat(Header subheader):
+ res = AltPat(subheader);
+ break;
default:
throw new ApplicationError();
}
diff --git a/sources/scalac/transformer/matching/PatternNodeCreator.java b/sources/scalac/transformer/matching/PatternNodeCreator.java
index 16574d625b..d0a2cddef1 100644
--- a/sources/scalac/transformer/matching/PatternNodeCreator.java
+++ b/sources/scalac/transformer/matching/PatternNodeCreator.java
@@ -17,6 +17,15 @@ import java.util.Vector ;
public class PatternNodeCreator extends PatternTool {
+ /** the owner of the variable symbols that might be created */
+ Symbol owner;
+
+ public PatternNodeCreator(Unit unit, Symbol owner) {
+ super(unit);
+ assert owner != null;
+ this.owner = owner;
+ }
+
public SequencePat SequencePat(int pos, Type type, int len) {
Symbol sym = newVar(Position.FIRSTPOS, type);
SequencePat node = new SequencePat(sym, len);
@@ -24,6 +33,7 @@ public class PatternNodeCreator extends PatternTool {
node.type = type;
return node;
}
+
public SeqContainerPat SeqContainerPat(int pos, Type type, Tree seqpat) {
Symbol sym = newVar(Position.NOPOS, type);
SeqContainerPat node = new SeqContainerPat(sym, seqpat);
@@ -31,29 +41,40 @@ public class PatternNodeCreator extends PatternTool {
node.type = type;
return node;
}
+
public static DefaultPat DefaultPat(int pos, Type type) {
- DefaultPat node = new DefaultPat();
- node.pos = pos;
- node.type = type;
- return node;
+ DefaultPat node = new DefaultPat();
+ node.pos = pos;
+ node.type = type;
+ return node;
}
+
public ConstrPat ConstrPat(int pos, Type type) {
- ConstrPat node = new ConstrPat(newVar(pos, type));
- node.pos = pos;
- node.type = type;
- return node;
+ ConstrPat node = new ConstrPat(newVar(pos, type));
+ node.pos = pos;
+ node.type = type;
+ return node;
}
+
public static ConstantPat ConstantPat(int pos, Type type, Object value) {
- ConstantPat node = new ConstantPat( value );
- node.pos = pos;
- node.type = type;
- return node;
+ ConstantPat node = new ConstantPat( value );
+ node.pos = pos;
+ node.type = type;
+ return node;
}
+
public static VariablePat VariablePat(int pos, Tree tree) {
- VariablePat node = new VariablePat( tree );
- node.pos = pos;
- node.type = tree.type;
- return node;
+ VariablePat node = new VariablePat( tree );
+ node.pos = pos;
+ node.type = tree.type;
+ return node;
+ }
+
+ public static AltPat AltPat(int pos, Header header) {
+ AltPat node = new AltPat(header);
+ node.pos = pos;
+ node.type = header.type;
+ return node;
}
// factories
@@ -64,11 +85,19 @@ public class PatternNodeCreator extends PatternTool {
node.type = type;
return node;
}
+
+ public Body Body(int pos) {
+ Body node = new Body(new ValDef[0][], new Tree[0], new Tree[0]);
+ node.pos = pos;
+ return node;
+ }
+
public Body Body(int pos, ValDef[] bound, Tree guard, Tree body) {
Body node = new Body(new ValDef[][]{bound}, new Tree[]{guard}, new Tree[]{body});
node.pos = pos;
return node;
}
+
public TermSymbol newVar(int pos, Name name, Type type) {
TermSymbol sym = new TermSymbol(pos, name, owner, 0);
sym.setType(type);
@@ -76,16 +105,8 @@ public class PatternNodeCreator extends PatternTool {
//System.out.println("owner: "+sym.owner());
return sym;
}
+
public TermSymbol newVar(int pos, Type type) {
return newVar(pos, fresh.newName("temp"), type);
}
-
- /** the owner of the variable symbols that might be created */
- Symbol owner;
-
- public PatternNodeCreator( Unit unit, Symbol owner ) {
- super( unit );
- assert owner != null;
- this.owner = owner;
- }
}
diff --git a/sources/scalac/util/AbstractFileReader.java b/sources/scalac/util/AbstractFileReader.java
index 2f7d0e1e21..3ecd385dc6 100644
--- a/sources/scalac/util/AbstractFileReader.java
+++ b/sources/scalac/util/AbstractFileReader.java
@@ -73,35 +73,35 @@ public class AbstractFileReader {
/** extract a character at position bp from buf
*/
- public char getChar(int bp) {
- return (char)(((buf[bp] & 0xff) << 8) + (buf[bp+1] & 0xff));
+ public char getChar(int mybp) {
+ return (char)(((buf[mybp] & 0xff) << 8) + (buf[mybp+1] & 0xff));
}
/** extract an integer at position bp from buf
*/
- public int getInt(int bp) {
- return ((buf[bp ] & 0xff) << 24) +
- ((buf[bp+1] & 0xff) << 16) +
- ((buf[bp+2] & 0xff) << 8) +
- (buf[bp+3] & 0xff);
+ public int getInt(int mybp) {
+ return ((buf[mybp ] & 0xff) << 24) +
+ ((buf[mybp+1] & 0xff) << 16) +
+ ((buf[mybp+2] & 0xff) << 8) +
+ (buf[mybp+3] & 0xff);
}
/** extract a long integer at position bp from buf
*/
- public long getLong(int bp) {
- return ((long)(getInt(bp)) << 32) + (getInt(bp + 4) & 0xffffffffL);
+ public long getLong(int mybp) {
+ return ((long)(getInt(mybp)) << 32) + (getInt(mybp + 4) & 0xffffffffL);
}
/** extract a float at position bp from buf
*/
- public strictfp float getFloat(int bp) {
- return Float.intBitsToFloat(getInt(bp));
+ public strictfp float getFloat(int mybp) {
+ return Float.intBitsToFloat(getInt(mybp));
}
/** extract a double at position bp from buf
*/
- public strictfp double getDouble(int bp) {
- return Double.longBitsToDouble(getLong(bp));
+ public strictfp double getDouble(int mybp) {
+ return Double.longBitsToDouble(getLong(mybp));
}
/** skip next 'n' bytes