From b2fbd5a79f687312ae32fe117e49e171fea01993 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 4 Jan 2011 23:40:28 +0000 Subject: Eliminated 16 avoidable closure objects in Stream. --- .../scala/tools/nsc/transform/UnCurry.scala | 6 ++ src/compiler/scala/tools/nsc/util/package.scala | 2 + .../scala/collection/immutable/Stream.scala | 64 +++++++++------------- test/files/run/lisp.scala | 14 ++--- 4 files changed, 40 insertions(+), 46 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index fcaa8b588b..cfa938e3dc 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -459,6 +459,12 @@ abstract class UnCurry extends InfoTransform with TypingTransformers with ast.Tr byNameArgs += arg arg setType functionType(List(), arg.tpe) } else { + if (opt.verboseDebug) { + val posstr = arg.pos.source.path + ":" + arg.pos.line + val permstr = if (fun.isPrivate) "private" else "notprivate" + log("byname | %s | %s | %s".format(posstr, fun.fullName, permstr)) + } + val result = localTyper.typed( Function(Nil, arg) setPos arg.pos).asInstanceOf[Function] new ChangeOwnerTraverser(currentOwner, result.symbol).traverse(arg) diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala index 2bede3c8ca..6de2f35796 100644 --- a/src/compiler/scala/tools/nsc/util/package.scala +++ b/src/compiler/scala/tools/nsc/util/package.scala @@ -16,6 +16,8 @@ package object util { /** Frequency counter */ def freq[T](xs: Traversable[T]): Map[T, Int] = xs groupBy identity mapValues (_.size) + def freqrank[T](xs: Traversable[(T, Int)]): List[(Int, T)] = xs.toList map (_.swap) sortBy (-_._1) + /** Execute code and then wait for all Threads created during its * execution to complete. */ diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 3f16c2c020..419bfd75d8 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -120,10 +120,8 @@ self => */ @inline private def asThat[That](x: AnyRef): That = x.asInstanceOf[That] @inline private def asStream[B](x: AnyRef): Stream[B] = x.asInstanceOf[Stream[B]] - @inline private def buildsThis[B, That](b: Builder[B, That]) = b.isInstanceOf[Stream.StreamBuilder[_]] - private def ifTargetThis[B, That](bf: CanBuildFrom[Stream[A], B, That])(ifIs: => Stream[B])(ifNot: => That): That = - if (buildsThis(bf(repr))) ifIs.asInstanceOf[That] - else ifNot + @inline private def isStreamBuilder[B, That](bf: CanBuildFrom[Stream[A], B, That]) = + bf(repr).isInstanceOf[Stream.StreamBuilder[_]] // Overridden methods from Traversable @@ -143,12 +141,11 @@ self => */ override def ++[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = // we assume there is no other builder factory on streams and therefore know that That = Stream[A] - ifTargetThis[B, That](bf) { + if (isStreamBuilder(bf)) asThat( if (isEmpty) that.toStream else new Stream.Cons(head, asStream[A](tail ++ that)) - } { - super.++(that)(bf) - } + ) + else super.++(that)(bf) /** * Create a new stream which contains all intermediate results of applying the operator @@ -156,12 +153,11 @@ self => * @note This works because the target type of the Builder That is a Stream. */ override final def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That = - ifTargetThis[B, That](bf) { + if (isStreamBuilder(bf)) asThat( if (isEmpty) Stream(z) else new Stream.Cons(z, asStream[B](tail.scanLeft(op(z, head))(op))) - } { - super.scanLeft(z)(op)(bf) - } + ) + else super.scanLeft(z)(op)(bf) /** Returns the stream resulting from applying the given function * `f` to each element of this stream. @@ -171,12 +167,11 @@ self => * sequence is a0, ..., an. */ override final def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { - ifTargetThis[B, That](bf) { + if (isStreamBuilder(bf)) asThat( if (isEmpty) Stream.Empty else new Stream.Cons(f(head), asStream[B](tail map f)) - } { - super.map(f)(bf) - } + ) + else super.map(f)(bf) } /** Applies the given function `f` to each element of @@ -191,7 +186,7 @@ self => // we assume there is no other builder factory on streams and therefore know that That = Stream[B] // optimisations are not for speed, but for functionality // see tickets #153, #498, #2147, and corresponding tests in run/ (as well as run/stream_flatmap_odds.scala) - ifTargetThis[B, That](bf) { + if (isStreamBuilder(bf)) asThat( if (isEmpty) Stream.Empty else { // establish !prefix.isEmpty || nonEmptyPrefix.isEmpty @@ -206,9 +201,8 @@ self => if (nonEmptyPrefix.isEmpty) Stream.empty else prefix append asStream[B](nonEmptyPrefix.tail flatMap f) } - } { - super.flatMap(f)(bf) - } + ) + else super.flatMap(f)(bf) /** Returns all the elements of this stream that satisfy the * predicate p. The order of the elements is preserved. @@ -234,24 +228,22 @@ self => override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { def tailMap = asStream[B](tail withFilter p map f) - ifTargetThis[B, That](bf) { + if (isStreamBuilder(bf)) asThat( if (isEmpty) Stream.Empty else if (p(head)) new Stream.Cons(f(head), tailMap) else tailMap - } { - super.map(f)(bf) - } + ) + else super.map(f)(bf) } override def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { def tailFlatMap = asStream[B](tail withFilter p flatMap f) - ifTargetThis[B, That](bf) { + if (isStreamBuilder(bf)) asThat( if (isEmpty) Stream.Empty else if (p(head)) f(head).toStream append tailFlatMap else tailFlatMap - } { - super.flatMap(f)(bf) - } + ) + else super.flatMap(f)(bf) } override def foreach[B](f: A => B) = @@ -336,12 +328,11 @@ self => */ override final def zip[A1 >: A, B, That](that: Iterable[B])(implicit bf: CanBuildFrom[Stream[A], (A1, B), That]): That = // we assume there is no other builder factory on streams and therefore know that That = Stream[(A1, B)] - ifTargetThis[(A1, B), That](bf) { + if (isStreamBuilder(bf)) asThat( if (this.isEmpty || that.isEmpty) Stream.Empty else new Stream.Cons((this.head, that.head), asStream[(A1, B)](this.tail zip that.tail)) - } { - super.zip(that)(bf) - } + ) + else super.zip(that)(bf) /** Zips this iterable with its indices. `s.zipWithIndex` is equivalent to * `s zip s.indices` @@ -475,13 +466,8 @@ self => if (these.isEmpty) Stream.fill(len)(elem) else new Stream.Cons(these.head, loop(len - 1, these.tail)) - ifTargetThis[B, That](bf) { - loop(len, this) - } { - super.padTo(len, elem)(bf) - } -// was: if (bf.isInstanceOf[Stream.StreamCanBuildFrom[_]]) loop(len, this).asInstanceOf[That] -// else super.padTo(len, elem) + if (isStreamBuilder(bf)) asThat(loop(len, this)) + else super.padTo(len, elem)(bf) } /** A list consisting of all elements of this list in reverse order. diff --git a/test/files/run/lisp.scala b/test/files/run/lisp.scala index fe3941d0db..3436594def 100644 --- a/test/files/run/lisp.scala +++ b/test/files/run/lisp.scala @@ -20,7 +20,7 @@ class LispTokenizer(s: String) extends Iterator[String] { do i = i + 1 while (!isDelimiter(s charAt i)) s.substring(start, i) - } else error("premature end of string") + } else system.error("premature end of string") } //############################################################################ @@ -102,7 +102,7 @@ object LispCaseClasses extends Lisp { var indent: Int = 0 def lispError[a](msg: String): a = - error("error: " + msg + "\n" + curexp); + system.error("error: " + msg + "\n" + curexp); trait Environment { def lookup(n: String): Data; @@ -201,7 +201,7 @@ object LispCaseClasses extends Lisp { val ps: List[String] = toList(params) map { case SYM(name) => name - case _ => error("illegal parameter list"); + case _ => system.error("illegal parameter list"); } FUN(args => eval(expr, extendEnv(env, ps, args))) @@ -237,7 +237,7 @@ object LispCaseClasses extends Lisp { val it = new LispTokenizer(s); def parseExpr(token: String): Data = { if (token == "(") parseList - else if (token == ")") error("unbalanced parentheses") + else if (token == ")") system.error("unbalanced parentheses") else if ('0' <= token.charAt(0) && token.charAt(0) <= '9') NUM(token.toInt) else if (token.charAt(0) == '\"' && token.charAt(token.length()-1)=='\"') @@ -270,7 +270,7 @@ object LispAny extends Lisp { var indent: Int = 0; def lispError[a](msg: String): a = - error("error: " + msg + "\n" + curexp); + system.error("error: " + msg + "\n" + curexp); trait Environment { def lookup(n: String): Data; @@ -392,7 +392,7 @@ object LispAny extends Lisp { val ps: List[String] = asList(params) map { case Symbol(name) => name - case _ => error("illegal parameter list"); + case _ => system.error("illegal parameter list"); } Lambda(args => eval(expr, extendEnv(env, ps, args))) @@ -428,7 +428,7 @@ object LispAny extends Lisp { val it = new LispTokenizer(s); def parseExpr(token: String): Data = { if (token == "(") parseList - else if (token == ")") error("unbalanced parentheses") + else if (token == ")") system.error("unbalanced parentheses") //else if (Character.isDigit(token.charAt(0))) else if (token.charAt(0).isDigit) token.toInt -- cgit v1.2.3