summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-05-19 11:12:09 +0000
committerMartin Odersky <odersky@gmail.com>2003-05-19 11:12:09 +0000
commitf7f15007686e355a2d8668bf890603be90810e29 (patch)
treebdb8a9a813fd1a8b32bc20b6988eafe16de4a2f8 /sources
parent2300aac76adab6945ca2d2e3cb15320621a76150 (diff)
downloadscala-f7f15007686e355a2d8668bf890603be90810e29.tar.gz
scala-f7f15007686e355a2d8668bf890603be90810e29.tar.bz2
scala-f7f15007686e355a2d8668bf890603be90810e29.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/$colon$colon.scala2
-rw-r--r--sources/scala/Array.java5
-rw-r--r--sources/scala/List.scala8
-rw-r--r--sources/scala/Predef.scala11
-rw-r--r--sources/scala/Stream.scala74
-rw-r--r--sources/scala/runtime/RunTime.java22
-rw-r--r--sources/scalac/symtab/Symbol.java3
-rw-r--r--sources/scalac/symtab/Type.java146
-rw-r--r--sources/scalac/transformer/LambdaLift.java7
-rw-r--r--sources/scalac/transformer/LambdaLiftPhase.java27
-rw-r--r--sources/scalac/typechecker/Analyzer.java76
11 files changed, 267 insertions, 114 deletions
diff --git a/sources/scala/$colon$colon.scala b/sources/scala/$colon$colon.scala
index 16ad50f31a..cb08998724 100644
--- a/sources/scala/$colon$colon.scala
+++ b/sources/scala/$colon$colon.scala
@@ -3,7 +3,7 @@ package scala {
/* A non empty list.
*
*/
- final case class ::[b, c <: b](hd: b, tl: List[c]) extends List[b] {
+ final case class ::[b](hd: b, tl: List[b]) extends List[b] {
def isEmpty: boolean = false;
def head: b = hd;
def tail: List[b] = tl;
diff --git a/sources/scala/Array.java b/sources/scala/Array.java
index 657210603e..b8b1ae1c30 100644
--- a/sources/scala/Array.java
+++ b/sources/scala/Array.java
@@ -15,11 +15,6 @@ package scala;
*/
public abstract class Array implements Function1 {
- /** @meta constr (scala.Int);
- */
- public Array(int n) {
- }
-
public boolean[] asBooleanArray() {
throw new ClassCastException();
}
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 29a512a3b1..79d182bff2 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -35,7 +35,7 @@ trait List[+a] extends Seq[a] {
* @return the list with <code>x</code> appended at the beginning.
*/
def ::[b >: a](x: b): List[b] =
- new scala.::[b, a](x, this);
+ new scala.::(x, this);
/** Returns a list resulting from the concatenation of the given
* list <code>prefix</code> and this list.
@@ -255,8 +255,8 @@ trait List[+a] extends Seq[a] {
* @return the given array <code>xs</code> filled with this list.
* @throws error if the list is empty.
*/
- def copyToArray[b >: a](xs: Array[b], start: Int): Array[b] = match {
- case Nil => xs
+ def copyToArray[b >: a](xs: Array[b], start: Int): int = match {
+ case Nil => start
case y :: ys => xs(start) = y; ys.copyToArray(xs, start + 1)
}
@@ -275,7 +275,7 @@ trait List[+a] extends Seq[a] {
*/
def mkString(start: String, sep: String, end: String): String =
start +
- (if (isEmpty) end
+ (if (isEmpty) end
else if (tail.isEmpty) head.toString() + end
else head.toString().concat(sep).concat(tail.mkString("", sep, end)));
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
index 6ead2be1c1..6f69c4453e 100644
--- a/sources/scala/Predef.scala
+++ b/sources/scala/Predef.scala
@@ -15,6 +15,17 @@ object Predef {
def List[a](x: a*): List[a] = x as List[a];
val List = scala.List;
+ def Array[a <: AnyRef](classname: String)(x: a*): Array[a] = {
+ System.out.println("array1");
+ val xs0: Array[java.lang.Object] = runtime.RunTime.oarray(x.length, classname);
+ val xs: Array[a] = xs0 as Array[a];
+ System.out.println("array2");
+ val elems = x.elements;
+ var i = 0;
+ while (elems.hasNext) { xs(i) = elems.next; System.out.println(xs(i)) }
+ xs
+ }
+
def error(x: String): All = new java.lang.RuntimeException(x).throw;
def try[a](def block: a): Except[a] =
diff --git a/sources/scala/Stream.scala b/sources/scala/Stream.scala
index 183940e009..7be860553b 100644
--- a/sources/scala/Stream.scala
+++ b/sources/scala/Stream.scala
@@ -1,17 +1,23 @@
package scala;
-trait Stream[+a] {
+trait Stream[+a] extends Seq[a] {
def isEmpty: Boolean;
def head: a;
def tail: Stream[a];
- def length: Int = if (isEmpty) 0 else tail.length + 1;
+ def length: int = if (isEmpty) 0 else tail.length + 1;
- def append(def rest: Stream[a]): Stream[a] =
+ def append[b >: a](def rest: Stream[b]): Stream[b] =
if (isEmpty) rest
else Stream.cons(head, tail.append(rest));
+ def elements: Iterator[a] = new Iterator[a] {
+ var current = Stream.this;
+ def hasNext: boolean = !current.isEmpty;
+ def next: a = { val result = current.head; current = current.tail; result }
+ }
+
def init: Stream[a] =
if (isEmpty) error("Stream.empty.init")
else if (tail.isEmpty) Stream.empty
@@ -22,6 +28,17 @@ trait Stream[+a] {
else if (tail.isEmpty) head
else tail.last;
+ def take(n: int): Stream[a] =
+ if (n == 0) Stream.empty
+ else Stream.cons(head, tail.take(n-1));
+
+ def drop(n: int): Stream[a] =
+ if (n == 0) this
+ else tail.drop(n-1);
+
+ def apply(n: int) = drop(n).head;
+ def at(n: int) = drop(n).head;
+
def takeWhile(p: a => Boolean): Stream[a] =
if (isEmpty || !p(head)) Stream.empty
else Stream.cons(head, tail.takeWhile(p));
@@ -30,21 +47,11 @@ trait Stream[+a] {
if (isEmpty || !p(head)) this
else tail.dropWhile(p);
- def take(n: Int): Stream[a] =
- if (n == 0) Stream.empty
- else Stream.cons(head, tail.take(n-1));
-
- def drop(n: Int): Stream[a] =
- if (n == 0) this
- else tail.drop(n-1);
-
- def at(n: Int) = drop(n).head;
-
def map[b](f: a => b): Stream[b] =
if (isEmpty) Stream.empty
else Stream.cons(f(head), tail.map(f));
- def foreach(f: a => Unit): Unit =
+ def foreach(f: a => unit): unit =
if (isEmpty) {}
else { f(head); tail.foreach(f) }
@@ -83,10 +90,8 @@ trait Stream[+a] {
if (isEmpty) Stream.empty
else f(head).append(tail.flatMap(f));
- def reverse: Stream[a] = {
- def snoc(xs: Stream[a], x: a): Stream[a] = Stream.cons(x, xs);
- foldLeft(Stream.empty: Stream[a])(snoc)
- }
+ def reverse: Stream[a] =
+ foldLeft(Stream.empty: Stream[a])((xs, x) => Stream.cons(x, xs));
// The following method is not compilable without run-time type
// information. It should therefore be left commented-out for
@@ -97,22 +102,26 @@ trait Stream[+a] {
// xs
// }
- def copyToArray[b >: a](xs: Array[b], start: Int): Int = {
- xs(start) = head;
- tail.copyToArray(xs, start + 1)
- }
+ def copyToArray[b >: a](xs: Array[b], start: int): int =
+ if (isEmpty) start
+ else { xs(start) = head; tail.copyToArray(xs, start + 1) }
def zip[b](that: Stream[b]): Stream[Tuple2[a, b]] =
if (this.isEmpty || that.isEmpty) Stream.empty
else Stream.cons(Tuple2(this.head, that.head), this.tail.zip(that.tail));
- def print: Unit =
+ def print: unit =
if (isEmpty) System.out.println("Stream.empty")
else {
System.out.print(head as java.lang.Object);
System.out.print(", ");
tail.print
}
+
+ override def toString() =
+ "Stream(" + printElems(new StringBuffer(), "") + ")";
+
+ def printElems(buf: StringBuffer, prefix: String): StringBuffer;
}
object Stream {
@@ -121,19 +130,22 @@ object Stream {
def isEmpty = true;
def head: All = error("head of empty stream");
def tail: Stream[All] = error("tail of empty stream");
- override def toString(): String = "Stream.empty";
+ def printElems(buf: StringBuffer, prefix: String): StringBuffer = buf;
}
- def cons[b](hd: b, def tl: Stream[b]): Stream[b] = new Stream[b] {
+ def cons[a](hd: a, def tl: Stream[a]) = new Stream[a] {
def isEmpty = false;
def head = hd;
- private var tlVal: Stream[b] = _;
- private var tlDefined: Boolean = false;
- def tail: Stream[b] = {
+ private var tlVal: Stream[a] = _;
+ private var tlDefined = false;
+ def tail: Stream[a] = {
if (!tlDefined) { tlVal = tl; tlDefined = true; }
tlVal
}
- override def toString(): String = "ConsStream(" + hd + ", ?)";
+ def printElems(buf: StringBuffer, prefix: String): StringBuffer = {
+ val buf1 = buf.append(prefix).append(hd as java.lang.Object);
+ if (tlDefined) printElems(buf1, ", ") else buf1 append ", ?";
+ }
}
def concat[a](xs: Seq[Stream[a]]): Stream[a] = concat(xs.elements);
@@ -142,4 +154,8 @@ object Stream {
if (xs.hasNext) xs.next append concat(xs)
else empty;
}
+
+ def range(start: int, end: int): Stream[int] =
+ if (start >= end) empty
+ else cons(start, range(start + 1, end));
}
diff --git a/sources/scala/runtime/RunTime.java b/sources/scala/runtime/RunTime.java
index d9f02392d3..9766085243 100644
--- a/sources/scala/runtime/RunTime.java
+++ b/sources/scala/runtime/RunTime.java
@@ -351,7 +351,7 @@ public abstract class RunTime {
}
public static Array box(final boolean[] xs) {
- return new Array(0) {
+ return new Array() {
public boolean[] asBooleanArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Boolean)x).asBoolean(); }
@@ -361,7 +361,7 @@ public abstract class RunTime {
}
public static Array box(final byte[] xs) {
- return new Array(0) {
+ return new Array() {
public byte[] asByteArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Byte)x).asByte(); }
@@ -371,7 +371,7 @@ public abstract class RunTime {
}
public static Array box(final short[] xs) {
- return new Array(0) {
+ return new Array() {
public short[] asShortArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Short)x).asShort(); }
@@ -381,7 +381,7 @@ public abstract class RunTime {
}
public static Array box(final char[] xs) {
- return new Array(0) {
+ return new Array() {
public char[] asCharArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Char)x).asChar(); }
@@ -391,7 +391,7 @@ public abstract class RunTime {
}
public static Array box(final int[] xs) {
- return new Array(0) {
+ return new Array() {
public int[] asIntArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Int)x).asInt(); }
@@ -401,7 +401,7 @@ public abstract class RunTime {
}
public static Array box(final long[] xs) {
- return new Array(0) {
+ return new Array() {
public long[] asLongArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Long)x).asLong(); }
@@ -411,7 +411,7 @@ public abstract class RunTime {
}
public static Array box(final float[] xs) {
- return new Array(0) {
+ return new Array() {
public float[] asFloatArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Float)x).asFloat(); }
@@ -421,7 +421,7 @@ public abstract class RunTime {
}
public static Array box(final double[] xs) {
- return new Array(0) {
+ return new Array() {
public double[] asDoubleArray() { return xs; }
public Object apply(int i) { return box(xs[i]); }
public void update(int i, Object x) { xs[i] = ((Double)x).asDouble(); }
@@ -431,7 +431,7 @@ public abstract class RunTime {
}
public static Array box(final Object[] xs) {
- return new Array(0) {
+ return new Array() {
public Object[] asObjectArray() { return xs; }
public Object apply(int i) { return xs[i]; }
public void update(int i, Object x) { xs[i] = x; }
@@ -472,10 +472,10 @@ public abstract class RunTime {
return new double[length];
}
- public static Object oarray(int length, String classname) {
+ public static Object[] oarray(int length, String classname) {
try {
Class clasz = Class.forName(classname, false, loader);
- return java.lang.reflect.Array.newInstance(clasz, length);
+ return (Object[]) java.lang.reflect.Array.newInstance(clasz, length);
} catch (ClassNotFoundException exception) {
throw new Error(exception.toString());
}
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 3bb3f76e87..a259e0d62f 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -748,7 +748,8 @@ public abstract class Symbol implements Modifiers, Kinds {
/** String representation of location.
*/
public String locationString() {
- if (owner.kind == CLASS && !owner.isAnonymousClass())
+ if (owner.kind == CLASS && !owner.isAnonymousClass() ||
+ Global.instance.debug)
return " in " + owner;
else
return "";
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 110a0f80bc..15c3d47649 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -141,6 +141,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
public Type widen() {
return type().widen();
}
+
/** If this type is a singleton type whose type is another, the end of the chain,
* otherwise the type itself.
*/
@@ -235,6 +236,25 @@ public class Type implements Modifiers, Kinds, TypeTags {
return this;
}
+ /** The lower approximation of this type (which must be a typeref)
+ */
+ public Type loBound() {
+ switch (unalias()) {
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ Type lb = Global.instance.definitions.ANY_TYPE;
+ if (sym.kind == TYPE) {
+ lb = sym.loBound().asSeenFrom(pre, sym.owner());
+ }
+ if (lb.isSameAs(Global.instance.definitions.ANY_TYPE) &&
+ this.isSubType(Global.instance.definitions.ANYREF_TYPE)) {
+ lb = Global.instance.definitions.ANYREF_TYPE;
+ }
+ return lb;
+ default:
+ throw new ApplicationError();
+ }
+ }
+
/** The thistype or singleton type corresponding to values of this type.
*/
public Type narrow() {
@@ -1306,9 +1326,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
case TypeRef(_, Symbol sym, _):
switch (that) {
case TypeRef(Type pre1, Symbol sym1, _):
- if (sym1.kind == TYPE &&
- this.isSubType(
- sym1.loBound().asSeenFrom(pre1, sym1.owner())))
+ if (sym1.kind == TYPE && this.isSubType(that.loBound()))
return true;
}
if (sym.kind == ALIAS)
@@ -1826,7 +1844,6 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
/** Return the least upper bound of non-empty array of types `tps'.
- * todo: treat types with refinements
*/
public static Type lub(Type[] tps) {
//System.out.println("lub" + ArrayApply.toString(tps));//DEBUG
@@ -1922,11 +1939,130 @@ public class Type implements Modifiers, Kinds, TypeTags {
}
private static Type glb(Type[] tps) {
+ // step one: eliminate redunandant types; return if one one is left
tps = elimRedundant(tps, false);
if (tps.length == 1) return tps[0];
- else return NoType;
+
+ // step two: build arrays of all typerefs and all refinements
+ Type.List treftl = Type.List.EMPTY;
+ Type.List comptl = Type.List.EMPTY;
+ for (int i = 0; i < tps.length; i++) {
+ switch (tps[i]) {
+ case TypeRef(_, _, _):
+ treftl = new Type.List(tps[i], treftl);
+ break;
+ case CompoundType(Type[] parents, Scope members):
+ if (members.elems != Scope.Entry.NONE)
+ comptl = new Type.List(tps[i], comptl);
+ for (int j = 0; j < parents.length; j++)
+ treftl = new Type.List(parents[i], treftl);
+ break;
+ case ThisType(_):
+ case SingleType(_, _):
+ return Global.instance.definitions.ALL_TYPE;
+ }
+ }
+
+ CompoundType glbType = compoundType(Type.EMPTY_ARRAY, new Scope());
+ Type glbThisType = glbType.narrow();
+
+ // step 3: compute glb of all refinements.
+ Scope members = Scope.EMPTY;
+ if (comptl != List.EMPTY) {
+ Type[] comptypes = comptl.toArrayReverse();
+ Scope[] refinements = new Scope[comptypes.length];
+ for (int i = 0; i < comptypes.length; i++)
+ refinements[i] = comptypes[i].members();
+ if (!setGlb(glbType.members, refinements, glbThisType)) {
+ // refinements don't have lower bound, so approximate
+ // by AllRef
+ glbType.members = Scope.EMPTY;
+ treftl = new Type.List(
+ Global.instance.definitions.ALLREF_TYPE, treftl);
+ }
+ }
+
+ // eliminate redudant typerefs
+ Type[] treftypes = elimRedundant(treftl.toArrayReverse(), false);
+ if (treftypes.length != 1 || glbType.members.elems != Scope.Entry.NONE) {
+ // step 4: replace all abstract types by their lower bounds.
+ boolean hasAbstract = false;
+ for (int i = 0; i < treftypes.length; i++) {
+ if (treftypes[i].unalias().symbol().kind == TYPE)
+ hasAbstract = true;
+ }
+ if (hasAbstract) {
+ treftl = Type.List.EMPTY;
+ for (int i = 0; i < treftypes.length; i++) {
+ if (treftypes[i].unalias().symbol().kind == TYPE)
+ treftl = new Type.List(treftypes[i].loBound(), treftl);
+ else
+ treftl = new Type.List(treftypes[i], treftl);
+ }
+ treftypes = elimRedundant(treftl.toArrayReverse(), false);
+ }
+ }
+
+ if (treftypes.length != 1) {
+ // step 5: if there are conflicting instantiations of same
+ // class, replace them by lower bound.
+ Type lb = NoType;
+ for (int i = 0;
+ i < treftypes.length &&
+ lb != Global.instance.definitions.ALL_TYPE;
+ i++) {
+ for (int j = 0; j < i; j++) {
+ if (treftypes[j].symbol() == treftypes[i].symbol())
+ lb = treftypes[i].loBound();
+ }
+ }
+ if (lb != NoType) return lb;
+ }
+
+ if (treftypes.length == 1 && glbType.members.elems == Scope.Entry.NONE) {
+ return treftypes[0];
+ } else {
+ glbType.parts = treftypes;
+ return glbType;
+ }
+ }
+
+ private static boolean setGlb(Scope result, Scope[] ss, Type glbThisType) {
+ for (int i = 0; i < ss.length; i++)
+ for (Scope.Entry e = ss[i].elems; e != Scope.Entry.NONE; e = e.next)
+ if (!addMember(result, e.sym, glbThisType)) return false;
+ return true;
}
+ private static boolean addMember(Scope s, Symbol sym, Type glbThisType) {
+ Type syminfo = sym.info().substThis(sym.owner(), glbThisType);
+ Scope.Entry e = s.lookupEntry(sym.name);
+ if (e == Scope.Entry.NONE) {
+ Symbol sym1 = sym.cloneSymbol();
+ sym1.setOwner(glbThisType.symbol());
+ sym1.setInfo(syminfo);
+ s.enter(sym1);
+ return true;
+ } else {
+ Type einfo = e.sym.info();
+ if (einfo.isSameAs(syminfo)) {
+ return true;
+ } else if (einfo.isSubType(syminfo) && sym.kind != ALIAS) {
+ return true;
+ } else if (syminfo.isSubType(einfo) && e.sym.kind != ALIAS) {
+ e.sym.setInfo(syminfo);
+ return true;
+ } else if (sym.kind == VAL && e.sym.kind == VAL ||
+ sym.kind == TYPE && e.sym.kind == TYPE) {
+ e.sym.setInfo(glb(new Type[]{einfo, syminfo}));
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+
// Erasure --------------------------------------------------------------------------
public static Map erasureMap = new MapOnlyTypes() {
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index e6d2fc902b..fd89c3c260 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -310,7 +310,9 @@ public class LambdaLift extends OwnerTransformer
public Tree transform(Tree tree) {
//global.debugPrinter.print("lifting ").print(tree).println().end();//DEBUG
+ //System.out.print(tree.type + " --> ");//DEBUG
tree.type = descr.transform(tree.type, currentOwner);
+ //System.out.println(tree.type);//DEBUG
switch (tree) {
case ClassDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
Symbol sym = tree.symbol();
@@ -403,7 +405,7 @@ public class LambdaLift extends OwnerTransformer
return copy.Apply(
tree, fn1, addFreeArgs(tree.pos, get(free.fvs, fsym), args1));
- case Ident(_):
+ case Ident(Name name):
Symbol sym = tree.symbol();
if (sym.isLocal() &&
(sym.kind == TYPE || (sym.kind == VAL && !sym.isMethod()))) {
@@ -411,6 +413,7 @@ public class LambdaLift extends OwnerTransformer
}
Tree tree1 = copy.Ident(tree, sym).setType(
sym.typeAt(descr.nextPhase));
+ if (name != sym.name) ((Ident)tree1).name = sym.name;
if ((sym.flags & CAPTURED) != 0) return gen.Select(tree1, Names.elem);
else return tree1;
@@ -563,7 +566,7 @@ public class LambdaLift extends OwnerTransformer
gen.mkRef(
pos,
global.definitions.getClass(Names.scala_COLONCOLON).constructor()),
- new Tree[]{gen.mkType(pos, elemtpe), gen.mkType(pos, elemtpe)}),
+ new Tree[]{gen.mkType(pos, elemtpe)}),
new Tree[]{hd, tl}));
}
}
diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java
index 11141db9b2..df31745da5 100644
--- a/sources/scalac/transformer/LambdaLiftPhase.java
+++ b/sources/scalac/transformer/LambdaLiftPhase.java
@@ -13,6 +13,7 @@ import scalac.util.*;
import scalac.parser.*;
import scalac.symtab.*;
import scalac.checkers.*;
+import java.util.ArrayList;
public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers {
@@ -43,7 +44,7 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
public Type transformInfo(Symbol sym, Type tp) {
if (global.debug)
- global.log("transform info for " + sym + sym.locationString());
+ global.log("transform info for " + sym + ":" + tp + sym.locationString());
Type tp1 = tp;
if (sym != Symbol.NONE) {
switch (tp) {
@@ -53,7 +54,7 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
break;
default:
if (sym.kind == CLASS)
- tp = transform(tp, sym);
+ tp1 = transform(tp, sym);
else
tp1 = transform(tp, sym.owner());
}
@@ -70,6 +71,7 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
private class TransformTypeMap extends Type.MapOnlyTypes {
Symbol owner;
+// ArrayList/*<Symbol>*/ excluded = new ArrayList();
Type.Map setOwner(Symbol owner) { this.owner = owner; return this; }
public Type apply(Type tp) {
@@ -95,9 +97,24 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
}
return Type.TypeRef(pre, sym, targs1);
}
+ } else if (sym.isLocal()) {
+ assert targs.length == 0;
+ return proxy(sym, owner).type();
}
}
break;
+/*
+ case PolyType(Symbol[] tparams, _):
+ if (tparams.length != 0) {
+ int len = excluded.size();
+ for (int i = 0; i < tparams.length; i++)
+ excluded.add(tparams[i]);
+ Type tp1 = map(tp);
+ for (int i = 0; i < tparams.length; i++)
+ excluded.remove(excluded.size() - 1);
+ return tp1;
+ }
+*/
}
return map(tp);
}
@@ -116,7 +133,7 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
*/
Symbol proxy(Symbol fv, Symbol owner) {
if (global.debug)
- global.log("proxy " + fv + " in " + LambdaLift.asFunction(owner));
+ global.log("proxy " + fv + " of " + fv.owner() + " in " + LambdaLift.asFunction(owner));
Symbol o = owner;
while (o.kind != NONE) {
if (global.debug)
@@ -134,9 +151,9 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers
}
assert o.owner() != o;
o = o.owner();
-
}
- throw new ApplicationError("proxy " + fv + " in " + owner);
+ return fv;
+ //throw new ApplicationError("proxy " + fv + " in " + owner);
}
/** The type scala.Ref[tp]
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index f4d2ed8fa0..2bec0ab167 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -380,39 +380,38 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
*/
void validateBaseTypes(Symbol clazz) {
validateBaseTypes(clazz, clazz.type().parents(),
- new boolean[clazz.closure().length], 0);
+ new Type[clazz.closure().length], 0);
}
//where
- void validateBaseTypes(Symbol clazz, Type[] tps, boolean[] seen, int start) {
+ void validateBaseTypes(Symbol clazz, Type[] tps, Type[] seen, int start) {
for (int i = tps.length - 1; i >= start; i--) {
validateBaseTypes(clazz, tps[i].unalias(), seen, i == 0 ? 0 : 1);
}
}
- void validateBaseTypes(Symbol clazz, Type tp, boolean[] seen, int start) {
+ void validateBaseTypes(Symbol clazz, Type tp, Type[] seen, int start) {
Symbol baseclazz = tp.symbol();
if (baseclazz.kind == CLASS) {
int index = clazz.closurePos(baseclazz);
if (index < 0) return;
- if (seen[index]) {
+ if (seen[index] != null) {
// check that only uniform classes are inherited several times.
if (!clazz.isCompoundSym() && !baseclazz.isTrait()) {
error(clazz.pos, "illegal inheritance;\n" + clazz +
" inherits " + baseclazz + " twice");
}
- // check no two different type instances of same class
- // are inherited.
- Type tp1 = clazz.closure()[index];
- if (!tp1.isSameAs(tp)) {
+ // if there are two different type instances of same class
+ // check that second is a subtype of first.
+ if (!seen[index].isSubType(tp)) {
if (clazz.isCompoundSym())
error(clazz.pos,
"illegal combination;\n " + "compound type " +
" combines different type instances of " +
- baseclazz + ":\n" + tp + " and " + tp1);
+ baseclazz + ":\n" + tp + " and " + seen[index]);
else
error(clazz.pos, "illegal inheritance;\n " + clazz +
" inherits different type instances of " +
- baseclazz + ":\n" + tp + " and " + tp1);
+ baseclazz + ":\n" + tp + " and " + seen[index]);
}
}
// check that case classes do not inherit from case classes
@@ -420,7 +419,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
error(clazz.pos, "illegal inheritance;\n " + "case " + clazz +
" inherits from other case " + baseclazz);
- seen[index] = true;
+ seen[index] = tp;
validateBaseTypes(clazz, tp.parents(), seen, start);
}
}
@@ -468,8 +467,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
checkNonCyclic(
pos, pre.memberInfo(sym).subst(sym.typeParams(), args));
if (sym.kind == TYPE)
- checkNonCyclic(
- pos, sym.loBound().asSeenFrom(pre, sym.owner()));
+ checkNonCyclic(pos, tp.loBound());
sym.flags &= ~LOCKED;
}
break;
@@ -755,7 +753,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
void validateVariance(Symbol base, Type all, Type[] tps, int variance, Symbol[] tparams) {
for (int i = 0; i < tps.length; i++)
- if (tps[i] != tparams[i].type())
+// if (tps[i] != tparams[i].type())
validateVariance(base, all, tps[i], variance * tparams[i].variance());
}
@@ -825,12 +823,16 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (clazz.isLocalClass()) unit.mangler.setMangledName(clazz);
enterSym(tree, clazz.constructor());
- if ((mods & (ABSTRACTCLASS | CASE)) == CASE) {
- // enter case constructor method.
- enterInScope(
- new TermSymbol(
- tree.pos, name.toTermName(), owner, mods & (ACCESSFLAGS | CASE))
- .setInfo(new LazyConstrMethodType(tree)));
+ if ((mods & CASE) != 0) {
+ if (vparams.length == 0) {
+ error(tree.pos, "case class needs () parameter section");
+ } else if ((mods & ABSTRACTCLASS) == 0) {
+ // enter case constructor method.
+ enterInScope(
+ new TermSymbol(
+ tree.pos, name.toTermName(), owner, mods & (ACCESSFLAGS | CASE))
+ .setInfo(new LazyConstrMethodType(tree)));
+ }
}
return enterSym(tree, clazz);
@@ -1755,30 +1757,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return tree;
} else {
Symbol sym = tree.symbol();
- // convert nullary case methods to types
- // check that other idents or selects are stable.
+ // check that idents or selects are stable.
switch (tree) {
case Ident(_):
- if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0)
- return transform(
- make.Apply(
- tree.pos,
- copy.Ident(tree, sym.type().resultType().symbol()),
- Tree.EMPTY_ARRAY),
- mode, pt);
- else
- checkStable(tree);
- break;
- case Select(Tree qual, _):
- if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0)
- return transform(
- make.Apply(
- tree.pos,
- copy.Select(tree, sym.type().resultType().symbol(), qual),
- Tree.EMPTY_ARRAY),
- mode, pt);
- else
- checkStable(tree);
+ case Select(_, _):
+ checkStable(tree);
}
}
} else if ((mode & EXPRmode) != 0) {
@@ -1815,15 +1798,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return tree;
}
//where
- boolean isNullaryMethod(Symbol sym) {
- switch (sym.type()) {
- case PolyType(_, Type restpe):
- return !(restpe instanceof Type.MethodType);
- default:
- return false;
- }
- }
-
Type seqConstructorType(Type paramtp, Type resulttp) {
Symbol constr = resulttp.symbol().constructor();
Symbol param = new TermSymbol(