diff options
author | Roland <rk@rkuhn.info> | 2012-09-19 21:46:04 +0200 |
---|---|---|
committer | Roland <rk@rkuhn.info> | 2012-09-20 13:19:57 +0200 |
commit | 05367235ef4c519521cb28073f951e3d55fe3aad (patch) | |
tree | fbcd805f07782a251c5ec6e5d97d3dc41ebf6011 | |
parent | 68c0e596549765a15474b56ab9013ed3ba53b0ce (diff) | |
download | scala-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)
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 } |