From ec46a90f5cd17d5ed506201bdc0b0a55324dffae Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 2 Sep 2003 12:57:45 +0000 Subject: *** empty log message *** --- sources/scala/collection/mutable/HashSet.scala | 2 +- sources/scala/collection/mutable/SetWrapper.scala | 2 +- sources/scalac/ast/TreeGen.java | 2 + sources/scalac/symtab/Definitions.java | 4 +- sources/scalac/symtab/Modifiers.java | 1 - sources/scalac/symtab/Symbol.java | 11 +-- sources/scalac/symtab/Type.java | 6 +- .../scalac/symtab/classfile/JavaTypeCreator.java | 8 ++- sources/scalac/typechecker/Analyzer.java | 79 ++++++++++++++-------- sources/scalac/typechecker/RefCheck.java | 71 +++++++++++++++---- 10 files changed, 127 insertions(+), 59 deletions(-) (limited to 'sources') diff --git a/sources/scala/collection/mutable/HashSet.scala b/sources/scala/collection/mutable/HashSet.scala index 9134ca9524..07cc6726c6 100644 --- a/sources/scala/collection/mutable/HashSet.scala +++ b/sources/scala/collection/mutable/HashSet.scala @@ -31,7 +31,7 @@ class HashSet[A] extends scala.collection.mutable.Set[A] with HashTable[A] { def elements = entries; - override def clear = { + def clear = { initTable(table); tableSize = 0; } diff --git a/sources/scala/collection/mutable/SetWrapper.scala b/sources/scala/collection/mutable/SetWrapper.scala index f8f53a8a32..920035542b 100644 --- a/sources/scala/collection/mutable/SetWrapper.scala +++ b/sources/scala/collection/mutable/SetWrapper.scala @@ -34,7 +34,7 @@ class SetWrapper[A](set: Set[A]) extends Set[A] override def intersect(that: Set[A]): Unit = set.intersect(that); - override def clear: Unit = set.clear; + def clear: Unit = set.clear; override def filter(p: A => Boolean): Unit = set.filter(p); } diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index 751e78044d..34a334b3e7 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -487,6 +487,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { Global.instance.nextPhase(); Type symtype = qual.type.memberType(sym); Global.instance.prevPhase(); + sym.flags |= ACCESSED | SELECTOR; return make.Select(pos, sym, qual).setType(deref(symtype)); } @@ -506,6 +507,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { Global.instance.nextPhase(); Type symtype = sym.type(); Global.instance.prevPhase(); + sym.flags |= ACCESSED; return make.Ident(pos, sym).setType(deref(symtype)); } diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index ac4d38e261..7a33403004 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -361,13 +361,13 @@ public class Definitions { EQUALS = new TermSymbol( Position.NOPOS, Names.equals, ANY_CLASS, 0); - EQUALS.setInfo(Type.MethodType(new Symbol[]{newParameter(EQUALS, JAVA_OBJECT_TYPE)}, + EQUALS.setInfo(Type.MethodType(new Symbol[]{newParameter(EQUALS, ANY_TYPE)}, BOOLEAN_TYPE)); ANY_CLASS.members().enter(EQUALS); EQ = new TermSymbol( Position.NOPOS, Names.eq, ANY_CLASS, 0); - EQ.setInfo(Type.MethodType(new Symbol[]{newParameter(EQ, JAVA_OBJECT_TYPE)}, + EQ.setInfo(Type.MethodType(new Symbol[]{newParameter(EQ, ANY_TYPE)}, BOOLEAN_TYPE)); ANY_CLASS.members().enter(EQ); diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index e53bbd92d4..242e6c64ce 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -62,7 +62,6 @@ public interface Modifiers { int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT | COVARIANT | CONTRAVARIANT; // these modifiers can be set in source programs. int ACCESSFLAGS = PRIVATE | PROTECTED; int VARIANCES = COVARIANT | CONTRAVARIANT; - int OVERLOADFLAGS = DEFERRED | OVERRIDE | FINAL; public static class Helper { diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index ca36dfb663..e36dc1489e 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -977,13 +977,8 @@ public abstract class Symbol implements Modifiers, Kinds { 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.flags & that.flags & JAVA) != 0 || - (this.flags & OVERLOADFLAGS) == (that.flags & OVERLOADFLAGS) - : Integer.toHexString(this.flags) + "@" + Debug.show(this) + " <> " + Integer.toHexString(that.flags) + "@" + Debug.show(that); assert this.isConstructor() == that.isConstructor(); - int overflags = - ((this.flags | that.flags) & (JAVA | OVERLOADFLAGS)) | - (this.flags & that.flags & ACCESSFLAGS); + int overflags = this.flags & that.flags & (JAVA | ACCESSFLAGS); TermSymbol overloaded = (this.isConstructor()) ? TermSymbol.newConstructor(this.constructorClass(), overflags) : new TermSymbol(pos, name, owner, overflags); @@ -1062,8 +1057,8 @@ public abstract class Symbol implements Modifiers, Kinds { } } - /** The symbol which is overridden by this symbol in base class `base' - * `base' must be a superclass of this.owner(). + /** The symbol which overrides this symbol in subclass `sub' + * `sub' must be a subclass of this.owner(). */ public Symbol overridingSymbol(Type sub) { assert !isOverloaded() : this; diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 339c09b38a..21fdf32917 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -1447,7 +1447,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { for (int i = 0; i < ps.length; i++) { Symbol p1 = ps1[i]; Symbol p = ps[i]; - if (!p1.type().isSubType(p.type()) || + if (!p1.type().isSameAs(p.type()) || (p1.flags & (Modifiers.DEF | Modifiers.REPEATED)) != (p.flags & (Modifiers.DEF | Modifiers.REPEATED))) return false; @@ -1461,8 +1461,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { 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).isSubType(ps[i].info()) || - !ps[i].loBound().isSubType(ps1[i].loBound().subst(ps1, ps))) + 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)); } diff --git a/sources/scalac/symtab/classfile/JavaTypeCreator.java b/sources/scalac/symtab/classfile/JavaTypeCreator.java index 9ef282ba56..395778adec 100644 --- a/sources/scalac/symtab/classfile/JavaTypeCreator.java +++ b/sources/scalac/symtab/classfile/JavaTypeCreator.java @@ -72,10 +72,16 @@ public class JavaTypeCreator implements JavaTypeFactory { for (int i = 0; i < args.length; i++) { args[i] = new TermSymbol( Position.NOPOS, Name.fromString("x" + i), Symbol.NONE, Modifiers.PARAM); - args[i].setInfo(argtpes[i]); + args[i].setInfo(objToAny(argtpes[i])); } return new MethodType(args, restpe); } + private Type objToAny(Type tp) { + if (tp.isSameAs(global.definitions.JAVA_OBJECT_TYPE)) + return global.definitions.ANY_TYPE; + else + return tp; + } public Type packageType(Name packagename) { return null; diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 6d54de146c..55b6324880 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -212,20 +212,44 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { /** Check that `sym' is accessible as a member of tree `site' in current context. */ - void checkAccessible(int pos, Symbol sym, Tree site) { - if (!isAccessible(sym, site)) { - error(pos, sym + " cannot be accessed in " + site.type); - } - if (site instanceof Tree.Super && (sym.flags & DEFERRED) != 0) { - Symbol sym1 = context.enclClass.owner.thisSym().info().lookup(sym.name); - if ((sym1.flags & OVERRIDE) == 0 || (sym1.flags & DEFERRED) != 0) - error(pos, "symbol accessed from super may not be abstract"); + Type checkAccessible(int pos, Symbol sym, Type symtype, Tree site) { + switch (symtype) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + int nacc = 0; + for (int i = 0; i < alts.length; i++) { + if (isAccessible(alts[i], site)) { + nacc++; + } + } + if (nacc == 0) { + error(pos, sym + " cannot be accessed in " + site.type.widen()); + return Type.ErrorType; + } else { + Symbol[] alts1 = new Symbol[nacc]; + Type[] alttypes1 = new Type[nacc]; + nacc = 0; + for (int i = 0; i < alts.length; i++) { + if (isAccessible(alts[i], site)) { + alts1[nacc] = alts[i]; + alttypes1[nacc] = alttypes[i]; + nacc++; + } + } + return Type.OverloadedType(alts1, alttypes1); + } + default: + if (isAccessible(sym, site)) { + return symtype; + } else { + error(pos, sym + " cannot be accessed in " + site.type.widen()); + return Type.ErrorType; + } } } /** Is `sym' accessible as a member of tree `site' in current context? */ - boolean isAccessible(Symbol sym, Tree site) { + private boolean isAccessible(Symbol sym, Tree site) { return (sym.flags & (PRIVATE | PROTECTED)) == 0 || @@ -783,8 +807,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Symbol owner = sym.owner(); if (sym.kind == VAL && (sym.flags & (PRIVATE | SEALED)) == 0 && owner != null && owner.kind == CLASS && - (owner.flags & FINAL) != 0) + (owner.flags & FINAL) != 0) { + System.out.println(sym + " is final"); sym.flags |= FINAL; + } sym = enterInScope(sym); } tree.setSymbol(sym); @@ -835,6 +861,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { context.scope.enter(sym); } else if (sym.kind == VAL && other.kind == VAL) { // it's an overloaded definition + /* if (((sym.flags ^ other.flags) & SOURCEFLAGS) != 0) { // todo: refine, DEFERRED, MUTABLE and OVERRIDE should be // treated specially; maybe only PRIVATE and PROTECTED? @@ -843,9 +870,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { ": modifier lists differ in " + Modifiers.Helper.toString( (sym.flags ^ other.flags) & SOURCEFLAGS)); - } else { - e.setSymbol(other.overloadWith(sym)); - } + */ + e.setSymbol(other.overloadWith(sym)); } else { error(sym.pos, sym.nameString() + " is already defined as " + @@ -1247,11 +1273,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (tree.type.isObjectType()) { // insert apply method Symbol applyMeth = tree.type.lookup(Names.apply); - if (applyMeth != Symbol.NONE && isAccessible(applyMeth, tree)) { - applyMeth.flags |= (ACCESSED | SELECTOR); + if (applyMeth != Symbol.NONE) { + Type applyType = checkAccessible( + tree.pos, applyMeth, tree.type.memberType(applyMeth), + tree); tree = make.Select(tree.pos, tree, Names.apply) .setSymbol(applyMeth) - .setType(tree.type.memberType(applyMeth)); + .setType(applyType); return adapt(tree, mode, pt); } } @@ -1362,14 +1390,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { //System.out.println(name);//DEBUG return error(tree.pos, "not found: " + decode(name)); } else { - sym.flags |= ACCESSED; if (sym.owner().kind == CLASS) { pre = nextcontext.enclClass.owner.thisType(); if (!sym.owner().isPackage()) { Tree qual1 = makeStableId(tree.pos, pre); tree = make.Select(tree.pos, qual1, name); - if (context.enclClass != nextcontext.enclClass) - sym.flags |= SELECTOR; //System.out.println(name + " :::> " + tree + " " + qual1.symbol());//DEBUG } } else { @@ -1395,15 +1420,15 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { nextimports = nextimports.prev; } sym = sym1; - sym.flags |= (ACCESSED | SELECTOR); qual = lastimports.importPrefix().duplicate(); pre = qual.type; //new TextTreePrinter().print(name + " => ").print(lastimports.tree).print("." + name).println().end();//DEBUG tree = make.Select(tree.pos, qual, name); } - if (qual != Tree.Empty) checkAccessible(tree.pos, sym, qual); Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type()) .asSeenFrom(pre, sym.owner()); + if (qual != Tree.Empty) + symtype = checkAccessible(tree.pos, sym, symtype, qual); if (symtype == Type.NoType) return error(tree.pos, "not found: " + decode(name)); if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) && sym.isStable()) { @@ -1430,14 +1455,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return error(tree.pos, decode(name) + " is not a member of " + qual.type.widen()); } else { - checkAccessible(tree.pos, sym, qual); - sym.flags |= ACCESSED; - if (!TreeInfo.isSelf(qual, context.enclClass.owner)) - sym.flags |= SELECTOR; Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type()) .asSeenFrom(qual.type, sym.owner()); if (symtype == Type.NoType) return error(tree.pos, "not found: " + decode(name)); + else + symtype = checkAccessible(tree.pos, sym, symtype, qual); //System.out.println(sym.name + ":" + symtype);//DEBUG if (uninst.length != 0) { switch (symtype) { @@ -2144,8 +2167,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Symbol tsym = TreeInfo.methSymbol(fn1); if (tsym.kind != ERROR) { assert tsym.isType() : tsym; - Type tp = fn1.type.unalias(); - switch (tp) { + switch (fn1.type.unalias()) { case TypeRef(Type pre, Symbol c, Type[] argtypes): if (c.kind == CLASS) { c.initialize(); @@ -2154,7 +2176,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { fn1 = gen.mkRef(fn1.pos, pre, constr); switch (fn1) { case Select(Tree fn1qual, _): - checkAccessible(fn1.pos, constr, fn1qual); + fn1.type = checkAccessible( + fn1.pos, constr, fn1.type, fn1qual); } if (tsym == c) { switch (fn0) { diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index d25c547e20..24c452cf70 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -43,6 +43,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { private Unit unit; private Definitions defs = global.definitions; private Infer infer = new Infer(this); + private Symbol enclClass; public void apply(Unit unit) { this.unit = unit; @@ -65,13 +66,17 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { Type[] closure = clazz.closure(); HashMap/**/ overrides = null; for (int i = 0; i < closure.length; i++) { - for (Scope.SymbolIterator it = closure[i].members().iterator(); + for (Scope.SymbolIterator it = closure[i].members().iterator(true); it.hasNext();) { Symbol other = it.next(); - Symbol member = ((other.flags & PRIVATE) != 0) ? other + Symbol members = ((other.flags & PRIVATE) != 0) ? other : clazz.info().lookup(other.name); - if (member != other && member.kind != NONE) - checkOverride(pos, clazz, member, other); + Symbol member = Symbol.NONE; + if (members.kind != NONE && + members.owner() != other.owner() && + (members.owner() == clazz || + !members.owner().isSubClass(other.owner()))) + member = checkOverride(pos, clazz, members, other); if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) { if ((member.flags & DEFERRED) != 0) { abstractClassError( @@ -97,7 +102,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { if ((other.flags & DEFERRED) != 0) { abstractClassError( clazz, member + member.locationString() + - " is marked `override' and overrides only abstract members"); + " is marked `override' and overrides only abstract members" + other + other.locationString()); } } } @@ -125,10 +130,33 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { * 7. If O and M are values, then M's type is a subtype of O's type. * 8. If O is an immutable value, then so is M. */ - void checkOverride(int pos, Symbol clazz, Symbol member, Symbol other) { + Symbol checkOverride(int pos, Symbol clazz, Symbol members, Symbol other) { + Type self = clazz.thisType(); + Symbol member = members; + Type memberinfo = normalizedInfo(self, member); + Type otherinfo = normalizedInfo(self, other); + switch (memberinfo) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + for (int i = 0; i < alts.length; i++) { + if (alttypes[i].isSubType(otherinfo)) { + if (member == members) { + member = alts[i]; + memberinfo = alttypes[i]; + } else { + unit.error( + pos, + "ambiguous override: both " + + member + ":" + memberinfo + + "\n and " + alts[i] + ":" + alttypes[i] + + "\n override " + other + ":" + otherinfo + + other.locationString()); + } + } + } + if (member == members) { + } + } if (member.owner() == clazz) pos = member.pos; - else if (member.owner().isSubClass(other.owner())) - return; // everything was already checked elsewhere if ((member.flags & PRIVATE) != 0) { overrideError(pos, member, other, "has weaker access privileges; it should not be private"); @@ -149,7 +177,6 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { ":\n both are inherited from mixin classes; " + "\n an overriding definition in the current template is required"); } else { - Type self = clazz.thisType(); switch (other.kind) { case CLASS: overrideError(pos, member, other, "cannot override a class"); @@ -162,9 +189,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { if (other.isConstructor()) overrideError(pos, member, other, "cannot override a class constructor"); - Type selftype = normalizedInfo(self, member); - Type othertype = normalizedInfo(self, other); - if (!selftype.isSubType(othertype)) + if (!memberinfo.isSubType(otherinfo)) overrideTypeError(pos, member, other, self, false); if (member.kind == TYPE && !self.memberLoBound(other).isSubType( @@ -173,6 +198,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { } } + return member; } void overrideError(int pos, Symbol member, Symbol other, String msg) { @@ -842,10 +868,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { Symbol sym = tree.symbol(); switch (tree) { case ClassDef(_, _, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ): + Symbol enclClassPrev = enclClass; + enclClass = sym; validateVariance(sym, sym.info(), CoVariance); validateVariance(sym, sym.typeOfThis(), CoVariance); - return super.transform( + Tree tree1 = super.transform( copy.ClassDef(tree, tree.symbol(), tparams, vparams, tpe, addCaseMethods(templ, tree.symbol()))); + enclClass = enclClassPrev; + return tree1; case DefDef(_, _, _, _, _, _): validateVariance(sym, sym.type(), CoVariance); @@ -933,10 +963,23 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { maxindex[i] = symindex; } } + sym.flags |= ACCESSED; return elimTypeNode(tree); + + case Select(Tree qual, Name name): + sym.flags |= ACCESSED; + if (!TreeInfo.isSelf(qual, enclClass)) + sym.flags |= SELECTOR; + if (qual instanceof Tree.Super && (sym.flags & DEFERRED) != 0) { + Symbol sym1 = enclClass.thisSym().info().lookup(sym.name); + if ((sym1.flags & OVERRIDE) == 0 || (sym1.flags & DEFERRED) != 0) + unit.error(tree.pos, + "symbol accessed from super may not be abstract"); + } + return elimTypeNode(super.transform(tree)); + default: return elimTypeNode(super.transform(tree)); } - } } -- cgit v1.2.3