diff options
author | Martin Odersky <odersky@gmail.com> | 2004-06-03 12:33:10 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2004-06-03 12:33:10 +0000 |
commit | 682856e0623ddc61442f644e4935ce449480a958 (patch) | |
tree | cff46c30cb93f91230cb24713013d3d80ecb1509 /sources/scalac | |
parent | d94a30d34746ddbe4274c00231734e2bbc3e9ff5 (diff) | |
download | scala-682856e0623ddc61442f644e4935ce449480a958.tar.gz scala-682856e0623ddc61442f644e4935ce449480a958.tar.bz2 scala-682856e0623ddc61442f644e4935ce449480a958.zip |
*** empty log message ***
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/symtab/Modifiers.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 69 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 101 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/ClassfileParser.java | 1 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/Pickle.java | 4 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/UnPickle.java | 4 | ||||
-rw-r--r-- | sources/scalac/transformer/AddInterfaces.java | 14 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurry.java | 9 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurryPhase.java | 2 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 14 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheckPhase.java | 3 |
11 files changed, 178 insertions, 45 deletions
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index 1b07e2967f..4ba225471a 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -41,7 +41,7 @@ public interface Modifiers { int PACKAGE = 0x00100000; // symbol is a java package. int STABLE = 0x00800000; // functions that are assumed to be stable - // (typically, access methods for valdefs) + // (typically, access methods for valdefs) int CAPTURED = 0x01000000; // variables is accessed from // nested function. Set by LambdaLift diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index c6c38c33bb..45c3b05548 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -1067,7 +1067,7 @@ public abstract class Symbol implements Modifiers, Kinds { String name1 = name.toString(); if (name1.endsWith(Names._EQ.toString())) name1 = name1.substring(0, name1.length() - Names._EQ.length()); - return owner.info().lookup(Name.fromString(name1 + "$")); + return owner.lookup(Name.fromString(name1 + "$")); } /** The members of this class or module symbol @@ -1503,10 +1503,15 @@ public abstract class Symbol implements Modifiers, Kinds { public Symbol overloadWith(Symbol that) { assert isTerm() : Debug.show(this); assert this.name == that.name : Debug.show(this) + " <> " + Debug.show(that); - assert this.owner == that.owner : Debug.show(this) + " != " + Debug.show(that); + //assert this.owner == that.owner : Debug.show(this) + " != " + Debug.show(that); assert this.isConstructor() == that.isConstructor(); - int overflags = (this.flags & that.flags & (JAVA | ACCESSFLAGS | DEFERRED | PARAM | SYNTHETIC)) | - ((this.flags | that.flags) & ACCESSOR); + int overflags; + //if (this.owner == that.owner) + overflags = (this.flags & that.flags & + (JAVA | ACCESSFLAGS | DEFERRED | PARAM | SYNTHETIC)) | + ((this.flags | that.flags) & ACCESSOR); + // else // it's an inherited overloaded alternative + // overflags = this.flags & SOURCEFLAGS; Symbol overloaded = (this.isConstructor()) ? this.constructorClass().newConstructor(this.constructorClass().pos, overflags) : owner.newTerm(pos, overflags, name, 0); @@ -1638,6 +1643,62 @@ public abstract class Symbol implements Modifiers, Kinds { public int tag() { return name.toString().hashCode(); } + + public void addInheritedOverloaded(Type owntype) { + if (false && owner().kind == CLASS && !isConstructor() && owner().lookup(name) == this) { + // it's a class member which is not an overloaded alternative + Symbol sym = Type.lookupNonPrivate(owner().parents(), name); + if (sym.kind == VAL) { + Type symtype = owner.thisType().memberType(sym); + switch (symtype) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + for (int i = 0; i < alts.length; i++) + addInheritedOverloaded(owntype, alts[i], alttypes[i]); + break; + default: + addInheritedOverloaded(owntype, sym, symtype); + } + } + } + } + + private void addInheritedOverloaded(Type owntype, Symbol sym, Type symtype) { + if (!owntype.overrides(symtype)) { + System.out.println(owner() + " inherits overloaded: " + sym + ":" + symtype + sym.locationString());//debug + owner().members().lookupEntry(name).setSymbol(overloadWith(sym)); + //System.out.println("type is now: " + owner().members().lookup(name).type()); + } + } + + public Type removeInheritedOverloaded(Type owntype) { + //assert name != Names.toString || + // Global.instance.currentPhase.id != Global.instance.PHASE.UNCURRY.id(); + switch (owntype) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + int n = 0; + for (int i = 0; i < alts.length; i++) + if (alts[i].owner() == owner()) n++; + if (n < alts.length) { + Symbol[] alts1 = new Symbol[n]; + Type[] alttypes1 = new Type[n]; + int j = 0; + for (int i = 0; i < alts.length; i++) { + if (alts[i].owner() == owner()) { + alts1[j] = alts[i]; + alttypes1[j] = alttypes[i]; + j++; + } else { + System.out.println("removing inherited alternatve " + alts[i] + ":" + alttypes[i]);//debug + } + } + return Type.OverloadedType(alts1, alttypes1); + } else { + return owntype; + } + default: + return owntype; + } + } } /** A class for term symbols diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 8f57093823..e88240a56f 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -197,7 +197,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } public static Type typeRef(Type pre, Symbol sym, Type[] args) { - if (!pre.isLegalPrefix() && !pre.isError()) + if (sym.kind == TYPE && !pre.isLegalPrefix() && !pre.isError()) throw new Type.Malformed(pre, sym.nameString()); rebind: if (sym.isAbstractType()) { @@ -225,7 +225,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return new ExtTypeRef(pre, sym, args); } private static boolean isLegalTypeRef(Type pre, Symbol sym, Type[] args) { - if (!pre.isLegalPrefix() && !pre.isError()) return false; + if (sym.kind == TYPE && !pre.isLegalPrefix() && !pre.isError()) return false; if (!sym.isType() && !sym.isError()) return false; // !!! return args.length == 0 || args.length == sym.typeParams().length; return true; @@ -687,9 +687,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return true; case TypeRef(_, Symbol sym, _): if (sym.isParameter() && sym.isSynthetic()) return true; + return false; + /* return sym.kind == CLASS && ((sym.flags & JAVA) != 0 || (sym.flags & (TRAIT | ABSTRACT)) == 0); + */ default: return false; } @@ -806,33 +809,34 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return sym.info().lookupNonPrivate(name); 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 > 0) { - i--; - Symbol sym1 = parts[i].lookupNonPrivate(name); - if (sym1.kind != NONE && - (sym1.flags & PRIVATE) == 0 && - (sym.kind == NONE - || - (sym.flags & DEFERRED) != 0 && - (sym1.flags & DEFERRED) == 0 - || - (sym.flags & DEFERRED) == (sym1.flags & DEFERRED) && - sym1.owner().isSubClass(sym.owner()))) - sym = sym1; - } - return sym; + if (sym.kind != NONE && (sym.flags & PRIVATE) == 0) return sym; + else return lookupNonPrivate(parts, name); default: return Symbol.NONE; } } + public static Symbol lookupNonPrivate(Type[] parts, Name name) { + // search base types in reverse; non-abstract members + // take precedence over abstract ones. + int i = parts.length; + Symbol sym = Symbol.NONE; + while (i > 0) { + i--; + Symbol sym1 = parts[i].lookupNonPrivate(name); + if (sym1.kind != NONE && + (sym.kind == NONE + || + (sym.flags & DEFERRED) != 0 && + (sym1.flags & DEFERRED) == 0 + || + (sym.flags & DEFERRED) == (sym1.flags & DEFERRED) && + sym1.owner().isSubClass(sym.owner()))) + sym = sym1; + } + return sym; + } + /** * Looks up in the current type a symbol with the same name as the * given symbol and whose type (as seen from the given prefix) is @@ -2342,6 +2346,55 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + /** Does this type match type `tp', so that corresponding symbols with + * the two types would be taken to override each other? + */ + public boolean overrides(Type tp) { + switch (this) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + for (int i = 0; i < alttypes.length; i++) { + if (alttypes[i].overrides(tp)) return true; + } + return false; + default: + switch (tp) { + 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.overrides(res1); + } + return false; + + 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)) || + !ps[i].vuBound().isSameAs(ps1[i].vuBound().subst(ps1, ps))) + return false; + return res.overrides(res1.subst(ps1, ps)); + } + return false; + + case OverloadedType(_, _): + throw new ApplicationError("overrides inapplicable for " + tp); + + default: + return true; + } + } + } + // Closures and Least Upper Bounds --------------------------------------------------- /** The closure of this type, i.e. the widened type itself followed by all diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java index c4eaab9e5c..73432a945f 100644 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ b/sources/scalac/symtab/classfile/ClassfileParser.java @@ -226,6 +226,7 @@ public class ClassfileParser implements ClassfileConstants { symbol = owner.newTerm(Position.NOPOS, sflags, name); } setParamOwners(type, symbol); + symbol.addInheritedOverloaded(type); symbol.setInfo(type); attrib.readAttributes(symbol, type, METH_ATTR); if (name != CONSTR_N) { diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java index 6891093e75..4bb9419b2b 100644 --- a/sources/scalac/symtab/classfile/Pickle.java +++ b/sources/scalac/symtab/classfile/Pickle.java @@ -138,7 +138,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags { putSymbol(it.next()); break; case VAL: - putType(sym.info()); + putType(sym.removeInheritedOverloaded(sym.info())); if (sym.isConstructor() && sym == sym.constructorClass().allConstructors()) putSymbol(sym.constructorClass()); @@ -358,7 +358,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags { writeRef(sym.allConstructors()); break; case VAL: - writeRef(sym.info()); + writeRef(sym.removeInheritedOverloaded(sym.info())); if (sym.isConstructor() && sym == sym.constructorClass().allConstructors()) writeRef(sym.constructorClass()); diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java index 6f6866782e..1c41932a6d 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -306,7 +306,9 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags { Symbol clasz = readSymbolRef(); assert clasz == sym.moduleClass(): Debug.show(sym); } - sym.setInfo(getType(inforef, sym)); + Type owntype = getType(inforef, sym); + sym.addInheritedOverloaded(owntype); + sym.setInfo(owntype); break; default: diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java index 82bd3d4fdd..a54bcc95e8 100644 --- a/sources/scalac/transformer/AddInterfaces.java +++ b/sources/scalac/transformer/AddInterfaces.java @@ -222,15 +222,21 @@ public class AddInterfaces extends GenTransformer { /** * Returns the tree of the given class whose body is built by * adding to the given body the class members. Non-abstract - * methods are removed from the given method map. All other + * methods are removed from the ngiven method map. All other * members are generated from their symbol. */ private Tree getClassTree(Symbol clasz, TreeList body, Map methods) { Scope members = clasz.nextInfo().members(); + /* + for (Scope.SymbolIterator i = members.iterator(false); i.hasNext(); ) { + Symbol sym = i.next(); + System.out.println(clasz + " defines " + sym + ":" + sym.getType()); + } + */ for (Scope.SymbolIterator i = members.iterator(true); i.hasNext(); ) { Symbol member = i.next(); if (!member.isTerm()) continue; - body.append(getMemberTree(member, methods)); + body.append(getMemberTree(clasz, member, methods)); } return gen.ClassDef(clasz, body.toArray()); } @@ -240,11 +246,11 @@ public class AddInterfaces extends GenTransformer { * removed from the given method map. All other members are * generated from their symbol. */ - private Tree getMemberTree(Symbol member, Map methods) { + private Tree getMemberTree(Symbol clasz, Symbol member, Map methods) { if (!member.isMethod()) return gen.ValDef(member, Tree.Empty); if (member.isDeferred()) return gen.DefDef(member, Tree.Empty); Tree method = (Tree)methods.remove(member); - assert method != null: Debug.show(member); + assert method != null: Debug.show(clasz + "." + member + ":" + member.info() + member.locationString()); return method; } diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java index f088ca6943..9eadc4d85f 100644 --- a/sources/scalac/transformer/UnCurry.java +++ b/sources/scalac/transformer/UnCurry.java @@ -113,7 +113,14 @@ public class UnCurry extends OwnerTransformer System.out.flush(); //uncurry type and symbol Type prevtype = tree.type; - if (prevtype != null) tree.type = descr.uncurry(prevtype); + if (prevtype != null) { + switch (prevtype) { + case OverloadedType(_, _): + assert tree.symbol() != null; + prevtype = tree.symbol().removeInheritedOverloaded(prevtype); + } + tree.type = descr.uncurry(prevtype); + } switch (tree) { case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): return copy.ClassDef( diff --git a/sources/scalac/transformer/UnCurryPhase.java b/sources/scalac/transformer/UnCurryPhase.java index 00a966b3eb..79b96f0094 100644 --- a/sources/scalac/transformer/UnCurryPhase.java +++ b/sources/scalac/transformer/UnCurryPhase.java @@ -30,7 +30,7 @@ public class UnCurryPhase extends Phase implements Modifiers { * - if symbol is a def parameter with transformed type T, return () => T */ public Type transformInfo(Symbol sym, Type tp0) { - Type tp1 = uncurry(tp0); + Type tp1 = uncurry(sym.removeInheritedOverloaded(tp0)); if (sym.isDefParameter()) return global.definitions.FUNCTION_TYPE(Type.EMPTY_ARRAY, tp1); else return tp1; } diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index 9358f39722..5239a4d68a 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -76,9 +76,12 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { void checkAllOverrides(int pos, Symbol clazz) { Type[] closure = clazz.closure(); for (int i = 0; i < closure.length; i++) { - for (Scope.SymbolIterator it = closure[i].members().iterator(true); + Type basetype = closure[i]; + Symbol baseclazz = basetype.symbol(); + for (Scope.SymbolIterator it = basetype.members().iterator(true); it.hasNext();) { - checkOverride(pos, clazz, it.next()); + Symbol sym = it.next(); + if (sym.owner() == baseclazz) checkOverride(pos, clazz, sym); } } @@ -86,12 +89,12 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { for (Scope.SymbolIterator it = clazz.members().iterator(true); it.hasNext();) { Symbol sym = it.next(); - if ((sym.flags & OVERRIDE) != 0) { + if ((sym.flags & OVERRIDE) != 0 && sym.owner() == clazz) { int i = parents.length - 1; while (i >= 0 && sym.overriddenSymbol(parents[i]).kind == NONE) i--; if (i < 0) { - unit.error(sym.pos, sym + " overrides nothing"); + unit.error(sym.pos, sym + ":" + sym.type() + sym.locationString() + " overrides nothing");//debug sym.flags &= ~OVERRIDE; } else if (sym.isAbstractOverride() && sym.overriddenSymbol(parents[0]).kind == NONE) { @@ -117,7 +120,8 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { switch (member1.info()) { case OverloadedType(Symbol[] alts, _): for (int i = 0; i < alts.length; i++) { - if (normalizedInfo(self, alts[i]).isSubType(template)) { + if (normalizedInfo(self, alts[i]).isSubType(template) && + alts[i].owner() == clazz) { if (member == other) member = alts[i]; else diff --git a/sources/scalac/typechecker/RefCheckPhase.java b/sources/scalac/typechecker/RefCheckPhase.java index e46ac290f9..ca73d37d6d 100644 --- a/sources/scalac/typechecker/RefCheckPhase.java +++ b/sources/scalac/typechecker/RefCheckPhase.java @@ -27,9 +27,8 @@ public class RefCheckPhase extends Phase { } public Type transformInfo(Symbol sym, Type tp) { - if (sym.isModule() && !sym.isStatic()) { + if (sym.isModule() && !sym.isStatic()) return Type.PolyType(Symbol.EMPTY_ARRAY, tp); - } else return tp; } |