diff options
author | Martin Odersky <odersky@gmail.com> | 2006-05-25 18:08:50 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-05-25 18:08:50 +0000 |
commit | e3b1cc9130d7046905cc86f0f25e25c1010c5900 (patch) | |
tree | 0abeb2581b9d492db0cfb26b16753306a1ee3227 | |
parent | 5da7b0a3958c3c66803ba375c7d43f2a471f5322 (diff) | |
download | scala-e3b1cc9130d7046905cc86f0f25e25c1010c5900.tar.gz scala-e3b1cc9130d7046905cc86f0f25e25c1010c5900.tar.bz2 scala-e3b1cc9130d7046905cc86f0f25e25c1010c5900.zip |
Some more changes to fix 605
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Mixin.scala | 50 | ||||
-rw-r--r-- | src/library/scala/Stream.scala | 150 |
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 } |