added manifests to most parts of standard library which deal with arrays.

One test is temporarily disabled, as it shows a deep problem with multi-dimensional arrays (which was present all along).

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@18589 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
odersky 2009-08-27 14:45:35 +00:00
parent c0c16089b8
commit 075214bef4
40 changed files with 2031 additions and 1826 deletions

File diff suppressed because it is too large Load Diff

View File

@ -512,7 +512,7 @@ abstract class TreeBuilder {
if (contextBounds.isEmpty) vparamss
else {
val mods = Modifiers(if (owner.isTypeName) PARAMACCESSOR | LOCAL | PRIVATE else PARAM)
def makeEvidenceParam(tpt: Tree) = ValDef(mods | IMPLICIT, freshName("man$"), tpt, EmptyTree)
def makeEvidenceParam(tpt: Tree) = ValDef(mods | IMPLICIT, freshName(nme.EVIDENCE_PARAM_PREFIX), tpt, EmptyTree)
vparamss ::: List(contextBounds map makeEvidenceParam)
}

View File

@ -649,6 +649,10 @@ trait Definitions {
addModuleMethod(DoubleClass, "NegativeInfinity", java.lang.Double.NEGATIVE_INFINITY)
}
/** Is symbol a phantom class for which no runtime representation exists? */
def isPhantomClass(sym: Symbol) =
sym == AnyClass || sym == AnyValClass || sym == NullClass || sym == NothingClass
/** Is symbol a value class? */
def isValueClass(sym: Symbol): Boolean =
(sym eq UnitClass) || (boxedClass contains sym)

View File

@ -82,6 +82,7 @@ trait StdNames {
val INTERPRETER_VAR_PREFIX = "res"
val INTERPRETER_IMPORT_WRAPPER = "$iw"
val INTERPRETER_SYNTHVAR_PREFIX = "synthvar$"
val EVIDENCE_PARAM_PREFIX = "evidence$"
def LOCAL(clazz: Symbol) = newTermName(LOCALDUMMY_PREFIX_STRING + clazz.name+">")
def TUPLE_FIELD(index: Int) = newTermName(TUPLE_FIELD_PREFIX_STRING + index)

View File

@ -21,10 +21,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
// @S: XXX: why is this here? earsure is a typer, if you comment this
// out erasure still works, uses its own typed methods.
lazy val typerXXX = this.typer
import typerXXX.{typed} // methods to type trees
import typerXXX.{typed, typedPos} // methods to type trees
import CODE._
def typedPos(pos: Position)(tree: Tree) = typed { atPos(pos)(tree) }
val phaseName: String = "erasure"
@ -387,7 +386,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
})
}
/** generate ScalaRuntime.boxArray(tree) */
/** generate ScalaRuntime.boxArray(tree)
* !!! todo: optimize this in case the runtime type is known
*/
private def boxArray(tree: Tree): Tree = tree match {
case LabelDef(name, params, rhs) =>
val rhs1 = boxArray(rhs)
@ -451,12 +452,12 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
ELSE (x())
)
)
else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass) once (x =>
(IF (x() IS_OBJ BoxedArrayClass.tpe) THEN (x()) ELSE boxArray(x()))
)
else if (isSeqClass(pt.typeSymbol)) once (x =>
(IF (x() IS_OBJ pt) THEN (x()) ELSE (boxArray(x())))
)
else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass)
once (x =>
(IF (x() IS_OBJ BoxedArrayClass.tpe) THEN (x()) ELSE boxArray(x())))
else if (isSeqClass(pt.typeSymbol))
once (x =>
(IF (x() IS_OBJ pt) THEN (x()) ELSE (boxArray(x()))))
else asPt(tree)
} else asPt(tree)
}
@ -560,12 +561,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
tree match {
case Apply(Select(New(tpt), name), args) if (tpt.tpe.typeSymbol == BoxedArrayClass) =>
assert(name == nme.CONSTRUCTOR);
val translated: Tree =
if (args.length >= 2) REF(ArrayModule) DOT nme.ofDim
else NEW(BoxedAnyArrayClass) DOT name
atPos(tree.pos) {
Typed(Apply(translated, args), tpt)
assert(args.length < 2)
typedPos(tree.pos) {
Typed(Apply(NEW(BoxedAnyArrayClass) DOT name, args), tpt)
}
case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_asInstanceOf =>
val qual1 = typedQualifier(qual)

View File

@ -392,15 +392,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
if (traversableTpe != NoType && toArray != NoSymbol) {
val arguments =
if (toArray.tpe.paramTypes.isEmpty) List() // !!! old style toArray
else { // new style, with manifest
val manifestOpt = localTyper.findManifest(tree.tpe.typeArgs.head, false)
if (manifestOpt.tree.isEmpty) {
unit.error(tree.pos, "cannot find class manifest for element type of "+tree.tpe)
List(Literal(Constant(null)))
} else {
List(manifestOpt.tree)
}
}
else List(localTyper.getManifestTree(tree.pos, tree.tpe.typeArgs.head, false)) // new style, with manifest
atPhase(phase.next) {
localTyper.typed {
atPos(pos) {

View File

@ -599,7 +599,7 @@ self: Analyzer =>
* reflect.Manifest for type 'tp'. An EmptyTree is returned if
* no manifest is found. todo: make this instantiate take type params as well?
*/
def manifestOfType(tp: Type, full: Boolean): Tree = {
private def manifestOfType(tp: Type, full: Boolean): Tree = {
/** Creates a tree that calls the factory method called constructor in object reflect.Manifest */
def manifestFactoryCall(constructor: String, args: Tree*): Tree =
@ -627,25 +627,22 @@ self: Analyzer =>
case ConstantType(value) =>
manifestOfType(tp0.deconst, full)
case TypeRef(pre, sym, args) =>
if (isValueClass(sym)) {
if (isValueClass(sym) || isPhantomClass(sym)) {
typed { atPos(tree.pos.focus) {
Select(gen.mkAttributedRef(FullManifestModule), sym.name.toString)
}}
}
else if (sym.isClass) {
} else if (sym.isClass) {
val suffix = gen.mkClassOf(tp0) :: (args map findSubManifest)
manifestFactoryCall(
"classType",
(if ((pre eq NoPrefix) || pre.typeSymbol.isStaticOwner) suffix
else findSubManifest(pre) :: suffix): _*)
}
else if (sym.isTypeParameterOrSkolem || sym.isExistential) {
EmptyTree // a manifest should have been found by normal searchImplicit
}
else {
} else if (sym.isAbstractType && !sym.isTypeParameterOrSkolem && !sym.isExistential) {
manifestFactoryCall(
"abstractType",
findSubManifest(pre) :: Literal(sym.name.toString) :: findManifest(tp0.bounds.hi) :: (args map findSubManifest): _*)
} else {
EmptyTree // a manifest should have been found by normal searchImplicit
}
case RefinedType(parents, decls) =>
// refinement is not generated yet

View File

@ -31,7 +31,7 @@ trait NamesDefaults { self: Analyzer =>
/** @param pos maps indicies from old to new */
def reorderArgs[T](args: List[T], pos: Int => Int): List[T] = {
def reorderArgs[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = {
val res = new Array[T](args.length)
// (hopefully) faster than zipWithIndex
(0 /: args) { case (index, arg) => res(pos(index)) = arg; index + 1 }
@ -39,7 +39,7 @@ trait NamesDefaults { self: Analyzer =>
}
/** @param pos maps indicies from new to old (!) */
def reorderArgsInv[T](args: List[T], pos: Int => Int): List[T] = {
def reorderArgsInv[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = {
val argsArray = args.toArray
val res = new ListBuffer[T]
for (i <- 0 until argsArray.length)

View File

@ -708,13 +708,7 @@ abstract class RefChecks extends InfoTransform {
List(transform(cdef))
}
} else {
val vdef =
localTyper.typed {
atPos(tree.pos) {
gen.mkModuleVarDef(sym)
}
}
val vdef = localTyper.typedPos(tree.pos) { gen.mkModuleVarDef(sym) }
val ddef =
atPhase(phase.next) {
localTyper.typed {
@ -930,6 +924,19 @@ abstract class RefChecks extends InfoTransform {
if (tpt.tpe.typeSymbol == ArrayClass && args.length >= 2) =>
unit.deprecationWarning(tree.pos,
"new Array(...) with multiple dimensions has been deprecated; use Array.ofDim(...) instead")
val manif = {
var etpe = tpt.tpe
for (_ <- args) { etpe = etpe.typeArgs.headOption.getOrElse(NoType) }
if (etpe == NoType) {
unit.error(tree.pos, "too many dimensions for array creation")
Literal(Constant(null))
} else {
localTyper.getManifestTree(tree.pos, etpe, false)
}
}
result = localTyper.typedPos(tree.pos) {
Apply(Apply(Select(gen.mkAttributedRef(ArrayModule), nme.ofDim), args), List(manif))
}
currentApplication = tree
case Apply(fn, args) =>

View File

@ -180,7 +180,7 @@ trait Typers { self: Analyzer =>
def applyImplicitArgs(fun: Tree): Tree = fun.tpe match {
case MethodType(params, _) =>
var positional = true
val argResults = params map (_.tpe) map (inferImplicit(fun, _, true, false, context))
val argResults = params map (p => inferImplicit(fun, p.tpe, true, false, context))
val args = argResults.zip(params) flatMap {
case (arg, param) =>
if (arg != SearchFailure) {
@ -188,8 +188,10 @@ trait Typers { self: Analyzer =>
else List(atPos(arg.tree.pos)(new AssignOrNamedArg(Ident(param.name), (arg.tree))))
} else {
if (!param.hasFlag(DEFAULTPARAM))
context.error(fun.pos, "could not find implicit value for parameter "+
param.name +":"+ param.tpe +".")
context.error(
fun.pos, "could not find implicit value for "+
(if (param.name startsWith nme.EVIDENCE_PARAM_PREFIX) "evidence parameter of type "
else "parameter "+param.name+": ")+param.tpe)
positional = false
Nil
}
@ -956,7 +958,7 @@ trait Typers { self: Analyzer =>
if (coercion != EmptyTree) {
if (settings.debug.value) log("inferred view from "+tree.tpe+" to "+pt+" = "+coercion+":"+coercion.tpe)
return newTyper(context.makeImplicit(context.reportAmbiguousErrors)).typed(
Apply(coercion, List(tree)) setPos tree.pos, mode, pt)
Apply(coercion, List(tree)) setPos tree.pos, mode, pt)
}
}
}
@ -3778,6 +3780,8 @@ trait Typers { self: Analyzer =>
ret
}
def typedPos(pos: Position)(tree: Tree) = typed(atPos(pos)(tree))
/** Types expression <code>tree</code> with given prototype <code>pt</code>.
*
* @param tree ...
@ -3851,6 +3855,16 @@ trait Typers { self: Analyzer =>
EmptyTree,
appliedType((if (full) FullManifestClass else PartialManifestClass).typeConstructor, List(tp)),
true, false, context)
def getManifestTree(pos: Position, tp: Type, full: Boolean): Tree = {
val manifestOpt = findManifest(tp, false)
if (manifestOpt.tree.isEmpty) {
error(pos, "cannot find "+(if (full) "" else "class ")+"manifest for element type of "+tp)
Literal(Constant(null))
} else {
manifestOpt.tree
}
}
/*
def convertToTypeTree(tree: Tree): Tree = tree match {
case TypeTree() => tree

View File

@ -12,21 +12,26 @@
package scala
import scala.collection.generic._
import scala.collection.mutable.{Vector, ArrayBuffer}
import scala.collection.Traversable
import scala.collection.mutable.{Vector, ArrayBuilder}
import compat.Platform.arraycopy
import scala.reflect.ClassManifest
/** This object contains utility methods operating on arrays.
*
* @author Martin Odersky
* @version 1.0
*/
object Array extends SequenceFactory[Array] {
object Array {
import runtime.BoxedArray;
import scala.runtime.ScalaRunTime.boxArray;
implicit def builderFactory[A]: BuilderFactory[A, Array[A], Coll] = new BuilderFactory[A, Array[A], Coll] { def apply(from: Coll) = newBuilder[A] }
def newBuilder[A]: Builder[A, Array[A]] = new ArrayBuffer[A].mapResult(_.toArray)
implicit def builderFactory[A]/* !!!(implicit m: ClassManifest[A])*/: BuilderFactory[A, Array[A], Array[_]] =
new BuilderFactory[A, Array[A], Array[_]] { def apply(from: Array[_]) = newBuilder[A](null) }
def newBuilder[A](implicit m: ClassManifest[A]): Builder[A, Array[A]] =
new ArrayBuilder[A](m).asInstanceOf[Builder[A, Array[A]]] // the cast is safe, because the erasure of Array[A] is BoxedArray[A]
private def slowcopy(
src : AnyRef,
@ -64,32 +69,15 @@ object Array extends SequenceFactory[Array] {
slowcopy(src, srcPos, dest, destPos, length)
}
/** Concatenate all argument sequences into a single array.
*
* @param xs the given argument sequences
* @return the array created from the concatenated arguments
*/
def concat[T](xs: Seq[T]*): Array[T] = {
var len = 0
for (x <- xs) len += x.length
val result = new Array[T](len)
var start = 0
for (x <- xs) {
copy(x.toArray, 0, result, start, x.length)
start += x.length
}
result
}
/** Returns array of length 0 */
override def empty[A]: Array[A] = new Array[A](0)
def empty[A: ClassManifest]: Array[A] = new Array[A](0)
/** Create an array with given elements.
*
* @param xs the elements to put in the array
* @return the array containing elements xs.
*/
override def apply[A](xs: A*): Array[A] = {
def apply[A: ClassManifest](xs: A*): Array[A] = {
val array = new Array[A](xs.length)
var i = 0
for (x <- xs.iterator) { array(i) = x; i += 1 }
@ -160,17 +148,186 @@ object Array extends SequenceFactory[Array] {
}
/** Create array with given dimensions */
def ofDim[A](n1: Int): Array[A] =
def ofDim[A: ClassManifest](n1: Int): Array[A] =
new Array[A](n1)
def ofDim[A](n1: Int, n2: Int): Array[Array[A]] =
def ofDim[A: ClassManifest](n1: Int, n2: Int): Array[Array[A]] =
tabulate(n1)(_ => ofDim[A](n2))
def ofDim[A](n1: Int, n2: Int, n3: Int): Array[Array[Array[A]]] =
def ofDim[A: ClassManifest](n1: Int, n2: Int, n3: Int): Array[Array[Array[A]]] =
tabulate(n1)(_ => ofDim[A](n2, n3))
def ofDim[A](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[A]]]] =
def ofDim[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[A]]]] =
tabulate(n1)(_ => ofDim[A](n2, n3, n4))
def ofDim[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[A]]]]] =
def ofDim[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[A]]]]] =
tabulate(n1)(_ => ofDim[A](n2, n3, n4, n5))
/** Concatenate all argument sequences into a single array.
*
* @param xs the given argument sequences
* @return the array created from the concatenated arguments
*/
def concat[A: ClassManifest](xss: Traversable[A]*): Array[A] = {
val b = newBuilder[A]
b.sizeHint(xss.map(_.size).sum)
for (xs <- xss) b ++= xs
b.result
}
/** An array that contains the results of some element computation a number of times.
* @param n the number of elements returned
* @param elem the element computation
*/
def fill[A: ClassManifest](n: Int)(elem: => A): Array[A] = {
val b = newBuilder[A]
var i = 0
while (i < n) {
b += elem
i += 1
}
b.result
}
/** A two-dimensional array that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param elem the element computation
*/
def fill[A: ClassManifest](n1: Int, n2: Int)(elem: => A): Array[Array[A]] =
tabulate(n1)(_ => fill(n2)(elem))
/** A three-dimensional array that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
* @param elem the element computation
*/
def fill[A: ClassManifest](n1: Int, n2: Int, n3: Int)(elem: => A): Array[Array[Array[A]]] =
tabulate(n1)(_ => fill(n2, n3)(elem))
/** A four-dimensional array that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
* @param n4 the number of elements in the 4th dimension
* @param elem the element computation
*/
def fill[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): Array[Array[Array[Array[A]]]] =
tabulate(n1)(_ => fill(n2, n3, n4)(elem))
/** A five-dimensional array that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
* @param n4 the number of elements in the 4th dimension
* @param n5 the number of elements in the 5th dimension
* @param elem the element computation
*/
def fill[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): Array[Array[Array[Array[Array[A]]]]] =
tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem))
/** An array containing values of a given function over a range of integer values starting from 0.
* @param n The number of elements in the traversable
* @param f The function computing element values
* @return A traversable consisting of elements `f(0), ..., f(n -1)`
*/
def tabulate[A: ClassManifest](n: Int)(f: Int => A): Array[A] = {
val b = newBuilder[A]
var i = 0
while (i < n) {
b += f(i)
i += 1
}
b.result
}
/** A two-dimensional array containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param f The function computing element values
*/
def tabulate[A: ClassManifest](n1: Int, n2: Int)(f: (Int, Int) => A): Array[Array[A]] =
tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))
/** A three-dimensional array containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
* @param f The function computing element values
*/
def tabulate[A: ClassManifest](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): Array[Array[Array[A]]] =
tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _)))
/** A four-dimensional array containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
* @param n4 the number of elements in the 4th dimension
* @param f The function computing element values
*/
def tabulate[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): Array[Array[Array[Array[A]]]] =
tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _)))
/** A five-dimensional array containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
* @param n4 the number of elements in the 4th dimension
* @param n5 the number of elements in the 5th dimension
* @param f The function computing element values
*/
def tabulate[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): Array[Array[Array[Array[Array[A]]]]] =
tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _)))
/** An array containing a sequence of increasing integers in a range.
*
* @param from the start value of the array
* @param end the end value of the array (the first value NOT returned)
* @return the array with values in range `start, start + 1, ..., end - 1`
* up to, but exclusding, `end`.
*/
def range(start: Int, end: Int): Array[Int] = range(start, end, 1)
/** An array containing equally spaced values in some integer interval.
* @param start the start value of the array
* @param end the end value of the array (the first value NOT returned)
* @param step the increment value of the array (must be positive or negative)
* @return the array with values in `start, start + step, ...` up to, but excluding `end`
*/
def range(start: Int, end: Int, step: Int): Array[Int] = {
if (step == 0) throw new IllegalArgumentException("zero step")
val b = newBuilder[Int]
var i = start
while (if (step < 0) end < i else i < end) {
b += i
i += step
}
b.result
}
/** An array containing repeated applications of a function to a start value.
*
* @param start the start value of the array
* @param len the number of elements returned by the array
* @param f the function that's repeatedly applied
* @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...`
*/
def iterate[A: ClassManifest](start: A, len: Int)(f: A => A): Array[A] = {
val b = newBuilder[A]
var acc = start
var i = 0
while (i < len) {
b += acc
acc = f(acc)
i += 1
}
b.result
}
/** This method is called in a pattern match { case Sequence(...) => }.
*
* @param x the selector value
* @return sequence wrapped in an option, if this is a Sequence, otherwise none
*/
def unapplySeq[A](x: Array[A]): Some[Array[A]] = Some(x)
/** Create an array containing several copies of an element.
*
* @param n the length of the resulting array
@ -178,7 +335,7 @@ object Array extends SequenceFactory[Array] {
* @return an array composed of n elements all equal to elem
*/
@deprecated("use `Array.fill' instead")
def make[A](n: Int, elem: A): Array[A] = {
def make[A: ClassManifest](n: Int, elem: A): Array[A] = {
val a = new Array[A](n)
var i = 0
while (i < n) {
@ -192,7 +349,7 @@ object Array extends SequenceFactory[Array] {
* over given range <code>[0..n)</code>
*/
@deprecated("use `Array.tabulate' instead")
def fromFunction[A](f: Int => A)(n: Int): Array[A] = {
def fromFunction[A: ClassManifest](f: Int => A)(n: Int): Array[A] = {
val a = new Array[A](n)
var i = 0
while (i < n) {
@ -206,28 +363,28 @@ object Array extends SequenceFactory[Array] {
* over given range <code>[0..n1, 0..n2)</code>
*/
@deprecated("use `Array.tabulate' instead")
def fromFunction[A](f: (Int, Int) => A)(n1: Int, n2: Int): Array[Array[A]] =
def fromFunction[A: ClassManifest](f: (Int, Int) => A)(n1: Int, n2: Int): Array[Array[A]] =
fromFunction(i => fromFunction(f(i, _))(n2))(n1)
/** Create an array containing the values of a given function <code>f</code>
* over given range <code>[0..n1, 0..n2, 0..n3)</code>
*/
@deprecated("use `Array.tabulate' instead")
def fromFunction[A](f: (Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int): Array[Array[Array[A]]] =
def fromFunction[A: ClassManifest](f: (Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int): Array[Array[Array[A]]] =
fromFunction(i => fromFunction(f(i, _, _))(n2, n3))(n1)
/** Create an array containing the values of a given function <code>f</code>
* over given range <code>[0..n1, 0..n2, 0..n3, 0..n4)</code>
*/
@deprecated("use `Array.tabulate' instead")
def fromFunction[A](f: (Int, Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[A]]]] =
def fromFunction[A: ClassManifest](f: (Int, Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[A]]]] =
fromFunction(i => fromFunction(f(i, _, _, _))(n2, n3, n4))(n1)
/** Create an array containing the values of a given function <code>f</code>
* over given range <code>[0..n1, 0..n2, 0..n3, 0..n4, 0..n5)</code>
*/
@deprecated("use `Array.tabulate' instead")
def fromFunction[A](f: (Int, Int, Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[A]]]]] =
def fromFunction[A: ClassManifest](f: (Int, Int, Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[A]]]]] =
fromFunction(i => fromFunction(f(i, _, _, _, _))(n2, n3, n4, n5))(n1)
}
@ -337,9 +494,21 @@ final class Array[A](_length: Int) extends Vector[A]
*/
override def update(i: Int, x: A) { throw new Error() }
/** Creates a possible nested vector which consists of all the elements
* of this array. If the elements are arrays themselves, the `deep' transformation
* is applied recursively to them. The stringPrefix of the vector is
* "Array", hence the vector prints like an array with all its
* elements shown, and the same recursively for any subarrays.
*
* Example: Array(Array(1, 2), Array(3, 4)).deep.toString
* prints: Array(Array(1, 2), Array(3, 4))
*/
def deep: Vector[Any] = throw new Error()
/**
* @return a deep string representation of this array.
*/
@deprecated("use deep.toString instead")
def deepToString(): String = throw new Error()
/** <p>
@ -358,6 +527,7 @@ final class Array[A](_length: Int) extends Vector[A]
* @param end ending string.
* @return a string representation of this array object.
*/
@deprecated("use deep.mkString instead")
def deepMkString(start: String, sep: String, end: String): String =
throw new Error()
@ -368,6 +538,7 @@ final class Array[A](_length: Int) extends Vector[A]
* @param sep separator string.
* @return a string representation of this array object.
*/
@deprecated("use deep.mkString instead")
def deepMkString(sep: String): String = throw new Error()
/** <p>
@ -389,8 +560,6 @@ final class Array[A](_length: Int) extends Vector[A]
* @param that the second
* @return <code>true</code> iff both arrays are deeply equal.
*/
@deprecated("use array1.deep.equals(array2.deep) instead")
def deepEquals(that: Any): Boolean = throw new Error()
@deprecated("use `slice' instead")
def subArray(from: Int, end: Int): Array[A] = throw new Error()
}

View File

@ -52,7 +52,7 @@ package scala.collection
object JavaConversions {
import java.{ lang => jl, util => ju }
import scala.collection.{ generic, immutable, mutable, Traversable }
import scala.reflect.Manifest
import scala.reflect.ClassManifest
// Scala => Java
@ -157,7 +157,7 @@ object JavaConversions {
* @param s The <code>Set</code> to be converted.
* @return A Java <code>Set</code> view of the argument.
*/
implicit def asSet[A](s : mutable.Set[A])(implicit m : Manifest[A]) : ju.Set[A] = s match {
implicit def asSet[A](s : mutable.Set[A])(implicit m : ClassManifest[A]) : ju.Set[A] = s match {
case JSetWrapper(wrapped) => wrapped
case _ => new MutableSetWrapper(s)(m)
}
@ -175,7 +175,7 @@ object JavaConversions {
* @param m The <code>Map</code> to be converted.
* @return A Java <code>Map</code> view of the argument.
*/
implicit def asMap[A, B](m : mutable.Map[A, B])(implicit ma : Manifest[A]) : ju.Map[A, B] = m match {
implicit def asMap[A, B](m : mutable.Map[A, B])(implicit ma : ClassManifest[A]) : ju.Map[A, B] = m match {
case JMapWrapper(wrapped) => wrapped
case _ => new MutableMapWrapper(m)(ma)
}
@ -365,7 +365,7 @@ object JavaConversions {
def result = this
}
case class MutableSetWrapper[A](underlying : mutable.Set[A])(m : Manifest[A]) extends ju.AbstractSet[A] {
case class MutableSetWrapper[A](underlying : mutable.Set[A])(m : ClassManifest[A]) extends ju.AbstractSet[A] {
self =>
def size = underlying.size
override def add(elem: A) = { val sz = underlying.size ; underlying += elem ; sz < underlying.size }
@ -408,7 +408,7 @@ object JavaConversions {
override def empty = JSetWrapper(new ju.HashSet[A])
}
case class MutableMapWrapper[A, B](underlying : mutable.Map[A, B])(m : Manifest[A]) extends ju.AbstractMap[A, B] {
case class MutableMapWrapper[A, B](underlying : mutable.Map[A, B])(m : ClassManifest[A]) extends ju.AbstractMap[A, B] {
self =>
override def size = underlying.size

View File

@ -74,7 +74,7 @@ trait Traversable[+A] extends TraversableTemplate[A, Traversable[A]]
override def copyToBuffer[B >: A](dest: Buffer[B])
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int)
override def copyToArray[B >: A](xs: Array[B], start: Int)
override def toArray[B >: A]: Array[B]
override def toArray[B >: A : ClassManifest]: Array[B]
override def toList: List[A]
override def toIterable: Iterable[A]
override def toSequence: Sequence[A]
@ -102,64 +102,5 @@ object Traversable extends TraversableFactory[Traversable] { self =>
implicit def builderFactory[A]: BuilderFactory[A, Traversable[A], Coll] = new VirtualBuilderFactory[A]
def newBuilder[A]: Builder[A, Traversable[A]] = immutable.Traversable.newBuilder[A]
/** A wrapper class which adds `flatten` and `transpose` methods to iterables or iterable element type`.
*/
class TraversableTraversableOps[This <: Traversable[Traversable[A]], A](self: This) {
/** Returns the concatenation of all elements of the wrapped iterable `self` */
def flatten[That](implicit bf: BuilderFactory[A, That, This]): That = {
val b = bf(self)
for (xs <- self)
b ++= xs
b.result
}
/** Returns the transposition of the wrapped iterable `self`: rows become columns and columns become rows.
*/
def transpose[Row, That](implicit bf: BuilderFactory[A, Row, This], bbf: BuilderFactory[Row, That, This]): That = {
val bs: Array[Builder[A, Row]] = self.head.map(_ => bf(self))(Traversable.builderFactory[Builder[A, Row]]).toArray
for (xs <- self) {
var i = 0
for (x <- xs) {
bs(i) += x
i += 1
}
}
val bb = bbf(self)
for (b <- bs) bb += b.result
bb.result
}
}
/** A wrapper class which adds an `unzip` method to iterable whose elements are pairs.
*/
class PairTraversableOps[This <: Traversable[(A1, A2)], A1, A2](self: This) {
/** Returns a pair of iterables consisting of the first, respectively second, component of all
* elements in the wrapped iterable `self`.
*/
def unzip[That1, That2](implicit bf1: BuilderFactory[A1, That1, This], bf2: BuilderFactory[A2, That2, This]): (That1, That2) = {
val b1 = bf1(self)
val b2 = bf2(self)
for ((x1, x2) <- self) {
b1 += x1
b2 += x2
}
(b1.result, b2.result)
}
}
/** Implicit wrapper conversion of iterables with iterable elements.
* @see TraversableTraversableOps
*/
implicit def traversableTraversableWrapper[This <: Traversable[Traversable[A]], A](self: This) =
new TraversableTraversableOps[This, A](self) // !!! error if type parameters are omitted
/** Implicit wrapper conversion of iterables with pairs as elements.
* @see PairTraversableOps
*/
implicit def pairTraversableWrapper[This <: Traversable[(A1, A2)], A1, A2](self: This) =
new PairTraversableOps[This, A1, A2](self)
}

View File

@ -11,6 +11,7 @@
package scala.collection.generic
import scala.collection._
import annotation.unchecked.uncheckedVariance
import mutable.{ListBuffer, HashMap}
@ -593,7 +594,7 @@ trait SequenceTemplate[+A, +This <: IterableTemplate[A, This] with Sequence[A]]
* .sortWith((e1, e2) => (e1 compareTo e2) &lt; 0) =
* List("Bob", "John", "Steve", "Tom")</pre>
*/
def sortWith(lt: (A, A) => Boolean): This = {
def sortWith(lt: (A, A) => Boolean)(implicit m: ClassManifest[A @uncheckedVariance]): This = {
val arr = toArray
import java.util.{Arrays, Comparator}
Arrays.sort(arr, new Comparator[A] {

View File

@ -29,29 +29,29 @@ trait TraversableClass[+A, +CC[X] <: Traversable[X]] {
/** The generic builder that builds instances of CC at arbitrary element types. */
def genericBuilder[B]: Builder[B, CC[B]] = companion.newBuilder[B]
def unzip[A1, A2](implicit toPair: A => (A1, A2)): (CC[A1], CC[A2]) = {
def unzip[A1, A2](implicit asPair: A => /*<:<!!!*/ (A1, A2)): (CC[A1], CC[A2]) = {
val b1 = genericBuilder[A1]
val b2 = genericBuilder[A2]
for (xy <- this) {
val (x, y) = toPair(xy)
val (x, y) = asPair(xy)
b1 += x
b2 += y
}
(b1.result, b2.result)
}
def flatten[B](implicit toTraversable: A => Traversable[B]): CC[B] = {
def flatten[B](implicit asTraversable: A => /*<:<!!!*/ Traversable[B]): CC[B] = {
val b = genericBuilder[B]
for (xs <- this)
b ++= toTraversable(xs)
b ++= asTraversable(xs)
b.result
}
def transpose[B](implicit toTraversable: A => Traversable[B]): CC[CC[B] @uncheckedVariance] = {
val bs: Array[Builder[B, CC[B]]] = head.map(_ => genericBuilder[B]).toArray
def transpose[B](implicit asTraversable: A => /*<:<!!!*/ Traversable[B]): CC[CC[B] @uncheckedVariance] = {
val bs: Vector[Builder[B, CC[B]]] = asTraversable(head).map(_ => genericBuilder[B]).toVector
for (xs <- this) {
var i = 0
for (x <- toTraversable(xs)) {
for (x <- asTraversable(xs)) {
bs(i) += x
i += 1
}

View File

@ -34,7 +34,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
b.result
}
/** An iterable that contains the results of some element computation a number of times.
/** A traversable that contains the results of some element computation a number of times.
* @param n the number of elements returned
* @param elem the element computation
*/
@ -48,7 +48,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
b.result
}
/** A two-dimensional iterable that contains the results of some element computation a number of times.
/** A two-dimensional traversable that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param elem the element computation
@ -56,7 +56,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def fill[A](n1: Int, n2: Int)(elem: => A): CC[CC[A]] =
tabulate(n1)(_ => fill(n2)(elem))
/** A three-dimensional iterable that contains the results of some element computation a number of times.
/** A three-dimensional traversable that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
@ -65,7 +65,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def fill[A](n1: Int, n2: Int, n3: Int)(elem: => A): CC[CC[CC[A]]] =
tabulate(n1)(_ => fill(n2, n3)(elem))
/** A four-dimensional iterable that contains the results of some element computation a number of times.
/** A four-dimensional traversable that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
@ -75,7 +75,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def fill[A](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): CC[CC[CC[CC[A]]]] =
tabulate(n1)(_ => fill(n2, n3, n4)(elem))
/** A five-dimensional iterable that contains the results of some element computation a number of times.
/** A five-dimensional traversable that contains the results of some element computation a number of times.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
@ -86,10 +86,10 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def fill[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): CC[CC[CC[CC[CC[A]]]]] =
tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem))
/** An iterable containing values of a given function over a range of integer values starting from 0.
* @param n The number of elements in the iterable
/** A traversable containing values of a given function over a range of integer values starting from 0.
* @param n The number of elements in the traversable
* @param f The function computing element values
* @return An iterable consisting of elements `f(0), ..., f(n -1)`
* @return A traversable consisting of elements `f(0), ..., f(n -1)`
*/
def tabulate[A](n: Int)(f: Int => A): CC[A] = {
val b = newBuilder[A]
@ -101,7 +101,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
b.result
}
/** A two-dimensional iterable containing values of a given function over ranges of integer values starting from 0.
/** A two-dimensional traversable containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param f The function computing element values
@ -109,7 +109,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def tabulate[A](n1: Int, n2: Int)(f: (Int, Int) => A): CC[CC[A]] =
tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))
/** A three-dimensional iterable containing values of a given function over ranges of integer values starting from 0.
/** A three-dimensional traversable containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
@ -118,7 +118,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def tabulate[A](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): CC[CC[CC[A]]] =
tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _)))
/** A four-dimensional iterable containing values of a given function over ranges of integer values starting from 0.
/** A four-dimensional traversable containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
@ -128,7 +128,7 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): CC[CC[CC[CC[A]]]] =
tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _)))
/** A five-dimensional iterable containing values of a given function over ranges of integer values starting from 0.
/** A five-dimensional traversable containing values of a given function over ranges of integer values starting from 0.
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3nd dimension
@ -139,21 +139,20 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): CC[CC[CC[CC[CC[A]]]]] =
tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _)))
/** An iterable containing a sequence of increasing integers in a range.
/** A traversable containing a sequence of increasing integers in a range.
*
* @param from the start value of the iterable
* @param end the end value of the iterable (the first value NOT returned)
* @return the iterable with values in range `start, start + 1, ..., end - 1`
* @param from the start value of the traversable
* @param end the end value of the traversable (the first value NOT returned)
* @return the traversable with values in range `start, start + 1, ..., end - 1`
* up to, but exclusding, `end`.
*/
def range[A](start: Int, end: Int): CC[Int] = range(start, end, 1)
def range(start: Int, end: Int): CC[Int] = range(start, end, 1)
/** An iterable containing equally spaced values in some integer interval.
* @param start the start value of the iterable
* @param end the end value of the iterable (the first value NOT returned)
* @param step the increment value of the iterable (must be positive or negative)
* @return the iterable with values in `start, start + step, ...` up to, but excluding `end`
/** A traversable containing equally spaced values in some integer interval.
* @param start the start value of the traversable
* @param end the end value of the traversable (the first value NOT returned)
* @param step the increment value of the traversable (must be positive or negative)
* @return the traversable with values in `start, start + step, ...` up to, but excluding `end`
*/
def range(start: Int, end: Int, step: Int): CC[Int] = {
if (step == 0) throw new IllegalArgumentException("zero step")
@ -166,12 +165,12 @@ abstract class TraversableFactory[CC[X] <: Traversable[X] with TraversableClass[
b.result
}
/** An iterable containing repeated applications of a function to a start value.
/** A traversable containing repeated applications of a function to a start value.
*
* @param start the start value of the iterable
* @param len the number of elements returned by the iterable
* @param start the start value of the traversable
* @param len the number of elements returned by the traversable
* @param f the function that's repeatedly applied
* @return the iterable returning `len` values in the sequence `start, f(start), f(f(start)), ...`
* @return the traversable returning `len` values in the sequence `start, f(start), f(f(start)), ...`
*/
def iterate[A](start: A, len: Int)(f: A => A): CC[A] = {
val b = newBuilder[A]

View File

@ -59,7 +59,7 @@ trait TraversableForwarder[+A] extends Traversable[A] {
override def reduceRightOption[B >: A](op: (A, B) => B): Option[B] = underlying.reduceRightOption(op)
override def copyToBuffer[B >: A](dest: Buffer[B]) = underlying.copyToBuffer(dest)
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) = underlying.copyToArray(xs, start, len)
override def toArray[B >: A]: Array[B] = underlying.toArray
override def toArray[B >: A : ClassManifest]: Array[B] = underlying.toArray
override def toList: List[A] = underlying.toList
override def toSequence: Sequence[A] = underlying.toSequence
override def toStream: Stream[A] = underlying.toStream

View File

@ -68,7 +68,7 @@ trait TraversableProxyTemplate[+A, +This <: TraversableTemplate[A, This] with Tr
override def copyToBuffer[B >: A](dest: Buffer[B]) = self.copyToBuffer(dest)
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) = self.copyToArray(xs, start, len)
override def copyToArray[B >: A](xs: Array[B], start: Int) = self.copyToArray(xs, start)
override def toArray[B >: A]: Array[B] = self.toArray
override def toArray[B >: A: ClassManifest]: Array[B] = self.toArray
override def toList: List[A] = self.toList
override def toIterable: Iterable[A] = self.toIterable
override def toSequence: Sequence[A] = self.toSequence

View File

@ -11,6 +11,7 @@
package scala.collection.generic
import scala.collection._
import scala.reflect.ClassManifest
// import immutable.{List, Stream, Nil} //!!!
import mutable.{Buffer, ArrayBuffer, ListBuffer}
@ -718,7 +719,7 @@ self =>
/** Converts this traversable to a fresh Array containing all elements.
* @note Will not terminate for infinite-sized collections.
*/
def toArray[B >: A]: Array[B] = {
def toArray[B >: A : ClassManifest]: Array[B] = {
val result = new Array[B](size)
copyToArray(result, 0)
result
@ -739,6 +740,11 @@ self =>
*/
def toSequence: Sequence[A] = toList
/** Returns a vector with all elements in this traversable object.
* @note Will not terminate for infinite-sized collections.
*/
def toVector[B >: A]: mutable.Vector[B] = (new ArrayBuffer[B] ++= thisCollection)
/** Returns a stream with all elements in this traversable object.
*/
def toStream: Stream[A] = toList.toStream

View File

@ -171,6 +171,7 @@ trait VectorTemplate[+A, +This <: VectorTemplate[A, This] with Vector[A]] extend
}
}
// Overridden methods from Sequence
override def lengthCompare(len: Int): Int = length - len
@ -259,6 +260,7 @@ trait VectorTemplate[+A, +This <: VectorTemplate[A, This] with Vector[A]] extend
super.endsWith(that)
}
override def equals(that: Any): Boolean = that match {
case that: Vector[_] => this.length == that.length && startsWith(that, 0)
case _ => super.equals(that)

View File

@ -370,7 +370,7 @@ self =>
result
}
override def flatten[B](implicit toTraversable: A => Traversable[B]): Stream[B] = {
override def flatten[B](implicit asTraversable: A => /*<:<!!!*/ Traversable[B]): Stream[B] = {
def flatten1(t: Traversable[B]): Stream[B] =
if (!t.isEmpty)
new Stream.Cons(t.head, flatten1(t.tail))
@ -380,7 +380,7 @@ self =>
if (isEmpty)
Stream.empty
else
flatten1(toTraversable(head))
flatten1(asTraversable(head))
}
/** Defines the prefix of this object's <code>toString</code> representation as ``Stream''.
@ -553,7 +553,7 @@ object Stream extends SequenceFactory[Stream] {
/** The concatenation of all streams returned by an iterator
*/
@deprecated("use xs.toStream.flatten instead")
def concat[A](xs: Iterator[Stream[A]]): Stream[A] = xs.toStream.flatten
def concat[A](xs: Iterator[Stream[A]]): Stream[A] = xs.toStream.flatten //(conforms[Stream[A], collection.Traversable[A]])
/**
* Create a stream with element values

View File

@ -23,9 +23,15 @@ class ArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, BoxedArray[
private var size: Int = 0
private def mkArray(size: Int): BoxedArray[A] = {
val newelems = manifest.newArray(size)
if (this.size > 0) Array.copy(elems.value, 0, newelems.value, 0, this.size)
newelems
if (manifest != null) {
val newelems = manifest.newArray(size)
if (this.size > 0) Array.copy(elems.value, 0, newelems.value, 0, this.size)
newelems
} else { // !!!
val newelems = new scala.runtime.BoxedAnyArray[A](size)
if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
newelems
}
}
private def resize(size: Int) {

View File

@ -14,6 +14,7 @@ package scala.collection.mutable
import collection.generic._
import scala.runtime.RichString
import compat.Platform.arraycopy
import scala.reflect.Manifest
/** <p>
* A mutable sequence of characters. This class provides an API compatible

View File

@ -104,31 +104,46 @@ object ClassManifest {
val Double = Manifest.Double
val Boolean = Manifest.Boolean
val Unit = Manifest.Unit
val Any = Manifest.Any
val AnyVal = Manifest.AnyVal
val Nothing = Manifest.Nothing
val Null = Manifest.Null
def singleType[T](value: Any): Manifest[T] = Manifest.singleType(value)
/** ClassManifest for the class type `clazz[args]', where `clazz' is
* a top-level or static class. */
def classType[T](clazz: Predef.Class[_], args: OptManifest[_]*): ClassManifest[T] =
classType(None, clazz, args: _*)
/** ClassManifest for the class type `clazz', where `clazz' is
* a top-level or static class.
* @note This no-prefix, no-arguments case is separate because we
* it's called from ScalaRunTime.boxArray itself. If we
* pass varargs as arrays into this, we get an infinitely recursive call
* to boxArray. (Besides, having a separate case is more efficient)
*/
def classType[T](clazz: Predef.Class[_]): ClassManifest[T] =
new ClassTypeManifest[T](None, clazz, Nil)
/** ClassManifest for the class type `clazz[args]', where `clazz' is
* a top-level or static class. */
* a top-level or static class and `args` are its type arguments */
def classType[T](clazz: Predef.Class[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] =
new ClassTypeManifest[T](None, clazz, arg1 :: args.toList)
/** ClassManifest for the class type `clazz[args]', where `clazz' is
* a class with non-package prefix type `prefix` and type arguments `args`.
*/
def classType[T](prefix: OptManifest[_], clazz: Predef.Class[_], args: OptManifest[_]*): ClassManifest[T] =
classType(Some(prefix), clazz, args: _*)
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
/** ClassManifest for the class type `clazz[args]', where `clazz' is
/** Manifest for the class type `clazz[args]', where `clazz' is
* a top-level or static class. */
def classType[T](prefix: Option[OptManifest[_]], clazz: Predef.Class[_], args: OptManifest[_]*): ClassManifest[T] =
new (ClassManifest[T] @serializable) {
def erasure = clazz
override val typeArguments = args.toList
override def toString =
(if (prefix.isEmpty) "" else prefix.get.toString+"#") +
(if (erasure.isArray) "Array" else erasure.getName) +
argString
}
@serializable
private class ClassTypeManifest[T](prefix: Option[OptManifest[_]],
val erasure: Predef.Class[_],
override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] {
override def toString =
(if (prefix.isEmpty) "" else prefix.get.toString+"#") +
(if (erasure.isArray) "Array" else erasure.getName) +
argString
}
/** ClassManifest for the abstract type `prefix # name'. `upperBound' is not
* strictly necessary as it could be obtained by reflection. It was
* added so that erasure can be calculated without reflection. */

View File

@ -95,6 +95,26 @@ object Manifest {
override def newArray(len: Int): BoxedArray[Unit] = new BoxedUnitArray(new Array[Unit](len))
}
val Any: Manifest[Any] = new ClassTypeManifest[Any](None, classOf[java.lang.Object], List()) {
override def toString = "Any"
// todo: re-implement <:<
}
val AnyVal: Manifest[AnyVal] = new ClassTypeManifest[AnyVal](None, classOf[java.lang.Object], List()) {
override def toString = "AnyVal"
// todo: re-implement <:<
}
val Null: Manifest[Null] = new ClassTypeManifest[Null](None, classOf[java.lang.Object], List()) {
override def toString = "Null"
// todo: re-implement <:<
}
val Nothing: Manifest[Nothing] = new ClassTypeManifest[Nothing](None, classOf[java.lang.Object], List()) {
override def toString = "Nothing"
// todo: re-implement <:<
}
/** Manifest for the singleton type `value.type'. */
def singleType[T](value: Any): Manifest[T] =
new (Manifest[T] @serializable) {
@ -106,27 +126,38 @@ object Manifest {
override lazy val toString = value.toString + ".type"
}
/** Manifest for the class type `clazz[args]', where `clazz' is
* a top-level or static class.
* @note This no-prefix, no-arguments case is separate because we
* it's called from ScalaRunTime.boxArray itself. If we
* pass varargs as arrays into this, we get an infinitely recursive call
* to boxArray. (Besides, having a separate case is more efficient)
*/
def classType[T](clazz: Predef.Class[_]): Manifest[T] =
new ClassTypeManifest[T](None, clazz, Nil)
/** Manifest for the class type `clazz', where `clazz' is
* a top-level or static class. */
def classType[T](clazz: Predef.Class[T], args: Manifest[_]*): Manifest[T] =
classType(None, clazz, args: _*)
* a top-level or static class and args are its type arguments. */
def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] =
new ClassTypeManifest[T](None, clazz, arg1 :: args.toList)
/** Manifest for the class type `clazz[args]', where `clazz' is
* a top-level or static class. */
* a class with non-package prefix type `prefix` and type arguments `args`.
*/
def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
classType(Some(prefix), clazz, args: _*)
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
/** Manifest for the class type `clazz[args]', where `clazz' is
* a top-level or static class. */
def classType[T](prefix: Option[Manifest[_]], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
new (Manifest[T] @serializable) {
def erasure = clazz
override val typeArguments = args.toList
override def toString =
(if (prefix.isEmpty) "" else prefix.get.toString+"#") +
(if (erasure.isArray) "Array" else erasure.getName) +
argString
}
@serializable
private class ClassTypeManifest[T](prefix: Option[Manifest[_]],
val erasure: Predef.Class[_],
override val typeArguments: List[Manifest[_]]) extends Manifest[T] {
override def toString =
(if (prefix.isEmpty) "" else prefix.get.toString+"#") +
(if (erasure.isArray) "Array" else erasure.getName) +
argString
}
/** Manifest for the abstract type `prefix # name'. `upperBound' is not
* strictly necessary as it could be obtained by reflection. It was

View File

@ -14,4 +14,6 @@ package scala.reflect
/** <p> One of the branches of an OptManifest
*/
@serializable
object NoManifest extends OptManifest[Nothing]
object NoManifest extends OptManifest[Nothing] {
override def toString = "<?>"
}

View File

@ -45,9 +45,49 @@ abstract class BoxedArray[A] extends Vector[A] with VectorTemplate[A, BoxedArray
// !!! todo: remove
override def genericBuilder[B]: Builder[B, BoxedArray[B]] = new ArrayBuffer[B].mapResult {
_.toArray.asInstanceOf[BoxedArray[B]]
_.toArray(null).asInstanceOf[BoxedArray[B]]
}
/** Convert to Java array.
* @param elemTag Either one of the tags ".N" where N is the name of a primitive type
* (@see ScalaRunTime), or a full class name.
*/
def unbox(elemClass: Class[_]): AnyRef
/** The underlying array value
*/
def value: AnyRef
def copyFrom(src: AnyRef, from: Int, to: Int, len: Int): Unit =
Array.copy(src, from, value, to, len)
def copyTo(from: Int, dest: AnyRef, to: Int, len: Int): Unit = {
Array.copy(value, from, dest, to, len)
}
override def toArray[B >: A](implicit m: ClassManifest[B]): Array[B] = {
if ((elemManifest ne null) && (elemManifest.erasure eq m.erasure)) this.asInstanceOf[Array[B]]
else super.toArray[B]
}
/*
override def equals(other: Any) =
(value eq other) ||
other.isInstanceOf[BoxedArray[_]] && (value == other.asInstanceOf[BoxedArray[_]].value)
override def hashCode(): Int = value.hashCode()
*/
/** Fills the given array <code>xs</code> with the elements of
* this sequence starting at position <code>start</code>.
*
* @param xs the array to fill.
* @param start starting index.
* @pre the array must be large enough to hold all elements.
*/
override def copyToArray[B](xs: Array[B], start: Int, len: Int): Unit =
copyTo(0, xs, start, len)
/** Creates a possible nested vector which consists of all the elements
* of this array. If the elements are arrays themselves, the `deep' transformation
* is applied recursively to them. The stringPrefix of the vector is
@ -66,46 +106,6 @@ abstract class BoxedArray[A] extends Vector[A] with VectorTemplate[A, BoxedArray
override def stringPrefix = "Array"
}
/*
override def genericBuilder[B]: Builder[B, BoxedArray[B]] = new ArrayBuffer[B].mapResult {
_.toArray.asInstanceOf[BoxedArray[B]]
}
*/
/** Convert to Java array.
* @param elemTag Either one of the tags ".N" where N is the name of a primitive type
* (@see ScalaRunTime), or a full class name.
*/
def unbox(elemClass: Class[_]): AnyRef
/** The underlying array value
*/
def value: AnyRef
def copyFrom(src: AnyRef, from: Int, to: Int, len: Int): Unit =
Array.copy(src, from, value, to, len)
def copyTo(from: Int, dest: AnyRef, to: Int, len: Int): Unit = {
Array.copy(value, from, dest, to, len)
}
/*
override def equals(other: Any) =
(value eq other) ||
other.isInstanceOf[BoxedArray[_]] && (value == other.asInstanceOf[BoxedArray[_]].value)
override def hashCode(): Int = value.hashCode()
*/
/** Fills the given array <code>xs</code> with the elements of
* this sequence starting at position <code>start</code>.
*
* @param xs the array to fill.
* @param start starting index.
* @pre the array must be large enough to hold all elements.
*/
override def copyToArray[B](xs: Array[B], start: Int, len: Int): Unit =
copyTo(0, xs, start, len)
@deprecated("use deep.toString instead")
final def deepToString() = deepMkString(stringPrefix + "(", ", ", ")")

View File

@ -17,7 +17,8 @@ import Predef._
@serializable
final class BoxedObjectArray[A <: AnyRef](val value: Array[AnyRef], val elemManifest: ClassManifest[A]) extends BoxedArray[A] {
def this(value: Array[AnyRef]) = this(value, null) // !!! todo: remove
// @deprecated("creating array w/o manifest")
def this(value: Array[AnyRef]) = this(value, null) // !!! todo: remove
def length: Int = value.length

View File

@ -31,7 +31,7 @@ object RichString {
import RichString._
class RichString(val self: String) extends Proxy with Vector[Char] with VectorTemplate[Char, RichString] with PartialFunction[Int, Char] with Ordered[String] {
class RichString(val self: String) extends Proxy with Vector[Char] with VectorTemplate[Char, RichString] with PartialFunction[Int, Char] with Ordered[String] with Boxed {
/** Creates a string builder buffer as builder for this class */
override protected[this] def newBuilder = RichString.newBuilder
@ -209,11 +209,13 @@ class RichString(val self: String) extends Proxy with Vector[Char] with VectorTe
else
throw new NumberFormatException("For input string: \"null\"")
/* !!! causes crash?
def toArray: Array[Char] = {
val result = new Array[Char](length)
self.getChars(0, length, result, 0)
result
}
*/
/** <p>
* Uses the underlying string as a pattern (in a fashion similar to
@ -230,7 +232,7 @@ class RichString(val self: String) extends Proxy with Vector[Char] with VectorTe
* @throws java.lang.IllegalArgumentException
*/
def format(args : Any*) : String =
java.lang.String.format(self, args.toArray[Any].asInstanceOf[Array[AnyRef]]: _*)
java.lang.String.format(self, args.asInstanceOf[Seq[AnyRef]].toArray: _*)
/** <p>
* Like format(args*) but takes an initial Locale parameter
@ -247,6 +249,6 @@ class RichString(val self: String) extends Proxy with Vector[Char] with VectorTe
* @throws java.lang.IllegalArgumentException
*/
def format(l: java.util.Locale, args: Any*): String =
java.lang.String.format(l, self, args.toArray[Any].asInstanceOf[Array[AnyRef]]: _*)
java.lang.String.format(l, self, args.asInstanceOf[Seq[AnyRef]].toArray: _*)
}

View File

@ -11,13 +11,16 @@
package scala.runtime
import scala.reflect.ClassManifest
/* The object <code>ScalaRunTime</code> provides ...
*/
object ScalaRunTime {
def isArray(x: AnyRef): Boolean = (x != null && x.getClass.isArray) || (x != null && x.isInstanceOf[BoxedArray[_]])
def isValueClass(clazz: Class[_]) = clazz.isPrimitive()
// todo: [for Gilles] replace with boxArray
def forceBoxedArray[A <: Any](xs: Seq[A]): Array[A] = {
val array = new Array[A](xs.length)
var i = 0
@ -117,19 +120,33 @@ object ScalaRunTime {
if (x eq null) null else x.unbox(elemClass)
def boxArray(value: AnyRef): BoxedArray[_] = value match {
case x: Array[Byte] => new BoxedByteArray(x)
case x: Array[Short] => new BoxedShortArray(x)
case x: Array[Char] => new BoxedCharArray(x)
case x: Array[AnyRef] => new BoxedObjectArray(x, ClassManifest.classType(x.getClass.getComponentType))
case x: Array[Int] => new BoxedIntArray(x)
case x: Array[Double] => new BoxedDoubleArray(x)
case x: Array[Long] => new BoxedLongArray(x)
case x: Array[Float] => new BoxedFloatArray(x)
case x: Array[Double] => new BoxedDoubleArray(x)
case x: Array[Char] => new BoxedCharArray(x)
case x: Array[Byte] => new BoxedByteArray(x)
case x: Array[Short] => new BoxedShortArray(x)
case x: Array[Boolean] => new BoxedBooleanArray(x)
case x: Array[AnyRef] => new BoxedObjectArray(x)
case x: BoxedArray[_] => x
case null => null
}
def box(value: AnyRef): AnyRef = value match {
case x: String => new RichString(x)
case x: Array[AnyRef] => new BoxedObjectArray(x, ClassManifest.classType(x.getClass.getComponentType))
case x: Array[Int] => new BoxedIntArray(x)
case x: Array[Double] => new BoxedDoubleArray(x)
case x: Array[Long] => new BoxedLongArray(x)
case x: Array[Float] => new BoxedFloatArray(x)
case x: Array[Char] => new BoxedCharArray(x)
case x: Array[Byte] => new BoxedByteArray(x)
case x: Array[Short] => new BoxedShortArray(x)
case x: Array[Boolean] => new BoxedBooleanArray(x)
case x => x
}
/** Given any Scala value, convert it to a String.
*
* The primary motivation for this method is to provide a means for

View File

@ -19,9 +19,9 @@ package scala.util
*/
object Marshal {
import java.io._
import scala.reflect.Manifest
import scala.reflect.ClassManifest
def dump[A](o: A)(implicit m: Manifest[A]): Array[Byte] = {
def dump[A](o: A)(implicit m: ClassManifest[A]): Array[Byte] = {
val ba = new ByteArrayOutputStream(512)
val out = new ObjectOutputStream(ba)
out.writeObject(m)
@ -33,9 +33,9 @@ object Marshal {
@throws(classOf[IOException])
@throws(classOf[ClassCastException])
@throws(classOf[ClassNotFoundException])
def load[A](buffer: Array[Byte])(implicit expected: Manifest[A]): A = {
def load[A](buffer: Array[Byte])(implicit expected: ClassManifest[A]): A = {
val in = new ObjectInputStream(new ByteArrayInputStream(buffer))
val found = in.readObject.asInstanceOf[Manifest[_]]
val found = in.readObject.asInstanceOf[ClassManifest[_]]
if (found <:< expected) {
val o = in.readObject.asInstanceOf[A]
in.close()

View File

@ -107,7 +107,7 @@ object Random extends Random
// only make it work that way if it's called like
// shuffle[Int,List](List.range(0,100))
// which nicely defeats the "convenience" portion of "convenience method".
val buf: Array[T] = seq.toArray
val buf = seq.toVector
def swap(i1: Int, i2: Int) {
val tmp = buf(i1)

View File

@ -10,6 +10,7 @@
package scala.util
import scala.reflect.ClassManifest
/** <p>
* The Sorting object provides functions that can sort various kinds of
@ -33,7 +34,7 @@ object Sorting {
* items. This doesn't quite work the way that I want yet -- K should be
* bounded as viewable, but the compiler rejects that.
*/
implicit def seq2RichSort[K <: Ordered[K]](s: Seq[K]) = new RichSorting[K](s)
implicit def seq2RichSort[K <: Ordered[K] : ClassManifest](s: Seq[K]) = new RichSorting[K](s)
/** Quickly sort an array of Doubles. */
def quickSort(a: Array[Double]) = sort1(a, 0, a.length)
@ -49,7 +50,7 @@ object Sorting {
/** Sort an array of K where K is Ordered, preserving the existing order
where the values are equal. */
def stableSort[K <% Ordered[K]](a: Array[K]) {
def stableSort[K <% Ordered[K] : ClassManifest](a: Array[K]) {
stableSort(a, 0, a.length-1, new Array[K](a.length), (a:K, b:K) => a < b)
}
@ -57,7 +58,7 @@ object Sorting {
* <code>f</code>. <code>f</code> should return <code>true</code> iff
* its first parameter is strictly less than its second parameter.
*/
def stableSort[K](a: Array[K], f: (K,K) => Boolean) {
def stableSort[K : ClassManifest](a: Array[K], f: (K,K) => Boolean) {
stableSort(a, 0, a.length-1, new Array[K](a.length), f)
}
@ -69,14 +70,14 @@ object Sorting {
* @param f the comparison function.
* @return the sorted sequence of items.
*/
def stableSort[K](a: Seq[K], f: (K,K) => Boolean): Array[K] = {
def stableSort[K : ClassManifest](a: Seq[K], f: (K,K) => Boolean): Array[K] = {
val ret = a.toArray
stableSort(ret, f)
ret
}
/** Sorts an arbitrary sequence of items that are viewable as ordered. */
def stableSort[K <% Ordered[K]](a: Seq[K]): Array[K] =
def stableSort[K <% Ordered[K] : ClassManifest](a: Seq[K]): Array[K] =
stableSort(a, (a:K, b:K) => a < b)
/** Stably sorts a sequence of items given an extraction function that will
@ -86,7 +87,7 @@ object Sorting {
* @param f the comparison function.
* @return the sorted sequence of items.
*/
def stableSort[K, M <% Ordered[M]](a: Seq[K], f: K => M): Array[K] =
def stableSort[K : ClassManifest, M <% Ordered[M]](a: Seq[K], f: K => M): Array[K] =
stableSort(a, (a: K, b: K) => f(a) < f(b))
private def sort1[K <% Ordered[K]](x: Array[K], off: Int, len: Int) {
@ -507,7 +508,7 @@ object Sorting {
sort2(off, len)
}
private def stableSort[K](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) {
private def stableSort[K : ClassManifest](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) {
if (lo < hi) {
val mid = (lo+hi) / 2
stableSort(a, lo, mid, scratch, f)
@ -584,7 +585,7 @@ object Sorting {
* the items are ordered.
* </p>
*/
class RichSorting[K <: Ordered[K]](s: Seq[K]) {
class RichSorting[K <: Ordered[K] : ClassManifest](s: Seq[K]) {
/** Returns an array with a sorted copy of the RichSorting's sequence.
*/

View File

@ -1,7 +1,7 @@
bug550.scala:6: error: type List takes type parameters
def sum[a](xs: List)(implicit m: Monoid[a]): a =
^
bug550.scala:8: error: could not find implicit value for parameter m:Monoid[a].
bug550.scala:8: error: could not find implicit value for parameter m: Monoid[a]
sum(List(1,2,3))
^
two errors found

View File

@ -1,7 +1,7 @@
multi-array.scala:6: warning: new Array(...) with multiple dimensions has been deprecated; use Array.ofDim(...) instead
val a: Array[Int] = new Array(10, 10)
^
multi-array.scala:6: error: too many arguments for array constructor: found 2 but array has only 1 dimension(s)
multi-array.scala:6: error: too many dimensions for array creation
val a: Array[Int] = new Array(10, 10)
^
one warning found

View File

@ -4,7 +4,7 @@ t0226.scala:5: error: not found: type A1
t0226.scala:5: error: not found: type A1
(implicit _1: Foo[List[A1]], _2: Foo[A2]): Foo[Tuple2[List[A1], A2]] =
^
t0226.scala:8: error: could not find implicit value for parameter rep:Test.this.Foo[((List[Char], Int), (object Nil, Int))].
t0226.scala:8: error: could not find implicit value for parameter rep: Test.this.Foo[((List[Char], Int), (object Nil, Int))]
foo(((List('b'), 3), (Nil, 4)))
^
three errors found

View File

@ -1,6 +1,7 @@
object Test extends Application
{
val a1 = Array(0,1,2,3).toArray[Any]
// val a1 = x1.toArray[Any]
val a2 = Array('a','b','c','d').toArray[Any]
val a3 = Array("e","f","g","h").toArray[Any]
@ -9,4 +10,4 @@ object Test extends Application
Array.copy(a2, 0, a1, 0, 4)
println(a1.mkString + a2.mkString + a3.mkString)
}
}

View File

@ -31,7 +31,7 @@ object Test extends Application {
assert(o.size == e.size)
val gs = ten groupBy (x => x / 4)
val vs1 = (for (k <- gs.keysIterator; v <- gs(k).toIterable.iterator) yield v).toList
val vs2 = Traversable.traversableTraversableWrapper[List[Traversable[Int]], Int](gs.values.toList).flatten
val vs2 = gs.values.toList.flatten
// val vs2 = gs.values.toList flatMap (xs => xs)
assert(ten.head == 1)
assert(ten.tail.head == 2)

View File

@ -5,7 +5,7 @@ object Test extends Application {
val aaiIncomplete = new Array[Array[Array[Int]]](3)
println(aaiIncomplete(0))
val aaiComplete: Array[Array[Int]] = new Array[Array[Int]](3, 3)
val aaiComplete: Array[Array[Int]] = Array.ofDim[Int](3, 3) // new Array[Array[Int]](3, 3)
for (i <- 0 until 3; j <- 0 until 3)
aaiComplete(i)(j) = i + j
println(aaiComplete.deepToString)

View File

@ -1,5 +1,8 @@
object Test extends Application {
class X[T] { val a = new Array[Array[T]](3,4) }
class X[T: ClassManifest] {
val a = new Array[Array[T]](3,4)
val b = Array.ofDim[T](3, 4)
}
val x = new X[String]
x.a(1)(2) = "hello"
assert(x.a(1)(2) == "hello")