From 957c42dadf55e3b67511077acfc4dd05e9a76b1d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 10 Sep 2003 13:50:32 +0000 Subject: *** empty log message *** --- .../meta/scalac/checkers/MetaCheckTreeNodes.java | 4 +- sources/scalac/symtab/Type.java | 48 +++----- sources/scalac/typechecker/Analyzer.java | 25 +++-- sources/scalac/typechecker/RefCheck.java | 123 ++++++++++----------- 4 files changed, 98 insertions(+), 102 deletions(-) (limited to 'sources') diff --git a/sources/meta/scalac/checkers/MetaCheckTreeNodes.java b/sources/meta/scalac/checkers/MetaCheckTreeNodes.java index d18d012d20..11ad75d77a 100644 --- a/sources/meta/scalac/checkers/MetaCheckTreeNodes.java +++ b/sources/meta/scalac/checkers/MetaCheckTreeNodes.java @@ -78,8 +78,8 @@ public class MetaCheckTreeNodes extends AbstractTreeCaseExpander { case TreeType.Name(TreeKind kind): if (kind != TreeKind.Any && kind != TreeKind.Test) { - writer.println("assert " + (kind == TreeKind.Type ? "" : "!")+ - name +".isTypeName() :").indent(); + writer.println("assert " + name + ".is" + kind + "Name() :") + .indent(); printWrongKind(node, name, kind); writer.println(";").undent(); } diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index e3526f8830..03bee60328 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -1727,36 +1727,23 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return result; } - public boolean specializes0(Symbol sym1) { - Symbol sym = lookup(sym1.name); - switch (sym.info()) { - case NoType: - return false; - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) { - if (specializes0(alts[i], sym1)) return true; - } - return false; - default: - return specializes0(sym, sym1); - } - } - - private boolean specializes0(Symbol sym, Symbol sym1) { + private boolean specializes0(Symbol sym1) { Type self = narrow(); Symbol[] tparams = symbol().typeParams(); Type[] targs = typeArgs(); + Symbol sym = lookup(sym1.name); return - 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())); + 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? @@ -2163,7 +2150,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (tps[i] == ErrorType) { return new Type[]{ErrorType}; } else { - assert tps[i].isObjectType() : tps[i]; + assert tps[i].isObjectType(): tps[i]; for (int j = 0; j < i && !redundant[i]; j++) { if (!redundant[j]) { if (tps[i].isSubType(tps[j])) { @@ -2197,6 +2184,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { 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. + // remove types that are subtypes of some other type. tps = elimRedundant(tps, true); if (tps.length == 1) return tps[0]; @@ -2231,8 +2221,6 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { while (j < tps.length) { rsyms[j] = tps[j].lookupNonPrivate(name); if (rsyms[j] == sym) break; - if (rsyms[j].isMethod()) break; // since methods cannot - // appear in refinements. rtps[j] = memberTp(tps[j], rsyms[j]) .substThis(tps[j].symbol(), lubThisType); rlbs[j] = tps[j].memberLoBound(rsyms[j]) @@ -2311,7 +2299,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (!members.isEmpty()) comptl = new Type.List(tps[i], comptl); for (int j = 0; j < parents.length; j++) - treftl = new Type.List(parents[i], treftl); + treftl = new Type.List(parents[j], treftl); break; case ThisType(_): case SingleType(_, _): diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index fc53218f5e..99629712a9 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -1117,7 +1117,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } catch (Type.Error ex) { reportTypeError(tree.pos, ex); tree.type = Type.ErrorType; - if (tree.hasSymbol() && tree.symbol() == null) tree.setSymbol(Symbol.ERROR); + if (tree.hasSymbol()) { + if (tree.symbol() != null) tree.symbol().setInfo(Type.ErrorType); + else tree.setSymbol(Symbol.ERROR); + } } this.unit = savedUnit; @@ -1235,7 +1238,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (clazz.isCaseClass()) { // set type to instantiated case class constructor - tree.type = clazz.primaryConstructor().type(); + tree.type = tree.type.prefix().memberType( + clazz.primaryConstructor()); switch (tree.type) { case PolyType(Symbol[] tparams, Type restp): try { @@ -2031,7 +2035,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return error(tree.pos, "method with return needs result type"); } else { Symbol enclFun = context.owner.enclMethod(); - if (enclFun.kind == VAL) { + if (enclFun.kind == VAL && !enclFun.isConstructor()) { Tree expr1 = transform( expr, EXPRmode, enclFun.type().resultType()); return copy.Return(tree, expr1) @@ -2178,7 +2182,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { assert tsym.isType() : tsym; switch (fn1.type.unalias()) { case TypeRef(Type pre, Symbol c, Type[] argtypes): - if (c.kind == CLASS) { + if (c.kind != CLASS) { + error(tree.pos, + tsym + " is not a class; cannot be instantiated"); + } else if (!pre.isStable()) { + error(tree.pos, pre + " is not a legal prefix for a constructor"); + } else { c.initialize(); Symbol constr = c.allConstructors(); Tree fn0 = fn1; @@ -2206,9 +2215,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } //System.out.println(TreeInfo.methSymbol(fn1) + ":" + tp + " --> " + fn1.type + " of " + fn1);//DEBUG selfcc = TreeInfo.isSelfConstrCall(fn0); - } else { - error(tree.pos, - tsym + " is not a class; cannot be instantiated"); } break; default: @@ -2475,7 +2481,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } catch (Type.Error ex) { reportTypeError(tree.pos, ex); tree.type = Type.ErrorType; - if (tree.hasSymbol() && tree.symbol() == null) tree.setSymbol(Symbol.ERROR); + if (tree.hasSymbol()) { + if (tree.symbol() != null) tree.symbol().setInfo(Type.ErrorType); + else tree.setSymbol(Symbol.ERROR); + } return tree; } } diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index d3a603642a..b2e394458a 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -58,54 +58,76 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { // Override checking ------------------------------------------------------------ /** 1. Check all members of class `clazz' for overriding conditions. - * 2. Check that only abstract classes have deferred members + * 2. Check that only abstract classes have deferred members* * 3. Check that every member with an `override' modifier * overrides a concrete member. */ void checkAllOverrides(int pos, Symbol clazz) { Type[] closure = clazz.closure(); - HashMap/**/ overrides = null; + HashMap/**/ overrides = new HashMap(); for (int i = 0; i < closure.length; i++) { for (Scope.SymbolIterator it = closure[i].members().iterator(true); it.hasNext();) { - Symbol other = it.next(); - Symbol member = ((other.flags & PRIVATE) != 0) ? other - : clazz.info().lookup(other.name); - if (member.owner() == other.owner()) - member = other; - else if (member.type() instanceof Type.OverloadedType) - member = findOverriding(pos, clazz, member, other); - if (member.kind != NONE && member != other) - checkOverride(pos, clazz, member, other); - if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) { - if ((member.flags & DEFERRED) != 0) { - abstractClassError( - clazz, - member + member.locationString() + " is not defined" + - (((member.flags & MUTABLE) == 0) ? "" - : "\n(Note that variables need to be initialized to be defined)")); - } else if ((member.flags & OVERRIDE) != 0) { - if (overrides == null) - overrides = new HashMap(); - if ((other.flags & DEFERRED) == 0 || - overrides.get(member) == null) - overrides.put(member, other); - } - } + checkOverride(pos, clazz, it.next(), overrides); } } - if (overrides != null) { - for (Iterator/**/ it = overrides.keySet().iterator(); - it.hasNext();) { - Symbol member = (Symbol) it.next(); - Symbol other = (Symbol) overrides.get(member); - if ((other.flags & DEFERRED) != 0) { - abstractClassError( - clazz, member + member.locationString() + - " is marked `override' and overrides only abstract members" + other + other.locationString()); + for (Iterator/**/ it = overrides.keySet().iterator(); + it.hasNext();) { + Symbol member = (Symbol) it.next(); + Symbol other = (Symbol) overrides.get(member); + if ((other.flags & DEFERRED) != 0) { + abstractClassError( + clazz, member + member.locationString() + + " is marked `override' and overrides only abstract members" + other + other.locationString()); + } + } + } + + void checkOverride(int pos, Symbol clazz, Symbol other, + HashMap/**/ overrides) { + Symbol member = other; + if ((other.flags & PRIVATE) == 0) { + Symbol member1 = clazz.info().lookup(other.name); + if (member1.kind != NONE && member1.owner() != other.owner()) { + switch (member1.info()) { + case OverloadedType(Symbol[] alts, _): + Type self = clazz.thisType(); + Type otherinfo = normalizedInfo(self, other); + for (int i = 0; i < alts.length; i++) { + if (normalizedInfo(self, alts[i]).isSubType(otherinfo)) { + if (member == other) + member = alts[i]; + else + unit.error( + pos, + "ambiguous override: both " + + member + ":" + normalizedInfo(self, member) + + "\n and " + alts[i] + ":" + normalizedInfo(self, alts[i]) + + "\n override " + other + ":" + otherinfo + + other.locationString()); + } + } + break; + default: + member = member1; } } } + if (member != other) { + checkOverride(pos, clazz, member, other); + } + if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) { + if ((member.flags & DEFERRED) != 0) { + abstractClassError( + clazz, + member + member.locationString() + " is not defined" + + (((member.flags & MUTABLE) == 0) ? "" + : "\n(Note that variables need to be initialized to be defined)")); + } else if ((member.flags & OVERRIDE) != 0 && + ((other.flags & DEFERRED) == 0 || + overrides.get(member) == null)) + overrides.put(member, other); + } } //where private void abstractClassError(Symbol clazz, String msg) { @@ -116,32 +138,6 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { clazz.flags |= ABSTRACTCLASS; } - Symbol findOverriding(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()); - } - } - } - } - return member; - } /** Check that all conditions for overriding `other' by `member' are met. * That is for overriding member M and overridden member O: @@ -232,7 +228,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { Type normalizedInfo(Type site, Symbol sym) { Type tp = site.memberInfo(sym); - if (sym.kind == VAL && (sym.flags & STABLE) != 0) tp = tp.resultType(); + switch (tp) { + case PolyType(Symbol[] tparams, Type restp): + if (tparams.length == 0) return restp; + } return tp; } -- cgit v1.2.3