diff options
Diffstat (limited to 'src')
33 files changed, 215 insertions, 144 deletions
diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala index 842851b4f6..e78589908c 100644 --- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala +++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala @@ -111,8 +111,8 @@ import scala.language.implicitConversions""" " */"), Op(">>", "/**\n" + - " * Returns this value bit-shifted left by the specified number of bits,\n" + - " * filling in the right bits with the same value as the left-most bit of this.\n" + + " * Returns this value bit-shifted right by the specified number of bits,\n" + + " * filling in the left bits with the same value as the left-most bit of this.\n" + " * The effect of this is to retain the sign of the value.\n" + " * @example {{{\n" + " * -21 >> 3 == -3\n" + diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 6d9b41ec45..02a199f7ac 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -59,14 +59,21 @@ trait DocComments { self: Global => comment.defineVariables(sym) } + + def replaceInheritDocToInheritdoc(docStr: String):String = { + docStr.replaceAll("""\{@inheritDoc\p{Zs}*\}""", "@inheritdoc") + } + /** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by * missing sections of an inherited doc comment. * If a symbol does not have a doc comment but some overridden version of it does, * the doc comment of the overridden version is copied instead. */ def cookedDocComment(sym: Symbol, docStr: String = ""): String = cookedDocComments.getOrElseUpdate(sym, { - val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse "" + var ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse "" else DocComment(docStr).template + ownComment = replaceInheritDocToInheritdoc(ownComment) + superComment(sym) match { case None => if (ownComment.indexOf("@inheritdoc") != -1) diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index c291961447..e47fdac938 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -446,8 +446,10 @@ abstract class ExplicitOuter extends InfoTransform // // See SI-6552 for an example of why `sym.owner.enclMethod hasAnnotation ScalaInlineClass` // is not suitable; if we make a method-local class non-private, it mangles outer pointer names. - if (currentClass != sym.owner || - (closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass)) + def enclMethodIsInline = closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass + // SI-8710 The extension method condition reflects our knowledge that a call to `new Meter(12).privateMethod` + // with later be rewritten (in erasure) to `Meter.privateMethod$extension(12)`. + if ((currentClass != sym.owner || enclMethodIsInline) && !sym.isMethodWithExtension) sym.makeNotPrivate(sym.owner) val qsym = qual.tpe.widen.typeSymbol diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 228c9da624..6349fc3fb9 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -208,7 +208,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { def makeExtensionMethodSymbol = { val extensionName = extensionNames(origMeth).head.toTermName val extensionMeth = ( - companion.moduleClass.newMethod(extensionName, tree.pos.focus, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL) + companion.moduleClass.newMethod(extensionName, tree.pos.focus, origMeth.flags & ~OVERRIDE & ~PROTECTED & ~PRIVATE & ~LOCAL | FINAL) setAnnotations origMeth.annotations ) origMeth.removeAnnotation(TailrecClass) // it's on the extension method, now. diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 905e925f57..66900e7258 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -211,6 +211,17 @@ sealed abstract class Option[+A] extends Product with Serializable { /** Tests whether the option contains a given value as an element. * + * @example {{{ + * // Returns true because Some instance contains string "something" which equals "something". + * Some("something") contains "something" + * + * // Returns false because "something" != "anything". + * Some("something") contains "anything" + * + * // Returns false when method called on None. + * None contains "anything" + * }}} + * * @param elem the element to test. * @return `true` if the option has an element that is equal (as * determined by `==`) to `elem`, `false` otherwise. @@ -251,6 +262,17 @@ sealed abstract class Option[+A] extends Product with Serializable { * nonempty '''and''' `pf` is defined for that value. * Returns $none otherwise. * + * @example {{{ + * // Returns Some(HTTP) because the partial function covers the case. + * Some("http") collect {case "http" => "HTTP"} + * + * // Returns None because the partial function doesn't cover the case. + * Some("ftp") collect {case "http" => "HTTP"} + * + * // Returns None because None is passed to the collect method. + * None collect {case value => value} + * }}} + * * @param pf the partial function. * @return the result of applying `pf` to this $option's * value (if possible), or $none. diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index 7f4a9dc45d..98dd35d306 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -20,6 +20,11 @@ package scala * {{{ * val f: PartialFunction[Int, Any] = { case _ => 1/0 } * }}} + * + * It is the responsibility of the caller to call `isDefinedAt` before + * calling `apply`, because if `isDefinedAt` is false, it is not guaranteed + * `apply` will throw an exception to indicate an error condition. If an + * exception is not thrown, evaluation may result in an arbitrary value. * * The main distinction between `PartialFunction` and [[scala.Function1]] is * that the user of a `PartialFunction` may choose to do something different @@ -156,10 +161,10 @@ trait PartialFunction[-A, +B] extends (A => B) { self => object PartialFunction { /** Composite function produced by `PartialFunction#orElse` method */ - private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) extends PartialFunction[A, B] { + private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) extends scala.runtime.AbstractPartialFunction[A, B] { def isDefinedAt(x: A) = f1.isDefinedAt(x) || f2.isDefinedAt(x) - def apply(x: A): B = f1.applyOrElse(x, f2) + override def apply(x: A): B = f1.applyOrElse(x, f2) override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = { val z = f1.applyOrElse(x, checkFallback[B]) diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index faeb1dcbe2..59c89df3fa 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -126,7 +126,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { def optManifest[T](implicit m: OptManifest[T]) = m // Minor variations on identity functions - def identity[A](x: A): A = x // @see `conforms` for the implicit version + @inline def identity[A](x: A): A = x // @see `conforms` for the implicit version @inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero` @inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements @@ -303,7 +303,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { @inline implicit def augmentString(x: String): StringOps = new StringOps(x) @inline implicit def unaugmentString(x: StringOps): String = x.repr - // printing and reading ----------------------------------------------- + // printing ----------------------------------------------------------- def print(x: Any) = Console.print(x) def println() = Console.println() diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index 20a328ec8f..2632994a34 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -38,7 +38,7 @@ import scala.annotation.tailrec * To provide your own string interpolator, create an implicit class * which adds a method to `StringContext`. Here's an example: * {{{ - * implicit class JsonHelper(val sc: StringContext) extends AnyVal { + * implicit class JsonHelper(private val sc: StringContext) extends AnyVal { * def json(args: Any*): JSONObject = ... * } * val x: JSONObject = json"{ a: $a }" diff --git a/src/library/scala/beans/BeanInfo.scala b/src/library/scala/beans/BeanInfo.scala index 799e93e71a..d7f0a1618b 100644 --- a/src/library/scala/beans/BeanInfo.scala +++ b/src/library/scala/beans/BeanInfo.scala @@ -17,4 +17,5 @@ package scala.beans * * @author Ross Judson (rjudson@managedobjects.com) */ +@deprecated(message = "the generation of BeanInfo classes is no longer supported", since = "2.12.0") class BeanInfo extends scala.annotation.Annotation diff --git a/src/library/scala/collection/GenMapLike.scala b/src/library/scala/collection/GenMapLike.scala index 4e7d359251..bce9740522 100644 --- a/src/library/scala/collection/GenMapLike.scala +++ b/src/library/scala/collection/GenMapLike.scala @@ -102,7 +102,7 @@ trait GenMapLike[A, +B, +Repr] extends GenIterableLike[(A, B), Repr] with Equals */ def mapValues[C](f: B => C): GenMap[A, C] - /** Compares two maps structurally; i.e. checks if all mappings + /** Compares two maps structurally; i.e., checks if all mappings * contained in this map are also contained in the other map, * and vice versa. * diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index a8c4e047ab..13cd99d910 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -75,7 +75,7 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { // at least indirectly. Currently, these are `ArrayOps` and `StringOps`. // It is also implemented in `TraversableOnce[A]`. /** A version of this collection with all - * of the operations implemented sequentially (i.e. in a single-threaded manner). + * of the operations implemented sequentially (i.e., in a single-threaded manner). * * This method returns a reference to this collection. In parallel collections, * it is redefined to return a sequential implementation of this collection. In diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index d3ff5e8abf..37a0b373da 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -469,7 +469,7 @@ self => else super.flatMap(f)(bf) /** Returns all the elements of this `Stream` that satisfy the predicate `p` - * in a new `Stream` - i.e. it is still a lazy data structure. The order of + * in a new `Stream` - i.e., it is still a lazy data structure. The order of * the elements is preserved * * @param p the predicate used to filter the stream. diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 8e1d950d00..738b294ce6 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -121,14 +121,14 @@ self => } /** Return all lines in this string in an iterator, excluding trailing line - * end characters, i.e. apply `.stripLineEnd` to all lines + * end characters, i.e., apply `.stripLineEnd` to all lines * returned by `linesWithSeparators`. */ def lines: Iterator[String] = linesWithSeparators map (line => new WrappedString(line).stripLineEnd) /** Return all lines in this string in an iterator, excluding trailing line - * end characters, i.e. apply `.stripLineEnd` to all lines + * end characters, i.e., apply `.stripLineEnd` to all lines * returned by `linesWithSeparators`. */ @deprecated("Use `lines` instead.","2.11.0") diff --git a/src/library/scala/collection/mutable/LongMap.scala b/src/library/scala/collection/mutable/LongMap.scala index 984ae6f7cc..e0aac6574b 100644 --- a/src/library/scala/collection/mutable/LongMap.scala +++ b/src/library/scala/collection/mutable/LongMap.scala @@ -557,7 +557,7 @@ object LongMap { /** Creates a new `LongMap` from keys and values. * Equivalent to but more efficient than `LongMap((keys zip values): _*)`. */ - def fromZip[V](keys: Iterable[Long], values: Iterable[V]): LongMap[V] = { + def fromZip[V](keys: collection.Iterable[Long], values: collection.Iterable[V]): LongMap[V] = { val sz = math.min(keys.size, values.size) val lm = new LongMap[V](sz * 2) val ki = keys.iterator diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 4ed0687334..e93a3284dc 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -102,7 +102,7 @@ trait Future[+T] extends Awaitable[T] { /* Callbacks */ - /** When this future is completed successfully (i.e. with a value), + /** When this future is completed successfully (i.e., with a value), * apply the provided partial function to the value if the partial function * is defined at that value. * @@ -118,7 +118,7 @@ trait Future[+T] extends Awaitable[T] { case _ => } - /** When this future is completed with a failure (i.e. with a throwable), + /** When this future is completed with a failure (i.e., with a throwable), * apply the provided callback to the throwable. * * $caughtThrowables diff --git a/src/library/scala/concurrent/duration/Deadline.scala b/src/library/scala/concurrent/duration/Deadline.scala index 61cbe47530..a25a478602 100644 --- a/src/library/scala/concurrent/duration/Deadline.scala +++ b/src/library/scala/concurrent/duration/Deadline.scala @@ -25,15 +25,15 @@ package scala.concurrent.duration */ case class Deadline private (time: FiniteDuration) extends Ordered[Deadline] { /** - * Return a deadline advanced (i.e. moved into the future) by the given duration. + * Return a deadline advanced (i.e., moved into the future) by the given duration. */ def +(other: FiniteDuration): Deadline = copy(time = time + other) /** - * Return a deadline moved backwards (i.e. towards the past) by the given duration. + * Return a deadline moved backwards (i.e., towards the past) by the given duration. */ def -(other: FiniteDuration): Deadline = copy(time = time - other) /** - * Calculate time difference between this and the other deadline, where the result is directed (i.e. may be negative). + * Calculate time difference between this and the other deadline, where the result is directed (i.e., may be negative). */ def -(other: Deadline): FiniteDuration = time - other.time /** diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala index 74c3e06839..dbd6a5f6f2 100644 --- a/src/library/scala/io/Source.scala +++ b/src/library/scala/io/Source.scala @@ -10,7 +10,7 @@ package scala package io import scala.collection.AbstractIterator -import java.io.{ FileInputStream, InputStream, PrintStream, File => JFile } +import java.io.{ FileInputStream, InputStream, PrintStream, File => JFile, Closeable } import java.net.{ URI, URL } /** This object provides convenience methods to create an iterable @@ -176,7 +176,7 @@ object Source { * @author Burak Emir * @version 1.0 */ -abstract class Source extends Iterator[Char] { +abstract class Source extends Iterator[Char] with Closeable { /** the actual iterator */ protected val iter: Iterator[Char] diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index bcbed645a7..5a81710986 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -617,10 +617,10 @@ extends ScalaNumber with ScalaNumericConversions with Serializable { */ def abs: BigDecimal = if (signum < 0) unary_- else this - /** Returns the sign of this BigDecimal, i.e. + /** Returns the sign of this BigDecimal; * -1 if it is less than 0, - * +1 if it is greater than 0 - * 0 if it is equal to 0 + * +1 if it is greater than 0, + * 0 if it is equal to 0. */ def signum: Int = this.bigDecimal.signum() diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index 689fc0c3e1..abc7371d9f 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -282,10 +282,10 @@ final class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNum */ def abs: BigInt = new BigInt(this.bigInteger.abs()) - /** Returns the sign of this BigInt, i.e. + /** Returns the sign of this BigInt; * -1 if it is less than 0, - * +1 if it is greater than 0 - * 0 if it is equal to 0 + * +1 if it is greater than 0, + * 0 if it is equal to 0. */ def signum: Int = this.bigInteger.signum() diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala index d1a4e7c35c..0d7ea8bce2 100644 --- a/src/library/scala/math/Ordering.scala +++ b/src/library/scala/math/Ordering.scala @@ -26,7 +26,7 @@ import scala.language.{implicitConversions, higherKinds} * val pairs = Array(("a", 5, 2), ("c", 3, 1), ("b", 1, 3)) * * // sort by 2nd element - * Sorting.quickSort(pairs)(Ordering.by[(String, Int, Int), Int](_._2) + * Sorting.quickSort(pairs)(Ordering.by[(String, Int, Int), Int](_._2)) * * // sort by the 3rd element, then 1st * Sorting.quickSort(pairs)(Ordering[(Int, String)].on(x => (x._3, x._1))) diff --git a/src/library/scala/math/PartialOrdering.scala b/src/library/scala/math/PartialOrdering.scala index 9e35381528..8d7fc32535 100644 --- a/src/library/scala/math/PartialOrdering.scala +++ b/src/library/scala/math/PartialOrdering.scala @@ -15,17 +15,24 @@ package math * latter. * * A [[http://en.wikipedia.org/wiki/Partial_order partial ordering]] is a - * binary relation on a type `T` that is also an equivalence relation on - * values of type `T`. This relation is exposed as the `lteq` method of - * the `PartialOrdering` trait. This relation must be: + * binary relation on a type `T`, exposed as the `lteq` method of this trait. + * This relation must be: * * - reflexive: `lteq(x, x) == '''true'''`, for any `x` of type `T`. - * - anti-symmetric: `lteq(x, y) == '''true'''` and `lteq(y, x) == true` - * then `equiv(x, y)`, for any `x` and `y` of type `T`. + * - anti-symmetric: if `lteq(x, y) == '''true'''` and + * `lteq(y, x) == '''true'''` + * then `equiv(x, y) == '''true'''`, for any `x` and `y` of type `T`. * - transitive: if `lteq(x, y) == '''true'''` and * `lteq(y, z) == '''true'''` then `lteq(x, z) == '''true'''`, * for any `x`, `y`, and `z` of type `T`. * + * Additionally, a partial ordering induces an + * [[http://en.wikipedia.org/wiki/Equivalence_relation equivalence relation]] + * on a type `T`: `x` and `y` of type `T` are equivalent if and only if + * `lteq(x, y) && lteq(y, x) == '''true'''`. This equivalence relation is + * exposed as the `equiv` method, inherited from the + * [[scala.math.Equiv Equiv]] trait. + * * @author Geoffrey Washburn * @version 1.0, 2008-04-0-3 * @since 2.7 diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 5fb24f2a36..f50059ce54 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -62,7 +62,7 @@ object ScalaRunTime { } /** Return the class object representing an unboxed value type, - * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler + * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler * rewrites expressions like 5.getClass to come here. */ def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = diff --git a/src/library/scala/sys/Prop.scala b/src/library/scala/sys/Prop.scala index 04c7b5108c..17ae8cb69c 100644 --- a/src/library/scala/sys/Prop.scala +++ b/src/library/scala/sys/Prop.scala @@ -20,7 +20,7 @@ package sys * @since 2.9 */ trait Prop[+T] { - /** The full name of the property, e.g. "java.awt.headless". + /** The full name of the property, e.g., "java.awt.headless". */ def key: String diff --git a/src/library/scala/sys/process/BasicIO.scala b/src/library/scala/sys/process/BasicIO.scala index b31bbf0540..866dac4458 100644 --- a/src/library/scala/sys/process/BasicIO.scala +++ b/src/library/scala/sys/process/BasicIO.scala @@ -221,7 +221,7 @@ object BasicIO { */ def transferFully(in: InputStream, out: OutputStream): Unit = try transferFullyImpl(in, out) - catch onInterrupt(()) + catch onIOInterrupt(()) private[this] def appendLine(buffer: Appendable): String => Unit = line => { buffer append line diff --git a/src/library/scala/sys/process/ProcessImpl.scala b/src/library/scala/sys/process/ProcessImpl.scala index 2b7fcdeb73..d15f1a2b3d 100644 --- a/src/library/scala/sys/process/ProcessImpl.scala +++ b/src/library/scala/sys/process/ProcessImpl.scala @@ -109,45 +109,46 @@ private[process] trait ProcessImpl { } private[process] class PipedProcesses(a: ProcessBuilder, b: ProcessBuilder, defaultIO: ProcessIO, toError: Boolean) extends CompoundProcess { - protected[this] override def runAndExitValue() = { - val currentSource = new SyncVar[Option[InputStream]] - val pipeOut = new PipedOutputStream - val source = new PipeSource(currentSource, pipeOut, a.toString) + protected[this] override def runAndExitValue() = runAndExitValue(new PipeSource(a.toString), new PipeSink(b.toString)) + protected[this] def runAndExitValue(source: PipeSource, sink: PipeSink): Option[Int] = { + source connectOut sink source.start() - - val pipeIn = new PipedInputStream(pipeOut) - val currentSink = new SyncVar[Option[OutputStream]] - val sink = new PipeSink(pipeIn, currentSink, b.toString) sink.start() - def handleOutOrError(fromOutput: InputStream) = currentSource put Some(fromOutput) + /** Release PipeSource, PipeSink and Process in the correct order. + * If once connect Process with Source or Sink, then the order of releasing them + * must be Source -> Sink -> Process, otherwise IOException will be thrown. */ + def releaseResources(so: PipeSource, sk: PipeSink, p: Process *) = { + so.release() + sk.release() + p foreach( _.destroy() ) + } val firstIO = - if (toError) - defaultIO.withError(handleOutOrError) - else - defaultIO.withOutput(handleOutOrError) - val secondIO = defaultIO.withInput(toInput => currentSink put Some(toInput)) - - val second = b.run(secondIO) - val first = a.run(firstIO) - try { - runInterruptible { - val exit1 = first.exitValue() - currentSource put None - currentSink put None - val exit2 = second.exitValue() - // Since file redirection (e.g. #>) is implemented as a piped process, - // we ignore its exit value so cmd #> file doesn't always return 0. - if (b.hasExitValue) exit2 else exit1 - } { - first.destroy() - second.destroy() + if (toError) defaultIO.withError(source.connectIn) + else defaultIO.withOutput(source.connectIn) + val secondIO = defaultIO.withInput(sink.connectOut) + + val second = + try b.run(secondIO) + catch onError { err => + releaseResources(source, sink) + throw err } - } - finally { - BasicIO close pipeIn - BasicIO close pipeOut + val first = + try a.run(firstIO) + catch onError { err => + releaseResources(source, sink, second) + throw err + } + runInterruptible { + val exit1 = first.exitValue() + val exit2 = second.exitValue() + // Since file redirection (e.g. #>) is implemented as a piped process, + // we ignore its exit value so cmd #> file doesn't always return 0. + if (b.hasExitValue) exit2 else exit1 + } { + releaseResources(source, sink, first, second) } } } @@ -168,37 +169,46 @@ private[process] trait ProcessImpl { } } - private[process] class PipeSource( - currentSource: SyncVar[Option[InputStream]], - pipe: PipedOutputStream, - label: => String - ) extends PipeThread(false, () => label) { - - final override def run(): Unit = currentSource.get match { - case Some(source) => - try runloop(source, pipe) - finally currentSource.unset() - - run() - case None => - currentSource.unset() - BasicIO close pipe + private[process] class PipeSource(label: => String) extends PipeThread(false, () => label) { + protected[this] val pipe = new PipedOutputStream + protected[this] val source = new LinkedBlockingQueue[Option[InputStream]] + override def run(): Unit = { + try { + source.take match { + case Some(in) => runloop(in, pipe) + case None => + } + } + catch onInterrupt(()) + finally BasicIO close pipe + } + def connectIn(in: InputStream): Unit = source add Some(in) + def connectOut(sink: PipeSink): Unit = sink connectIn pipe + def release(): Unit = { + interrupt() + source add None + join() } } - private[process] class PipeSink( - pipe: PipedInputStream, - currentSink: SyncVar[Option[OutputStream]], - label: => String - ) extends PipeThread(true, () => label) { - - final override def run(): Unit = currentSink.get match { - case Some(sink) => - try runloop(pipe, sink) - finally currentSink.unset() - - run() - case None => - currentSink.unset() + private[process] class PipeSink(label: => String) extends PipeThread(true, () => label) { + protected[this] val pipe = new PipedInputStream + protected[this] val sink = new LinkedBlockingQueue[Option[OutputStream]] + override def run(): Unit = { + try { + sink.take match { + case Some(out) => runloop(pipe, out) + case None => + } + } + catch onInterrupt(()) + finally BasicIO close pipe + } + def connectOut(out: OutputStream): Unit = sink add Some(out) + def connectIn(pipeOut: PipedOutputStream): Unit = pipe connect pipeOut + def release(): Unit = { + interrupt() + sink add None + join() } } diff --git a/src/library/scala/sys/process/package.scala b/src/library/scala/sys/process/package.scala index 1340a6c415..91fa99e3df 100644 --- a/src/library/scala/sys/process/package.scala +++ b/src/library/scala/sys/process/package.scala @@ -224,16 +224,26 @@ package scala.sys { final val processDebug = props contains "scala.process.debug" dbg("Initializing process package.") - type =?>[-A, +B] = PartialFunction[A, B] - type Closeable = java.io.Closeable - type File = java.io.File - type IOException = java.io.IOException - type InputStream = java.io.InputStream - type JProcess = java.lang.Process - type JProcessBuilder = java.lang.ProcessBuilder - type OutputStream = java.io.OutputStream - type SyncVar[T] = scala.concurrent.SyncVar[T] - type URL = java.net.URL + type =?>[-A, +B] = PartialFunction[A, B] + type Closeable = java.io.Closeable + type File = java.io.File + type IOException = java.io.IOException + type InterruptedIOException = java.io.InterruptedIOException + type InputStream = java.io.InputStream + type JProcess = java.lang.Process + type JProcessBuilder = java.lang.ProcessBuilder + type LinkedBlockingQueue[T] = java.util.concurrent.LinkedBlockingQueue[T] + type OutputStream = java.io.OutputStream + type SyncVar[T] = scala.concurrent.SyncVar[T] + type URL = java.net.URL + + def onError[T](handler: Throwable => T): Throwable =?> T = { + case e @ _ => handler(e) + } + + def onIOInterrupt[T](handler: => T): Throwable =?> T = { + case _: InterruptedIOException => handler + } def onInterrupt[T](handler: => T): Throwable =?> T = { case _: InterruptedException => handler diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index 2daa4de9a6..8835730d95 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -107,7 +107,7 @@ private[scala] trait PropertiesTrait { val versionString = "version " + scalaPropOrElse("version.number", "(unknown)") val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2013, LAMP/EPFL") - /** This is the encoding to use reading in source files, overridden with -encoding + /** This is the encoding to use reading in source files, overridden with -encoding. * Note that it uses "prop" i.e. looks in the scala jar, not the system properties. */ def sourceEncoding = scalaPropOrElse("file.encoding", "UTF-8") diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala index 2ea3a0eb7c..4b40d25c17 100644 --- a/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala @@ -11,6 +11,7 @@ import reporters.Reporter import typechecker.Analyzer import scala.reflect.internal.util.{ BatchSourceFile, RangePosition } + trait ScaladocGlobalTrait extends Global { outer => diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala index a8e1dee4a0..44683f1755 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Settings.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala @@ -66,7 +66,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) val docsourceurl = StringSetting ( "-doc-source-url", "url", - "A URL pattern used to build links to template sources; use variables, for example: ?{TPL_NAME} ('Seq'), ?{TPL_OWNER} ('scala.collection'), ?{FILE_PATH} ('scala/collection/Seq')", + s"A URL pattern used to link to the source file; the following variables are available: €{TPL_NAME}, €{TPL_OWNER} and respectively €{FILE_PATH}. For example, for `scala.collection.Seq`, the variables will be expanded to `Seq`, `scala.collection` and respectively `scala/collection/Seq` (without the backquotes). To obtain a relative path for €{FILE_PATH} instead of an absolute one, use the ${sourcepath.name} setting.", "" ) diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala index 19cc27b40b..d5e2f9a2c4 100755 --- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala @@ -131,18 +131,19 @@ trait CommentFactoryBase { this: MemberLookupBase => /** Javadoc tags that should be replaced by something useful, such as wiki * syntax, or that should be dropped. */ private val JavadocTags = - new Regex("""\{\@(code|docRoot|inheritDoc|link|linkplain|literal|value)([^}]*)\}""") + new Regex("""\{\@(code|docRoot|linkplain|link|literal|value)\p{Zs}*([^}]*)\}""") /** Maps a javadoc tag to a useful wiki replacement, or an empty string if it cannot be salvaged. */ - private def javadocReplacement(mtch: Regex.Match): String = mtch.group(1) match { - case "code" => "`" + mtch.group(2) + "`" - case "docRoot" => "" - case "inheritDoc" => "" - case "link" => "`" + mtch.group(2) + "`" - case "linkplain" => "`" + mtch.group(2) + "`" - case "literal" => mtch.group(2) - case "value" => "`" + mtch.group(2) + "`" - case _ => "" + private def javadocReplacement(mtch: Regex.Match): String = { + mtch.group(1) match { + case "code" => "<code>" + mtch.group(2) + "</code>" + case "docRoot" => "" + case "link" => "`[[" + mtch.group(2) + "]]`" + case "linkplain" => "[[" + mtch.group(2) + "]]" + case "literal" => "`" + mtch.group(2) + "`" + case "value" => "`" + mtch.group(2) + "`" + case _ => "" + } } /** Safe HTML tags that can be kept. */ @@ -680,7 +681,6 @@ trait CommentFactoryBase { this: MemberLookupBase => jump("[[") val parens = 2 + repeatJump('[') val stop = "]" * parens - //println("link with " + parens + " matching parens") val target = readUntil { check(stop) || check(" ") } val title = if (!check(stop)) Some({ diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala index b5a8d1ac36..45cef88f7a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala @@ -143,7 +143,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else { if (!tpl.linearizationTemplates.isEmpty) - <div id="ancestors"> + <div class="ancestors"> <span class="filtertype">Inherited<br/> </span> <ol id="linearization"> @@ -153,7 +153,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp else NodeSeq.Empty } ++ { if (!tpl.conversions.isEmpty) - <div id="ancestors"> + <div class="ancestors"> <span class="filtertype">Implicitly<br/> </span> <ol id="implicits"> { @@ -167,7 +167,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp </div> else NodeSeq.Empty } ++ - <div id="ancestors"> + <div class="ancestors"> <span class="filtertype"></span> <ol> <li class="hideall out"><span>Hide All</span></li> @@ -201,28 +201,28 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp } { if (absValueMembers.isEmpty) NodeSeq.Empty else - <div id="values" class="values members"> + <div class="values members"> <h3>Abstract Value Members</h3> <ol>{ absValueMembers map (memberToHtml(_, tpl)) }</ol> </div> } { if (concValueMembers.isEmpty) NodeSeq.Empty else - <div id="values" class="values members"> + <div class="values members"> <h3>{ if (absValueMembers.isEmpty) "Value Members" else "Concrete Value Members" }</h3> <ol>{ concValueMembers map (memberToHtml(_, tpl)) }</ol> </div> } { if (shadowedImplicitMembers.isEmpty) NodeSeq.Empty else - <div id="values" class="values members"> + <div class="values members"> <h3>Shadowed Implicit Value Members</h3> <ol>{ shadowedImplicitMembers map (memberToHtml(_, tpl)) }</ol> </div> } { if (deprValueMembers.isEmpty) NodeSeq.Empty else - <div id="values" class="values members"> + <div class="values members"> <h3>Deprecated Value Members</h3> <ol>{ deprValueMembers map (memberToHtml(_, tpl)) }</ol> </div> @@ -287,13 +287,19 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp } def memberToHtml(mbr: MemberEntity, inTpl: DocTemplateEntity): NodeSeq = { + // Sometimes it's same, do we need signatureCompat still? + val sig = if (mbr.signature == mbr.signatureCompat) { + <a id={ mbr.signature }/> + } else { + <a id={ mbr.signature }/><a id={ mbr.signatureCompat }/> + } + val memberComment = memberToCommentHtml(mbr, inTpl, isSelf = false) <li name={ mbr.definitionName } visbl={ if (mbr.visibility.isProtected) "prt" else "pub" } data-isabs={ mbr.isAbstract.toString } fullComment={ if(memberComment.filter(_.label=="div").isEmpty) "no" else "yes" } group={ mbr.group }> - <a id={ mbr.signature }/> - <a id={ mbr.signatureCompat }/> + { sig } { signature(mbr, isSelf = false) } { memberComment } </li> diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css index 35f66cd5df..6d94452f3a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css @@ -217,7 +217,7 @@ dl.attributes > dd { height: 18px; } -#values ol li:last-child { +.values ol li:last-child { margin-bottom: 5px; } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js index 1ebcb67f04..5ef03848b2 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js @@ -147,19 +147,19 @@ $(document).ready(function(){ filter(); }); - $("#mbrsel > div[id=ancestors] > ol > li.hideall").click(function() { + $("#mbrsel > div.ancestors > ol > li.hideall").click(function() { $("#linearization li.in").removeClass("in").addClass("out"); $("#linearization li:first").removeClass("out").addClass("in"); $("#implicits li.in").removeClass("in").addClass("out"); - if ($(this).hasClass("out") && $("#mbrsel > div[id=ancestors] > ol > li.showall").hasClass("in")) { + if ($(this).hasClass("out") && $("#mbrsel > div.ancestors > ol > li.showall").hasClass("in")) { $(this).removeClass("out").addClass("in"); - $("#mbrsel > div[id=ancestors] > ol > li.showall").removeClass("in").addClass("out"); + $("#mbrsel > div.ancestors > ol > li.showall").removeClass("in").addClass("out"); } filter(); }) - $("#mbrsel > div[id=ancestors] > ol > li.showall").click(function() { + $("#mbrsel > div.ancestors > ol > li.showall").click(function() { var filteredLinearization = $("#linearization li.out").filter(function() { return ! isHiddenClass($(this).attr("name")); @@ -172,9 +172,9 @@ $(document).ready(function(){ }); filteredImplicits.removeClass("out").addClass("in"); - if ($(this).hasClass("out") && $("#mbrsel > div[id=ancestors] > ol > li.hideall").hasClass("in")) { + if ($(this).hasClass("out") && $("#mbrsel > div.ancestors > ol > li.hideall").hasClass("in")) { $(this).removeClass("out").addClass("in"); - $("#mbrsel > div[id=ancestors] > ol > li.hideall").removeClass("in").addClass("out"); + $("#mbrsel > div.ancestors > ol > li.hideall").removeClass("in").addClass("out"); } filter(); @@ -275,7 +275,7 @@ function orderAlpha() { $("#order > ol > li.group").removeClass("in").addClass("out"); $("#template > div.parent").hide(); $("#template > div.conversion").hide(); - $("#mbrsel > div[id=ancestors]").show(); + $("#mbrsel > div.ancestors").show(); filter(); }; @@ -285,7 +285,7 @@ function orderInherit() { $("#order > ol > li.group").removeClass("in").addClass("out"); $("#template > div.parent").show(); $("#template > div.conversion").show(); - $("#mbrsel > div[id=ancestors]").hide(); + $("#mbrsel > div.ancestors").hide(); filter(); }; @@ -295,7 +295,7 @@ function orderGroup() { $("#order > ol > li.inherit").removeClass("in").addClass("out"); $("#template > div.parent").hide(); $("#template > div.conversion").hide(); - $("#mbrsel > div[id=ancestors]").show(); + $("#mbrsel > div.ancestors").show(); filter(); }; @@ -350,7 +350,7 @@ function initInherit() { } }); - $("#values > ol > li").each(function(){ + $(".values > ol > li").each(function(){ var mbr = $(this); this.mbrText = mbr.find("> .fullcomment .cmt").text(); var qualName = mbr.attr("name"); |