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 *** --- sources/scalac/typechecker/Analyzer.java | 25 +++++-- sources/scalac/typechecker/RefCheck.java | 123 +++++++++++++++---------------- 2 files changed, 78 insertions(+), 70 deletions(-) (limited to 'sources/scalac/typechecker') 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