summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-09-15 20:20:14 +0000
committerMartin Odersky <odersky@gmail.com>2003-09-15 20:20:14 +0000
commitdc6ec50a08dcd17aa65a73701abd6963b78a00bc (patch)
tree00e884ffbe6776f51be59bb249012190ab757a08 /sources
parent1b77651f90d9b4132e419409295f0d3c6153cf41 (diff)
downloadscala-dc6ec50a08dcd17aa65a73701abd6963b78a00bc.tar.gz
scala-dc6ec50a08dcd17aa65a73701abd6963b78a00bc.tar.bz2
scala-dc6ec50a08dcd17aa65a73701abd6963b78a00bc.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r--sources/scalac/ast/parser/Parser.java62
-rw-r--r--sources/scalac/symtab/Symbol.java21
-rw-r--r--sources/scalac/symtab/Type.java182
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java28
-rw-r--r--sources/scalac/typechecker/Analyzer.java14
-rw-r--r--sources/scalac/typechecker/Infer.java18
-rw-r--r--sources/scalac/typechecker/RefCheck.java55
7 files changed, 283 insertions, 97 deletions
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 12eb76dd2c..cbceab76f4 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -1121,11 +1121,11 @@ public class Parser implements Tokens {
return enums.toArray();
}
- /** Generator ::= val Pattern `<-' Expr
+ /** Generator ::= val Pattern1 `<-' Expr
*/
Tree generator() {
int pos = accept(VAL);
- Tree pat = validPattern();
+ Tree pat = validPattern1();
accept(LARROW);
Tree rhs = expr();
if (!TreeInfo.isVarPattern(pat))
@@ -1162,6 +1162,22 @@ public class Parser implements Tokens {
return make.Bad(pos);
}
+ /** Pattern1 ( see pattern1() ) which is checked for validity
+ */
+ Tree validPattern1() {
+ int pos = s.pos;
+
+ Tree pat = pattern1();
+
+ if( this.pN.check( pat ) ) { // reports syntax errors as side effect
+ // normalize
+ Tree res = pN.wrapAlternative( pN.elimSequence( pN.flattenSequence ( pat )));
+ return res;
+ }
+ //syntaxError( pos, "invalid pattern", false );
+ return make.Bad(pos);
+ }
+
/** Patterns ::= Pattern {`,' Pattern}
*/
Tree[] patterns() {
@@ -1174,18 +1190,17 @@ public class Parser implements Tokens {
return ts.toArray();
}
- /** Pattern ::= TreePattern { `|' TreePattern }
+ /** Pattern ::= Pattern1 { `|' Pattern1 }
*/
-
Tree pattern() {
int pos = s.pos;
- Tree first = treePattern();
+ Tree first = pattern1();
if(( s.token == IDENTIFIER )&&( s.name == BAR )) {
TreeList choices = new TreeList();
choices.append( first );
while(( s.token == IDENTIFIER )&&( s.name == BAR )) {
s.nextToken();
- choices.append( treePattern() );
+ choices.append( pattern1() );
}
TreeList ts = pN.flattenAlternativeChildren( choices.toArray() );
return pN.flattenAlternative( make.Alternative( pos, ts.toArray() ) );
@@ -1193,12 +1208,11 @@ public class Parser implements Tokens {
return first;
}
- /** TreePattern ::= varid `:' Type1
- * | `_' `:' Type1
- * | SimplePattern [ '*' | '?' | '+' ]
- * | SimplePattern {Id SimplePattern} // op2 must not be empty
+ /** Pattern1 ::= varid `:' Type1
+ * | `_' `:' Type1
+ * | Pattern2
*/
- Tree treePattern() {
+ Tree pattern1() {
int base = sp;
Tree top = simplePattern();
if (s.token == COLON) {
@@ -1206,6 +1220,17 @@ public class Parser implements Tokens {
return make.Typed(s.skipToken(), top, type1());
}
}
+ return pattern1rest(base, top);
+ }
+
+ /* Pattern2 ::= SimplePattern [ '*' | '?' | '+' ]
+ * | SimplePattern {Id SimplePattern} // op2 must not be empty
+ */
+ Tree pattern2() {
+ return pattern1rest(sp, simplePattern());
+ }
+
+ Tree pattern1rest(int base, Tree top) {
if (s.token == IDENTIFIER) {
if (s.name == STAR) { /* p* becomes z@( |(p,z)) */
s.nextToken();
@@ -1683,22 +1708,13 @@ public class Parser implements Tokens {
}
}
- /** PatDef ::= Pattern `=' Expr
+ /** PatDef ::= Pattern2 [`:' Type] `=' Expr
* ValDcl ::= Id `:' Type
*/
Tree patDefOrDcl(int mods) {
int pos = s.pos;
- Tree pat = validPattern();
- Tree tp;
- switch (pat) {
- case Typed(Tree pat1, Tree tp1):
- pat = pat1;
- tp = tp1;
- break;
- default:
- if (s.token == COLON) tp = typedOpt();
- else tp = Tree.Empty;
- }
+ Tree pat = pattern2();
+ Tree tp = (s.token == COLON) ? typedOpt() : Tree.Empty;
switch (pat) {
case Ident(Name name):
if (tp == Tree.Empty || s.token == EQUALS)
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 364324a3cb..200e9acecf 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -1130,16 +1130,15 @@ public abstract class Symbol implements Modifiers, Kinds {
if (sym1.kind == Kinds.NONE || (sym1.flags & STATIC) != 0) {
return Symbol.NONE;
} else {
- //System.out.println(this + ":" + this.type() + locationString() + " overrides? " + sym1 + sym1.type() + sym1.locationString()); //DEBUG
- //System.out.println(owner.thisType());//DEBUG
+ //System.out.println(this + ":" + this.type() + locationString() + " overrides? " + sym1 + ":" + owner.thisType().memberType(sym1) + sym1.locationString()); //DEBUG
- Type symtype = this.type();//owner.thisType().memberType(this);
- //todo: try whether we can do: this.type(); instead
- Type sym1type = owner.thisType().memberType(sym1);
+ Type symtype = this.type().derefDef();
+ Type sym1type = owner.thisType().memberType(sym1).derefDef();
switch (sym1type) {
case OverloadedType(Symbol[] alts, Type[] alttypes):
for (int i = 0; i < alts.length; i++) {
- if (symtype.isSubType(alttypes[i])) return alts[i];
+ if (symtype.isSubType(alttypes[i].derefDef()))
+ return alts[i];
}
return Symbol.NONE;
default:
@@ -1164,12 +1163,12 @@ public abstract class Symbol implements Modifiers, Kinds {
//System.out.println(this + ":" + this.type() + locationString() + " overrides? " + sym1 + sym1.type() + sym1.locationString()); //DEBUG
//System.out.println(owner.thisType());//DEBUG
- Type symtype = sub.memberType(this);
- Type sym1type = sub.memberType(sym1);
+ Type symtype = sub.memberType(this).derefDef();
+ Type sym1type = sub.memberType(sym1).derefDef();
switch (sym1type) {
case OverloadedType(Symbol[] alts, Type[] alttypes):
for (int i = 0; i < alts.length; i++) {
- if (alttypes[i].isSubType(symtype)) return alts[i];
+ if (alttypes[i].derefDef().isSubType(symtype)) return alts[i];
}
return Symbol.NONE;
default:
@@ -1188,8 +1187,8 @@ public abstract class Symbol implements Modifiers, Kinds {
return
((this.flags | that.flags) & (PRIVATE | STATIC)) == 0 &&
this.name == that.name &&
- owner.thisType().memberType(this).isSubType(
- owner.thisType().memberType(that));
+ owner.thisType().memberType(this).derefDef().isSubType(
+ owner.thisType().memberType(that).derefDef());
}
/** Reset symbol to initial state
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 2b05469f58..acdf8e1d13 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -316,6 +316,17 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
}
}
+ /** If this type is a parameterless method, its underlying resulttype;
+ * otherwise the type itself
+ */
+ public Type derefDef() {
+ switch (this) {
+ case PolyType(Symbol[] tparams, Type restp):
+ if (tparams.length == 0) return restp;
+ }
+ return this;
+ }
+
/** The lower approximation of this type (which must be a typeref)
*/
public Type loBound() {
@@ -706,6 +717,32 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
}
}
+// Set Owner ------------------------------------------------------------------
+
+ public Type setOwner(Symbol owner) {
+ switch (this) {
+ case PolyType(Symbol[] tparams, Type restpe):
+ Type restpe1 = restpe.setOwner(owner);
+ if (restpe1 == restpe) return this;
+ else return Type.PolyType(tparams, restpe1);
+ case MethodType(Symbol[] params, Type restpe):
+ Symbol[] params1 = params;
+ if (params.length > 0 &&
+ params[0].owner() != owner && params[0].owner() != Symbol.NONE) {
+ params1 = new Symbol[params.length];
+ for (int i = 0; i < params.length; i++)
+ params1[i] = params[i].cloneSymbol();
+ }
+ for (int i = 0; i < params.length; i++)
+ params1[i].setOwner(owner);
+ Type restpe1 = restpe.setOwner(owner);
+ if (params1 == params && restpe1 == restpe) return this;
+ else return Type.MethodType(params1, restpe1);
+ default:
+ return this;
+ }
+ }
+
// Maps --------------------------------------------------------------------------
/** The type of type-to-type functions.
@@ -1555,8 +1592,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
Symbol p1 = ps1[i];
Symbol p = ps[i];
if (!p1.type().isSameAs(p.type()) ||
- (p1.flags & (Modifiers.DEF | Modifiers.REPEATED)) !=
- (p.flags & (Modifiers.DEF | Modifiers.REPEATED)))
+ (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED)))
return false;
}
return res.isSubType(res1);
@@ -1828,8 +1864,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
Symbol p1 = ps1[i];
Symbol p = ps[i];
if (!p1.type().isSameAs(p.type()) ||
- (p1.flags & (Modifiers.DEF | Modifiers.REPEATED)) !=
- (p.flags & (Modifiers.DEF | Modifiers.REPEATED)))
+ (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED)))
return false;
}
return res.isSameAs(res1);
@@ -2147,9 +2182,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
int nredundant = 0;
boolean[] redundant = new boolean[tps.length];
for (int i = 0; i < tps.length; i++) {
- if (tps[i] == ErrorType) {
+ switch (tps[i]) {
+ case ErrorType:
return new Type[]{ErrorType};
- } else {
+ case MethodType(_, _):
+ case PolyType(_, _):
+ case OverloadedType(_, _):
+ return new Type[]{NoType};
+ default:
assert tps[i].isObjectType(): tps[i];
for (int j = 0; j < i && !redundant[i]; j++) {
if (!redundant[j]) {
@@ -2186,6 +2226,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
//If all types are method types with same parameters,
//compute lub of their result types.
+ switch (tps[0]) {
+ case PolyType(Symbol[] tparams, _):
+ return polyLub(tps, tparams);
+ case MethodType(Symbol[] vparams, _):
+ return methodLub(tps, vparams);
+ }
// remove types that are subtypes of some other type.
tps = elimRedundant(tps, true);
@@ -2250,6 +2296,66 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
return sym.kind == CLASS ? base.memberType(sym) : base.memberInfo(sym);
}
+ private static Type polyLub(Type[] tps, Symbol[] tparams0) {
+ Type[][] hiboundss = new Type[tparams0.length][tps.length];
+ Type[][] loboundss = new Type[tparams0.length][tps.length];
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case PolyType(Symbol[] tparams, Type restp):
+ if (tparams.length == tparams0.length) {
+ for (int j = 0; j < tparams0.length; j++) {
+ hiboundss[j][i] = tparams[j].info()
+ .subst(tparams, tparams0);
+ loboundss[j][i] = tparams[j].loBound()
+ .subst(tparams, tparams0);
+ }
+ restps[i] = restp.subst(tparams, tparams0);
+ } else {
+ return Type.NoType;
+ }
+ break;
+ default:
+ return Type.NoType;
+ }
+ }
+ Type[] hibounds = new Type[tparams0.length];
+ Type[] lobounds = new Type[tparams0.length];
+ for (int j = 0; j < tparams0.length; j++) {
+ hibounds[j] = glb(hiboundss[j]);
+ lobounds[j] = lub(loboundss[j]);
+ }
+ Symbol[] tparams = new Symbol[tparams0.length];
+ for (int j = 0; j < tparams.length; j++) {
+ tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE)
+ .setInfo(hibounds[j].subst(tparams0, tparams))
+ .setLoBound(lobounds[j].subst(tparams0, tparams));
+ }
+ return Type.PolyType(tparams, lub(restps).subst(tparams0, tparams));
+ }
+
+ private static Type methodLub(Type[] tps, Symbol[] vparams0) {
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case MethodType(Symbol[] vparams, Type restp):
+ if (vparams.length != vparams0.length)
+ return Type.NoType;
+ for (int j = 0; j < vparams.length; j++)
+ if (!vparams[i].type().isSameAs(vparams0[i].type()) ||
+ (vparams[i].flags & (DEF | REPEATED)) !=
+ (vparams0[i].flags & (DEF | REPEATED)))
+ return Type.NoType;
+ restps[i] = restp;
+ }
+ }
+ Symbol[] vparams = new Symbol[vparams0.length];
+ for (int j = 0; j < vparams.length; j++) {
+ vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE);
+ }
+ return Type.MethodType(vparams, lub(restps));
+ }
+
private static Symbol lub(Symbol[] syms, Type[] tps, Type[] lbs, Symbol owner) {
//System.out.println("lub" + ArrayApply.toString(syms));//DEBUG
int lubKind = syms[0].kind;
@@ -2276,7 +2382,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
default:
throw new ApplicationError();
}
- lubSym.setInfo(lubType);
+ lubSym.setInfo(lubType.setOwner(lubSym));
return lubSym;
}
@@ -2426,7 +2532,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
e.sym.setInfo(syminfo);
} else if (sym.kind == VAL && e.sym.kind == VAL ||
sym.kind == TYPE && e.sym.kind == TYPE) {
- e.sym.setInfo(glb(new Type[]{einfo, syminfo}));
+ e.sym.setInfo(glb(new Type[]{einfo, syminfo}).setOwner(e.sym));
} else {
return false;
}
@@ -2444,6 +2550,66 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
return true;
}
+ private static Type polyGlb(Type[] tps, Symbol[] tparams0) {
+ Type[][] hiboundss = new Type[tparams0.length][tps.length];
+ Type[][] loboundss = new Type[tparams0.length][tps.length];
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case PolyType(Symbol[] tparams, Type restp):
+ if (tparams.length == tparams0.length) {
+ for (int j = 0; j < tparams0.length; j++) {
+ hiboundss[j][i] = tparams[j].info()
+ .subst(tparams, tparams0);
+ loboundss[j][i] = tparams[j].loBound()
+ .subst(tparams, tparams0);
+ }
+ restps[i] = restp.subst(tparams, tparams0);
+ } else {
+ return Type.NoType;
+ }
+ break;
+ default:
+ return Type.NoType;
+ }
+ }
+ Type[] hibounds = new Type[tparams0.length];
+ Type[] lobounds = new Type[tparams0.length];
+ for (int j = 0; j < tparams0.length; j++) {
+ hibounds[j] = lub(hiboundss[j]);
+ lobounds[j] = glb(loboundss[j]);
+ }
+ Symbol[] tparams = new Symbol[tparams0.length];
+ for (int j = 0; j < tparams.length; j++) {
+ tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE)
+ .setInfo(hibounds[j].subst(tparams0, tparams))
+ .setLoBound(lobounds[j].subst(tparams0, tparams));
+ }
+ return Type.PolyType(tparams, glb(restps).subst(tparams0, tparams));
+ }
+
+ private static Type methodGlb(Type[] tps, Symbol[] vparams0) {
+ Type[] restps = new Type[tps.length];
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case MethodType(Symbol[] vparams, Type restp):
+ if (vparams.length != vparams0.length)
+ return Type.NoType;
+ for (int j = 0; j < vparams.length; j++)
+ if (!vparams[i].type().isSameAs(vparams0[i].type()) ||
+ (vparams[i].flags & (DEF | REPEATED)) !=
+ (vparams0[i].flags & (DEF | REPEATED)))
+ return Type.NoType;
+ restps[i] = restp;
+ }
+ }
+ Symbol[] vparams = new Symbol[vparams0.length];
+ for (int j = 0; j < vparams.length; j++) {
+ vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE);
+ }
+ return Type.MethodType(vparams, glb(restps));
+ }
+
// Erasure --------------------------------------------------------------------------
public static Map erasureMap = new MapOnlyTypes() {
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
index ed3dd1bac8..e76b9f03cb 100644
--- a/sources/scalac/symtab/classfile/UnPickle.java
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -77,30 +77,6 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
}
}
- Type setOwner(Type tp, Symbol owner) {
- switch (tp) {
- case PolyType(Symbol[] tparams, Type restpe):
- Type restpe1 = setOwner(restpe, owner);
- if (restpe1 == restpe) return tp;
- else return Type.PolyType(tparams, restpe1);
- case MethodType(Symbol[] params, Type restpe):
- Symbol[] params1 = params;
- if (params.length > 0 &&
- params[0].owner() != owner && params[0].owner() != Symbol.NONE) {
- params1 = new Symbol[params.length];
- for (int i = 0; i < params.length; i++)
- params1[i] = params[i].cloneSymbol();
- }
- for (int i = 0; i < params.length; i++)
- params1[i].setOwner(owner);
- Type restpe1 = setOwner(restpe, owner);
- if (params1 == params && restpe1 == restpe) return tp;
- else return Type.MethodType(params1, restpe1);
- default:
- return tp;
- }
- }
-
int readByte() {
return bytes[bp++];
}
@@ -288,7 +264,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
entries[n] = sym = moduleroot;
}
Type tp = getType(inforef);
- sym.setFirstInfo(setOwner(tp, sym));
+ sym.setFirstInfo(tp.setOwner(sym));
break;
default:
@@ -387,7 +363,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
: alts.length + "!=" + alttypes.length +
" at " + bp0 + "/" + bp1 + "/" + bp;
for (int i = 0; i < alts.length; i++)
- alttypes[i] = setOwner(alttypes[i], alts[i]);
+ alttypes[i] = alttypes[i].setOwner(alts[i]);
tpe = Type.OverloadedType(alts, alttypes);
break;
case FLAGGEDtpe:
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 063108a9d0..05657ba759 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -319,20 +319,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
sym.flags &= ~DEFERRED;
}
}
- if ((sym.flags & OVERRIDE) != 0) {
- int i = -1;
- if (sym.owner().kind == CLASS) {
- Type[] parents = sym.owner().info().parents();
- i = parents.length - 1;
- while (i >= 0 &&
- parents[i].lookupNonPrivate(sym.name).kind == NONE)
- i--;
- }
- if (i < 0) {
- error(sym.pos, sym + " overrides nothing");
- sym.flags &= ~OVERRIDE;
- }
- }
checkNoConflict(sym, DEFERRED, PRIVATE);
checkNoConflict(sym, FINAL, SEALED);
checkNoConflict(sym, FINAL, PRIVATE);
diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java
index 5dcf9bf0db..05d8916d66 100644
--- a/sources/scalac/typechecker/Infer.java
+++ b/sources/scalac/typechecker/Infer.java
@@ -123,6 +123,24 @@ public class Infer implements Modifiers, Kinds {
}
}
return tree;
+
+ case TypeApply(Tree fun, Tree[] targs):
+ boolean proceed = true;
+ switch (fun.type) {
+ case PolyType(Symbol[] tparams1, _):
+ if (tparams1.length == tparams.length &&
+ tparams1[0] == tparams[0] &&
+ targs.length == tparams.length) {
+ proceed = false;
+ for (int i = 0; i < tparams.length; i++)
+ if (!typeSubstituter.matches(targs[i].type.symbol(), tparams[i]))
+ proceed = true;
+ }
+ }
+ Tree fun1 = proceed ? transform(fun) : fun;
+ Tree[] targs1 = transform(targs);
+ return copy.TypeApply(tree, fun1, targs1);
+
/*
case TypeTerm():
Symbol sym = tree.type.symbol();
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index da3bef4476..9c493db761 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -71,6 +71,22 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
checkOverride(pos, clazz, it.next(), overrides);
}
}
+
+ Type[] parents = clazz.info().parents();
+ for (Scope.SymbolIterator it = clazz.members().iterator(true);
+ it.hasNext();) {
+ Symbol sym = it.next();
+ if ((sym.flags & OVERRIDE) != 0) {
+ 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");
+ sym.flags &= ~OVERRIDE;
+ }
+ }
+ }
+
for (Iterator/*<Symbol>*/ it = overrides.keySet().iterator();
it.hasNext();) {
Symbol member = (Symbol) it.next();
@@ -89,12 +105,13 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
if ((other.flags & PRIVATE) == 0) {
Symbol member1 = clazz.info().lookup(other.name);
if (member1.kind != NONE && member1.owner() != other.owner()) {
+ Type self = clazz.thisType();
+ Type otherinfo = normalizedInfo(self, other);
+ Type template = resultToAny(otherinfo);
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 (normalizedInfo(self, alts[i]).isSubType(template)) {
if (member == other)
member = alts[i];
else
@@ -109,12 +126,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
break;
default:
- member = member1;
+ if (normalizedInfo(self, member1).isSubType(template)) {
+ member = member1;
+ }
}
}
- }
- if (member != other) {
- checkOverride(pos, clazz, member, other);
+ if (member != other) {
+ checkOverride(pos, clazz, member, other);
+ }
}
if (clazz.kind == CLASS && (clazz.flags & ABSTRACTCLASS) == 0) {
if ((member.flags & DEFERRED) != 0) {
@@ -123,13 +142,24 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
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 &&
+ } else if (member != other &&
+ (member.flags & OVERRIDE) != 0 &&
((other.flags & DEFERRED) == 0 ||
overrides.get(member) == null))
overrides.put(member, other);
}
}
//where
+ private Type resultToAny(Type tp) {
+ switch (tp) {
+ case PolyType(Symbol[] tparams, Type restp):
+ return Type.PolyType(tparams, resultToAny(restp));
+ case MethodType(Symbol[] tparams, Type restp):
+ return Type.MethodType(tparams, Type.AnyType);
+ default:
+ return defs.ANY_TYPE;
+ }
+ }
private void abstractClassError(Symbol clazz, String msg) {
if (clazz.isAnonymousClass())
unit.error(clazz.pos, "object creation impossible, since " + msg);
@@ -227,12 +257,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
Type normalizedInfo(Type site, Symbol sym) {
- Type tp = site.memberInfo(sym);
- switch (tp) {
- case PolyType(Symbol[] tparams, Type restp):
- if (tparams.length == 0) return restp;
- }
- return tp;
+ return site.memberInfo(sym).derefDef();
}
String infoString(Symbol sym, Type symtype, boolean lobound) {
@@ -946,7 +971,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
//System.out.println("name: "+name);
Scope.Entry e = scopes[level].lookupEntry(name);
//System.out.println("sym: "+sym);
- if (sym.isLocal() && sym == e.sym) {
+ if (sym != null && sym.isLocal() && sym == e.sym) {
int i = level;
while (scopes[i] != e.owner) i--;
int symindex = ((Integer) symIndex.get(tree.symbol())).intValue();