diff options
author | Martin Odersky <odersky@gmail.com> | 2009-09-24 09:30:24 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-09-24 09:30:24 +0000 |
commit | 87a113f132473036e6b975962fdb5cea8364b532 (patch) | |
tree | 672c468bb290c2088b9bc90573bcdb61559708b4 /src | |
parent | 21035aa14125ccc3a9d9366988dc14472320a7a2 (diff) | |
download | scala-87a113f132473036e6b975962fdb5cea8364b532.tar.gz scala-87a113f132473036e6b975962fdb5cea8364b532.tar.bz2 scala-87a113f132473036e6b975962fdb5cea8364b532.zip |
moved sortWith from Iterable to Sequence (becau...
moved sortWith from Iterable to Sequence (becaus eit does not
make sense for sets or maps). Fixed problem interfacing with Java
Array[T] parameters. Made manifests compile under 1.5 by avoiding
multi-dimensional Array.newInstance.
Diffstat (limited to 'src')
6 files changed, 58 insertions, 47 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 6f264b3c13..25330bd641 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -545,8 +545,14 @@ abstract class ClassfileParser { val formals = tp.paramTypes assert(formals.last.typeSymbol == definitions.ArrayClass) val method = params.last.owner - val newParams = method.newSyntheticValueParams(formals.init ::: - List(appliedType(definitions.JavaRepeatedParamClass.typeConstructor, List(formals.last.typeArgs.head)))) + val elemtp = formals.last.typeArgs.head match { + case RefinedType(List(t1, t2), _) if (t1.typeSymbol.isAbstractType && t2.typeSymbol == definitions.ObjectClass) => + t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them. + case t => + t + } + val newParams = method.newSyntheticValueParams( + formals.init ::: List(appliedType(definitions.JavaRepeatedParamClass.typeConstructor, List(elemtp)))) MethodType(newParams, rtpe) case PolyType(tparams, rtpe) => PolyType(tparams, arrayToRepeated(rtpe)) @@ -641,7 +647,13 @@ abstract class ClassfileParser { tpe case ARRAY_TAG => while ('0' <= sig(index) && sig(index) <= '9') index += 1 - appliedType(definitions.ArrayClass.tpe, List(sig2type(tparams, skiptvs))) + var elemtp = sig2type(tparams, skiptvs) + // make unbounded Array[T] where T is a type variable into Array[T with Object] + // (this is necessary because such arrays have a representation which is incompatibe + // with arrays of primitive types. + if (elemtp.typeSymbol.isAbstractType && !(elemtp <:< definitions.ObjectClass.tpe)) + elemtp = intersectionType(List(elemtp, definitions.ObjectClass.tpe)) + appliedType(definitions.ArrayClass.tpe, List(elemtp)) case '(' => // we need a method symbol. given in line 486 by calling getType(methodSym, ..) assert(sym ne null) diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index cd691bb430..49fdbf4868 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -312,31 +312,6 @@ self => b.result } - /** Sort the iterable according to the comparison function - * <code><(e1: a, e2: a) => Boolean</code>, - * which should be true iff <code>e1</code> is smaller than - * <code>e2</code>. - * The sort is stable. That is elements that are equal wrt `lt` appear in the - * same order in the sorted sequence as in the original. - * - * @param lt the comparison function - * @return an iterable sorted according to the comparison function - * <code><(e1: a, e2: a) => Boolean</code>. - * @ex <pre> - * List("Steve", "Tom", "John", "Bob") - * .sortWith((e1, e2) => (e1 compareTo e2) < 0) = - * List("Bob", "John", "Steve", "Tom")</pre> - */ - def sortWith(lt: (A, A) => Boolean)(implicit m: ClassManifest[A @uncheckedVariance]): Repr = { - // !!! can we supply a default argument to m: ClassManifest ? - val arr = toArray - java.util.Arrays.sort(arr, Ordering fromLessThan lt) - - val b = newBuilder - for (x <- arr) b += x - b.result - } - /** Checks if the other iterable object contains the same elements as this one. * * @note will not terminate for infinite-sized iterables. diff --git a/src/library/scala/collection/SequenceLike.scala b/src/library/scala/collection/SequenceLike.scala index baa4d47646..7223f0f1f7 100644 --- a/src/library/scala/collection/SequenceLike.scala +++ b/src/library/scala/collection/SequenceLike.scala @@ -11,7 +11,7 @@ package scala.collection import generic._ -import mutable.{ListBuffer, HashMap} +import mutable.{ListBuffer, HashMap, GenericArray} // import immutable.{List, Nil, ::} import generic._ @@ -422,6 +422,35 @@ trait SequenceLike[+A, +Repr] extends IterableLike[A, Repr] { self => b.result } + /** Sort the iterable according to the comparison function + * <code><(e1: a, e2: a) => Boolean</code>, + * which should be true iff <code>e1</code> is smaller than + * <code>e2</code>. + * The sort is stable. That is elements that are equal wrt `lt` appear in the + * same order in the sorted sequence as in the original. + * + * @param lt the comparison function + * @return an iterable sorted according to the comparison function + * <code><(e1: a, e2: a) => Boolean</code>. + * @ex <pre> + * List("Steve", "Tom", "John", "Bob") + * .sortWith((e1, e2) => (e1 compareTo e2) < 0) = + * List("Bob", "John", "Steve", "Tom")</pre> + */ + def sortWith(lt: (A, A) => Boolean): Repr = { + val arr = new GenericArray[A](this.length) + var i = 0 + for (x <- this) { + arr(i) = x + i += 1 + } + java.util.Arrays.sort( + arr.array, (Ordering fromLessThan lt).asInstanceOf[Ordering[Object]]) + val b = newBuilder + for (x <- arr) b += x + b.result + } + /** * Overridden for efficiency. * diff --git a/src/library/scala/collection/mutable/GenericArray.scala b/src/library/scala/collection/mutable/GenericArray.scala index 43cc03f07a..87ffd63a82 100644 --- a/src/library/scala/collection/mutable/GenericArray.scala +++ b/src/library/scala/collection/mutable/GenericArray.scala @@ -27,7 +27,7 @@ extends Vector[A] override def companion: Companion[GenericArray] = GenericArray - var array: Array[AnyRef] = new Array[AnyRef](length) + val array: Array[AnyRef] = new Array[AnyRef](length) def apply(idx: Int): A = { if (idx >= length) throw new IndexOutOfBoundsException(idx.toString) diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala index 4dc9631710..327054354d 100644 --- a/src/library/scala/reflect/ClassManifest.scala +++ b/src/library/scala/reflect/ClassManifest.scala @@ -72,35 +72,30 @@ trait ClassManifest[T] extends OptManifest[T] { case _ => false } - protected def arrayClass: Predef.Class[Array[T]] = - java.lang.reflect.Array.newInstance(erasure, 0).getClass - .asInstanceOf[Predef.Class[Array[T]]] + protected def arrayClass[T](tp: Predef.Class[_]): Predef.Class[Array[T]] = + java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[Predef.Class[Array[T]]] def arrayManifest: ClassManifest[Array[T]] = - ClassManifest.classType[Array[T]](arrayClass) + ClassManifest.classType[Array[T]](arrayClass[T](erasure)) def newArray(len: Int): Array[T] = java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] def newArray2(len: Int): Array[Array[T]] = - java.lang.reflect.Array.newInstance( - java.lang.reflect.Array.newInstance(erasure, 0).getClass, len) - .asInstanceOf[Array[Array[T]]] + java.lang.reflect.Array.newInstance(arrayClass[T](erasure), len) + .asInstanceOf[Array[Array[T]]] def newArray3(len: Int): Array[Array[Array[T]]] = - java.lang.reflect.Array.newInstance( - java.lang.reflect.Array.newInstance(erasure, 0, 0).getClass, len) - .asInstanceOf[Array[Array[Array[T]]]] + java.lang.reflect.Array.newInstance(arrayClass[Array[T]](arrayClass[T](erasure)), len) + .asInstanceOf[Array[Array[Array[T]]]] def newArray4(len: Int): Array[Array[Array[Array[T]]]] = - java.lang.reflect.Array.newInstance( - java.lang.reflect.Array.newInstance(erasure, 0, 0, 0).getClass, len) - .asInstanceOf[Array[Array[Array[Array[T]]]]] + java.lang.reflect.Array.newInstance(arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure))), len) + .asInstanceOf[Array[Array[Array[Array[T]]]]] def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = - java.lang.reflect.Array.newInstance( - java.lang.reflect.Array.newInstance(erasure, 0, 0, 0, 0).getClass, len) - .asInstanceOf[Array[Array[Array[Array[Array[T]]]]]] + java.lang.reflect.Array.newInstance(arrayClass[Array[Array[Array[T]]]](arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure)))), len) + .asInstanceOf[Array[Array[Array[Array[Array[T]]]]]] def newWrappedArray(len: Int): WrappedArray[T] = // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala index f0c5183e6a..f8a3c13f49 100644 --- a/src/library/scala/reflect/Manifest.scala +++ b/src/library/scala/reflect/Manifest.scala @@ -30,7 +30,7 @@ trait Manifest[T] extends ClassManifest[T] { override def typeArguments: List[Manifest[_]] = List() override def arrayManifest: Manifest[Array[T]] = - Manifest.classType[Array[T]](arrayClass) + Manifest.classType[Array[T]](arrayClass[T](erasure)) } /** <ps> |