summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-05-25 18:08:50 +0000
committerMartin Odersky <odersky@gmail.com>2006-05-25 18:08:50 +0000
commite3b1cc9130d7046905cc86f0f25e25c1010c5900 (patch)
tree0abeb2581b9d492db0cfb26b16753306a1ee3227 /src
parent5da7b0a3958c3c66803ba375c7d43f2a471f5322 (diff)
downloadscala-e3b1cc9130d7046905cc86f0f25e25c1010c5900.tar.gz
scala-e3b1cc9130d7046905cc86f0f25e25c1010c5900.tar.bz2
scala-e3b1cc9130d7046905cc86f0f25e25c1010c5900.zip
Some more changes to fix 605
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala50
-rw-r--r--src/library/scala/Stream.scala150
4 files changed, 135 insertions, 74 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 81696a5612..fa7ddc1ce7 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -202,14 +202,15 @@ trait Symbols requires SymbolTable {
/** Is this symbol an implementation class for a mixin? */
final def isImplClass: boolean = isClass && hasFlag(IMPLCLASS);
+ /** Is this symbol a trait which needs an implementation class? */
final def needsImplClass: boolean =
isTrait && (!hasFlag(INTERFACE) || hasFlag(lateINTERFACE)) && !isImplClass;
+ /** Is this a symbol which exists only in the implementation class, not in its trait? */
final def isImplOnly: boolean = (
hasFlag(PRIVATE) ||
(owner.isImplClass || owner.isTrait) &&
- (hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR) ||
- isConstructor)
+ (hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR) || isConstructor)
);
/** Is this symbol a module variable ? */
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 5914c7cb53..6f10e487e4 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -360,7 +360,7 @@ trait Types requires SymbolTable {
}
//todo: use narrow only for modules? (correct? efficiency gain?)
- def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
+ def findMember(name: Name, excludedFlags: int, requiredFlags: long): Symbol = {
if (util.Statistics.enabled) findMemberCount = findMemberCount + 1;
val startTime = if (util.Statistics.enabled) System.currentTimeMillis() else 0l;
@@ -475,7 +475,7 @@ trait Types requires SymbolTable {
// todo see whether we can do without
override def isError: boolean = true;
override def decls: Scope = new ErrorScope(NoSymbol);
- override def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
+ override def findMember(name: Name, excludedFlags: int, requiredFlags: long): Symbol = {
var sym = decls lookup name;
if (sym == NoSymbol) {
sym = NoSymbol.newErrorSymbol(name);
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 1baba07e32..f81bc4d0a1 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -67,8 +67,6 @@ abstract class Mixin extends InfoTransform {
def addLateInterfaceMembers(clazz: Symbol): unit =
if (!(clazz hasFlag MIXEDIN)) {
clazz setFlag MIXEDIN;
- for (val bc <- clazz.info.baseClasses.reverse)
- if (bc.hasFlag(lateINTERFACE)) addLateInterfaceMembers(bc)
def newGetter(field: Symbol): Symbol =
clazz.newMethod(field.pos, nme.getterName(field.name))
.setFlag(field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | DEFERRED | SYNTHETIC)
@@ -110,25 +108,53 @@ abstract class Mixin extends InfoTransform {
addMixedinMembers(superclazz);
//System.out.println("adding members of " + clazz.info.baseClasses.tail.takeWhile(superclazz !=) + " to " + clazz);//DEBUG
val mixins = clazz.info.baseClasses.tail.takeWhile(superclazz !=);
- def mixinMembers(mixinClass: Symbol, mmap: Symbol => Symbol): unit = {
+ def mixinMembers(mixinClass: Symbol): unit = {
//Console.println("mixin members of "+mixinClass+" to "+clazz+" "+clazz.info.baseClasses)//DEBUG
if (mixinClass.isImplClass) {
addLateInterfaceMembers(mixinClass.toInterface);
for (val member <- mixinClass.info.decls.toList) {
+ if (isForwarded(member) && !member.isImplOnly) {
+ val imember = member.overriddenSymbol(mixinClass.toInterface)
+ if (imember.overridingSymbol(clazz) == NoSymbol &&
+ atPhase(phase.next)(clazz.info)
+ .findMember(member.name, 0, lateDEFERRED).alternatives.contains(imember)) {
+ val member1 = addMember(
+ clazz,
+ member.cloneSymbol(clazz) setPos clazz.pos resetFlag (DEFERRED | lateDEFERRED))
+ member1.asInstanceOf[TermSymbol] setAlias member;
+ }
+ }
+/*
//System.out.println("adding forwarded method " + member + " " + mmap(member) + member.locationString + " to " + clazz + " " + (clazz.info.member(member.name).alternatives));//DEBUG
- if (isForwarded(member) && !isStatic(member) &&
- (clazz.info.findMember(member.name, 0, 0).alternatives contains mmap(member))) {
- val member1 = addMember(
- clazz,
- member.cloneSymbol(clazz) setPos clazz.pos resetFlag (DEFERRED | lateDEFERRED));
- member1.asInstanceOf[TermSymbol] setAlias member;
- }
+ if (isForwarded(member) && !isStatic(member)) {
+ if (clazz.info.findMember(member.name, 0, 0).alternatives contains mmap(member)) {
+ val mmember = member.overriddenSymbol(mixinClass.toInterface)
+ if (!mmember.hasFlag(lateDEFERRED))
+ Console.println("SURPRISE0: "+member+" "+mmember+mmember.locationString+" is not late deferred")
+ if (mmember.overridingSymbol(clazz) != NoSymbol)
+ Console.println("SURPRISE1: "+member+" "+mmember+mmember.locationString+" is overridden by class")
+ if (!atPhase(phase.next)(clazz.info).findMember(member.name, 0, lateDEFERRED).alternatives.contains(mmember))
+ Console.println("SURPRISE2: "+member+" "+mmember+mmember.locationString+" is not among late deferred members")
+ val member1 = addMember(
+ clazz,
+ member.cloneSymbol(clazz) setPos clazz.pos resetFlag (DEFERRED | lateDEFERRED));
+ member1.asInstanceOf[TermSymbol] setAlias member;
+ } else {
+ val mmember = member.overriddenSymbol(mixinClass.toInterface)
+ if (!mmember.hasFlag(lateDEFERRED))
+ Console.println("SURPRISE3: "+member+" "+mmember+mmember.locationString+" is not late deferred")
+ if (mmember.overridingSymbol(clazz) == NoSymbol)
+ if (atPhase(phase.next)(clazz.info).findMember(member.name, 0, lateDEFERRED).alternatives.contains(mmember))
+ Console.println("SURPRISE4: "+member+" "+mmember+mmember.locationString+" is mixed in but violates conditions")
+ }
+ }
+*/
}
} else if (mixinClass.hasFlag(lateINTERFACE)) {
addLateInterfaceMembers(mixinClass);
val impl = implClass(mixinClass);
//System.out.println("late impl " + mixinClass + " " + impl);//DEBUG
- if (!(mixins contains impl)) mixinMembers(impl, .overriddenSymbol(mixinClass));
+ if (!(mixins contains impl)) mixinMembers(impl);
for (val member <- mixinClass.info.decls.toList) {
if (member hasFlag ACCESSOR) {
val member1 = addMember(
@@ -160,7 +186,7 @@ abstract class Mixin extends InfoTransform {
}
}
// for (val mixinClass <- mixins) if (mixinClass.hasFlag(lateINTERFACE)) addLateInterfaceMembers(mixinClass);
- for (val mixinClass <- mixins) mixinMembers(mixinClass, identity);
+ for (val mixinClass <- mixins) mixinMembers(mixinClass);
if (settings.debug.value) log("new defs of " + clazz + " = " + clazz.info.decls);
}
}
diff --git a/src/library/scala/Stream.scala b/src/library/scala/Stream.scala
index 4f4f65b183..2319d642fb 100644
--- a/src/library/scala/Stream.scala
+++ b/src/library/scala/Stream.scala
@@ -39,7 +39,7 @@ object Stream {
}
def printElems(buf: StringBuffer, prefix: String): StringBuffer = {
val buf1 = buf.append(prefix).append(hd);
- if (tlDefined) printElems(buf1, ", ") else buf1 append ", ?";
+ if (tlDefined) tlVal.printElems(buf1, ", ") else buf1 append ", ?";
}
}
@@ -146,124 +146,158 @@ object Stream {
*/
trait Stream[+a] extends Seq[a] {
- def isEmpty: Boolean;
- def head: a;
- def tail: Stream[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[b >: a](rest: => Stream[b]): Stream[b] =
if (isEmpty) rest
- else Stream.cons(head, tail.append(rest));
+ else Stream.cons(head, tail.append(rest))
def elements: Iterator[a] = new Iterator[a] {
- var current = Stream.this;
- def hasNext: boolean = !current.isEmpty;
+ 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
- else Stream.cons(head, tail.init);
+ else Stream.cons(head, tail.init)
def last: a =
if (isEmpty) error("Stream.empty.last")
- else if (tail.isEmpty) head
- else tail.last;
+ else {
+ def loop(s: Stream[a]): a = {
+ if (s.tail.isEmpty) s.head
+ else loop(s.tail)
+ }
+ loop(this)
+ }
- override def take(n: int): Stream[a] =
+ override def take(n: Int): Stream[a] =
if (n == 0) Stream.empty
- else Stream.cons(head, tail.take(n-1));
+ else Stream.cons(head, tail.take(n-1))
- override def drop(n: int): Stream[a] =
- if (n == 0) this
- else tail.drop(n-1);
+ override def drop(n: Int): Stream[a] = {
+ def loop(s: Stream[a], n: Int): Stream[a] =
+ if (n == 0) s
+ else loop(s.tail, n-1)
+ loop(this, n)
+ }
- def apply(n: int) = drop(n).head;
- def at(n: int) = drop(n).head;
+ 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));
+ else Stream.cons(head, tail.takeWhile(p))
- def dropWhile(p: a => Boolean): Stream[a] =
- if (isEmpty || !p(head)) this
- else tail.dropWhile(p);
+ def dropWhile(p: a => Boolean): Stream[a] = {
+ def loop(s: Stream[a]): Stream[a] =
+ if (s.isEmpty || !p(s.head)) this
+ else loop(s.tail)
+ loop(this)
+ }
def map[b](f: a => b): Stream[b] =
if (isEmpty) Stream.empty
- else Stream.cons(f(head), tail.map(f));
+ else Stream.cons(f(head), tail.map(f))
- override def foreach(f: a => unit): unit =
- if (isEmpty) {}
- else { f(head); tail.foreach(f) }
+ override def foreach(f: a => unit): unit = {
+ def loop(s: Stream[a]): unit =
+ if (s.isEmpty) {}
+ else { f(s.head); loop(s.tail) }
+ loop(this)
+ }
- def filter(p: a => Boolean): Stream[a] =
- if (isEmpty) this
- else if (p(head)) Stream.cons(head, tail.filter(p))
- else tail.filter(p);
+ def filter(p: a => Boolean): Stream[a] = {
+ def loop(s: Stream[a]): Stream[a] =
+ if (s.isEmpty) s
+ else if (p(s.head)) Stream.cons(head, loop(s.tail))
+ else loop(s.tail)
+ loop(this)
+ }
- override def forall(p: a => Boolean): Boolean =
- isEmpty || (p(head) && tail.forall(p));
+ override def forall(p: a => Boolean): Boolean = {
+ def loop(s: Stream[a]): Boolean = {
+ if (s.isEmpty) true
+ else if (p(s.head)) loop(s.tail)
+ else false
+ }
+ loop(this)
+ }
- override def exists(p: a => Boolean): Boolean =
- !isEmpty && (p(head) || tail.exists(p));
+ override def exists(p: a => Boolean): Boolean = {
+ def loop(s: Stream[a]): Boolean = {
+ if (s.isEmpty) false
+ else if (p(s.head)) true
+ else loop(s.tail)
+ }
+ loop(this)
+ }
- override def foldLeft[b](z: b)(f: (b, a) => b): b =
- if (isEmpty) z
- else tail.foldLeft[b](f(z, head))(f);
+ override def foldLeft[b](z: b)(f: (b, a) => b): b = {
+ def loop(s: Stream[a], z: b): b =
+ if (s.isEmpty) z
+ else loop(s.tail, f(z, s.head))
+ loop(this, z)
+ }
override def foldRight[b](z: b)(f: (a, b) => b): b =
if (isEmpty) z
- else f(head, tail.foldRight(z)(f));
+ else f(head, tail.foldRight(z)(f))
def reduceLeft[b >: a](f: (b, b) => b): b =
if (isEmpty) error("Stream.empty.reduceLeft")
- else ((tail: Stream[b]) foldLeft (head: b))(f);
+ else ((tail: Stream[b]) foldLeft (head: b))(f)
def reduceRight[b >: a](f: (b, b) => b): b =
if (isEmpty) error("Stream.empty.reduceRight")
else if (tail.isEmpty) head: b
- else f(head, tail.reduceRight(f));
+ else f(head, tail.reduceRight(f))
def flatMap[b](f: a => Stream[b]): Stream[b] =
if (isEmpty) Stream.empty
- else f(head).append(tail.flatMap(f));
+ else f(head).append(tail.flatMap(f))
def reverse: Stream[a] =
- foldLeft(Stream.empty: Stream[a])((xs, x) => Stream.cons(x, xs));
+ 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
// now.
// def toArray: Array[a] = {
- // val xs = new Array[a](length);
- // copyToArray(xs, 0);
+ // val xs = new Array[a](length)
+ // copyToArray(xs, 0)
// xs
// }
- override def copyToArray[b >: a](xs: Array[b], start: int): Array[b] =
- if (isEmpty) xs
- else { xs(start) = head; tail.copyToArray(xs, start + 1) }
+ override def copyToArray[b >: a](xs: Array[b], start: Int): Array[b] = {
+ def loop(s: Stream[a], start: Int): Array[b] =
+ if (s.isEmpty) xs
+ else { xs(start) = head; loop(s.tail, start + 1) }
+ loop(this, start)
+ }
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));
+ else Stream.cons(Tuple2(this.head, that.head), this.tail.zip(that.tail))
- def zipWithIndex: Stream[Tuple2[a, int]] =
+ def zipWithIndex: Stream[Tuple2[a, Int]] =
zip(Stream.from(0))
- def print: unit =
- if (isEmpty) Console.println("Stream.empty")
- else {
- Console.print(head);
- Console.print(", ");
- tail.print
- }
+ def print: unit = {
+ def loop(s: Stream[a]): unit =
+ if (s.isEmpty) Console.println("Stream.empty")
+ else { Console.print(s.head); Console.print(", "); loop(s.tail) }
+ loop(this)
+ }
override def toString() =
- "Stream(" + printElems(new StringBuffer(), "") + ")";
+ "Stream(" + printElems(new StringBuffer(), "") + ")"
- def printElems(buf: StringBuffer, prefix: String): StringBuffer;
+ def printElems(buf: StringBuffer, prefix: String): StringBuffer
}