summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland <rk@rkuhn.info>2012-09-19 21:46:04 +0200
committerRoland <rk@rkuhn.info>2012-09-20 13:19:57 +0200
commit05367235ef4c519521cb28073f951e3d55fe3aad (patch)
treefbcd805f07782a251c5ec6e5d97d3dc41ebf6011
parent68c0e596549765a15474b56ab9013ed3ba53b0ce (diff)
downloadscala-05367235ef4c519521cb28073f951e3d55fe3aad.tar.gz
scala-05367235ef4c519521cb28073f951e3d55fe3aad.tar.bz2
scala-05367235ef4c519521cb28073f951e3d55fe3aad.zip
some small remaining fixes
- added test for “span” and “fromNow” qualifiers - make those actually work even when there is an expected type - add ScalaDoc to them - verify (and fix) conversion Deadline -> FiniteDuration - also make Int * Duration => FiniteDuration work (and test it)
-rw-r--r--src/library/scala/concurrent/duration/Deadline.scala1
-rw-r--r--src/library/scala/concurrent/duration/Duration.scala10
-rw-r--r--src/library/scala/concurrent/duration/DurationConversions.scala46
-rw-r--r--src/library/scala/concurrent/duration/package.scala24
-rw-r--r--test/files/jvm/duration-tck.scala5
5 files changed, 58 insertions, 28 deletions
diff --git a/src/library/scala/concurrent/duration/Deadline.scala b/src/library/scala/concurrent/duration/Deadline.scala
index beeedec7bc..50e9a75ff7 100644
--- a/src/library/scala/concurrent/duration/Deadline.scala
+++ b/src/library/scala/concurrent/duration/Deadline.scala
@@ -77,4 +77,5 @@ object Deadline {
implicit object DeadlineIsOrdered extends Ordering[Deadline] {
def compare(a: Deadline, b: Deadline) = a compare b
}
+
}
diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala
index 81efc5c117..79f9b4db86 100644
--- a/src/library/scala/concurrent/duration/Duration.scala
+++ b/src/library/scala/concurrent/duration/Duration.scala
@@ -12,11 +12,6 @@ import java.lang.{ Double => JDouble, Long => JLong }
import scala.language.implicitConversions
object Duration {
- /**
- * This implicit conversion allows the use of a Deadline in place of a Duration, which will
- * insert the time left until the deadline in its place.
- */
- implicit def timeLeft(implicit d: Deadline): Duration = d.timeLeft
/**
* Construct a Duration from the given length and unit. Observe that nanosecond precision may be lost if
@@ -29,11 +24,13 @@ object Duration {
* @throws IllegalArgumentException if the length was finite but the resulting duration cannot be expressed as a [[FiniteDuration]]
*/
def apply(length: Double, unit: TimeUnit): Duration = fromNanos(unit.toNanos(1) * length)
+
/**
* Construct a finite duration from the given length and time unit. The unit given is retained
* throughout calculations as long as possible, so that it can be retrieved later.
*/
def apply(length: Long, unit: TimeUnit): FiniteDuration = new FiniteDuration(length, unit)
+
/**
* Construct a finite duration from the given length and time unit, where the latter is
* looked up in a list of string representation. Valid choices are:
@@ -44,7 +41,7 @@ object Duration {
def apply(length: Long, unit: String): FiniteDuration = new FiniteDuration(length, Duration.timeUnit(unit))
// Double stores 52 bits mantissa, but there is an implied '1' in front, making the limit 2^53
- final val maxPreciseDouble = 9007199254740992d
+ private[this] final val maxPreciseDouble = 9007199254740992d
/**
* Parse String into Duration. Format is `"<length><unit>"`, where
@@ -525,6 +522,7 @@ sealed abstract class Duration extends Serializable with Ordered[Duration] {
}
object FiniteDuration {
+
implicit object FiniteDurationIsOrdered extends Ordering[FiniteDuration] {
def compare(a: FiniteDuration, b: FiniteDuration) = a compare b
}
diff --git a/src/library/scala/concurrent/duration/DurationConversions.scala b/src/library/scala/concurrent/duration/DurationConversions.scala
index 14f26e05b2..2c7e192a0e 100644
--- a/src/library/scala/concurrent/duration/DurationConversions.scala
+++ b/src/library/scala/concurrent/duration/DurationConversions.scala
@@ -42,45 +42,51 @@ trait DurationConversions extends Any {
def days = durationIn(DAYS)
def day = days
- def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(nanoseconds)
- def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = nanoseconds(c)
- def nanosecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = nanoseconds(c)
- def nano[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = nanoseconds(c)
+ def nanoseconds[C](c: C)(implicit ev: Classifier[C]): ev.R = ev.convert(nanoseconds)
+ def nanos[C](c: C)(implicit ev: Classifier[C]): ev.R = nanoseconds(c)
+ def nanosecond[C](c: C)(implicit ev: Classifier[C]): ev.R = nanoseconds(c)
+ def nano[C](c: C)(implicit ev: Classifier[C]): ev.R = nanoseconds(c)
- def microseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(microseconds)
- def micros[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = microseconds(c)
- def microsecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = microseconds(c)
- def micro[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = microseconds(c)
+ def microseconds[C](c: C)(implicit ev: Classifier[C]): ev.R = ev.convert(microseconds)
+ def micros[C](c: C)(implicit ev: Classifier[C]): ev.R = microseconds(c)
+ def microsecond[C](c: C)(implicit ev: Classifier[C]): ev.R = microseconds(c)
+ def micro[C](c: C)(implicit ev: Classifier[C]): ev.R = microseconds(c)
- def milliseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(milliseconds)
- def millis[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = milliseconds(c)
- def millisecond[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = milliseconds(c)
- def milli[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = milliseconds(c)
+ def milliseconds[C](c: C)(implicit ev: Classifier[C]): ev.R = ev.convert(milliseconds)
+ def millis[C](c: C)(implicit ev: Classifier[C]): ev.R = milliseconds(c)
+ def millisecond[C](c: C)(implicit ev: Classifier[C]): ev.R = milliseconds(c)
+ def milli[C](c: C)(implicit ev: Classifier[C]): ev.R = milliseconds(c)
- def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(seconds)
- def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = seconds(c)
+ def seconds[C](c: C)(implicit ev: Classifier[C]): ev.R = ev.convert(seconds)
+ def second[C](c: C)(implicit ev: Classifier[C]): ev.R = seconds(c)
- def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(minutes)
- def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = minutes(c)
+ def minutes[C](c: C)(implicit ev: Classifier[C]): ev.R = ev.convert(minutes)
+ def minute[C](c: C)(implicit ev: Classifier[C]): ev.R = minutes(c)
- def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(hours)
- def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = hours(c)
+ def hours[C](c: C)(implicit ev: Classifier[C]): ev.R = ev.convert(hours)
+ def hour[C](c: C)(implicit ev: Classifier[C]): ev.R = hours(c)
- def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(days)
- def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = days(c)
+ def days[C](c: C)(implicit ev: Classifier[C]): ev.R = ev.convert(days)
+ def day[C](c: C)(implicit ev: Classifier[C]): ev.R = days(c)
}
+/**
+ * This object just holds some cogs which make the DSL machine work, not for direct consumption.
+ */
object DurationConversions {
trait Classifier[C] {
type R
def convert(d: FiniteDuration): R
}
+
implicit object spanConvert extends Classifier[span.type] {
type R = FiniteDuration
def convert(d: FiniteDuration) = d
}
+
implicit object fromNowConvert extends Classifier[fromNow.type] {
type R = Deadline
def convert(d: FiniteDuration) = Deadline.now + d
}
+
}
diff --git a/src/library/scala/concurrent/duration/package.scala b/src/library/scala/concurrent/duration/package.scala
index 1a62a01b03..2fd735f19e 100644
--- a/src/library/scala/concurrent/duration/package.scala
+++ b/src/library/scala/concurrent/duration/package.scala
@@ -3,8 +3,28 @@ package scala.concurrent
import scala.language.implicitConversions
package object duration {
- // FIXME - these need documenting.
+ /**
+ * This object can be used as closing token if you prefer dot-less style but do not want
+ * to enable language.postfixOps:
+ *
+ * {{{
+ * import scala.concurrent.duration._
+ *
+ * val duration = 2 seconds span
+ * }}}
+ */
object span
+
+ /**
+ * This object can be used as closing token for declaring a deadline at some future point
+ * in time:
+ *
+ * {{{
+ * import scala.concurrent.duration._
+ *
+ * val deadline = 3 seconds fromNow
+ * }}}
+ */
object fromNow
type TimeUnit = java.util.concurrent.TimeUnit
@@ -41,10 +61,12 @@ package object duration {
*/
implicit final class IntMult(val i: Int) extends AnyVal {
def *(d: Duration) = d * i
+ def *(d: FiniteDuration) = d * i
}
implicit final class LongMult(val i: Long) extends AnyVal {
def *(d: Duration) = d * i
+ def *(d: FiniteDuration) = d * i
}
implicit final class DoubleMult(val f: Double) extends AnyVal {
diff --git a/test/files/jvm/duration-tck.scala b/test/files/jvm/duration-tck.scala
index 40073c0b3f..df1052fed3 100644
--- a/test/files/jvm/duration-tck.scala
+++ b/test/files/jvm/duration-tck.scala
@@ -186,6 +186,9 @@ object Test extends App {
// check statically retaining finite-ness
val finiteDuration: FiniteDuration = 1.second * 2 / 3 mul 5 div 4 plus 3.seconds minus 1.millisecond min 1.second max 1.second
-
+ val finite2: FiniteDuration = 2 * 1.second + 3L * 2.seconds
+ finite2 mustBe 8.seconds
+ ((2 seconds fromNow).timeLeft: FiniteDuration) < 4.seconds mustBe true
+ val finite3: FiniteDuration = 3.5 seconds span
}