summaryrefslogtreecommitdiff
path: root/sources/scalac/typechecker
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-09-10 13:50:32 +0000
committerMartin Odersky <odersky@gmail.com>2003-09-10 13:50:32 +0000
commit957c42dadf55e3b67511077acfc4dd05e9a76b1d (patch)
tree2d2e3e6f8b0c903963d5b3a228bcaa0172dc4041 /sources/scalac/typechecker
parent86451906a534a8a09eafde0f35591071f0f0d5a3 (diff)
downloadscala-957c42dadf55e3b67511077acfc4dd05e9a76b1d.tar.gz
scala-957c42dadf55e3b67511077acfc4dd05e9a76b1d.tar.bz2
scala-957c42dadf55e3b67511077acfc4dd05e9a76b1d.zip
*** empty log message ***
Diffstat (limited to 'sources/scalac/typechecker')
-rw-r--r--sources/scalac/typechecker/Analyzer.java25
-rw-r--r--sources/scalac/typechecker/RefCheck.java123
2 files changed, 78 insertions, 70 deletions
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/*<Symbol,Symbol>*/ overrides = null;
+ HashMap/*<Symbol,Symbol>*/ 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/*<Symbol>*/ 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/*<Symbol>*/ 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/*<Symbol,Symbol>*/ 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;
}