From ce9a82d6382486a0badc794b22807fc53de2f63e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 9 May 2003 12:32:49 +0000 Subject: *** empty log message *** --- sources/scalac/symtab/Type.java | 43 ++++++++++++++++++++------------ sources/scalac/typechecker/RefCheck.java | 29 +++++++++++++++------ 2 files changed, 48 insertions(+), 24 deletions(-) (limited to 'sources') diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 4289498818..f98be55b21 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -1771,29 +1771,24 @@ public class Type implements Modifiers, Kinds, TypeTags { return result; } - /** Return the least upper bound of non-empty array of types `tps'. + /** remove types that are subtypes of some other type. */ - public static Type lub(Type[] tps) { - //System.out.println("lub" + ArrayApply.toString(tps));//DEBUG - - // 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++) { - if (tps[i] == ErrorType) - return ErrorType; - else if (!tps[i].isObjectType()) { - System.out.println("not an object type"); - return Type.NoType;//todo: change + if (tps[i] == ErrorType) { + return new Type[]{ErrorType}; } else { + 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[i] = true; + redundant[elimLower ? i : j] = true; nredundant++; } else if (tps[j].isSubType(tps[i])) { - redundant[j] = true; + redundant[elimLower ? j : i] = true; nredundant++; } } @@ -1807,9 +1802,21 @@ public class Type implements Modifiers, Kinds, TypeTags { for (int i = 0; i < tps.length; i++) { if (!redundant[i]) tps1[n++] = tps[i]; } - tps = tps1; + return tps1; + } else { + return tps; } + } + + /** Return the least upper bound of non-empty array of types `tps'. + * todo: treat types with refinements + */ + public static Type lub(Type[] tps) { + //System.out.println("lub" + ArrayApply.toString(tps));//DEBUG + + // 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. @@ -1866,9 +1873,7 @@ public class Type implements Modifiers, Kinds, TypeTags { private static Type commonType(Type[] tps) { Type tp = tps[0]; if (tp.isSameAsAll(tps)) return tp; - //tp = tp.widen(); - //if (tp.isSameAsAll(widen(tps))) return tp; - return NoType; + else return NoType; } private static Symbol lub(Symbol[] syms, Type[] tps, Symbol owner) { @@ -1899,6 +1904,12 @@ public class Type implements Modifiers, Kinds, TypeTags { return lubSym; } + private static Type glb(Type[] tps) { + tps = elimRedundant(tps, false); + if (tps.length == 1) return tps[0]; + else return NoType; + } + // Erasure -------------------------------------------------------------------------- public static Map erasureMap = new MapOnlyTypes() { diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index 0d5caa78e4..9ea4f125f0 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -152,7 +152,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { Tree vdef = gen.ValDef(mvar, gen.Ident(tree.pos, defs.NULL)); // { if (null == m$) m$ = new m$class; m$ } - Symbol eqMethod = getMemberMethod( + Symbol eqMethod = getUnaryMemberMethod( sym.type(), Names.EQEQ, defs.ANY_TYPE); Tree body = gen.Block(new Tree[]{ gen.If( @@ -185,7 +185,20 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { return sym; } - private Symbol getMemberMethod(Type site, Name name, Type paramtype) { + private Symbol getNullaryMemberMethod(Type site, Name name) { + Symbol sym = getMember(site, name); + switch (sym.type()) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + for (int i = 0; i < alts.length; i++) { + if (alttypes[i].firstParams().length == 0) return alts[i]; + } + } + assert sym.type().firstParams().length == 0 + : "no nullary method " + name + " among " + sym.type() + " at " + site; + return sym; + } + + private Symbol getUnaryMemberMethod(Type site, Name name, Type paramtype) { Symbol sym = getMember(site, name); switch (sym.type()) { case OverloadedType(Symbol[] alts, Type[] alttypes): @@ -306,7 +319,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { } private Tree eqOp(Tree l, Tree r) { - Symbol eqMethod = getMemberMethod(l.type, Names.EQEQ, r.type); + Symbol eqMethod = getUnaryMemberMethod(l.type, Names.EQEQ, r.type); return gen.Apply(gen.Select(l, eqMethod), new Tree[]{r}); } @@ -316,10 +329,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { .setInfo(defs.HASHCODE.type()); clazz.info().members().enter(hashCodeSym); Tree[] fields = caseFields(clazz); - Symbol getClassMethod = getMember(clazz.type(), Names.getClass); - Symbol addMethod = getMemberMethod( + Symbol getClassMethod = getNullaryMemberMethod(clazz.type(), Names.getClass); + Symbol addMethod = getUnaryMemberMethod( defs.INT_TYPE, Names.ADD, defs.INT_TYPE); - Symbol mulMethod = getMemberMethod( + Symbol mulMethod = getUnaryMemberMethod( defs.INT_TYPE, Names.MUL, defs.INT_TYPE); Tree body = gen.Apply( @@ -327,13 +340,13 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { gen.Apply( gen.mkRef(clazz.pos, clazz.thisType(), getClassMethod), Tree.EMPTY_ARRAY), - getMember(getClassMethod.type().resultType(), Names.hashCode)), + getNullaryMemberMethod(getClassMethod.type().resultType(), Names.hashCode)), Tree.EMPTY_ARRAY); for (int i = 0; i < fields.length; i++) { Tree operand = gen.Apply( gen.Select( fields[i], - getMember(fields[i].type, Names.hashCode)), + getNullaryMemberMethod(fields[i].type, Names.hashCode)), Tree.EMPTY_ARRAY); body = gen.Apply( -- cgit v1.2.3