From 58e044950b5e4dd622ee630be79c17d09bb2f5f4 Mon Sep 17 00:00:00 2001 From: Bill Venners Date: Thu, 30 Jul 2026 11:15:09 -0700 Subject: [PATCH] Add Scaladoc for undocumented core array, function, tuple, and sys APIs --- library/src/scala/Array.scala | 41 ++++ library/src/scala/Function0.scala | 1 + library/src/scala/Function1.scala | 6 + library/src/scala/Function10.scala | 1 + library/src/scala/Function11.scala | 1 + library/src/scala/Function12.scala | 1 + library/src/scala/Function13.scala | 1 + library/src/scala/Function14.scala | 1 + library/src/scala/Function15.scala | 1 + library/src/scala/Function16.scala | 1 + library/src/scala/Function17.scala | 1 + library/src/scala/Function18.scala | 1 + library/src/scala/Function19.scala | 1 + library/src/scala/Function2.scala | 1 + library/src/scala/Function20.scala | 1 + library/src/scala/Function21.scala | 1 + library/src/scala/Function22.scala | 1 + library/src/scala/Function3.scala | 1 + library/src/scala/Function4.scala | 1 + library/src/scala/Function5.scala | 1 + library/src/scala/Function6.scala | 1 + library/src/scala/Function7.scala | 1 + library/src/scala/Function8.scala | 1 + library/src/scala/Function9.scala | 1 + library/src/scala/IArray.scala | 21 ++ library/src/scala/Option.scala | 41 ++++ library/src/scala/Predef.scala | 87 ++++++++ library/src/scala/Product1.scala | 6 + library/src/scala/Product10.scala | 16 ++ library/src/scala/Product11.scala | 17 ++ library/src/scala/Product12.scala | 18 ++ library/src/scala/Product13.scala | 19 ++ library/src/scala/Product14.scala | 20 ++ library/src/scala/Product15.scala | 21 ++ library/src/scala/Product16.scala | 22 ++ library/src/scala/Product17.scala | 23 +++ library/src/scala/Product18.scala | 24 +++ library/src/scala/Product19.scala | 25 +++ library/src/scala/Product2.scala | 7 + library/src/scala/Product20.scala | 26 +++ library/src/scala/Product21.scala | 27 +++ library/src/scala/Product22.scala | 27 +++ library/src/scala/Product3.scala | 8 + library/src/scala/Product4.scala | 10 + library/src/scala/Product5.scala | 11 + library/src/scala/Product6.scala | 12 ++ library/src/scala/Product7.scala | 12 ++ library/src/scala/Product8.scala | 14 ++ library/src/scala/Product9.scala | 15 ++ library/src/scala/Tuple.scala | 24 +++ library/src/scala/Tuple1.scala | 1 + library/src/scala/Tuple10.scala | 1 + library/src/scala/Tuple11.scala | 1 + library/src/scala/Tuple12.scala | 1 + library/src/scala/Tuple13.scala | 1 + library/src/scala/Tuple14.scala | 1 + library/src/scala/Tuple15.scala | 1 + library/src/scala/Tuple16.scala | 1 + library/src/scala/Tuple17.scala | 1 + library/src/scala/Tuple18.scala | 1 + library/src/scala/Tuple19.scala | 1 + library/src/scala/Tuple2.scala | 1 + library/src/scala/Tuple20.scala | 1 + library/src/scala/Tuple21.scala | 1 + library/src/scala/Tuple22.scala | 1 + library/src/scala/Tuple3.scala | 1 + library/src/scala/Tuple4.scala | 1 + library/src/scala/Tuple5.scala | 1 + library/src/scala/Tuple6.scala | 1 + library/src/scala/Tuple7.scala | 1 + library/src/scala/Tuple8.scala | 1 + library/src/scala/Tuple9.scala | 1 + .../src/scala/runtime/AbstractFunction0.scala | 7 + .../src/scala/runtime/AbstractFunction1.scala | 8 + .../scala/runtime/AbstractFunction10.scala | 17 ++ .../scala/runtime/AbstractFunction11.scala | 18 ++ .../scala/runtime/AbstractFunction12.scala | 19 ++ .../scala/runtime/AbstractFunction13.scala | 19 ++ .../scala/runtime/AbstractFunction14.scala | 18 ++ .../scala/runtime/AbstractFunction15.scala | 22 ++ .../scala/runtime/AbstractFunction16.scala | 23 +++ .../scala/runtime/AbstractFunction17.scala | 24 +++ .../scala/runtime/AbstractFunction18.scala | 25 +++ .../scala/runtime/AbstractFunction19.scala | 26 +++ .../src/scala/runtime/AbstractFunction2.scala | 8 + .../scala/runtime/AbstractFunction20.scala | 27 +++ .../scala/runtime/AbstractFunction21.scala | 28 +++ .../scala/runtime/AbstractFunction22.scala | 29 +++ .../src/scala/runtime/AbstractFunction3.scala | 9 + .../src/scala/runtime/AbstractFunction4.scala | 10 + .../src/scala/runtime/AbstractFunction5.scala | 11 + .../src/scala/runtime/AbstractFunction6.scala | 12 ++ .../src/scala/runtime/AbstractFunction7.scala | 13 ++ .../src/scala/runtime/AbstractFunction8.scala | 14 ++ .../src/scala/runtime/AbstractFunction9.scala | 15 ++ library/src/scala/sys/BooleanProp.scala | 43 ++++ library/src/scala/sys/Prop.scala | 6 + library/src/scala/sys/PropImpl.scala | 33 +++ .../src/scala/sys/ShutdownHookThread.scala | 8 + library/src/scala/sys/SystemProperties.scala | 63 ++++++ library/src/scala/sys/process/BasicIO.scala | 53 +++++ library/src/scala/sys/process/Parser.scala | 10 +- .../scala/sys/process/ProcessBuilder.scala | 2 + .../sys/process/ProcessBuilderImpl.scala | 192 ++++++++++++++++++ library/src/scala/sys/process/ProcessIO.scala | 8 +- .../src/scala/sys/process/ProcessImpl.scala | 94 ++++++++- .../src/scala/sys/process/ProcessLogger.scala | 16 ++ library/src/scala/sys/process/package.scala | 35 ++++ 108 files changed, 1605 insertions(+), 4 deletions(-) diff --git a/library/src/scala/Array.scala b/library/src/scala/Array.scala index c9fd67ff74c5..008ed7e45e46 100644 --- a/library/src/scala/Array.scala +++ b/library/src/scala/Array.scala @@ -55,7 +55,13 @@ object Array { implicit def toFactory[A : ClassTag](dummy: Array.type): Factory[A, Array[A]] = new ArrayFactory(dummy) @SerialVersionUID(3L) private class ArrayFactory[A : ClassTag](dummy: Array.type) extends Factory[A, Array[A]] with Serializable { + /** Builds an array containing the elements of the given collection. + * + * @param it the source of elements to include in the array + * @return a new `Array[A]` holding the elements of `it`, in iteration order + */ def fromSpecific(it: IterableOnce[A]^): Array[A] = Array.from[A](it) + /** Returns a new builder that accumulates elements into an `Array[A]`. */ def newBuilder: mutable.Builder[A, Array[A]] = Array.newBuilder[A] } @@ -704,12 +710,47 @@ object Array { */ def unapplySeq[T](x: Array[T]): UnapplySeqWrapper[T] = new UnapplySeqWrapper(x) + /** A wrapper that lets an array be destructured by a sequence pattern such as + * `case Array(x, y, z) =>`. + * + * The members below implement the name-based extractor protocol directly against + * the wrapped array, so a fixed-arity pattern matches without building an + * intermediate sequence. + * + * @tparam T the element type of the wrapped array + * @param a the array to be destructured + */ final class UnapplySeqWrapper[T](private val a: Array[T]) extends AnyVal { + /** Returns `false`, since this extractor never yields an empty result. + * + * The literal type `false` tells the compiler that the extraction itself cannot fail, so + * [[get]] is always available. Whether a particular sequence pattern matches is decided + * separately, by [[lengthCompare]] and the element accessors. + */ def isEmpty: false = false + /** Returns this wrapper, whose sequence-like operations supply the elements of the pattern. */ def get: UnapplySeqWrapper[T] = this + /** Compares the length of the wrapped array to a test value. + * + * @param len the test value that gets compared with the length + * @return a value less than, equal to, or greater than `0` as the length of the array is less than, equal to, or greater than `len` + */ def lengthCompare(len: Int): Int = a.lengthCompare(len) + /** Returns the element of the wrapped array at the given index. + * + * @param i the index, which must be in the range from `0` until the length of the array + * @return the element at index `i` + * @throws ArrayIndexOutOfBoundsException if `i < 0` or the length of the wrapped array `<= i` + */ def apply(i: Int): T = a(i) + /** Returns all elements of the wrapped array except the first `n`, as needed to bind the + * variable-length part of a pattern such as `case Array(x, rest*) =>`. + * + * @param n the number of leading elements to skip + * @return a sequence backed by a fresh copy of the remaining elements, even when `n` is `0` + */ def drop(n: Int): scala.Seq[T] = ArraySeq.unsafeWrapArray(a.drop(n)) // clones the array, also if n == 0 + /** Returns the elements of the wrapped array as a sequence backed by a copy of the array. */ def toSeq: scala.Seq[T] = a.toSeq // clones the array } } diff --git a/library/src/scala/Function0.scala b/library/src/scala/Function0.scala index e2bab9eec04b..a8fd64d86f22 100644 --- a/library/src/scala/Function0.scala +++ b/library/src/scala/Function0.scala @@ -37,5 +37,6 @@ trait Function0[@specialized(Specializable.Primitives) +R] extends AnyRef { */ def apply(): R + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function1.scala b/library/src/scala/Function1.scala index ac7a34f2e743..8bc2c1b0e5ad 100644 --- a/library/src/scala/Function1.scala +++ b/library/src/scala/Function1.scala @@ -16,6 +16,11 @@ import scala.language.`2.13` object Function1 { + /** Provides the [[UnliftOps.unlift]] method on functions that return an [[scala.Option]]. + * + * @tparam A the argument type of the wrapped function + * @tparam B the type of the value contained in the `Option` result of the wrapped function + */ implicit final class UnliftOps[A, B] private[Function1](private val f: A => Option[B]) extends AnyVal { /** Converts an optional function to a partial function. * @@ -87,5 +92,6 @@ trait Function1[@specialized(Specializable.Arg) -T1, @specialized(Specializable. */ @annotation.unspecialized def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function10.scala b/library/src/scala/Function10.scala index d02d08144fcf..d9ae8a939deb 100644 --- a/library/src/scala/Function10.scala +++ b/library/src/scala/Function10.scala @@ -60,5 +60,6 @@ trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function11.scala b/library/src/scala/Function11.scala index e7bdc3eb2636..5edfcdf5af6f 100644 --- a/library/src/scala/Function11.scala +++ b/library/src/scala/Function11.scala @@ -62,5 +62,6 @@ trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] ex @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function12.scala b/library/src/scala/Function12.scala index 130001979f6b..a7be58e6dad3 100644 --- a/library/src/scala/Function12.scala +++ b/library/src/scala/Function12.scala @@ -64,5 +64,6 @@ trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function13.scala b/library/src/scala/Function13.scala index 983dc7284855..89473e968e60 100644 --- a/library/src/scala/Function13.scala +++ b/library/src/scala/Function13.scala @@ -66,5 +66,6 @@ trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function14.scala b/library/src/scala/Function14.scala index b91965db10fd..eb2f289edd5f 100644 --- a/library/src/scala/Function14.scala +++ b/library/src/scala/Function14.scala @@ -68,5 +68,6 @@ trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function15.scala b/library/src/scala/Function15.scala index d6e9cb492f55..9493d10900fa 100644 --- a/library/src/scala/Function15.scala +++ b/library/src/scala/Function15.scala @@ -70,5 +70,6 @@ trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function16.scala b/library/src/scala/Function16.scala index 4a28b1f8b7ac..b7c1bc7bbba0 100644 --- a/library/src/scala/Function16.scala +++ b/library/src/scala/Function16.scala @@ -72,5 +72,6 @@ trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function17.scala b/library/src/scala/Function17.scala index 007f2766a1be..76129f5ba7ba 100644 --- a/library/src/scala/Function17.scala +++ b/library/src/scala/Function17.scala @@ -74,5 +74,6 @@ trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function18.scala b/library/src/scala/Function18.scala index 46bb186ac69f..1f51b0ea3f3e 100644 --- a/library/src/scala/Function18.scala +++ b/library/src/scala/Function18.scala @@ -76,5 +76,6 @@ trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function19.scala b/library/src/scala/Function19.scala index aeca2a45705a..b68618a6c1e3 100644 --- a/library/src/scala/Function19.scala +++ b/library/src/scala/Function19.scala @@ -78,5 +78,6 @@ trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function2.scala b/library/src/scala/Function2.scala index b88a9facf85e..31cca4b87d26 100644 --- a/library/src/scala/Function2.scala +++ b/library/src/scala/Function2.scala @@ -54,5 +54,6 @@ trait Function2[@specialized(Specializable.Args) -T1, @specialized(Specializable @annotation.unspecialized def tupled: ((T1, T2)) => R = { case ((x1, x2)) => apply(x1, x2) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function20.scala b/library/src/scala/Function20.scala index ff086b6c5edc..b578a25b595d 100644 --- a/library/src/scala/Function20.scala +++ b/library/src/scala/Function20.scala @@ -80,5 +80,6 @@ trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function21.scala b/library/src/scala/Function21.scala index 3591f30c9c47..1c7002ed6aec 100644 --- a/library/src/scala/Function21.scala +++ b/library/src/scala/Function21.scala @@ -82,5 +82,6 @@ trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function22.scala b/library/src/scala/Function22.scala index 169e54fa8200..d0cf0a679917 100644 --- a/library/src/scala/Function22.scala +++ b/library/src/scala/Function22.scala @@ -84,5 +84,6 @@ trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function3.scala b/library/src/scala/Function3.scala index ec1328a0cead..30eaf0415af0 100644 --- a/library/src/scala/Function3.scala +++ b/library/src/scala/Function3.scala @@ -46,5 +46,6 @@ trait Function3[-T1, -T2, -T3, +R] extends AnyRef { @annotation.unspecialized def tupled: ((T1, T2, T3)) => R = { case ((x1, x2, x3)) => apply(x1, x2, x3) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function4.scala b/library/src/scala/Function4.scala index 397062b06970..a447e72e40b5 100644 --- a/library/src/scala/Function4.scala +++ b/library/src/scala/Function4.scala @@ -48,5 +48,6 @@ trait Function4[-T1, -T2, -T3, -T4, +R] extends AnyRef { @annotation.unspecialized def tupled: ((T1, T2, T3, T4)) => R = { case ((x1, x2, x3, x4)) => apply(x1, x2, x3, x4) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function5.scala b/library/src/scala/Function5.scala index 9ce9e9a8a413..1dd06f3f72af 100644 --- a/library/src/scala/Function5.scala +++ b/library/src/scala/Function5.scala @@ -50,5 +50,6 @@ trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends AnyRef { @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5)) => R = { case ((x1, x2, x3, x4, x5)) => apply(x1, x2, x3, x4, x5) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function6.scala b/library/src/scala/Function6.scala index d3449403587f..ada516dd04d3 100644 --- a/library/src/scala/Function6.scala +++ b/library/src/scala/Function6.scala @@ -52,5 +52,6 @@ trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends AnyRef { @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6)) => R = { case ((x1, x2, x3, x4, x5, x6)) => apply(x1, x2, x3, x4, x5, x6) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function7.scala b/library/src/scala/Function7.scala index 256a4f98614e..55a0156f73ad 100644 --- a/library/src/scala/Function7.scala +++ b/library/src/scala/Function7.scala @@ -54,5 +54,6 @@ trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends AnyRef { @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7)) => R = { case ((x1, x2, x3, x4, x5, x6, x7)) => apply(x1, x2, x3, x4, x5, x6, x7) } + /** TODO FILL IN */ override def toString(): String = "" } diff --git a/library/src/scala/Function8.scala b/library/src/scala/Function8.scala index e9d4c4d3ef63..13f6d41aa33e 100644 --- a/library/src/scala/Function8.scala +++ b/library/src/scala/Function8.scala @@ -56,5 +56,6 @@ trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends AnyRef { @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8)) => apply(x1, x2, x3, x4, x5, x6, x7, x8) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/Function9.scala b/library/src/scala/Function9.scala index 47954cb29851..90f3851d30fb 100644 --- a/library/src/scala/Function9.scala +++ b/library/src/scala/Function9.scala @@ -58,5 +58,6 @@ trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends AnyRef @annotation.unspecialized def tupled: ((T1, T2, T3, T4, T5, T6, T7, T8, T9)) => R = { case ((x1, x2, x3, x4, x5, x6, x7, x8, x9)) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9) } + /** Returns the string `""`. */ override def toString(): String = "" } diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 53369fdcd8bb..6d16365f9605 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -740,6 +740,12 @@ object IArray: def from[A : ClassTag](it: IterableOnce[A]^): IArray[A] = unsafeFromArray(Array.from(it)) + /** Returns a new empty builder for immutable arrays of element type `T`. + * + * @tparam T the element type of the array + * @param t the `ClassTag` for the element type `T`, used to allocate the underlying array + * @return a new builder that produces an `IArray[T]` from the elements added to it + */ def newBuilder[T](using t: ClassTag[T]): Builder[T, IArray[T]] = ArrayBuilder.make[T].mapResult(IArray.unsafeFromArray) @@ -995,6 +1001,21 @@ object IArray: b.result() } + /** Builds a new array by applying a function to each element of this array + * that satisfies this filter's predicate and using the elements of the + * resulting collections. + * + * Unlike the overload taking an `IterableOnce`-valued function, `f` may return + * any type that can be viewed as an `Iterable[U]`. + * + * @tparam BS the result type of `f`, which must be viewable as an `Iterable[U]`. + * @tparam U the element type of the returned array. + * @param f the function to apply to each element. + * @param asIterable the implicit conversion viewing the result of `f` as an `Iterable[U]`. + * @param m the `ClassTag` for the returned array's element type `U`. + * @return a new array resulting from applying `f` to each element of this array + * that satisfies the filter predicate and concatenating the results. + */ def flatMap[BS, U](f: T => BS)(using asIterable: BS => Iterable[U]^, m: ClassTag[U]): IArray[U] = flatMap[U](x => asIterable(f(x))) diff --git a/library/src/scala/Option.scala b/library/src/scala/Option.scala index d38baffb2ebd..b3135ddcfd70 100644 --- a/library/src/scala/Option.scala +++ b/library/src/scala/Option.scala @@ -164,6 +164,11 @@ object Option { * @tparam A the type of the value contained in the option */ @SerialVersionUID(-114498752079829388L) // value computed by serialver for 2.11.2, annotation added in 2.11.4 +/** Represents optional values. Instances of `Option` are either an instance + * of [[scala.Some]] or the object `None`. + * + * @tparam A the type of the value contained in the option + */ sealed abstract class Option[+A] extends IterableOnce[A] with Product with Serializable { self => @@ -195,6 +200,7 @@ sealed abstract class Option[+A] extends IterableOnce[A] with Product with Seria */ final def isDefined: Boolean = !isEmpty + /** Returns the number of elements this option contains: 0 if it is $none, 1 otherwise. */ override final def knownSize: Int = if (isEmpty) 0 else 1 /** Returns the option's value. @@ -411,9 +417,37 @@ sealed abstract class Option[+A] extends IterableOnce[A] with Product with Seria * @param p the predicate used to filter the option value */ class WithFilter(p: A => Boolean) { + /** Returns a $some containing the result of applying $f to the filtered + * $option's value, or $none if the $option is empty or its value does not + * satisfy $p. + * + * @tparam B the result type of the function `f` + * @param f the function to apply + * @return a `Some` containing `f` applied to the option's value if the option + * is nonempty and its value satisfies `p`, otherwise `None` + */ def map[B](f: A => B): Option[B] = self filter p map f + /** Returns the result of applying $f to the filtered $option's value, or + * $none if the $option is empty or its value does not satisfy $p. + * + * @tparam B the element type of the returned option + * @param f the function to apply + * @return the result of applying `f` to the option's value if the option is + * nonempty and its value satisfies `p`, otherwise `None` + */ def flatMap[B](f: A => Option[B]): Option[B] = self filter p flatMap f + /** Applies the given procedure $f to the filtered $option's value, if the + * $option is nonempty and its value satisfies $p. Otherwise, does nothing. + * + * @tparam U the result type of the procedure `f` (result is discarded) + * @param f the procedure to apply + */ def foreach[U](f: A => U): Unit = self filter p foreach f + /** Returns a `WithFilter` whose predicate is the conjunction of $p and `q`. + * + * @param q the additional predicate used to test the option's value + * @return a `WithFilter` whose predicate holds only when both `p` and `q` hold + */ def withFilter(q: A => Boolean): WithFilter = new WithFilter(x => p(x) && q(x)) } @@ -692,7 +726,13 @@ sealed abstract class Option[+A] extends IterableOnce[A] with Product with Seria * @param value the contained value */ @SerialVersionUID(1234815782226070388L) // value computed by serialver for 2.11.2, annotation added in 2.11.4 +/** Represents an existing value of type `A`. + * + * @tparam A the type of the contained value + * @param value the contained value + */ final case class Some[+A](value: A) extends Option[A] { + /** Returns the contained value. */ def get: A = value } @@ -700,5 +740,6 @@ final case class Some[+A](value: A) extends Option[A] { /** This case object represents non-existent values. */ @SerialVersionUID(5066590221178148012L) // value computed by serialver for 2.11.2, annotation added in 2.11.4 case object None extends Option[Nothing] { + /** Throws a `NoSuchElementException`, since `None` holds no value. */ def get: Nothing = throw new NoSuchElementException("None.get") } diff --git a/library/src/scala/Predef.scala b/library/src/scala/Predef.scala index e7febb2783bd..ca993daa1103 100644 --- a/library/src/scala/Predef.scala +++ b/library/src/scala/Predef.scala @@ -218,9 +218,21 @@ object Predef extends LowPriorityImplicits { // TODO undeprecated until Scala reflection becomes non-experimental // @deprecated("use scala.reflect.classTag[T] and scala.reflect.runtime.universe.typeTag[T] instead", "2.10.0") + /** Summons the [[Manifest]] for type `T`. Usually, the argument is not passed explicitly. + * + * @tparam T the type whose `Manifest` is summoned + * @param m the implicit `Manifest` for `T` + * @return the `Manifest` describing the erasure and type arguments of `T` + */ def manifest[T](implicit m: Manifest[T]): Manifest[T] = m // TODO undeprecated until Scala reflection becomes non-experimental // @deprecated("this notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0") + /** Summons the [[OptManifest]] for type `T`. Usually, the argument is not passed explicitly. + * + * @tparam T the type whose `OptManifest` is summoned + * @param m the implicit `OptManifest` for `T` + * @return the `OptManifest` for `T`, which is [[NoManifest]] when no full `Manifest` is available + */ def optManifest[T](implicit m: OptManifest[T]): OptManifest[T] = m // Minor variations on identity functions @@ -415,6 +427,12 @@ object Predef extends LowPriorityImplicits { @deprecated("Use `->` extension method instead.", since = "3.10.0") // no longer implicit, but direct calls should still resolve. + /** Wraps a value so that the pair-construction operators `->` and `→` can be applied to it. + * + * @tparam A the type of the left-hand side of the arrow association + * @param self the value to use as the first element of the resulting tuple + * @return an [[ArrowAssoc]] wrapping `self` + */ final def ArrowAssoc[A >: Nothing <: Any](self: A): ArrowAssoc[A] = new ArrowAssoc[A](self) /** @@ -424,9 +442,31 @@ object Predef extends LowPriorityImplicits { * @param self the value to check postconditions against */ implicit final class Ensuring[A](private val self: A) extends AnyVal { + /** Tests a postcondition, throwing an `AssertionError` if it does not hold. + * + * @param cond the postcondition to test + * @return the value on which `ensuring` was invoked, unchanged + */ def ensuring(cond: Boolean): A = { assert(cond); self } + /** Tests a postcondition, throwing an `AssertionError` including `msg` if it does not hold. + * + * @param cond the postcondition to test + * @param msg a value to include in the failure message + * @return the value on which `ensuring` was invoked, unchanged + */ def ensuring(cond: Boolean, msg: => Any): A = { assert(cond, msg); self } + /** Tests a postcondition on the value, throwing an `AssertionError` if `cond` does not hold for it. + * + * @param cond the predicate applied to the value + * @return the value on which `ensuring` was invoked, unchanged + */ def ensuring(cond: A => Boolean): A = { assert(cond(self)); self } + /** Tests a postcondition on the value, throwing an `AssertionError` including `msg` if `cond` does not hold for it. + * + * @param cond the predicate applied to the value + * @param msg a value to include in the failure message + * @return the value on which `ensuring` was invoked, unchanged + */ def ensuring(cond: A => Boolean, msg: => Any): A = { assert(cond(self), msg); self } } @@ -463,9 +503,21 @@ object Predef extends LowPriorityImplicits { * @param sequenceOfChars the indexed sequence of characters to wrap as a `CharSequence` */ final class SeqCharSequence(sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence { + /** Returns the number of characters in the wrapped sequence. */ def length: Int = sequenceOfChars.length + /** Returns the character at position `index` of the wrapped sequence. + * + * @param index the zero-based position of the character to retrieve + */ def charAt(index: Int): Char = sequenceOfChars(index) + /** Returns the characters from `start` (inclusive) to `end` (exclusive) as a `CharSequence`. + * + * @param start the position of the first character of the subsequence + * @param end the position one past the last character of the subsequence + * @return a new `SeqCharSequence` over a slice of the wrapped sequence + */ def subSequence(start: Int, end: Int): CharSequence = new SeqCharSequence(sequenceOfChars.slice(start, end)) + /** Returns the wrapped characters concatenated into a `String`. */ override def toString() = sequenceOfChars.mkString } @@ -483,9 +535,21 @@ object Predef extends LowPriorityImplicits { * @param arrayOfChars the array of characters to wrap as a `CharSequence` */ final class ArrayCharSequence(arrayOfChars: Array[Char]) extends CharSequence { + /** Returns the number of characters in the wrapped array. */ def length: Int = arrayOfChars.length + /** Returns the character at position `index` of the wrapped array. + * + * @param index the zero-based position of the character to retrieve + */ def charAt(index: Int): Char = arrayOfChars(index) + /** Returns the characters from `start` (inclusive) to `end` (exclusive) as a `CharSequence`. + * + * @param start the position of the first character of the subsequence + * @param end the position one past the last character of the subsequence + * @return a [[scala.runtime.ArrayCharSequence]] viewing that range of the wrapped array, without copying it + */ def subSequence(start: Int, end: Int): CharSequence = new runtime.ArrayCharSequence(arrayOfChars, start, end) + /** Returns the wrapped characters concatenated into a `String`. */ override def toString() = arrayOfChars.mkString } @@ -548,8 +612,25 @@ object Predef extends LowPriorityImplicits { // these two are morally deprecated but the @deprecated annotation has been moved to the extension method themselves, // in order to provide a more specific deprecation method. @nowarn("""cat=deprecation&origin=scala\.runtime\.Tuple2Zipped""") + /** Adds the deprecated `zipped` and `invert` operations to a pair, each of which + * additionally requires the pair's elements to be collections. + * + * @tparam T1 the type of the first element of the pair + * @tparam T2 the type of the second element of the pair + * @param x the pair to enrich + * @return an `Ops` wrapper around `x` providing `zipped` and `invert` + */ implicit def tuple2ToZippedOps[T1, T2](x: (T1, T2)): runtime.Tuple2Zipped.Ops[T1, T2] = new runtime.Tuple2Zipped.Ops(x) @nowarn("""cat=deprecation&origin=scala\.runtime\.Tuple3Zipped""") + /** Adds the deprecated `zipped` and `invert` operations to a triple, each of which + * additionally requires the triple's elements to be collections. + * + * @tparam T1 the type of the first element of the triple + * @tparam T2 the type of the second element of the triple + * @tparam T3 the type of the third element of the triple + * @param x the triple to enrich + * @return an `Ops` wrapper around `x` providing `zipped` and `invert` + */ implicit def tuple3ToZippedOps[T1, T2, T3](x: (T1, T2, T3)): runtime.Tuple3Zipped.Ops[T1, T2, T3] = new runtime.Tuple3Zipped.Ops(x) // Not specialized anymore since 2.13 but we still need separate methods @@ -899,6 +980,12 @@ private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2 private[scala] abstract class LowPriorityImplicits2 { @deprecated("implicit conversions from Array to immutable.IndexedSeq are implemented by copying; use `toIndexedSeq` explicitly if you want to copy, or use the more efficient non-copying ArraySeq.unsafeWrapArray", since="2.13.0") + /** Copies an array into an immutable [[scala.collection.immutable.IndexedSeq]]. + * + * @tparam T the element type of the array + * @param xs the array whose elements are copied + * @return a new immutable `IndexedSeq` holding the elements of `xs`, or `null` if `xs` is `null` + */ implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T]): IndexedSeq[T] = mapNull(xs, new ArrayOps(xs).toIndexedSeq) } diff --git a/library/src/scala/Product1.scala b/library/src/scala/Product1.scala index 20e2b83a2294..bf846185025f 100644 --- a/library/src/scala/Product1.scala +++ b/library/src/scala/Product1.scala @@ -15,6 +15,12 @@ package scala import scala.language.`2.13` object Product1 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product1` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the single component of the product + * @param x the product to extract from + */ def unapply[T1](x: Product1[T1]): Option[Product1[T1]] = Some(x) } diff --git a/library/src/scala/Product10.scala b/library/src/scala/Product10.scala index d7d1774a2d8e..4a9beee7475e 100644 --- a/library/src/scala/Product10.scala +++ b/library/src/scala/Product10.scala @@ -15,6 +15,22 @@ package scala import scala.language.`2.13` object Product10 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product10` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](x: Product10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): Option[Product10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] = Some(x) } diff --git a/library/src/scala/Product11.scala b/library/src/scala/Product11.scala index e1338b7c7b35..9d06909e11dc 100644 --- a/library/src/scala/Product11.scala +++ b/library/src/scala/Product11.scala @@ -15,6 +15,23 @@ package scala import scala.language.`2.13` object Product11 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product11` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](x: Product11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]): Option[Product11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] = Some(x) } diff --git a/library/src/scala/Product12.scala b/library/src/scala/Product12.scala index 4c1ca393f677..8f1ad7e32013 100644 --- a/library/src/scala/Product12.scala +++ b/library/src/scala/Product12.scala @@ -15,6 +15,24 @@ package scala import scala.language.`2.13` object Product12 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product12` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](x: Product12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]): Option[Product12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] = Some(x) } diff --git a/library/src/scala/Product13.scala b/library/src/scala/Product13.scala index 1978cbec24fa..3870e36eda8d 100644 --- a/library/src/scala/Product13.scala +++ b/library/src/scala/Product13.scala @@ -15,6 +15,25 @@ package scala import scala.language.`2.13` object Product13 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product13` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](x: Product13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): Option[Product13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] = Some(x) } diff --git a/library/src/scala/Product14.scala b/library/src/scala/Product14.scala index b0966f12b3e0..83fd471b9d32 100644 --- a/library/src/scala/Product14.scala +++ b/library/src/scala/Product14.scala @@ -15,6 +15,26 @@ package scala import scala.language.`2.13` object Product14 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product14` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](x: Product14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]): Option[Product14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] = Some(x) } diff --git a/library/src/scala/Product15.scala b/library/src/scala/Product15.scala index fd5aa882a9cc..6d9d846e17fc 100644 --- a/library/src/scala/Product15.scala +++ b/library/src/scala/Product15.scala @@ -15,6 +15,27 @@ package scala import scala.language.`2.13` object Product15 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product15` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](x: Product15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]): Option[Product15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] = Some(x) } diff --git a/library/src/scala/Product16.scala b/library/src/scala/Product16.scala index dc07b93a9d88..d9fd8994836c 100644 --- a/library/src/scala/Product16.scala +++ b/library/src/scala/Product16.scala @@ -15,6 +15,28 @@ package scala import scala.language.`2.13` object Product16 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product16` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @tparam T16 the type of the 16th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](x: Product16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]): Option[Product16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] = Some(x) } diff --git a/library/src/scala/Product17.scala b/library/src/scala/Product17.scala index 2111cca6d6c0..0d08eaeca454 100644 --- a/library/src/scala/Product17.scala +++ b/library/src/scala/Product17.scala @@ -15,6 +15,29 @@ package scala import scala.language.`2.13` object Product17 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product17` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @tparam T16 the type of the 16th component of the product + * @tparam T17 the type of the 17th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](x: Product17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]): Option[Product17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] = Some(x) } diff --git a/library/src/scala/Product18.scala b/library/src/scala/Product18.scala index 87a05b9de5c6..2e1e0dd01f1b 100644 --- a/library/src/scala/Product18.scala +++ b/library/src/scala/Product18.scala @@ -15,6 +15,30 @@ package scala import scala.language.`2.13` object Product18 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product18` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @tparam T16 the type of the 16th component of the product + * @tparam T17 the type of the 17th component of the product + * @tparam T18 the type of the 18th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](x: Product18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]): Option[Product18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] = Some(x) } diff --git a/library/src/scala/Product19.scala b/library/src/scala/Product19.scala index ff246f57b886..2c917c4de985 100644 --- a/library/src/scala/Product19.scala +++ b/library/src/scala/Product19.scala @@ -15,6 +15,31 @@ package scala import scala.language.`2.13` object Product19 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product19` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @tparam T16 the type of the 16th component of the product + * @tparam T17 the type of the 17th component of the product + * @tparam T18 the type of the 18th component of the product + * @tparam T19 the type of the 19th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](x: Product19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]): Option[Product19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] = Some(x) } diff --git a/library/src/scala/Product2.scala b/library/src/scala/Product2.scala index 05f076172377..3e4b647895e7 100644 --- a/library/src/scala/Product2.scala +++ b/library/src/scala/Product2.scala @@ -15,6 +15,13 @@ package scala import scala.language.`2.13` object Product2 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product2` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @param x the product to extract from + */ def unapply[T1, T2](x: Product2[T1, T2]): Option[Product2[T1, T2]] = Some(x) } diff --git a/library/src/scala/Product20.scala b/library/src/scala/Product20.scala index 82fe54d2d100..690a35833fec 100644 --- a/library/src/scala/Product20.scala +++ b/library/src/scala/Product20.scala @@ -15,6 +15,32 @@ package scala import scala.language.`2.13` object Product20 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product20` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @tparam T16 the type of the 16th component of the product + * @tparam T17 the type of the 17th component of the product + * @tparam T18 the type of the 18th component of the product + * @tparam T19 the type of the 19th component of the product + * @tparam T20 the type of the 20th component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](x: Product20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]): Option[Product20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] = Some(x) } diff --git a/library/src/scala/Product21.scala b/library/src/scala/Product21.scala index 47d09b4395a4..bdbb61781839 100644 --- a/library/src/scala/Product21.scala +++ b/library/src/scala/Product21.scala @@ -15,6 +15,33 @@ package scala import scala.language.`2.13` object Product21 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product21` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @tparam T16 the type of the 16th component of the product + * @tparam T17 the type of the 17th component of the product + * @tparam T18 the type of the 18th component of the product + * @tparam T19 the type of the 19th component of the product + * @tparam T20 the type of the 20th component of the product + * @tparam T21 the type of the 21st component of the product + * @param x the product to extract from + * @return `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](x: Product21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]): Option[Product21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] = Some(x) } diff --git a/library/src/scala/Product22.scala b/library/src/scala/Product22.scala index b52b1f011a22..c2ce42557722 100644 --- a/library/src/scala/Product22.scala +++ b/library/src/scala/Product22.scala @@ -15,6 +15,33 @@ package scala import scala.language.`2.13` object Product22 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product22` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @tparam T9 the type of the 9th component of the product + * @tparam T10 the type of the 10th component of the product + * @tparam T11 the type of the 11th component of the product + * @tparam T12 the type of the 12th component of the product + * @tparam T13 the type of the 13th component of the product + * @tparam T14 the type of the 14th component of the product + * @tparam T15 the type of the 15th component of the product + * @tparam T16 the type of the 16th component of the product + * @tparam T17 the type of the 17th component of the product + * @tparam T18 the type of the 18th component of the product + * @tparam T19 the type of the 19th component of the product + * @tparam T20 the type of the 20th component of the product + * @tparam T21 the type of the 21st component of the product + * @tparam T22 the type of the 22nd component of the product + * @param x the product to extract from + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](x: Product22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]): Option[Product22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] = Some(x) } diff --git a/library/src/scala/Product3.scala b/library/src/scala/Product3.scala index 1c7b2a2b33ee..8b8dde7a8b56 100644 --- a/library/src/scala/Product3.scala +++ b/library/src/scala/Product3.scala @@ -15,6 +15,14 @@ package scala import scala.language.`2.13` object Product3 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product3` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @param x the product to extract from + */ def unapply[T1, T2, T3](x: Product3[T1, T2, T3]): Option[Product3[T1, T2, T3]] = Some(x) } diff --git a/library/src/scala/Product4.scala b/library/src/scala/Product4.scala index a09f62f60581..f35afe01df93 100644 --- a/library/src/scala/Product4.scala +++ b/library/src/scala/Product4.scala @@ -15,6 +15,16 @@ package scala import scala.language.`2.13` object Product4 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product4` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @param x the product to extract from + * @return the product `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4](x: Product4[T1, T2, T3, T4]): Option[Product4[T1, T2, T3, T4]] = Some(x) } diff --git a/library/src/scala/Product5.scala b/library/src/scala/Product5.scala index bbfa0c449ccf..0b2bf9543113 100644 --- a/library/src/scala/Product5.scala +++ b/library/src/scala/Product5.scala @@ -15,6 +15,17 @@ package scala import scala.language.`2.13` object Product5 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product5` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @param x the product to extract from + * @return the product `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5](x: Product5[T1, T2, T3, T4, T5]): Option[Product5[T1, T2, T3, T4, T5]] = Some(x) } diff --git a/library/src/scala/Product6.scala b/library/src/scala/Product6.scala index 125fbc40ce7c..67dc5348d439 100644 --- a/library/src/scala/Product6.scala +++ b/library/src/scala/Product6.scala @@ -15,6 +15,18 @@ package scala import scala.language.`2.13` object Product6 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product6` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @param x the product to extract from + * @return the product `x` wrapped in a [[scala.Some]] + */ def unapply[T1, T2, T3, T4, T5, T6](x: Product6[T1, T2, T3, T4, T5, T6]): Option[Product6[T1, T2, T3, T4, T5, T6]] = Some(x) } diff --git a/library/src/scala/Product7.scala b/library/src/scala/Product7.scala index c50eb9e07c2c..3d757a6facc8 100644 --- a/library/src/scala/Product7.scala +++ b/library/src/scala/Product7.scala @@ -15,6 +15,18 @@ package scala import scala.language.`2.13` object Product7 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product7` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @param x the product to extract from + */ def unapply[T1, T2, T3, T4, T5, T6, T7](x: Product7[T1, T2, T3, T4, T5, T6, T7]): Option[Product7[T1, T2, T3, T4, T5, T6, T7]] = Some(x) } diff --git a/library/src/scala/Product8.scala b/library/src/scala/Product8.scala index afaaba9a6f7c..c1261b00f65d 100644 --- a/library/src/scala/Product8.scala +++ b/library/src/scala/Product8.scala @@ -15,6 +15,20 @@ package scala import scala.language.`2.13` object Product8 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product8` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st component of the product + * @tparam T2 the type of the 2nd component of the product + * @tparam T3 the type of the 3rd component of the product + * @tparam T4 the type of the 4th component of the product + * @tparam T5 the type of the 5th component of the product + * @tparam T6 the type of the 6th component of the product + * @tparam T7 the type of the 7th component of the product + * @tparam T8 the type of the 8th component of the product + * @param x the product to extract from + * @return `Some(x)` + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8](x: Product8[T1, T2, T3, T4, T5, T6, T7, T8]): Option[Product8[T1, T2, T3, T4, T5, T6, T7, T8]] = Some(x) } diff --git a/library/src/scala/Product9.scala b/library/src/scala/Product9.scala index 2ed71b52165e..781a31480592 100644 --- a/library/src/scala/Product9.scala +++ b/library/src/scala/Product9.scala @@ -15,6 +15,21 @@ package scala import scala.language.`2.13` object Product9 { + /** Returns the given product wrapped in a [[scala.Some]], making `Product9` usable + * as an extractor in a pattern match. The extraction always succeeds. + * + * @tparam T1 the type of the 1st element of the product + * @tparam T2 the type of the 2nd element of the product + * @tparam T3 the type of the 3rd element of the product + * @tparam T4 the type of the 4th element of the product + * @tparam T5 the type of the 5th element of the product + * @tparam T6 the type of the 6th element of the product + * @tparam T7 the type of the 7th element of the product + * @tparam T8 the type of the 8th element of the product + * @tparam T9 the type of the 9th element of the product + * @param x the product to extract from + * @return `Some(x)` + */ def unapply[T1, T2, T3, T4, T5, T6, T7, T8, T9](x: Product9[T1, T2, T3, T4, T5, T6, T7, T8, T9]): Option[Product9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] = Some(x) } diff --git a/library/src/scala/Tuple.scala b/library/src/scala/Tuple.scala index e1df38d7ade0..3e17aa7413ce 100644 --- a/library/src/scala/Tuple.scala +++ b/library/src/scala/Tuple.scala @@ -385,6 +385,15 @@ object Tuple { def fromProduct(product: Product): Tuple = runtime.Tuples.fromProduct(product) + /** Converts a `Product` into a tuple whose arity and element types are statically + * known, as described by the product's mirror. + * + * @tparam P the type of the product to convert + * @param p the product to convert into a tuple + * @param m the mirror of `P`, which determines the element types of the result + * @return a tuple whose elements are the elements of `p` in declaration order, + * typed as `m.MirroredElemTypes` + */ def fromProductTyped[P <: Product](p: P)(using m: scala.deriving.Mirror.ProductOf[P]): m.MirroredElemTypes = runtime.Tuples.fromProduct(p).asInstanceOf[m.MirroredElemTypes] @@ -399,6 +408,7 @@ type EmptyTuple = EmptyTuple.type /** A tuple of 0 elements. */ case object EmptyTuple extends Tuple { + /** Returns the string representation of the empty tuple, `"()"`. */ override def toString(): String = "()" } @@ -406,8 +416,22 @@ case object EmptyTuple extends Tuple { sealed trait NonEmptyTuple extends Tuple @showAsInfix +/** A tuple whose first element has type `H` and whose remaining elements form a + * tuple of type `T`. + * + * @tparam H the type of the head element + * @tparam T the type of the tail, itself a tuple + */ sealed abstract class *:[+H, +T <: Tuple] extends NonEmptyTuple object *: { + /** Decomposes a non-empty tuple into its head element and its tail, so that a + * tuple can be matched with the `h *: t` pattern. + * + * @tparam H the type of the head element + * @tparam T the type of the tail, itself a tuple + * @param x the tuple to decompose + * @return a pair of the head of `x` and its tail + */ def unapply[H, T <: Tuple](x: H *: T): (H, T) = (x.head, x.tail) } diff --git a/library/src/scala/Tuple1.scala b/library/src/scala/Tuple1.scala index 1cc62247c9a2..478432a486b6 100644 --- a/library/src/scala/Tuple1.scala +++ b/library/src/scala/Tuple1.scala @@ -22,6 +22,7 @@ import scala.language.`2.13` final case class Tuple1[@specialized(Int, Long, Double) +T1](_1: T1) extends Product1[T1] { + /** Returns a string representation of this tuple, the element enclosed in parentheses. */ override def toString(): String = "(" + _1 + ")" } diff --git a/library/src/scala/Tuple10.scala b/library/src/scala/Tuple10.scala index cd5d37f89b7e..8384273852bd 100644 --- a/library/src/scala/Tuple10.scala +++ b/library/src/scala/Tuple10.scala @@ -41,6 +41,7 @@ import scala.language.`2.13` final case class Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10) extends Product10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + ")" } diff --git a/library/src/scala/Tuple11.scala b/library/src/scala/Tuple11.scala index 00c8c641f817..2a6de955bd4d 100644 --- a/library/src/scala/Tuple11.scala +++ b/library/src/scala/Tuple11.scala @@ -43,6 +43,7 @@ import scala.language.`2.13` final case class Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11) extends Product11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + ")" } diff --git a/library/src/scala/Tuple12.scala b/library/src/scala/Tuple12.scala index de737b43e60a..c6a05a053ea1 100644 --- a/library/src/scala/Tuple12.scala +++ b/library/src/scala/Tuple12.scala @@ -45,6 +45,7 @@ import scala.language.`2.13` final case class Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12) extends Product12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + ")" diff --git a/library/src/scala/Tuple13.scala b/library/src/scala/Tuple13.scala index 1997c9dd56f3..554fd3348e90 100644 --- a/library/src/scala/Tuple13.scala +++ b/library/src/scala/Tuple13.scala @@ -47,6 +47,7 @@ import scala.language.`2.13` final case class Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13) extends Product13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + ")" diff --git a/library/src/scala/Tuple14.scala b/library/src/scala/Tuple14.scala index 45c1f7a3f385..117b71e46496 100644 --- a/library/src/scala/Tuple14.scala +++ b/library/src/scala/Tuple14.scala @@ -49,6 +49,7 @@ import scala.language.`2.13` final case class Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14) extends Product14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + ")" diff --git a/library/src/scala/Tuple15.scala b/library/src/scala/Tuple15.scala index 10af44b0c7f8..33587ec9460e 100644 --- a/library/src/scala/Tuple15.scala +++ b/library/src/scala/Tuple15.scala @@ -51,6 +51,7 @@ import scala.language.`2.13` final case class Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15) extends Product15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + ")" diff --git a/library/src/scala/Tuple16.scala b/library/src/scala/Tuple16.scala index 5000ddb54956..65347c798aab 100644 --- a/library/src/scala/Tuple16.scala +++ b/library/src/scala/Tuple16.scala @@ -53,6 +53,7 @@ import scala.language.`2.13` final case class Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16) extends Product16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + ")" diff --git a/library/src/scala/Tuple17.scala b/library/src/scala/Tuple17.scala index d5b911cd05e8..fe3f5ca292d3 100644 --- a/library/src/scala/Tuple17.scala +++ b/library/src/scala/Tuple17.scala @@ -55,6 +55,7 @@ import scala.language.`2.13` final case class Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17) extends Product17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + ")" diff --git a/library/src/scala/Tuple18.scala b/library/src/scala/Tuple18.scala index f831101dbd0f..da0f87467e8a 100644 --- a/library/src/scala/Tuple18.scala +++ b/library/src/scala/Tuple18.scala @@ -57,6 +57,7 @@ import scala.language.`2.13` final case class Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18) extends Product18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + ")" diff --git a/library/src/scala/Tuple19.scala b/library/src/scala/Tuple19.scala index 141faaca0a5b..a920147cf4c9 100644 --- a/library/src/scala/Tuple19.scala +++ b/library/src/scala/Tuple19.scala @@ -59,6 +59,7 @@ import scala.language.`2.13` final case class Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19) extends Product19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + ")" diff --git a/library/src/scala/Tuple2.scala b/library/src/scala/Tuple2.scala index 3e4141f40076..111a8d2279b8 100644 --- a/library/src/scala/Tuple2.scala +++ b/library/src/scala/Tuple2.scala @@ -23,6 +23,7 @@ import scala.language.`2.13` final case class Tuple2[@specialized(Int, Long, Double, Char, Boolean/*, AnyRef*/) +T1, @specialized(Int, Long, Double, Char, Boolean/*, AnyRef*/) +T2](_1: T1, _2: T2) extends Product2[T1, T2] { + /** Returns a string representation of this tuple, with the two elements separated by a comma and enclosed in parentheses, as in `(1,two)`. */ override def toString(): String = "(" + _1 + "," + _2 + ")" /** Swaps the elements of this `Tuple`. diff --git a/library/src/scala/Tuple20.scala b/library/src/scala/Tuple20.scala index 193afb3fd51e..0e942c8431e4 100644 --- a/library/src/scala/Tuple20.scala +++ b/library/src/scala/Tuple20.scala @@ -61,6 +61,7 @@ import scala.language.`2.13` final case class Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20) extends Product20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + ")" diff --git a/library/src/scala/Tuple21.scala b/library/src/scala/Tuple21.scala index c524e4beed6e..f6dd3ccf43a4 100644 --- a/library/src/scala/Tuple21.scala +++ b/library/src/scala/Tuple21.scala @@ -63,6 +63,7 @@ import scala.language.`2.13` final case class Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21) extends Product21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + "," + _21 + ")" diff --git a/library/src/scala/Tuple22.scala b/library/src/scala/Tuple22.scala index e10a9bfb38b8..f5735402ed35 100644 --- a/library/src/scala/Tuple22.scala +++ b/library/src/scala/Tuple22.scala @@ -65,6 +65,7 @@ import scala.language.`2.13` final case class Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9, _10: T10, _11: T11, _12: T12, _13: T13, _14: T14, _15: T15, _16: T16, _17: T17, _18: T18, _19: T19, _20: T20, _21: T21, _22: T22) extends Product22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] { + /** Returns a string representation of this tuple, the elements separated by commas and enclosed in parentheses. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + "," + _21 + "," + _22 + ")" diff --git a/library/src/scala/Tuple3.scala b/library/src/scala/Tuple3.scala index 07536ba36471..cd3e9c40a4b8 100644 --- a/library/src/scala/Tuple3.scala +++ b/library/src/scala/Tuple3.scala @@ -27,6 +27,7 @@ import scala.language.`2.13` final case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) extends Product3[T1, T2, T3] { + /** Returns a string representation of this tuple, with the three elements separated by commas and enclosed in parentheses, as in `(1,two,3.0)`. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + ")" } diff --git a/library/src/scala/Tuple4.scala b/library/src/scala/Tuple4.scala index 31d3d6dc37e5..25cfed383f77 100644 --- a/library/src/scala/Tuple4.scala +++ b/library/src/scala/Tuple4.scala @@ -29,6 +29,7 @@ import scala.language.`2.13` final case class Tuple4[+T1, +T2, +T3, +T4](_1: T1, _2: T2, _3: T3, _4: T4) extends Product4[T1, T2, T3, T4] { + /** Returns a string representation of this tuple, with the four elements separated by commas and enclosed in parentheses, as in `(1,two,3.0,four)`. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + ")" } diff --git a/library/src/scala/Tuple5.scala b/library/src/scala/Tuple5.scala index 76aa8836afe3..0aae910d062e 100644 --- a/library/src/scala/Tuple5.scala +++ b/library/src/scala/Tuple5.scala @@ -31,6 +31,7 @@ import scala.language.`2.13` final case class Tuple5[+T1, +T2, +T3, +T4, +T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5) extends Product5[T1, T2, T3, T4, T5] { + /** Returns a string representation of this tuple, with the five elements separated by commas and enclosed in parentheses, as in `(1,two,3.0,four,5)`. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + ")" } diff --git a/library/src/scala/Tuple6.scala b/library/src/scala/Tuple6.scala index c2a885689e61..f6046865dc6f 100644 --- a/library/src/scala/Tuple6.scala +++ b/library/src/scala/Tuple6.scala @@ -33,6 +33,7 @@ import scala.language.`2.13` final case class Tuple6[+T1, +T2, +T3, +T4, +T5, +T6](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6) extends Product6[T1, T2, T3, T4, T5, T6] { + /** Returns a string representation of this tuple, with the six elements separated by commas and enclosed in parentheses, as in `(1,two,3.0,four,5,six)`. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + ")" } diff --git a/library/src/scala/Tuple7.scala b/library/src/scala/Tuple7.scala index da370fd3cc6d..9daa82e5870c 100644 --- a/library/src/scala/Tuple7.scala +++ b/library/src/scala/Tuple7.scala @@ -35,6 +35,7 @@ import scala.language.`2.13` final case class Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7) extends Product7[T1, T2, T3, T4, T5, T6, T7] { + /** Returns a string representation of this tuple, with the seven elements separated by commas and enclosed in parentheses, as in `(1,two,3.0,four,5,six,7)`. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + ")" } diff --git a/library/src/scala/Tuple8.scala b/library/src/scala/Tuple8.scala index c5b6ba3eaa05..4ae02be90d94 100644 --- a/library/src/scala/Tuple8.scala +++ b/library/src/scala/Tuple8.scala @@ -37,6 +37,7 @@ import scala.language.`2.13` final case class Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8) extends Product8[T1, T2, T3, T4, T5, T6, T7, T8] { + /** Returns a string representation of this tuple, with the eight elements separated by commas and enclosed in parentheses, as in `(1,two,3.0,four,5,six,7,eight)`. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + ")" } diff --git a/library/src/scala/Tuple9.scala b/library/src/scala/Tuple9.scala index 5bc76f302274..d46a74c2eb2e 100644 --- a/library/src/scala/Tuple9.scala +++ b/library/src/scala/Tuple9.scala @@ -39,6 +39,7 @@ import scala.language.`2.13` final case class Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9) extends Product9[T1, T2, T3, T4, T5, T6, T7, T8, T9] { + /** Returns a string representation of this tuple, with the nine elements separated by commas and enclosed in parentheses, as in `(1,two,3.0,four,5,six,7,eight,9)`. */ override def toString(): String = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + ")" } diff --git a/library/src/scala/runtime/AbstractFunction0.scala b/library/src/scala/runtime/AbstractFunction0.scala index 474492c904ed..f7ce4c0e2ab5 100644 --- a/library/src/scala/runtime/AbstractFunction0.scala +++ b/library/src/scala/runtime/AbstractFunction0.scala @@ -14,6 +14,13 @@ package scala.runtime import scala.language.`2.13` +/** A base class for zero-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function0]] + * trait. + * + * The result type is specialized over the primitive types, so a subclass can + * produce an unboxed result. + */ abstract class AbstractFunction0[@specialized(Specializable.Primitives) +R] extends Function0[R] { } diff --git a/library/src/scala/runtime/AbstractFunction1.scala b/library/src/scala/runtime/AbstractFunction1.scala index cc3b422e3ab9..d0fa4e2ce2ab 100644 --- a/library/src/scala/runtime/AbstractFunction1.scala +++ b/library/src/scala/runtime/AbstractFunction1.scala @@ -14,6 +14,14 @@ package scala.runtime import scala.language.`2.13` +/** A base class for one-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function1]] + * trait. + * + * Both the argument type and the result type are specialized over a selection of + * the primitive types, so a subclass can accept an unboxed argument and produce + * an unboxed result. + */ abstract class AbstractFunction1[@specialized(Specializable.Arg) -T1, @specialized(Specializable.Return) +R] extends Function1[T1, R] { } diff --git a/library/src/scala/runtime/AbstractFunction10.scala b/library/src/scala/runtime/AbstractFunction10.scala index e55fa73f8781..e9273244d921 100644 --- a/library/src/scala/runtime/AbstractFunction10.scala +++ b/library/src/scala/runtime/AbstractFunction10.scala @@ -14,6 +14,23 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction10` is a base class for ten-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function10]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] { } diff --git a/library/src/scala/runtime/AbstractFunction11.scala b/library/src/scala/runtime/AbstractFunction11.scala index df0cfbe6427b..0636e7af3d03 100644 --- a/library/src/scala/runtime/AbstractFunction11.scala +++ b/library/src/scala/runtime/AbstractFunction11.scala @@ -14,6 +14,24 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction11` is a base class for eleven-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function11]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] { } diff --git a/library/src/scala/runtime/AbstractFunction12.scala b/library/src/scala/runtime/AbstractFunction12.scala index 9ff62db2d141..80416df062df 100644 --- a/library/src/scala/runtime/AbstractFunction12.scala +++ b/library/src/scala/runtime/AbstractFunction12.scala @@ -14,6 +14,25 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction12` is a base class for twelve-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function12]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] { } diff --git a/library/src/scala/runtime/AbstractFunction13.scala b/library/src/scala/runtime/AbstractFunction13.scala index 3598d549c857..22024c500ed5 100644 --- a/library/src/scala/runtime/AbstractFunction13.scala +++ b/library/src/scala/runtime/AbstractFunction13.scala @@ -14,6 +14,25 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction13` is a base class for thirteen-parameter function + * implementations. It allows a function value to be defined by extending a class + * rather than the [[scala.Function13]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] { } diff --git a/library/src/scala/runtime/AbstractFunction14.scala b/library/src/scala/runtime/AbstractFunction14.scala index ec668f06c994..8dac27f1ac28 100644 --- a/library/src/scala/runtime/AbstractFunction14.scala +++ b/library/src/scala/runtime/AbstractFunction14.scala @@ -14,6 +14,24 @@ package scala.runtime import scala.language.`2.13` +/** TODO FILL IN + * + * @tparam T1 TODO FILL IN + * @tparam T2 TODO FILL IN + * @tparam T3 TODO FILL IN + * @tparam T4 TODO FILL IN + * @tparam T5 TODO FILL IN + * @tparam T6 TODO FILL IN + * @tparam T7 TODO FILL IN + * @tparam T8 TODO FILL IN + * @tparam T9 TODO FILL IN + * @tparam T10 TODO FILL IN + * @tparam T11 TODO FILL IN + * @tparam T12 TODO FILL IN + * @tparam T13 TODO FILL IN + * @tparam T14 TODO FILL IN + * @tparam R TODO FILL IN + */ abstract class AbstractFunction14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] { } diff --git a/library/src/scala/runtime/AbstractFunction15.scala b/library/src/scala/runtime/AbstractFunction15.scala index 8bb01b0cb79b..4d50d5491dce 100644 --- a/library/src/scala/runtime/AbstractFunction15.scala +++ b/library/src/scala/runtime/AbstractFunction15.scala @@ -14,6 +14,28 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction15` is a base class for fifteen-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function15]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] { } diff --git a/library/src/scala/runtime/AbstractFunction16.scala b/library/src/scala/runtime/AbstractFunction16.scala index 0ea5487ea39f..b512e4edc491 100644 --- a/library/src/scala/runtime/AbstractFunction16.scala +++ b/library/src/scala/runtime/AbstractFunction16.scala @@ -14,6 +14,29 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction16` is a base class for sixteen-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function16]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam T16 the type of the 16th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] { } diff --git a/library/src/scala/runtime/AbstractFunction17.scala b/library/src/scala/runtime/AbstractFunction17.scala index 3f0149d1ad76..c2a1bf66fabb 100644 --- a/library/src/scala/runtime/AbstractFunction17.scala +++ b/library/src/scala/runtime/AbstractFunction17.scala @@ -14,6 +14,30 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction17` is a base class for seventeen-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function17]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam T16 the type of the 16th argument + * @tparam T17 the type of the 17th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] { } diff --git a/library/src/scala/runtime/AbstractFunction18.scala b/library/src/scala/runtime/AbstractFunction18.scala index 90741e19468b..81bb79110b7c 100644 --- a/library/src/scala/runtime/AbstractFunction18.scala +++ b/library/src/scala/runtime/AbstractFunction18.scala @@ -14,6 +14,31 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction18` is a base class for eighteen-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function18]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam T16 the type of the 16th argument + * @tparam T17 the type of the 17th argument + * @tparam T18 the type of the 18th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] { } diff --git a/library/src/scala/runtime/AbstractFunction19.scala b/library/src/scala/runtime/AbstractFunction19.scala index 348f53d9f58c..0e6ffdce154c 100644 --- a/library/src/scala/runtime/AbstractFunction19.scala +++ b/library/src/scala/runtime/AbstractFunction19.scala @@ -14,6 +14,32 @@ package scala.runtime import scala.language.`2.13` +/** `AbstractFunction19` is a base class for nineteen-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function19]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam T16 the type of the 16th argument + * @tparam T17 the type of the 17th argument + * @tparam T18 the type of the 18th argument + * @tparam T19 the type of the 19th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] { } diff --git a/library/src/scala/runtime/AbstractFunction2.scala b/library/src/scala/runtime/AbstractFunction2.scala index 653caadb390e..cb4e45b00893 100644 --- a/library/src/scala/runtime/AbstractFunction2.scala +++ b/library/src/scala/runtime/AbstractFunction2.scala @@ -14,6 +14,14 @@ package scala.runtime import scala.language.`2.13` +/** A base class for two-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function2]] + * trait. + * + * Both argument types and the result type are specialized over a selection of + * the primitive types, so a subclass can accept unboxed arguments and produce + * an unboxed result. + */ abstract class AbstractFunction2[@specialized(Specializable.Args) -T1, @specialized(Specializable.Args) -T2, @specialized(Specializable.Return) +R] extends Function2[T1, T2, R] { } diff --git a/library/src/scala/runtime/AbstractFunction20.scala b/library/src/scala/runtime/AbstractFunction20.scala index 8559e50375df..5616fbf1448b 100644 --- a/library/src/scala/runtime/AbstractFunction20.scala +++ b/library/src/scala/runtime/AbstractFunction20.scala @@ -14,6 +14,33 @@ package scala.runtime import scala.language.`2.13` +/** A base class for twenty-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function20]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam T16 the type of the 16th argument + * @tparam T17 the type of the 17th argument + * @tparam T18 the type of the 18th argument + * @tparam T19 the type of the 19th argument + * @tparam T20 the type of the 20th argument + * @tparam R the return type of this function + */ abstract class AbstractFunction20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] { } diff --git a/library/src/scala/runtime/AbstractFunction21.scala b/library/src/scala/runtime/AbstractFunction21.scala index 55170eabdc2d..3dcc436a8ae3 100644 --- a/library/src/scala/runtime/AbstractFunction21.scala +++ b/library/src/scala/runtime/AbstractFunction21.scala @@ -14,6 +14,34 @@ package scala.runtime import scala.language.`2.13` +/** A base class for twenty-one-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function21]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam T16 the type of the 16th argument + * @tparam T17 the type of the 17th argument + * @tparam T18 the type of the 18th argument + * @tparam T19 the type of the 19th argument + * @tparam T20 the type of the 20th argument + * @tparam T21 the type of the 21st argument + * @tparam R the return type of this function + */ abstract class AbstractFunction21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] { } diff --git a/library/src/scala/runtime/AbstractFunction22.scala b/library/src/scala/runtime/AbstractFunction22.scala index d06afc3d80d5..74c12ec94174 100644 --- a/library/src/scala/runtime/AbstractFunction22.scala +++ b/library/src/scala/runtime/AbstractFunction22.scala @@ -14,6 +14,35 @@ package scala.runtime import scala.language.`2.13` +/** A base class for twenty-two-parameter function implementations. + * + * Extending this class allows a function value to be defined by extending a class + * rather than the [[scala.Function22]] trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam T10 the type of the 10th argument + * @tparam T11 the type of the 11th argument + * @tparam T12 the type of the 12th argument + * @tparam T13 the type of the 13th argument + * @tparam T14 the type of the 14th argument + * @tparam T15 the type of the 15th argument + * @tparam T16 the type of the 16th argument + * @tparam T17 the type of the 17th argument + * @tparam T18 the type of the 18th argument + * @tparam T19 the type of the 19th argument + * @tparam T20 the type of the 20th argument + * @tparam T21 the type of the 21st argument + * @tparam T22 the type of the 22nd argument + * @tparam R the return type of this function + */ abstract class AbstractFunction22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R] extends Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] { } diff --git a/library/src/scala/runtime/AbstractFunction3.scala b/library/src/scala/runtime/AbstractFunction3.scala index cb14d76cac23..a9059f17832c 100644 --- a/library/src/scala/runtime/AbstractFunction3.scala +++ b/library/src/scala/runtime/AbstractFunction3.scala @@ -14,6 +14,15 @@ package scala.runtime import scala.language.`2.13` +/** A base class for three-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function3]] + * trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam R the return type of the function + */ abstract class AbstractFunction3[-T1, -T2, -T3, +R] extends Function3[T1, T2, T3, R] { } diff --git a/library/src/scala/runtime/AbstractFunction4.scala b/library/src/scala/runtime/AbstractFunction4.scala index a280f757b071..8efceb22cf9d 100644 --- a/library/src/scala/runtime/AbstractFunction4.scala +++ b/library/src/scala/runtime/AbstractFunction4.scala @@ -14,6 +14,16 @@ package scala.runtime import scala.language.`2.13` +/** A base class for four-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function4]] + * trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam R the return type of the function + */ abstract class AbstractFunction4[-T1, -T2, -T3, -T4, +R] extends Function4[T1, T2, T3, T4, R] { } diff --git a/library/src/scala/runtime/AbstractFunction5.scala b/library/src/scala/runtime/AbstractFunction5.scala index e51923764eff..e3711d82bc0a 100644 --- a/library/src/scala/runtime/AbstractFunction5.scala +++ b/library/src/scala/runtime/AbstractFunction5.scala @@ -14,6 +14,17 @@ package scala.runtime import scala.language.`2.13` +/** A base class for five-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function5]] + * trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam R the return type of the function + */ abstract class AbstractFunction5[-T1, -T2, -T3, -T4, -T5, +R] extends Function5[T1, T2, T3, T4, T5, R] { } diff --git a/library/src/scala/runtime/AbstractFunction6.scala b/library/src/scala/runtime/AbstractFunction6.scala index 22a5fbe5d188..a64a5fe2c2de 100644 --- a/library/src/scala/runtime/AbstractFunction6.scala +++ b/library/src/scala/runtime/AbstractFunction6.scala @@ -14,6 +14,18 @@ package scala.runtime import scala.language.`2.13` +/** A base class for six-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function6]] + * trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam R the return type of the function + */ abstract class AbstractFunction6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends Function6[T1, T2, T3, T4, T5, T6, R] { } diff --git a/library/src/scala/runtime/AbstractFunction7.scala b/library/src/scala/runtime/AbstractFunction7.scala index 70c0effc89d0..07f10028f139 100644 --- a/library/src/scala/runtime/AbstractFunction7.scala +++ b/library/src/scala/runtime/AbstractFunction7.scala @@ -14,6 +14,19 @@ package scala.runtime import scala.language.`2.13` +/** A base class for seven-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function7]] + * trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam R the return type of the function + */ abstract class AbstractFunction7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends Function7[T1, T2, T3, T4, T5, T6, T7, R] { } diff --git a/library/src/scala/runtime/AbstractFunction8.scala b/library/src/scala/runtime/AbstractFunction8.scala index 0c73d8f15f1c..906c38fdd13f 100644 --- a/library/src/scala/runtime/AbstractFunction8.scala +++ b/library/src/scala/runtime/AbstractFunction8.scala @@ -14,6 +14,20 @@ package scala.runtime import scala.language.`2.13` +/** A base class for eight-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function8]] + * trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam R the return type of the function + */ abstract class AbstractFunction8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] { } diff --git a/library/src/scala/runtime/AbstractFunction9.scala b/library/src/scala/runtime/AbstractFunction9.scala index a6a322ddd469..a22ce5a57a69 100644 --- a/library/src/scala/runtime/AbstractFunction9.scala +++ b/library/src/scala/runtime/AbstractFunction9.scala @@ -14,6 +14,21 @@ package scala.runtime import scala.language.`2.13` +/** A base class for nine-parameter function implementations, allowing a function + * value to be defined by extending a class rather than the [[scala.Function9]] + * trait. + * + * @tparam T1 the type of the 1st argument + * @tparam T2 the type of the 2nd argument + * @tparam T3 the type of the 3rd argument + * @tparam T4 the type of the 4th argument + * @tparam T5 the type of the 5th argument + * @tparam T6 the type of the 6th argument + * @tparam T7 the type of the 7th argument + * @tparam T8 the type of the 8th argument + * @tparam T9 the type of the 9th argument + * @tparam R the return type of the function + */ abstract class AbstractFunction9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] { } diff --git a/library/src/scala/sys/BooleanProp.scala b/library/src/scala/sys/BooleanProp.scala index 0a09f7b50d0c..11a5e7a8aee3 100644 --- a/library/src/scala/sys/BooleanProp.scala +++ b/library/src/scala/sys/BooleanProp.scala @@ -37,29 +37,67 @@ trait BooleanProp extends Prop[Boolean] { object BooleanProp { private[sys] + /** A `BooleanProp` backed by a system property, whose truth is decided by `valueFn`. + * + * @param key the system property key used to look up the value + * @param valueFn the function deciding whether the raw `String` property value counts as true + */ class BooleanPropImpl(key: String, valueFn: String => Boolean) extends PropImpl(key, valueFn) with BooleanProp { + /** Sets the property to `newValue`, clearing it instead when `newValue` is `false`. + * + * @tparam T1 a supertype of `Boolean`, used as the input type since `Prop` is covariant in `T` + * @param newValue the value to set for this property + * @return the previous value of this property + */ override def setValue[T1 >: Boolean](newValue: T1): Boolean = newValue match { case x: Boolean if !x => val old = value ; clear() ; old case x => super.setValue(newValue) } + /** Sets the raw property value to `"true"`, so that `value` will be whatever `valueFn` returns for `"true"`. */ def enable() = this setValue true + /** Removes the property from the underlying map, so that `value` will be false. */ def disable() = this.clear() + /** Disables the property if `value` is currently true, otherwise enables it. */ def toggle() = if (value) disable() else enable() } private[sys] + /** A `BooleanProp` with a fixed value, backed by no map, whose mutating operations do nothing. + * + * @param key the name of the property + * @param value the constant value of this property + */ class ConstantImpl(val key: String, val value: Boolean) extends BooleanProp { val isSet = value + /** Ignores `newValue` and returns the string form of the constant value. + * + * @param newValue the new string value, which is discarded + */ def set(newValue: String) = "" + value + /** Ignores `newValue` and leaves the constant value in place. + * + * @tparam T1 a supertype of `Boolean`, used as the input type since `Prop` is covariant in `T` + * @param newValue the value to set for this property, which is discarded + * @return the constant value of this property + */ def setValue[T1 >: Boolean](newValue: T1): Boolean = value + /** Returns the string form of the constant value, either `"true"` or `"false"`. */ def get: String = "" + value + /** Returns `Some(true)` if the constant value is true, `None` otherwise. */ def option = if (isSet) Some(value) else None //def or[T1 >: Boolean](alt: => T1): T1 = if (value) true else alt + /** Does nothing, since the value of this property is constant. */ def clear() = () + /** Does nothing, since the value of this property is constant. */ def enable() = () + /** Does nothing, since the value of this property is constant. */ def disable() = () + /** Does nothing, since the value of this property is constant. */ def toggle() = () + /** The default `false` required by the `Prop` contract, never consulted here + * because `value` is fixed at construction. + */ protected def zero = false } @@ -92,5 +130,10 @@ object BooleanProp { */ def constant(key: String, isOn: Boolean): BooleanProp = new ConstantImpl(key, isOn) + /** Returns the `value` of the given property, so that a `BooleanProp` can be used + * where a `Boolean` is expected. + * + * @param b the property to convert + */ implicit def booleanPropAsBoolean(b: BooleanProp): Boolean = b.value } diff --git a/library/src/scala/sys/Prop.scala b/library/src/scala/sys/Prop.scala index 26536056f2aa..43e107c3e05f 100644 --- a/library/src/scala/sys/Prop.scala +++ b/library/src/scala/sys/Prop.scala @@ -103,5 +103,11 @@ object Prop { implicit object IntProp extends CreatorImpl[Int](_.toInt) implicit object DoubleProp extends CreatorImpl[Double](_.toDouble) + /** Creates a `Prop[T]` for the given key using the implicit `Creator[T]`. + * + * @tparam T the type of the property value after conversion from string + * @param key the property name used for lookup + * @return the `Prop[T]` produced by the implicit `Creator[T]` for `key` + */ def apply[T: Creator](key: String): Prop[T] = implicitly[Creator[T]] apply key } diff --git a/library/src/scala/sys/PropImpl.scala b/library/src/scala/sys/PropImpl.scala index 9c08e6700c14..09e4561e5612 100644 --- a/library/src/scala/sys/PropImpl.scala +++ b/library/src/scala/sys/PropImpl.scala @@ -23,34 +23,67 @@ import scala.collection.mutable * @param valueFn the function that converts the raw `String` property value to type `T` */ private[sys] class PropImpl[+T](val key: String, valueFn: String => T) extends Prop[T] { + /** Returns the property value converted by `valueFn`, or `zero` if the property is not set. */ def value: T = if (isSet) valueFn(get) else zero + /** Indicates whether the underlying map contains `key`. */ def isSet = underlying contains key + /** Sets the property to the given string value. + * + * @param newValue the new string value to store under `key` + * @return the previous string value, or `null` if the property was unset + */ def set(newValue: String): String | Null = { val old: String | Null = if (isSet) get else null underlying(key) = newValue old } + /** Sets the property to the string form of the given value. + * + * A `null` value is passed on unchanged, which causes a `NullPointerException` + * in `java.lang.System.setProperty`. + * + * @tparam T1 a supertype of `T`, used as the input type since `Prop` is covariant in `T` + * @param newValue the value whose string form becomes the new property value + * @return the previous converted value, or `zero` if the property was unset + */ def setValue[T1 >: T](newValue: T1): T = { val old = value if (newValue == null) set(null.asInstanceOf[String]) // will cause NPE in java.lang.System.setProperty else set("" + newValue) old } + /** Returns the current string value, or the empty string if the property is not set. */ def get: String = if (isSet) underlying.getOrElse(key, "").nn else "" + /** Removes the property from the underlying map. */ def clear(): Unit = underlying -= key + /** Returns `Some` of the converted value if the property is set, `None` otherwise. */ def option: Option[T] = if (isSet) Some(value) else None + /** Returns the converted property value if the property is set, otherwise the given alternative. + * + * @tparam T1 a supertype of `T`, the result type + * @param alt the alternative value, evaluated only if the property is not set + */ def or[T1 >: T](alt: => T1): T1 = if (isSet) value else alt /** The underlying property map, in our case always `sys.props`. */ protected def underlying: mutable.Map[String, String | Null] = scala.sys.props + /** Returns the value used when the property is unset, obtained by casting `null` to `T`. */ protected def zero: T = null.asInstanceOf[T] private def getString = if (isSet) "currently: " + get else "unset" + /** Returns the key followed by `(currently: )`, where `` is the current + * string value, or by `(unset)` if the property is not set. + */ override def toString() = s"$key ($getString)" } private[sys] abstract class CreatorImpl[+T](f: String => T) extends Prop.Creator[T] { + /** Creates a `Prop[T]` for the given key that converts its raw `String` value with `f`. + * + * @param key the property name used for lookup + * @return a new `Prop[T]` backed by `key` and `f` + */ def apply(key: String): Prop[T] = new PropImpl[T](key, f) } diff --git a/library/src/scala/sys/ShutdownHookThread.scala b/library/src/scala/sys/ShutdownHookThread.scala index cbcedeb00256..ac2033c3692c 100644 --- a/library/src/scala/sys/ShutdownHookThread.scala +++ b/library/src/scala/sys/ShutdownHookThread.scala @@ -19,6 +19,14 @@ import scala.language.`2.13` * how to unregister itself. */ class ShutdownHookThread private (runnable: Runnable, name: String) extends Thread(runnable, name) { + /** Returns `true` if this hook was still registered with the JVM and was + * successfully unregistered, `false` otherwise. + * + * Throws an `IllegalStateException` if the JVM has already begun shutting + * down, because hooks can no longer be removed once shutdown is in progress, + * or a `SecurityException` if a security manager is present and denies + * `RuntimePermission("shutdownHooks")`. + */ def remove() = Runtime.getRuntime.removeShutdownHook(this) } diff --git a/library/src/scala/sys/SystemProperties.scala b/library/src/scala/sys/SystemProperties.scala index 93b6a64a8905..31962678905e 100644 --- a/library/src/scala/sys/SystemProperties.scala +++ b/library/src/scala/sys/SystemProperties.scala @@ -31,29 +31,81 @@ import scala.language.implicitConversions class SystemProperties extends mutable.AbstractMap[String, String | Null] { + /** Returns a new, empty $coll which is not backed by the System properties. */ override def empty: mutable.Map[String, String | Null] = mutable.Map[String, String | Null]() + /** Returns `null`, the default value of this $coll, which `apply` returns + * for a key with no value in the map. + * + * @param key the name of the property being looked up, which is not used + */ override def default(key: String): String | Null = null + /** Returns an iterator over the string-valued System properties, that is, + * those whose name and value are both `String`s, or an empty iterator if + * the properties may not be read. + */ def iterator: Iterator[(String, String)] = wrapAccess { val ps = System.getProperties() names map (k => (k, ps.getProperty(k))) filter (_._2 ne null) } getOrElse Iterator.empty + /** Returns `true` if this $coll exposes no properties, which is the case + * when no string-valued System property is set, or if the properties may + * not be read. + */ override def isEmpty: Boolean = iterator.isEmpty + /** Returns an iterator over the names of the string-valued System properties, + * that is, those whose name and value are both `String`s, or an empty + * iterator if the properties may not be read. + */ def names: Iterator[String] = wrapAccess ( System.getProperties().stringPropertyNames().asScala.iterator ) getOrElse Iterator.empty + /** Optionally returns the value of the System property named `key`. + * + * @param key the name of the property to look up + * @return the property value, or `None` if the property is unset, has a + * non-`String` value, or may not be read + */ def get(key: String): Option[String] = wrapAccess(Option(System.getProperty(key))) flatMap (x => x) + /** Returns `true` if a System property named `key` is set to a `String` value. + * + * @param key the name of the property to look up + * @return whether the property is set to a `String` value, or `false` if the + * properties may not be read + */ override def contains(key: String): Boolean = wrapAccess(super.contains(key)) exists (x => x) + /** Removes all of the System properties, doing nothing if they may not be written. */ override def clear(): Unit = wrapAccess(System.getProperties().clear()) + /** Removes the System property named `key`, doing nothing if it may not be written. + * + * @param key the name of the property to remove + * @return this $coll + */ def subtractOne (key: String): this.type = { wrapAccess(System.clearProperty(key)) ; this } + /** Sets the System property named by the first element of `kv` to its second + * element, doing nothing if the property may not be written. Both elements + * must be non-`null`; a `null` value results in a `NullPointerException`. + * + * @param kv the name and value of the property to set + * @return this $coll + */ def addOne (kv: (String, String | Null)): this.type = { wrapAccess(System.setProperty(kv._1, kv._2)) ; this } @annotation.nowarn("cat=deprecation") // AccessControlException is deprecated on JDK 17 + /** Evaluates `body`, catching and discarding any `AccessControlException` it + * raises. This is intended for accessing the System properties, where such + * an exception indicates that a security manager denied access. + * + * @tparam T the return type of the body expression + * @param body the code to evaluate, typically a System property access + * @return the result of `body` wrapped in `Some`, or `None` if an + * `AccessControlException` was caught + */ def wrapAccess[T](body: => T): Option[T] = try Some(body) catch { case _: AccessControlException => None } } @@ -75,6 +127,11 @@ object SystemProperties { def exclusively[T](body: => T): T = this.synchronized: body + /** Returns this companion object, so that the properties it defines can be + * selected on any `SystemProperties` instance. + * + * @param p the instance being converted, whose value is not used + */ implicit def systemPropertiesToCompanion(p: SystemProperties): SystemProperties.type = this private final val HeadlessKey = "java.awt.headless" @@ -82,6 +139,12 @@ object SystemProperties { private final val PreferIPv6AddressesKey = "java.net.preferIPv6Addresses" private final val NoTraceSuppressionKey = "scala.control.noTraceSuppression" + /** Returns a short description of the meaning of the System property named `key`. + * + * @param key the name of the property to describe + * @return the description, or the empty string if `key` is not one of the + * properties defined here + */ def help(key: String): String = key match { case HeadlessKey => "system should not utilize a display device" case PreferIPv4StackKey => "system should prefer IPv4 sockets" diff --git a/library/src/scala/sys/process/BasicIO.scala b/library/src/scala/sys/process/BasicIO.scala index 11fa9ba5d9ab..6abf2ab549f7 100644 --- a/library/src/scala/sys/process/BasicIO.scala +++ b/library/src/scala/sys/process/BasicIO.scala @@ -45,6 +45,22 @@ object BasicIO { ) private[process] object LazilyListed { + /** Creates a `LazilyListed` backed by a bounded blocking queue, so that the elements + * handed to its `process` function are consumed lazily through its `lazyList`. + * + * The `lazyList` ends when `done` is called, which is how the producer signals the + * process exit code. A producer that outpaces the consumer blocks once `capacity` + * elements are queued. + * + * @tparam T the type of the elements passed to `process` and read from `lazyList` + * @param nonzeroException if true, evaluating `lazyList` throws a `RuntimeException` + * when `done` reports a nonzero exit code, instead of simply + * ending the list + * @param capacity the number of elements the underlying queue holds before `process` + * blocks + * @return a `LazilyListed` whose `process`, `done` and `lazyList` members share one + * queue + */ def apply[T](nonzeroException: Boolean, capacity: Integer): LazilyListed[T] = { val queue = new LinkedBlockingQueue[Either[Int, T]](capacity) val ll = LazyList.unfold(queue) { q => @@ -67,6 +83,22 @@ object BasicIO { @deprecated("internal", since = "2.13.4") private[process] object Streamed { + /** Creates a `Streamed` backed by a bounded blocking queue, so that the elements handed + * to its `process` function are consumed lazily through the `Stream` its `stream` + * function returns. + * + * The stream ends when `done` is called, which is how the producer signals the process + * exit code. A producer that outpaces the consumer blocks once `capacity` elements are + * queued. + * + * @tparam T the type of the elements passed to `process` and read from the stream + * @param nonzeroException if true, evaluating the stream throws a `RuntimeException` + * when `done` reports a nonzero exit code, instead of simply + * ending the stream + * @param capacity the number of elements the underlying queue holds before `process` + * blocks + * @return a `Streamed` whose `process`, `done` and `stream` members share one queue + */ def apply[T](nonzeroException: Boolean, capacity: Integer): Streamed[T] = { val q = new LinkedBlockingQueue[Either[Int, T]](capacity) def next(): Stream[T] = q.take() match { @@ -79,12 +111,33 @@ object BasicIO { } private[process] trait Uncloseable extends Closeable { + /** Does nothing, leaving the underlying resource open. */ final override def close(): Unit = () } private[process] object Uncloseable { + /** Returns a view of `in` that reads through to it but whose `close` does nothing. + * + * @param in the input stream to shield from closing + */ def apply(in: InputStream): InputStream = new FilterInputStream(in) with Uncloseable { } + /** Returns a view of `out` that writes through to it but whose `close` does nothing. + * + * @param out the output stream to shield from closing + */ def apply(out: OutputStream): OutputStream = new FilterOutputStream(out) with Uncloseable { } + /** Shields the standard input stream from being closed by code that consumes it. + * + * @param in the input stream to check + * @return an uncloseable view of `in` if it is `stdin`, otherwise `in` itself + */ def protect(in: InputStream): InputStream = if (in eq stdin) Uncloseable(in) else in + /** Shields the standard output and error streams from being closed by code that writes + * to them. + * + * @param out the output stream to check + * @return an uncloseable view of `out` if it is `stdout` or `stderr`, otherwise `out` + * itself + */ def protect(out: OutputStream): OutputStream = if ((out eq stdout) || (out eq stderr)) Uncloseable(out) else out } diff --git a/library/src/scala/sys/process/Parser.scala b/library/src/scala/sys/process/Parser.scala index 8b6d7a58403a..d086c18c9314 100644 --- a/library/src/scala/sys/process/Parser.scala +++ b/library/src/scala/sys/process/Parser.scala @@ -21,7 +21,8 @@ private[scala] object Parser { private final val SQ = '\'' private final val EOF = -1 - /** Splits the line into tokens separated by whitespace or quotes. + /** Splits the line into whitespace-delimited tokens, recognizing single- and + * double-quoted segments and removing their enclosing quotes. * * @param line the command line string to parse * @param errorFn the error handler invoked with a message when parsing fails (e.g., unmatched quote) @@ -112,5 +113,12 @@ private[scala] object Parser { loop() } + /** Splits the line into whitespace-delimited tokens, recognizing single- and + * double-quoted segments and removing their enclosing quotes, throwing a + * `RuntimeException` if the line is malformed, such as when a quote is unmatched. + * + * @param line the command line string to parse + * @return a list of parsed tokens in order of appearance + */ def tokenize(line: String): List[String] = tokenize(line, scala.sys.error) } diff --git a/library/src/scala/sys/process/ProcessBuilder.scala b/library/src/scala/sys/process/ProcessBuilder.scala index 8c611b03a15c..2457436cb39d 100644 --- a/library/src/scala/sys/process/ProcessBuilder.scala +++ b/library/src/scala/sys/process/ProcessBuilder.scala @@ -502,6 +502,7 @@ object ProcessBuilder extends ProcessBuilderImpl { * [[scala.sys.process.ProcessBuilder]]. */ trait Source { + /** Returns a [[scala.sys.process.ProcessBuilder]] that produces the data of this `Source` as its output. */ protected def toSource: ProcessBuilder /** Writes the output stream of this process to the given file. @@ -543,6 +544,7 @@ object ProcessBuilder extends ProcessBuilderImpl { * [[scala.sys.process.ProcessBuilder]]. */ trait Sink { + /** Returns a [[scala.sys.process.ProcessBuilder]] that writes its input to this `Sink`. */ protected def toSink: ProcessBuilder /** Reads the given file into the input stream of this process. diff --git a/library/src/scala/sys/process/ProcessBuilderImpl.scala b/library/src/scala/sys/process/ProcessBuilderImpl.scala index 9fa255370110..1b8a1b4aa7c5 100644 --- a/library/src/scala/sys/process/ProcessBuilderImpl.scala +++ b/library/src/scala/sys/process/ProcessBuilderImpl.scala @@ -29,16 +29,37 @@ private[process] trait ProcessBuilderImpl { self: ProcessBuilder.type => private[process] final class DaemonBuilder(underlying: ProcessBuilder) extends AbstractBuilder { + /** Starts the process represented by the underlying builder, with the threads that run + * the supplied `ProcessIO`'s input, output, and error handlers marked as daemon threads. + * + * Threads a compound command starts outside those handlers, such as the transfer threads + * of a pipe, are not daemonized by this builder. + * + * @param io the `ProcessIO` that handles the process's streams; a daemonized copy of it is used + * @return the started `Process` + */ override def run(io: ProcessIO): Process = underlying.run(io.daemonized()) } private[process] final class Dummy(override val toString: String, exitValue: => Int) extends AbstractBuilder { + /** Creates a `Process` that starts no external command and whose exit value is the one + * supplied to this builder. + * + * @param io the `ProcessIO` that would handle the process's streams; it is ignored, since no external command runs + * @return a `Process` yielding this builder's exit value + */ override def run(io: ProcessIO): Process = new DummyProcess(exitValue) + /** Returns `true`, since a dummy command can be the target of a pipe. */ override def canPipeTo = true } private[process] final class URLInput(url: URL) extends ThreadBuilder(url.toString) { + /** Returns `false`, since copying the contents of a URL yields no exit code worth propagating. */ override def hasExitValue = false + /** Opens the URL and hands the resulting stream to `io` as the process output. + * + * @param io the `ProcessIO` whose `processOutput` function consumes the URL's contents + */ override def runImpl(io: ProcessIO): Unit = io.processOutput(protect(url.openStream())) } @@ -46,23 +67,46 @@ private[process] trait ProcessBuilderImpl { // this class should not be reused in a context where the call-by-name argument does something sensitive, // like `url.openStream()`, since otherwise there is a hypothetical possibility of a Java deserialization gadget chain. private[process] final class IStreamBuilder(stream: => InputStream, label: String) extends ThreadBuilder(label) { + /** Returns `false`, since copying the contents of an input stream yields no exit code worth propagating. */ override def hasExitValue = false + /** Evaluates the by-name stream and hands it to `io` as the process output, guarding the + * JVM's own standard input against being closed. + * + * @param io the `ProcessIO` whose `processOutput` function consumes the stream + */ override def runImpl(io: ProcessIO): Unit = io.processOutput(protect(stream)) } private[process] final class FileInput(file: File) extends ThreadBuilder(file.getAbsolutePath) { + /** Returns `false`, since copying the contents of a file yields no exit code worth propagating. */ override def hasExitValue = false + /** Opens the file for reading and hands the resulting stream to `io` as the process output. + * + * @param io the `ProcessIO` whose `processOutput` function consumes the file's contents + */ override def runImpl(io: ProcessIO): Unit = io.processOutput(protect(new FileInputStream(file))) } // Same remark as IStreamBuilder private[process] final class OStreamBuilder(stream: => OutputStream, label: String) extends ThreadBuilder(label) { + /** Returns `false`, since writing to an output stream yields no exit code worth propagating. */ override def hasExitValue = false + /** Evaluates the by-name stream and hands it to `io` to be filled as the process input, + * guarding the JVM's own standard output and error against being closed. + * + * @param io the `ProcessIO` whose `writeInput` function writes to the stream + */ override def runImpl(io: ProcessIO): Unit = io.writeInput(protect(stream)) } private[process] final class FileOutput(file: File, append: Boolean) extends ThreadBuilder(file.getAbsolutePath) { + /** Returns `false`, since writing to a file yields no exit code worth propagating. */ override def hasExitValue = false + /** Opens the file for writing, appending to or truncating it as this builder was + * configured, and hands the resulting stream to `io` to be filled as the process input. + * + * @param io the `ProcessIO` whose `writeInput` function writes to the stream + */ override def runImpl(io: ProcessIO): Unit = io.writeInput(protect(new FileOutputStream(file, append))) } @@ -70,8 +114,17 @@ private[process] trait ProcessBuilderImpl { override val toString: String ) extends AbstractBuilder { + /** Performs this builder's I/O work, which `run` carries out on a separate thread. + * + * @param io the `ProcessIO` supplying the functions that handle the streams + */ def runImpl(io: ProcessIO): Unit + /** Spawns a thread that performs `runImpl` and returns immediately. + * + * @param io the `ProcessIO` supplying the functions that handle the streams + * @return a `Process` backed by that thread, whose exit value is 0 if `runImpl` completed normally and 1 if it threw + */ override def run(io: ProcessIO): Process = { val success = new LinkedBlockingQueue[Boolean](1) def go(): Unit = { @@ -91,6 +144,17 @@ private[process] trait ProcessBuilderImpl { * @param p the underlying `java.lang.ProcessBuilder` used to start the external process */ private[process] class Simple(p: JProcessBuilder) extends AbstractBuilder { + /** Starts the external command and spawns the threads that pump its input, output, and + * error streams through `io`. + * + * No input thread is spawned when `io` writes input with `BasicIO.connectToStdIn`, in + * which case the command inherits the standard input of the current process, nor when + * it writes input with `BasicIO.connectNoOp`. No error thread is spawned when the + * underlying `java.lang.ProcessBuilder` merges error output into standard output. + * + * @param io the `ProcessIO` supplying the functions that handle the streams + * @return the started `Process` + */ override def run(io: ProcessIO): Process = { import java.lang.ProcessBuilder.Redirect.{INHERIT => Inherit} import io.{daemonizeThreads, processError, processOutput, writeInput} @@ -111,12 +175,16 @@ private[process] trait ProcessBuilderImpl { new SimpleProcess(process, inThread, outThread :: errorThread) } + /** Returns the string form of the underlying `java.lang.ProcessBuilder`'s command. */ override def toString() = p.command.toString + /** Returns `true`, since a simple command can be the target of a pipe. */ override def canPipeTo = true } private[scala] abstract class AbstractBuilder extends ProcessBuilder with Sink with Source { + /** Returns this builder itself, which serves as its own source. */ protected def toSource: AbstractBuilder = this + /** Returns this builder itself, which serves as its own sink. */ protected def toSink: AbstractBuilder = this private val defaultStreamCapacity = 4096 @@ -129,9 +197,30 @@ private[process] trait ProcessBuilderImpl { def #&&(other: ProcessBuilder): ProcessBuilder = new AndBuilder(this, other) def ###(other: ProcessBuilder): ProcessBuilder = new SequenceBuilder(this, other) + /** Returns the started `Process` for this builder, run with its output and error sent to + * the console and with no input given to it. + */ def run(): Process = run(connectInput = false) + /** Starts the process represented by this builder, sending its output and error to the + * console. + * + * @param connectInput whether the process reads from the standard input of the current process + * @return the started `Process` + */ def run(connectInput: Boolean): Process = run(BasicIO.standard(connectInput)) + /** Starts the process represented by this builder, sending its output and error to `log` + * and giving it no input. + * + * @param log the `ProcessLogger` to receive standard output and error + * @return the started `Process` + */ def run(log: ProcessLogger): Process = run(log, connectInput = false) + /** Starts the process represented by this builder, sending its output and error to `log`. + * + * @param log the `ProcessLogger` to receive standard output and error + * @param connectInput whether the process reads from the standard input of the current process + * @return the started `Process` + */ def run(log: ProcessLogger, connectInput: Boolean): Process = run(BasicIO(connectInput, log)) def !! = slurp(None, withIn = false) @@ -139,13 +228,71 @@ private[process] trait ProcessBuilderImpl { def !!< = slurp(None, withIn = true) def !!<(log: ProcessLogger) = slurp(Some(log), withIn = true) + /** Returns the standard output of the process represented by this builder as a `LazyList` + * of lines that blocks until each line becomes available, starting that process as a side + * effect. Standard error is sent to the console, and a non-zero exit code raises an + * exception after the last line. + */ def lazyLines: LazyList[String] = lazyLines(withInput = false, nonZeroException = true, None, defaultStreamCapacity) + /** Starts the process represented by this builder and returns its standard output as a + * `LazyList` of lines that blocks until each line becomes available. A non-zero exit + * code raises an exception after the last line. + * + * @param log the `ProcessLogger` to receive standard error output + * @return a `LazyList` of the process's standard output lines, whose evaluation raises an + * exception once every line has been yielded if the exit code is non-zero + */ def lazyLines(log: ProcessLogger): LazyList[String] = lazyLines(withInput = false, nonZeroException = true, Some(log), defaultStreamCapacity) + /** Returns the standard output of the process represented by this builder as a `LazyList` + * of lines that blocks until each line becomes available, starting that process as a side + * effect. Standard error is sent to the console, and a non-zero exit code raises no + * exception. + */ def lazyLines_! : LazyList[String] = lazyLines(withInput = false, nonZeroException = false, None, defaultStreamCapacity) + /** Returns the standard output of the process represented by this builder as a `LazyList` + * of lines that blocks until each line becomes available, starting that process as a side + * effect. Standard error is sent to the given `ProcessLogger`, and a non-zero exit code + * raises no exception. + */ def lazyLines_!(log: ProcessLogger): LazyList[String] = lazyLines(withInput = false, nonZeroException = false, Some(log), defaultStreamCapacity) + /** Starts the process represented by this builder and returns its standard output as a + * `LazyList` of lines that blocks until each line becomes available. Standard error is + * sent to the console, and a non-zero exit code raises an exception after the last line. + * + * @param capacity the maximum number of lines to buffer before blocking the producer; it must + * be non-null and positive, since a null or non-positive value fails when the + * underlying buffer is created + * @return a `LazyList` of the process's standard output lines, whose evaluation raises an + * exception once every line has been yielded if the exit code is non-zero + */ def lazyLines(capacity: Integer): LazyList[String] = lazyLines(withInput = false, nonZeroException = true, None, capacity) + /** Starts the process represented by this builder and returns its standard output as a + * `LazyList` of lines that blocks until each line becomes available. A non-zero exit + * code raises an exception after the last line. + * + * @param log the `ProcessLogger` to receive standard error output + * @param capacity the maximum number of lines to buffer before blocking the producer; it must + * be non-null and positive, since a null or non-positive value fails when the + * underlying buffer is created + * @return a `LazyList` of the process's standard output lines, whose evaluation raises an + * exception once every line has been yielded if the exit code is non-zero + */ def lazyLines(log: ProcessLogger, capacity: Integer): LazyList[String] = lazyLines(withInput = false, nonZeroException = true, Some(log), capacity) + /** Returns the standard output of the process represented by this builder as a `LazyList` + * of lines that blocks until each line becomes available, buffering at most `capacity` + * lines ahead of the consumer and starting that process as a side effect. The capacity must + * be non-null and positive, since a null or non-positive value fails when the underlying + * buffer is created. Standard error is sent to the console, and a non-zero exit code raises + * no exception. + */ def lazyLines_!(capacity: Integer) : LazyList[String] = lazyLines(withInput = false, nonZeroException = false, None, capacity) + /** Returns the standard output of the process represented by this builder as a `LazyList` + * of lines that blocks until each line becomes available, buffering at most `capacity` + * lines ahead of the consumer and starting that process as a side effect. The capacity must + * be non-null and positive, since a null or non-positive value fails when the underlying + * buffer is created. Standard error is sent to the given `ProcessLogger`, and a non-zero exit + * code raises no exception. + */ def lazyLines_!(log: ProcessLogger, capacity: Integer): LazyList[String] = lazyLines(withInput = false, nonZeroException = false, Some(log), capacity) @deprecated("internal", since = "2.13.4") def lineStream: Stream[String] = lineStream(withInput = false, nonZeroException = true, None, defaultStreamCapacity) @@ -222,15 +369,20 @@ private[process] trait ProcessBuilderImpl { private def runBuffered(log: ProcessLogger, connectInput: Boolean) = log buffer run(log, connectInput).exitValue() + /** Returns `false`, since a command cannot be the target of a pipe unless it says otherwise. */ def canPipeTo = false + /** Returns `true`, since a command's exit code is propagated to the user unless it says otherwise. */ def hasExitValue = true } private[process] class URLImpl(url: URL) extends URLBuilder with Source { + /** Returns a builder that opens this `URL` and produces its contents as process output. */ protected def toSource: URLInput = new URLInput(url) } private[process] class FileImpl(base: File) extends FileBuilder with Sink with Source { + /** Returns a builder that reads this file and produces its contents as process output. */ protected def toSource: FileInput = new FileInput(base) + /** Returns a builder that writes its process input to this file, replacing any existing contents. */ protected def toSink: FileOutput = new FileOutput(base, append = false) def #<<(f: File): ProcessBuilder = #<<(new FileInput(f)) @@ -240,12 +392,27 @@ private[process] trait ProcessBuilderImpl { } private[process] abstract class BasicBuilder extends AbstractBuilder { + /** Checks that `a` is not this builder, throwing an `IllegalArgumentException` if it is, + * since a compound command cannot contain itself. + * + * @param a the component command to check + */ protected def checkNotThis(a: ProcessBuilder) = require(a != this, "Compound process '" + a + "' cannot contain itself.") + /** Creates the process for this compound command and starts it. + * + * @param io the `ProcessIO` supplying the functions that handle the streams + * @return the started `Process` + */ final def run(io: ProcessIO): Process = { val p = createProcess(io) p.start() p } + /** Creates the process that carries out this compound command, without starting it. + * + * @param io the `ProcessIO` supplying the functions that handle the streams + * @return an unstarted `BasicProcess` for this command + */ protected def createProcess(io: ProcessIO): BasicProcess } @@ -257,6 +424,7 @@ private[process] trait ProcessBuilderImpl { checkNotThis(a) checkNotThis(b) + /** Returns the two component commands joined by this builder's operator and enclosed in parentheses. */ override def toString() = " ( " + a + " " + operatorString + " " + b + " ) " } @@ -266,6 +434,12 @@ private[process] trait ProcessBuilderImpl { toError: Boolean ) extends SequentialBuilder(first, second, if (toError) "#|!" else "#|") { + /** Creates a process that runs both commands concurrently, feeding the output of the + * first, or its error output when this builder pipes to error, into the input of the second. + * + * @param io the `ProcessIO` supplying the functions that handle the streams left unpiped + * @return an unstarted `PipedProcesses` for the two commands + */ override def createProcess(io: ProcessIO): PipedProcesses = new PipedProcesses(first, second, io, toError) } @@ -273,6 +447,12 @@ private[process] trait ProcessBuilderImpl { first: ProcessBuilder, second: ProcessBuilder ) extends SequentialBuilder(first, second, "#&&") { + /** Creates a process that runs the first command and then the second only if the first + * exits with zero. + * + * @param io the `ProcessIO` supplying the functions that handle both commands' streams + * @return an unstarted `AndProcess` for the two commands + */ override def createProcess(io: ProcessIO): AndProcess = new AndProcess(first, second, io) } @@ -280,6 +460,12 @@ private[process] trait ProcessBuilderImpl { first: ProcessBuilder, second: ProcessBuilder ) extends SequentialBuilder(first, second, "#||") { + /** Creates a process that runs the first command and then the second only if the first + * exits with a non-zero value. + * + * @param io the `ProcessIO` supplying the functions that handle both commands' streams + * @return an unstarted `OrProcess` for the two commands + */ override def createProcess(io: ProcessIO): OrProcess = new OrProcess(first, second, io) } @@ -287,6 +473,12 @@ private[process] trait ProcessBuilderImpl { first: ProcessBuilder, second: ProcessBuilder ) extends SequentialBuilder(first, second, "###") { + /** Creates a process that runs the first command and then the second, whatever the first + * command's exit value. + * + * @param io the `ProcessIO` supplying the functions that handle both commands' streams + * @return an unstarted `ProcessSequence` for the two commands + */ override def createProcess(io: ProcessIO): ProcessSequence = new ProcessSequence(first, second, io) } } diff --git a/library/src/scala/sys/process/ProcessIO.scala b/library/src/scala/sys/process/ProcessIO.scala index ee8cc37f32de..9965e5bd671e 100644 --- a/library/src/scala/sys/process/ProcessIO.scala +++ b/library/src/scala/sys/process/ProcessIO.scala @@ -57,6 +57,12 @@ final class ProcessIO( val processError: InputStream => Unit, val daemonizeThreads: Boolean ) { + /** Creates a `ProcessIO` with `daemonizeThreads` set to `false`. + * + * @param in function that will be called with the `OutputStream` to which all input to the process must be written + * @param out function that will be called with the `InputStream` from which all normal output of the process must be read + * @param err function that will be called with the `InputStream` from which all error output of the process must be read + */ def this(in: OutputStream => Unit, out: InputStream => Unit, err: InputStream => Unit) = this(in, out, err, daemonizeThreads = false) /** Creates a new `ProcessIO` with a different handler for the process input. @@ -82,7 +88,7 @@ final class ProcessIO( /** Creates a new `ProcessIO`, with `daemonizeThreads` true. * - * @return a new `ProcessIO` that runs all I/O threads as daemon threads + * @return a copy of this `ProcessIO` with `daemonizeThreads` set to `true` */ def daemonized(): ProcessIO = new ProcessIO(writeInput, processOutput, processError, daemonizeThreads = true) } diff --git a/library/src/scala/sys/process/ProcessImpl.scala b/library/src/scala/sys/process/ProcessImpl.scala index 039983aa889d..7641de05cb5b 100644 --- a/library/src/scala/sys/process/ProcessImpl.scala +++ b/library/src/scala/sys/process/ProcessImpl.scala @@ -23,6 +23,13 @@ private[process] trait ProcessImpl { /** Runs provided code in a new Thread and returns the Thread instance. */ private[process] object Spawn { + /** Runs `f` in a newly created thread, which is started before returning. + * + * @param prefix a label prepended to the thread's name, for diagnostics + * @param daemon whether the new thread is a daemon thread, and so does not keep the JVM alive + * @param f the by-name computation to run in the new thread + * @return the started thread running `f` + */ def apply(prefix: String, daemon: Boolean = false)(f: => Unit): Thread = { val thread = new Thread() { override def run() = f } thread.setName(prefix + "-spawn-" + thread.getName) @@ -32,6 +39,13 @@ private[process] trait ProcessImpl { } } private[process] object Future { + /** Evaluates `f` in a new thread, started before returning. + * + * @tparam T the type of the value computed by `f` + * @param f the by-name computation to evaluate in the new thread + * @return a pair of the thread evaluating `f` and a function that blocks until the + * result is available, rethrowing any exception thrown by `f` + */ def apply[T](f: => T): (Thread, () => T) = { val result = new LinkedBlockingQueue[Either[Throwable, T]](1) def run(): Unit = { @@ -73,6 +87,9 @@ private[process] trait ProcessImpl { evaluateSecondProcess: Int => Boolean ) extends CompoundProcess { + /** Runs `a` and then, if `evaluateSecondProcess` accepts its exit code, runs `b`, yielding the exit code of + * the last process run in `Some`, or `None` if waiting for either process is interrupted. + */ protected override def runAndExitValue() = { val first = a.run(io) runInterruptible(first.exitValue())(first.destroy()) flatMap { codeA => @@ -86,13 +103,20 @@ private[process] trait ProcessImpl { } private[process] abstract class BasicProcess extends Process { + /** Starts this process running, without waiting for it to exit. */ def start(): Unit } private[process] abstract class CompoundProcess extends BasicProcess { + /** Returns `true` if the thread running the underlying processes has not yet terminated. */ def isAlive() = processThread.isAlive() + /** Destroys this process by interrupting the thread running the underlying processes. */ def destroy() = destroyer() + /** Blocks until this process exits and returns its exit code, throwing a `RuntimeException` if no exit code was + * produced, as happens when the process is destroyed. + */ def exitValue() = futureValue() getOrElse scala.sys.error("No exit code: process destroyed.") + /** Starts this process by forcing the threads that run the underlying processes to be created. */ def start() = { futureThread ;() } protected lazy val (processThread, (futureThread, futureValue: (() => Option[Int])), destroyer) = { @@ -121,6 +145,13 @@ private[process] trait ProcessImpl { /** Starts and blocks until the exit value is available and then returns it in Some. Returns None if destroyed (use 'run'). */ protected def runAndExitValue(): Option[Int] + /** Evaluates `action`, performing `destroyImpl` instead if evaluating `action` throws an `InterruptedException`. + * + * @tparam T the type of the value computed by `action` + * @param action the by-name computation to evaluate + * @param destroyImpl the clean-up to perform if `action` throws an `InterruptedException` + * @return the result of `action` in `Some`, or `None` if `action` threw an `InterruptedException` + */ protected def runInterruptible[T](action: => T)(destroyImpl: => Unit): Option[T] = { try Some(action) catch onInterrupt { destroyImpl; None } @@ -128,9 +159,23 @@ private[process] trait ProcessImpl { } private[process] class PipedProcesses(a: ProcessBuilder, b: ProcessBuilder, defaultIO: ProcessIO, toError: Boolean) extends CompoundProcess { + /** Creates the thread that reads the output of the first process into the pipe, labeled with that process. */ protected def newSource: PipeSource = new PipeSource(a.toString) + /** Creates the thread that writes the contents of the pipe to the input of the second process, labeled with that process. */ protected def newSink: PipeSink = new PipeSink(b.toString) + /** Runs both processes connected by a freshly created pipe source and sink. */ protected override def runAndExitValue() = runAndExitValue(newSource, newSink) + /** Runs both processes with the output of the first connected through `source` and `sink` to the input of the second. + * + * The first process writes to its error stream rather than its output stream when this + * is a pipe to error. All of the pipe threads and processes are released if either + * process fails to start or the pipeline is interrupted. + * + * @param source the pipe thread reading the output of the first process + * @param sink the pipe thread writing to the input of the second process + * @return the exit code of the second process in `Some`, or that of the first process + * if the second builder has no exit value of its own; `None` if interrupted + */ protected def runAndExitValue(source: PipeSource, sink: PipeSink): Option[Int] = { source connectOut sink source.start() @@ -179,6 +224,7 @@ private[process] trait ProcessImpl { } private[process] abstract class PipeThread(isSink: Boolean, labelFn: () => String) extends Thread { + /** Transfers data between the streams this thread connects, for as long as it has work to do. */ def run(): Unit private[process] def runloop(src: InputStream, dst: OutputStream): Unit = { @@ -196,6 +242,10 @@ private[process] trait ProcessImpl { setName(s"PipeSource($label)-$getName") protected val pipe = new PipedOutputStream protected val source = new LinkedBlockingQueue[Option[InputStream]](1) + /** Copies each connected input stream into the pipe in turn, finishing once the stream being copied is exhausted + * and the end marker queued by `done()` is taken, or as soon as an `InterruptedException` is thrown, and closes + * the pipe on the way out. + */ override final def run(): Unit = { @tailrec def go(): Unit = source.take() match { @@ -206,13 +256,23 @@ private[process] trait ProcessImpl { catch onInterrupt(()) finally BasicIO close pipe } + /** Hands `in` to this thread as the next stream to copy into the pipe, blocking while a previous stream is still queued. + * + * @param in the stream, typically the output of a process, whose contents are copied into the pipe + */ def connectIn(in: InputStream): Unit = source.put(Some(in)) + /** Connects the far end of this source's pipe to `sink`, so that what is copied here is read by `sink`. + * + * @param sink the pipe sink that consumes the contents of this source's pipe + */ def connectOut(sink: PipeSink): Unit = sink connectIn pipe + /** Interrupts this thread, signals that no more input streams follow, and blocks until it has terminated. */ def release(): Unit = { interrupt() done() join() } + /** Signals that no further input streams will be connected, letting this thread finish. */ def done() = source.put(None) } @nowarn("msg=Calling the external method .*Name") // setName+getName are safe to call in a constructor @@ -220,6 +280,10 @@ private[process] trait ProcessImpl { setName(s"PipeSink($label)-$getName") protected val pipe = new PipedInputStream protected val sink = new LinkedBlockingQueue[Option[OutputStream]](1) + /** Copies the pipe into each connected output stream in turn, finishing once the transfer in progress completes + * and the end marker queued by `done()` is taken, or as soon as an `InterruptedException` is thrown, and closes + * the pipe on the way out. + */ override def run(): Unit = { @tailrec def go(): Unit = sink.take() match { @@ -230,25 +294,40 @@ private[process] trait ProcessImpl { catch onInterrupt(()) finally BasicIO close pipe } + /** Hands `out` to this thread as the next stream to receive the contents of the pipe, blocking while a previous stream is still queued. + * + * @param out the stream, typically the input of a process, that the pipe's contents are copied to + */ def connectOut(out: OutputStream): Unit = sink.put(Some(out)) + /** Connects this sink's pipe to `pipeOut`, so that what is written there is read here. + * + * @param pipeOut the piped output stream of the pipe source feeding this sink + */ def connectIn(pipeOut: PipedOutputStream): Unit = pipe.connect(pipeOut) + /** Interrupts this thread, signals that no more output streams follow, and blocks until it has terminated. */ def release(): Unit = { interrupt() done() join() } + /** Signals that no further output streams will be connected, letting this thread finish. */ def done() = sink.put(None) } - /** A thin wrapper around a java.lang.Process. `ioThreads` are the Threads created to do I/O. - * The implementation of `exitValue` waits until these threads die before returning. + /** A process that runs no native process, and is instead backed by a thread evaluating `action`. + * The implementation of `exitValue` waits until that thread produces a result before returning. * * @param action the by-name computation whose result will be used as the exit value */ private[process] class DummyProcess(action: => Int) extends Process { private val (thread, value) = Future(action) + /** Returns `true` if the thread computing the exit value has not yet terminated. */ override def isAlive() = thread.isAlive() + /** Blocks until the computation finishes and returns its result as the exit code, rethrowing any exception the + * computation threw. + */ override def exitValue() = value() + /** Does nothing, as there is no native process to destroy. */ override def destroy(): Unit = { } } @@ -268,7 +347,12 @@ private[process] trait ProcessImpl { * @param outputThreads the threads reading from the process's stdout and stderr streams */ private[process] class SimpleProcess(p: JProcess, inputThread: Thread | Null, outputThreads: List[Thread]) extends Process { + /** Returns `true` if the underlying `java.lang.Process` has not yet terminated. */ override def isAlive() = p.isAlive() + /** Blocks until the underlying process terminates, then waits for all of its output to be read and returns its + * exit code. If the wait for the process is interrupted, the input thread is still interrupted but the + * `InterruptedException` propagates without waiting for the output threads. + */ override def exitValue() = { try p.waitFor() // wait for the process to terminate finally interrupt() @@ -276,6 +360,7 @@ private[process] trait ProcessImpl { p.exitValue() } + /** Destroys the underlying process, abandoning any of its output that has not yet been read. */ override def destroy() = { try { outputThreads foreach (_.interrupt()) // on destroy, don't bother consuming any more output @@ -287,8 +372,13 @@ private[process] trait ProcessImpl { private def interrupt(): Unit = if (inputThread != null) inputThread.interrupt() } private[process] final class ThreadProcess(thread: Thread, success: LinkedBlockingQueue[Boolean]) extends Process { + /** Returns `true` if the thread doing this process's work has not yet terminated. */ override def isAlive() = thread.isAlive() + /** Blocks until the thread reports its outcome and returns `0` if it succeeded, `1` otherwise, throwing an + * `InterruptedException` if the wait is interrupted. + */ override def exitValue() = if (success.take()) 0 else 1 // thread.join() + /** Destroys this process by interrupting the thread doing its work. */ override def destroy() = thread.interrupt() } } diff --git a/library/src/scala/sys/process/ProcessLogger.scala b/library/src/scala/sys/process/ProcessLogger.scala index 48115a58cd7b..ff2f7fd18a72 100644 --- a/library/src/scala/sys/process/ProcessLogger.scala +++ b/library/src/scala/sys/process/ProcessLogger.scala @@ -81,10 +81,26 @@ class FileProcessLogger(file: File) extends ProcessLogger with Closeable with Fl ) ) ) + /** Appends the given line of process output, followed by a line separator, to the file. + * + * @param s a lazily-evaluated line from the process standard output + */ def out(s: => String): Unit = writer.println(s) + /** Appends the given line of process error output, followed by a line separator, to the file. + * + * @param s a lazily-evaluated line from the process standard error + */ def err(s: => String): Unit = writer.println(s) + /** Evaluates `f` without setting up any additional buffering. + * + * @tparam T the return type of `f` + * @param f the code to execute, evaluated by name + * @return the result produced by evaluating `f` + */ def buffer[T](f: => T): T = f + /** Closes the file, first writing out any output not yet written. */ def close(): Unit = writer.close() + /** Writes out to the file any output not yet written. */ def flush(): Unit = writer.flush() } diff --git a/library/src/scala/sys/process/package.scala b/library/src/scala/sys/process/package.scala index dc994358faf7..3e0340c174ff 100644 --- a/library/src/scala/sys/process/package.scala +++ b/library/src/scala/sys/process/package.scala @@ -241,22 +241,57 @@ import scala.language.`2.13` @deprecated("Use `java.util.concurrent.LinkedBlockingQueue with capacity 1` instead.", since = "2.13.4") type SyncVar[T] = scala.concurrent.SyncVar[T] + /** Returns a partial function, suitable as a `catch` clause, that applies + * `handler` to any caught `Throwable`. + * + * @tparam T the result type of `handler` + * @param handler the function applied to the caught exception + */ def onError[T](handler: Throwable => T): Throwable =?> T = { case e @ _ => handler(e) } + /** Returns a partial function, suitable as a `catch` clause, that evaluates + * `handler` when a `java.io.InterruptedIOException` is caught, and is + * undefined for every other `Throwable`. + * + * @tparam T the result type of `handler` + * @param handler the expression evaluated on interruption, by name + */ def onIOInterrupt[T](handler: => T): Throwable =?> T = { case _: InterruptedIOException => handler } + /** Returns a partial function, suitable as a `catch` clause, that evaluates + * `handler` when an `InterruptedException` is caught, and is undefined for + * every other `Throwable`. + * + * @tparam T the result type of `handler` + * @param handler the expression evaluated on interruption, by name + */ def onInterrupt[T](handler: => T): Throwable =?> T = { case _: InterruptedException => handler } + /** Returns a partial function, suitable as a `catch` clause, that applies + * `handler` to a caught `java.io.IOException`, and is undefined for every + * other `Throwable`. + * + * @tparam T the result type of `handler` + * @param handler the function applied to the caught exception + */ def ioFailure[T](handler: IOException => T): Throwable =?> T = { case e: IOException => handler(e) } + /** Prints the given messages to the console, separated by spaces and prefixed + * with `[process]`, when process debugging is enabled. + * + * Debugging is enabled by defining the `scala.process.debug` system property, + * and is read once when this object is initialized. + * + * @param msgs the values whose string representations make up the message + */ def dbg(msgs: Any*) = if (processDebug) { Console.println("[process] " + (msgs mkString " ")) }