summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-06-13 11:34:44 +0000
committerMartin Odersky <odersky@gmail.com>2003-06-13 11:34:44 +0000
commit84af8bf38da09da1a4fe183696739d045a72ac79 (patch)
tree0d540061d277f2705c66d82d484546a50ac941d2
parent43a8b154ed15b2b893f54abe24761cae660867e1 (diff)
downloadscala-84af8bf38da09da1a4fe183696739d045a72ac79.tar.gz
scala-84af8bf38da09da1a4fe183696739d045a72ac79.tar.bz2
scala-84af8bf38da09da1a4fe183696739d045a72ac79.zip
*** empty log message ***
-rw-r--r--sources/scalac/symtab/Symbol.java10
-rw-r--r--sources/scalac/symtab/Type.java5
-rw-r--r--sources/scalac/typechecker/Analyzer.java7
-rw-r--r--sources/scalac/typechecker/RefCheck.java59
-rw-r--r--test/files/pos/stable.scala6
-rw-r--r--test/files/pos/valdefs.scala4
-rw-r--r--test/pos/stable.scala6
-rw-r--r--test/pos/valdefs.scala4
8 files changed, 72 insertions, 29 deletions
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index f69506fc6d..7ab12576da 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -195,8 +195,14 @@ public abstract class Symbol implements Modifiers, Kinds {
if (infos.limit < 0) return false;
switch (rawInfo()) {
case MethodType(_, _):
- case PolyType(_, _): return true;
- default: return false;
+ case PolyType(_, _):
+ return true;
+ case OverloadedType(Symbol[] alts, _):
+ for (int i = 0; i < alts.length; i++)
+ if (alts[i].isMethod()) return true;
+ return false;
+ default:
+ return false;
}
}
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 7fa877dc82..36e7431fdf 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -1320,7 +1320,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
if (!isSubType(alttypes1[i]))
return false;
}
- break;
+ return true;
case UnboxedType(int tag1):
switch (this) {
@@ -1948,13 +1948,14 @@ public class Type implements Modifiers, Kinds, TypeTags {
e = e.next) {
Name name = e.sym.name;
if ((e.sym.flags & PRIVATE) == 0 && lubType.lookup(name) == e.sym) {
- //todo: not info?
Type symType = memberTp(lubThisType, e.sym);
Type symLoBound = lubThisType.memberLoBound(e.sym);
int j = 0;
while (j < tps.length) {
rsyms[j] = tps[j].lookupNonPrivate(name);
if (rsyms[j] == e.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])
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index c4b404cc9a..b4b9d078d0 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -133,7 +133,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// expressions may be packages and
// Java statics modules.
- static final int SUPERmode = 0x080; // orthogonal to above. When set
+ static final int SUPERmode = 0x080; // Goes with CONSTRmode. When set
// we are checking a superclass
// constructor invocation.
@@ -192,6 +192,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
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");
+ }
}
/** Is `sym' accessible as a member of tree `site' in current context?
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index 3719fe0664..dc6cfe73f2 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -55,7 +55,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
// Override checking ------------------------------------------------------------
- /** Check all members of class `clazz' for overriding conditions.
+ /** 1. Check all members of class `clazz' for overriding conditions.
+ * 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();
@@ -67,28 +70,56 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
if (other != member && (other.flags & PRIVATE) == 0 &&
member.kind != NONE)
checkOverride(pos, clazz, member, other);
- if ((member.flags & DEFERRED) != 0 &&
- clazz.kind == CLASS &&
- (clazz.flags & ABSTRACTCLASS) == 0) {
- if (clazz.isAnonymousClass())
- unit.error(
- clazz.pos, "object creation impossible, since " +
+ 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
- unit.error(clazz.pos,
- clazz + " needs to be abstract; it does not define " +
- member + member.locationString() +
- (((member.flags & MUTABLE) == 0) ? ""
- : "\n(Note that variables need to be initialized to be defined)"));
- clazz.flags |= ABSTRACTCLASS;
+ }
+ if ((other.flags & OVERRIDE) != 0) {
+ Type[] clparents = closure[i].parents();
+ Symbol sym1 = null;
+ for (int j = clparents.length - 1; sym1 == null && j > 0; j--)
+ sym1 = clparents[j].lookup(other.name);
+ if (sym1 == null) {
+ Symbol superclazz = clazz.info().parents()[0].symbol();
+ if (superclazz.isSubClass(closure[i].symbol()))
+ superclazz = clparents[0].symbol();
+ sym1 = superclazz.lookup(other.name);
+ }
+ if (sym1 != null && (sym1.flags & DEFERRED) != 0)
+ abstractClassError(
+ clazz, other + other.locationString() +
+ " is marked `override' and overrides an abstract member" + sym1.locationString());
+ }
}
}
}
}
+ //where
+ private void abstractClassError(Symbol clazz, String msg) {
+ if (clazz.isAnonymousClass())
+ unit.error(clazz.pos, "object creation impossible, since " + msg);
+ else
+ unit.error(clazz.pos, clazz + " needs to be abstract, since " + msg);
+ clazz.flags |= ABSTRACTCLASS;
+ }
/** Check that all conditions for overriding `other' by `member' are met.
+ * That is for overriding member M and overridden member O:
+ *
+ * 1. M must have the same or stronger access priviliges as O.
+ * 2. O must not be final.
+ * 3. O is deferred, or M has `override' modifier.
+ * 4. O is not a class, nor a class constructor.
+ * 5. If O is a type alias, then M is an alias of O.
+ * 6. If O is an abstract type then
+ * either M is an abstract type, and M's bounds are sharper than O's bounds.
+ * or M is a type alias or class which conforms to O's bounds.
+ * 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) {
if (member.owner() == clazz) pos = member.pos;
diff --git a/test/files/pos/stable.scala b/test/files/pos/stable.scala
index 2ae6e2dcec..267a36fe5c 100644
--- a/test/files/pos/stable.scala
+++ b/test/files/pos/stable.scala
@@ -5,7 +5,7 @@ trait Base {
}
class Sub() extends Base {
- override val x: Int = 1;
- override val y: Int = 2;
- override var z: Int = 3;
+ val x: Int = 1;
+ val y: Int = 2;
+ var z: Int = 3;
}
diff --git a/test/files/pos/valdefs.scala b/test/files/pos/valdefs.scala
index f9150ea509..6e91b020b5 100644
--- a/test/files/pos/valdefs.scala
+++ b/test/files/pos/valdefs.scala
@@ -10,7 +10,7 @@ object test {
override val y = 1;
}
- class Sub2() extends Base() {
+ abstract class Sub2() extends Base() {
override val Pair(x, y) = Pair("abc", 1);
}
-} \ No newline at end of file
+}
diff --git a/test/pos/stable.scala b/test/pos/stable.scala
index 2ae6e2dcec..267a36fe5c 100644
--- a/test/pos/stable.scala
+++ b/test/pos/stable.scala
@@ -5,7 +5,7 @@ trait Base {
}
class Sub() extends Base {
- override val x: Int = 1;
- override val y: Int = 2;
- override var z: Int = 3;
+ val x: Int = 1;
+ val y: Int = 2;
+ var z: Int = 3;
}
diff --git a/test/pos/valdefs.scala b/test/pos/valdefs.scala
index f9150ea509..6e91b020b5 100644
--- a/test/pos/valdefs.scala
+++ b/test/pos/valdefs.scala
@@ -10,7 +10,7 @@ object test {
override val y = 1;
}
- class Sub2() extends Base() {
+ abstract class Sub2() extends Base() {
override val Pair(x, y) = Pair("abc", 1);
}
-} \ No newline at end of file
+}