diff options
author | Paul Phillips <paulp@improving.org> | 2009-06-24 15:19:09 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-06-24 15:19:09 +0000 |
commit | 1c9870541fb22ac032edaa0be0103cc1aa2c99b4 (patch) | |
tree | 881d38aa5dfba0542295e7e56e642a77cd3852b6 | |
parent | 6ab1f0b7710af132401848bc25da9101a364093b (diff) | |
download | scala-1c9870541fb22ac032edaa0be0103cc1aa2c99b4.tar.gz scala-1c9870541fb22ac032edaa0be0103cc1aa2c99b4.tar.bz2 scala-1c9870541fb22ac032edaa0be0103cc1aa2c99b4.zip |
More work and documentation for GenericRanges, ...
More work and documentation for GenericRanges, plus minor findbugs
noticed issues.
-rw-r--r-- | src/dotnet-library/scala/runtime/RichChar.scala | 2 | ||||
-rw-r--r-- | src/dotnet-library/scala/runtime/RichInt.scala | 7 | ||||
-rw-r--r-- | src/library/scala/BigDecimal.scala | 24 | ||||
-rw-r--r-- | src/library/scala/BigInt.scala | 21 | ||||
-rwxr-xr-x | src/library/scala/Numeric.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Range.scala | 80 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/PagedSeq.scala | 11 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/ArrayStack.scala | 1 | ||||
-rw-r--r-- | src/library/scala/runtime/RichChar.scala | 2 | ||||
-rw-r--r-- | src/library/scala/runtime/RichDouble.scala | 21 | ||||
-rw-r--r-- | src/library/scala/runtime/RichInt.scala | 7 | ||||
-rw-r--r-- | src/library/scala/runtime/RichLong.scala | 23 | ||||
-rw-r--r-- | src/library/scala/util/control/Exception.scala | 8 | ||||
-rw-r--r-- | src/library/scala/xml/Group.scala | 4 | ||||
-rw-r--r-- | src/library/scala/xml/NamespaceBinding.scala | 4 | ||||
-rw-r--r-- | src/swing/scala/swing/BufferWrapper.scala | 3 |
16 files changed, 141 insertions, 79 deletions
diff --git a/src/dotnet-library/scala/runtime/RichChar.scala b/src/dotnet-library/scala/runtime/RichChar.scala index 5c88cce137..7c6e3f6791 100644 --- a/src/dotnet-library/scala/runtime/RichChar.scala +++ b/src/dotnet-library/scala/runtime/RichChar.scala @@ -67,7 +67,7 @@ final class RichChar(x: Char) extends Proxy with Ordered[Char] { } } - /** Create a <code>RandomAccessSeq.Projection[Char]</code> over the characters from 'x' to 'y' + /** Create a <code>VectorView[Char]</code> over the characters from 'x' to 'y' */ def to(y: Char): VectorView[Char, Vector[Char]] = until((y + 1).toChar) diff --git a/src/dotnet-library/scala/runtime/RichInt.scala b/src/dotnet-library/scala/runtime/RichInt.scala index 3ebfc12a89..390188c139 100644 --- a/src/dotnet-library/scala/runtime/RichInt.scala +++ b/src/dotnet-library/scala/runtime/RichInt.scala @@ -21,13 +21,10 @@ final class RichInt(val start: Int) extends Proxy with Ordered[Int] { def compare(that: Int): Int = if (start < that) -1 else if (start > that) 1 else 0 /** See <code>Iterator.range</code>. */ - def until(end: Int): Range = new Range(start, end, 1) - - /** See <code>Iterator.range</code>. */ - def until(end: Int, step: Int): Range = new Range(start, end, step) + def until(end: Int, step: Int = 1): Range = new Range(start, end, step) /** like <code>until</code>, but includes the last index */ - def to(end: Int) = Range.inclusive(start, end, 1) + def to(end: Int, step: Int = 1) = Range.inclusive(start, end, step) def min(that: Int): Int = if (start < that) start else that def max(that: Int): Int = if (start > that) start else that diff --git a/src/library/scala/BigDecimal.scala b/src/library/scala/BigDecimal.scala index b4d4732951..020a58edc9 100644 --- a/src/library/scala/BigDecimal.scala +++ b/src/library/scala/BigDecimal.scala @@ -345,10 +345,30 @@ extends java.lang.Number def intValueExact: Int = bigDecimal.intValueExact def longValueExact: Long = bigDecimal.longValueExact - /** See <code>Iterator.range</code>. */ + /** Creates a partially constructed GenericRange[BigDecimal] in range + * <code>[start;end)</code>, where start is the target BigDecimal. The step + * must be supplied via the "by" method of the returned object in order + * to receive the fully constructed range. For example: + * <pre> + * val partial = BigDecimal(1.0) to 2.0 // not usable yet + * val range = partial by 0.01 // now a GenericRange + * val range2 = BigDecimal(0) to 1.0 by 0.01 // all at once of course is fine too + * </pre> + * + * @param end the end value of the range (exclusive) + * @return the partially constructed GenericRange + */ + def until(end: BigDecimal): Range.Partial[BigDecimal, GenericRange.Exclusive[BigDecimal]] = + new Range.Partial(until(end, _)) + + /** Same as the one-argument <code>until</code>, but creates the range immediately. */ def until(end: BigDecimal, step: BigDecimal) = Range.BigDecimal(this, end, step) - /** like <code>until</code>, but includes the last index */ + /** Like <code>until</code>, but inclusive of the end value. */ + def to(end: BigDecimal): Range.Partial[BigDecimal, GenericRange.Inclusive[BigDecimal]] = + new Range.Partial(to(end, _)) + + /** Like <code>until</code>, but inclusive of the end value. */ def to(end: BigDecimal, step: BigDecimal) = Range.BigDecimal.inclusive(this, end, step) /** Converts this <code>BigDecimal</code> to a scala.BigInt. diff --git a/src/library/scala/BigInt.scala b/src/library/scala/BigInt.scala index 6ec02d0100..9e54e9bee2 100644 --- a/src/library/scala/BigInt.scala +++ b/src/library/scala/BigInt.scala @@ -338,17 +338,18 @@ class BigInt(val bigInteger: BigInteger) extends jl.Number */ def doubleValue = this.bigInteger.doubleValue - /** See <code>Iterator.range</code>. */ - def until(end: BigInt) = Range.BigInt(this, end, BigInt(1)) - - /** See <code>Iterator.range</code>. */ - def until(end: BigInt, step: BigInt) = Range.BigInt(this, end, step) - - /** like <code>until</code>, but includes the last index */ - def to(end: BigInt) = Range.BigInt.inclusive(this, end, BigInt(1)) + /** Create a GenericRange[BigInt] in range <code>[start;end)</code> + * with the specified step, where start is the target BigInt. + * + * @param end the end value of the range (exclusive) + * @param step the distance between elements (defaults to 1) + * @return the range + */ + def until(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt(this, end, step) - /** like <code>until</code>, but includes the last index */ - def to(end: BigInt, step: BigInt) = Range.BigInt.inclusive(this, end, step) + /** Like until, but inclusive of the end value. + */ + def to(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt.inclusive(this, end, step) /** Returns the decimal String representation of this BigInt. */ diff --git a/src/library/scala/Numeric.scala b/src/library/scala/Numeric.scala index a9fc0c08f8..5cdbb32a68 100755 --- a/src/library/scala/Numeric.scala +++ b/src/library/scala/Numeric.scala @@ -74,7 +74,7 @@ object Numeric { } implicit object DoubleIsFractional extends DoubleIsFractional with Ordering.DoubleOrdering - trait BigDecimalIsConflicted { + trait BigDecimalIsConflicted extends Numeric[BigDecimal] { def plus(x: BigDecimal, y: BigDecimal): BigDecimal = x + y def minus(x: BigDecimal, y: BigDecimal): BigDecimal = x - y def times(x: BigDecimal, y: BigDecimal): BigDecimal = x * y diff --git a/src/library/scala/Range.scala b/src/library/scala/Range.scala index d7ee1d7a38..992a6a2e1b 100644 --- a/src/library/scala/Range.scala +++ b/src/library/scala/Range.scala @@ -10,6 +10,7 @@ package scala +import annotation.experimental import collection.immutable.Vector import collection.generic.VectorView import util.control.Exception.catching @@ -21,9 +22,9 @@ import util.Hashable * It must be supplied with an Integral implementation of the * range type. * - * Factories for likely types include Range.BigInt and Range.Long. - * Range.Int exists for completeness, but the Int-based scala.Range - * should be more performant. + * Factories for likely types include Range.BigInt, Range.Long, + * and Range.BigDecimal. Range.Int exists for completeness, but + * the Int-based scala.Range should be more performant. * </p><pre> * <b>val</b> r1 = new Range(0, 100, 1) * <b>val</b> veryBig = Math.MAX_INT.toLong + 1 @@ -34,6 +35,7 @@ import util.Hashable * @author Paul Phillips * @version 2.8 */ +@experimental abstract class GenericRange[T] (val start: T, val end: T, val step: T, val isInclusive: Boolean = false) (implicit num: Integral[T]) @@ -53,9 +55,17 @@ extends VectorView[T, Vector[T]] with RangeToString[T] with Hashable { /** Create a new range with the start and end values of this range and * a new <code>step</code>. */ - def by(step: T): GenericRange[T] = - if (isInclusive) GenericRange.inclusive(start, end, step) - else GenericRange(start, end, step) + def by(newStep: T): GenericRange[T] = copy(start, end, newStep) + + /** Create a copy of this range. + */ + def copy(start: T, end: T, step: T): GenericRange[T] + + /** Shift or multiply the entire range by some constant. + */ + def -(shift: T) = this + negate(shift) + def +(shift: T) = copy(this.start + shift, this.end + shift, step) + def *(mult: T) = copy(this.start * mult, this.end * mult, step * mult) override def foreach[U](f: T => U) { var i = start @@ -132,21 +142,23 @@ private[scala] trait RangeToString[T] extends VectorView[T, Vector[T]] { } -object GenericRange { +object GenericRange +{ class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) extends GenericRange(start, end, step, true) { - def exclusive: Exclusive[T] = new Exclusive(start, end, step) + def exclusive: Exclusive[T] = GenericRange(start, end, step) + def copy(start: T, end: T, step: T): Inclusive[T] = GenericRange.inclusive(start, end, step) } class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) extends GenericRange(start, end, step, false) { - def inclusive: Inclusive[T] = new Inclusive(start, end, step) + def inclusive: Inclusive[T] = GenericRange.inclusive(start, end, step) + def copy(start: T, end: T, step: T): Exclusive[T] = GenericRange(start, end, step) } - def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]) = + def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] = new Exclusive(start, end, step) - - def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) = + def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] = new Inclusive(start, end, step) } @@ -210,6 +222,12 @@ extends VectorView[Int, Vector[Int]] with RangeToString[Int] else start >= x && x > end def inclusive = Range.inclusive(start, end, step) + // XXX right now (1 to 10).toList == (1 to 10) but their hashCodes are unequal. + override def equals(other: Any) = other match { + case x: Range => start == x.start && end == x.end && step == x.step + case _ => super.equals(other) + } + override def hashCode = start + end + step } object Range { @@ -219,33 +237,45 @@ object Range { override def by(step: Int): Range = new Inclusive(start, end0, step) } + // The standard / Int-specific Range. def apply(start: Int, end: Int, step: Int) = new Range(start, end, step) - def inclusive(start: Int, end: Int, step: Int): Range = new Range.Inclusive(start, end, step) + // BigInt and Long are straightforward generic ranges. object BigInt { def apply(start: BigInt, end: BigInt, step: BigInt) = GenericRange(start, end, step) def inclusive(start: BigInt, end: BigInt, step: BigInt) = GenericRange.inclusive(start, end, step) } - // The BigDecimal and Double ranges will throw an exception if they cannot - // step exactly as requested. - object BigDecimal { - def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - GenericRange(start, end, step)(Numeric.BigDecimalAsIfIntegral) - def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = - GenericRange.inclusive(start, end, step)(Numeric.BigDecimalAsIfIntegral) - } object Long { def apply(start: Long, end: Long, step: Long) = GenericRange(start, end, step) def inclusive(start: Long, end: Long, step: Long) = GenericRange.inclusive(start, end, step) } + + // BigDecimal uses an alternative implementation of Numeric in which + // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for + // details. The intention is for it to throw an exception anytime + // imprecision or surprises might result from anything, although this may + // not yet be fully implemented. + object BigDecimal { + implicit val bigDecAsIntegral = scala.Numeric.BigDecimalAsIfIntegral + + def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + GenericRange(start, end, step) + def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) = + GenericRange.inclusive(start, end, step) + } + // Double re-uses BigDecimal's range. object Double { - def apply(start: Double, end: Double, step: Double) = - BigDecimal(scala.BigDecimal(start), scala.BigDecimal(end), scala.BigDecimal(step)) - def inclusive(start: Double, end: Double, step: Double) = - BigDecimal.inclusive(scala.BigDecimal(start), scala.BigDecimal(end), scala.BigDecimal(step)) + def apply(start: Double, end: Double, step: Double) = scala.BigDecimal(start) until end by step + def inclusive(start: Double, end: Double, step: Double) = scala.BigDecimal(start) to end by step + } + + // As there is no appealing default step size for not-really-integral ranges, + // we offer a partially constructed object. + class Partial[T, U](f: T => U) { + def by(x: T): U = f(x) } // Illustrating genericity with Int Range, which should have the same behavior diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index fe34195238..3b839fe678 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -14,7 +14,6 @@ package scala.collection.immutable import java.io._ import util.matching.Regex - /** The PagedSeq object defines a lazy implementations of * a random access sequence. */ @@ -108,9 +107,13 @@ import PagedSeq._ * * @author Martin Odersky */ -class PagedSeq[T] protected (more: (Array[T], Int, Int) => Int, - first1: Page[T], start: Int, end: Int) extends RandomAccessSeq[T] { - +class PagedSeq[T] protected( + more: (Array[T], Int, Int) => Int, + first1: Page[T], + start: Int, + end: Int) +extends collection.Vector[T] +{ /** A paged sequence is constructed from a method that produces more characters when asked. * The producer method is analogous to the read method in java.io.Reader. * It takes three parameters: an array of characters, a start index, and an end index. diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala index b0090da156..bc3e8eea0d 100644 --- a/src/library/scala/collection/mutable/ArrayStack.scala +++ b/src/library/scala/collection/mutable/ArrayStack.scala @@ -31,6 +31,7 @@ private object Utils{ * * @author David MacIver */ +@cloneable class ArrayStack[T] private(private var table : Array[AnyRef], private var index : Int) extends Iterable[T]{ def this() = this(new Array[AnyRef](1), 0); diff --git a/src/library/scala/runtime/RichChar.scala b/src/library/scala/runtime/RichChar.scala index 943e5516f5..cbc8f88ab0 100644 --- a/src/library/scala/runtime/RichChar.scala +++ b/src/library/scala/runtime/RichChar.scala @@ -67,7 +67,7 @@ final class RichChar(x: Char) extends Proxy with Ordered[Char] { } } - /** Create a <code>RandomAccessSeq.Projection[Char]</code> over the characters from 'x' to 'y' + /** Create a <code>VectorView[Char]</code> over the characters from 'x' to 'y' */ def to(y: Char): VectorView[Char, Vector[Char]] = until((y + 1).toChar) diff --git a/src/library/scala/runtime/RichDouble.scala b/src/library/scala/runtime/RichDouble.scala index 5c20745f60..c9e25e4edf 100644 --- a/src/library/scala/runtime/RichDouble.scala +++ b/src/library/scala/runtime/RichDouble.scala @@ -13,12 +13,9 @@ package scala.runtime final class RichDouble(x: Double) extends Proxy with Ordered[Double] { - // Proxy.self def self: Any = x - // Ordered[Double].compare - //def compare(y: Double): Int = if (x < y) -1 else if (x > y) 1 else 0 def compare(y: Double): Int = java.lang.Double.compare(x, y) def min(y: Double): Double = Math.min(x, y) @@ -29,11 +26,21 @@ final class RichDouble(x: Double) extends Proxy with Ordered[Double] { def ceil: Double = Math.ceil(x) def floor: Double = Math.floor(x) - /** See <code>Iterator.range</code>. */ - def until(end: Double, step: Double) = Range.Double(x, end, step) + /** See <code>BigDecimal.until</code>. */ + def until(end: Double): Range.Partial[Double, GenericRange.Exclusive[BigDecimal]] = + new Range.Partial(until(end, _)) + + /** See <code>BigDecimal.until</code>. */ + def until(end: Double, step: Double): GenericRange.Exclusive[BigDecimal] = + BigDecimal(x).until(end, step) + + /** See <code>BigDecimal.to</code>. */ + def to(end: Double): Range.Partial[Double, GenericRange.Inclusive[BigDecimal]] = + new Range.Partial(to(end, _)) - /** like <code>until</code>, but includes the last index */ - def to(end: Double, step: Double) = Range.Double.inclusive(x, end, step) + /** See <code>BigDecimal.to</code>. */ + def to(end: Double, step: Double): GenericRange.Inclusive[BigDecimal] = + BigDecimal(x).to(end, step) /** Converts an angle measured in degrees to an approximately equivalent * angle measured in radians. diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala index bb01e0de35..921416d28a 100644 --- a/src/library/scala/runtime/RichInt.scala +++ b/src/library/scala/runtime/RichInt.scala @@ -21,13 +21,10 @@ final class RichInt(val start: Int) extends Proxy with Ordered[Int] { def compare(that: Int): Int = if (start < that) -1 else if (start > that) 1 else 0 /** See <code>Iterator.range</code>. */ - def until(end: Int): Range = new Range(start, end, 1) - - /** See <code>Iterator.range</code>. */ - def until(end: Int, step: Int): Range = new Range(start, end, step) + def until(end: Int, step: Int = 1): Range = new Range(start, end, step) /** like <code>until</code>, but includes the last index */ - def to(end: Int) = Range.inclusive(start, end, 1) + def to(end: Int, step: Int = 1): Range = Range.inclusive(start, end, step) def min(that: Int): Int = if (start < that) start else that def max(that: Int): Int = if (start > that) start else that diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala index 5eddaf0ec3..7eac1e0cab 100644 --- a/src/library/scala/runtime/RichLong.scala +++ b/src/library/scala/runtime/RichLong.scala @@ -20,17 +20,18 @@ final class RichLong(x: Long) extends Proxy with Ordered[Long] { // Ordered[Long].compare def compare(y: Long): Int = if (x < y) -1 else if (x > y) 1 else 0 - /** See <code>Iterator.range</code>. */ - def until(end: Long) = Range.Long(x, end, 1L) - - /** See <code>Iterator.range</code>. */ - def until(end: Long, step: Long) = Range.Long(x, end, step) - - /** like <code>until</code>, but includes the last index */ - def to(end: Long) = Range.Long.inclusive(x, end, 1L) - - /** like <code>until</code>, but includes the last index */ - def to(end: Long, step: Long) = Range.Long.inclusive(x, end, step) + /** Create a GenericRange[Long] in range <code>[start;end)</code> + * with the specified step, where start is the target Long. + * + * @param end the end value of the range (exclusive) + * @param step the distance between elements (defaults to 1) + * @return the range + */ + def until(end: Long, step: Long = 1L): GenericRange.Exclusive[Long] = Range.Long(x, end, step) + + /** Like until, but inclusive of the end value. + */ + def to(end: Long, step: Long = 1L): GenericRange.Inclusive[Long] = Range.Long.inclusive(x, end, step) def min(y: Long): Long = if (x < y) x else y def max(y: Long): Long = if (x > y) x else y diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala index 769be2fef8..3b0590ca37 100644 --- a/src/library/scala/util/control/Exception.scala +++ b/src/library/scala/util/control/Exception.scala @@ -167,8 +167,12 @@ object Exception * an exception handler function as an argument to "by". Example: * handling(ex1, ex2) by (_.printStackTrace) */ - def handling[T](exceptions: Class[_]*) = new { - def by(f: (Throwable) => T): Catch[T] = catching(exceptions: _*) withApply f + class By[T,R](f: T => R) { + def by(x: T): R = f(x) + } + def handling[T](exceptions: Class[_]*) = { + def fun(f: Throwable => T) = catching(exceptions: _*) withApply f + new By[Throwable => T, Catch[T]](fun _) } /** Returns a Catch object with no catch logic and the argument as Finally. */ diff --git a/src/library/scala/xml/Group.scala b/src/library/scala/xml/Group.scala index 9e18ecb5f0..7e4b983ec6 100644 --- a/src/library/scala/xml/Group.scala +++ b/src/library/scala/xml/Group.scala @@ -21,7 +21,7 @@ case class Group(val nodes: Seq[Node]) extends Node { override def theSeq = nodes - /** structural equality */ + /** XXX this is ridiculous, we can't do equality like this. */ override def equals(x: Any) = x match { case z:Group => (length == z.length) && sameElements(z) case z:Node => (length == 1) && z == apply(0) @@ -29,6 +29,8 @@ case class Group(val nodes: Seq[Node]) extends Node { case z:String => text == z case _ => false } + /* As if there were a hashCode which could back up the above implementation! */ + override def hashCode = nodes.hashCode /** * @throws Predef.UnsupportedOperationException (always) diff --git a/src/library/scala/xml/NamespaceBinding.scala b/src/library/scala/xml/NamespaceBinding.scala index 9af256501c..567686d58b 100644 --- a/src/library/scala/xml/NamespaceBinding.scala +++ b/src/library/scala/xml/NamespaceBinding.scala @@ -22,13 +22,11 @@ import Utility.sbToString * @author Burak Emir * @version 1.0 */ -@serializable +@SerialVersionUID(0 - 2518644165573446725L) class NamespaceBinding(val prefix: String, val uri: String, val parent: NamespaceBinding) extends AnyRef { - private val serialVersionUID = 0 - 2518644165573446725L - if (null != prefix && 0 == prefix.length()) throw new IllegalArgumentException("zero length prefix not allowed") diff --git a/src/swing/scala/swing/BufferWrapper.scala b/src/swing/scala/swing/BufferWrapper.scala index 9e563e230e..6704bfc0f9 100644 --- a/src/swing/scala/swing/BufferWrapper.scala +++ b/src/swing/scala/swing/BufferWrapper.scala @@ -1,6 +1,7 @@ package scala.swing import scala.collection.mutable.Buffer +import scala.collection.Vector /** * Default partial implementation for buffer adapters. @@ -20,7 +21,7 @@ protected[swing] abstract class BufferWrapper[A] extends Buffer[A] { outer => } protected def insertAt(n: Int, a: A) - def readOnly : RandomAccessSeq[A] = new RandomAccessSeq[A] { + def readOnly: Vector[A] = new Vector[A] { def length = outer.length def apply(idx : Int) = outer.apply(idx) override def stringPrefix = outer.stringPrefix + "RO" |