diff options
49 files changed, 557 insertions, 213 deletions
diff --git a/build.number b/build.number index 21ce660958..142ae5027d 100644 --- a/build.number +++ b/build.number @@ -1,7 +1,7 @@ #Tue Sep 11 19:21:09 CEST 2007 version.major=2 -version.minor=11 -version.patch=3 +version.minor=12 +version.patch=0 # This is the -N part of a version. if it's 0, it's dropped from maven versions. version.bnum=0 @@ -1537,8 +1537,9 @@ TODO: <target name="test.bc-opt" description="Optimized version of test.bc."> <optimized name="test.bc"/></target> <target name="test.bc" depends="bc.prepare, pack.lib, pack.reflect" unless="test.bc.skip"> - <bc.check project="library"/> - <bc.check project="reflect"/> + <echo message="binary compatibility testing disabled in the 2.12.x branch"/> + <!-- <bc.check project="library"/> --> + <!-- <bc.check project="reflect"/> --> </target> <!-- =========================================================================== 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/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index bedca88974..aafe73d88d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -84,24 +84,6 @@ trait SyntheticMethods extends ast.TreeDSL { def accessors = clazz.caseFieldAccessors val arity = accessors.size - // If this is ProductN[T1, T2, ...], accessorLub is the lub of T1, T2, ..., . - // !!! Hidden behind -Xexperimental due to bummer type inference bugs. - // Refining from Iterator[Any] leads to types like - // - // Option[Int] { def productIterator: Iterator[String] } - // - // appearing legitimately, but this breaks invariant places - // like Tags and Arrays which are not robust and infer things - // which they shouldn't. - val accessorLub = ( - if (settings.Xexperimental) { - global.lub(accessors map (_.tpe.finalResultType)) match { - case RefinedType(parents, decls) if !decls.isEmpty => intersectionType(parents) - case tp => tp - } - } - else AnyTpe - ) def forwardToRuntime(method: Symbol): Tree = forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_")))(mkThis :: _) @@ -122,8 +104,8 @@ trait SyntheticMethods extends ast.TreeDSL { } } def productIteratorMethod = { - createMethod(nme.productIterator, iteratorOfType(accessorLub))(_ => - gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(mkThis)) + createMethod(nme.productIterator, iteratorOfType(AnyTpe))(_ => + gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(AnyTpe), List(mkThis)) ) } @@ -243,7 +225,7 @@ trait SyntheticMethods extends ast.TreeDSL { List( Product_productPrefix -> (() => constantNullary(nme.productPrefix, clazz.name.decode)), Product_productArity -> (() => constantNullary(nme.productArity, arity)), - Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(mkThisSelect)), + Product_productElement -> (() => perElementMethod(nme.productElement, AnyTpe)(mkThisSelect)), Product_iterator -> (() => productIteratorMethod), Product_canEqual -> (() => canEqualMethod) // This is disabled pending a reimplementation which doesn't add any diff --git a/src/eclipse/partest/.classpath b/src/eclipse/partest/.classpath index 7f28868d95..7e2f119193 100644 --- a/src/eclipse/partest/.classpath +++ b/src/eclipse/partest/.classpath @@ -5,7 +5,7 @@ <classpathentry combineaccessrules="false" kind="src" path="/repl"/> <classpathentry kind="var" path="M2_REPO/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar"/> <classpathentry kind="var" path="M2_REPO/org/scala-sbt/test-interface/1.0/test-interface-1.0.jar"/> - <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11.0-M7/1.0.0-RC8/scala-partest_2.11.0-M7-1.0.0-RC8.jar"/> + <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11/1.0.0/scala-partest_2.11-1.0.0.jar"/> <classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> diff --git a/src/eclipse/repl/.classpath b/src/eclipse/repl/.classpath index 8ff9aabfbf..cbaabb9af1 100644 --- a/src/eclipse/repl/.classpath +++ b/src/eclipse/repl/.classpath @@ -3,7 +3,6 @@ <classpathentry kind="src" path="repl"/> <classpathentry combineaccessrules="false" kind="src" path="/asm"/> <classpathentry kind="var" path="M2_REPO/jline/jline/2.12/jline-2.12.jar"/> - <!-- <classpathentry kind="var" path="SCALA_BASEDIR/build/deps/repl/jline-2.12.jar"/> --> <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> diff --git a/src/eclipse/scaladoc/.classpath b/src/eclipse/scaladoc/.classpath index c8f0e89b8a..ee6427176a 100644 --- a/src/eclipse/scaladoc/.classpath +++ b/src/eclipse/scaladoc/.classpath @@ -6,8 +6,8 @@ <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> <classpathentry combineaccessrules="false" kind="src" path="/partest-extras"/> - <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-xml_2.11.0-M7/1.0.0-RC7/scala-xml_2.11.0-M7-1.0.0-RC7.jar"/> - <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-parser-combinators_2.11.0-M7/1.0.0-RC5/scala-parser-combinators_2.11.0-M7-1.0.0-RC5.jar"/> - <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11.0-M7/1.0.0-RC8/scala-partest_2.11.0-M7-1.0.0-RC8.jar"/> + <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-xml_2.11/1.0.2/scala-xml_2.11-1.0.2.jar"/> + <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-parser-combinators_2.11/1.0.1/scala-parser-combinators_2.11-1.0.1.jar"/> + <classpathentry kind="var" path="M2_REPO/org/scala-lang/modules/scala-partest_2.11/1.0.0/scala-partest_2.11-1.0.0.jar"/> <classpathentry kind="output" path="build-quick-scaladoc"/> </classpath> diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 174254d523..fdedaa600c 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -19,6 +19,8 @@ import scala.annotation.{ elidable, tailrec } import scala.language.implicitConversions import scala.tools.nsc.typechecker.Typers import scala.util.control.Breaks._ +import java.util.concurrent.ConcurrentHashMap +import scala.collection.JavaConverters.mapAsScalaMapConverter /** * This trait allows the IDE to have an instance of the PC that @@ -160,19 +162,18 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") /** A map of all loaded files to the rich compilation units that correspond to them. */ - val unitOfFile = new LinkedHashMap[AbstractFile, RichCompilationUnit] with - SynchronizedMap[AbstractFile, RichCompilationUnit] { + val unitOfFile = mapAsScalaMapConverter(new ConcurrentHashMap[AbstractFile, RichCompilationUnit] { override def put(key: AbstractFile, value: RichCompilationUnit) = { val r = super.put(key, value) - if (r.isEmpty) debugLog("added unit for "+key) + if (r == null) debugLog("added unit for "+key) r } - override def remove(key: AbstractFile) = { + override def remove(key: Any) = { val r = super.remove(key) - if (r.nonEmpty) debugLog("removed unit for "+key) + if (r != null) debugLog("removed unit for "+key) r } - } + }).asScala /** A set containing all those files that need to be removed * Units are removed by getUnit, typically once a unit is finished compiled. @@ -1091,7 +1092,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") val implicitlyAdded = viaView != NoSymbol members.add(sym, pre, implicitlyAdded) { (s, st) => new TypeMember(s, st, - context.isAccessible(if (s.hasGetter) s.getter(s.owner) else s, pre, superAccess && !implicitlyAdded), + context.isAccessible(if (s.hasGetter) s.getterIn(s.owner) else s, pre, superAccess && !implicitlyAdded), inherited, viaView) } diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index fba759eb32..98dd35d306 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -161,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 7f717aa6e4..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 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/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index aa9dec2761..a8f1149615 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -13,7 +13,7 @@ package immutable import generic._ import mutable.{Builder, ListBuffer} import scala.annotation.tailrec -import java.io._ +import java.io.{ObjectOutputStream, ObjectInputStream} /** A class for immutable linked lists representing ordered collections * of elements of type. @@ -85,7 +85,7 @@ sealed abstract class List[+A] extends AbstractSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]] - with Serializable { + with scala.Serializable { override def companion: GenericCompanion[List] = List import scala.collection.{Iterable, Traversable, Seq, IndexedSeq} diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index 3a64820be6..fb9f6703a9 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -12,7 +12,7 @@ package scala package collection package immutable -import java.io._ +import java.io.{File, FileReader, Reader} import scala.util.matching.Regex import scala.reflect.ClassTag diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index 5e838d0d88..d6a4d92139 100644 --- a/src/library/scala/collection/mutable/ListBuffer.scala +++ b/src/library/scala/collection/mutable/ListBuffer.scala @@ -12,7 +12,7 @@ package mutable import generic._ import immutable.{List, Nil, ::} -import java.io._ +import java.io.{ObjectOutputStream, ObjectInputStream} import scala.annotation.migration /** A `Buffer` implementation back up by a list. It provides constant time diff --git a/src/library/scala/collection/mutable/LongMap.scala b/src/library/scala/collection/mutable/LongMap.scala index ef488a3697..4c24c036f9 100644 --- a/src/library/scala/collection/mutable/LongMap.scala +++ b/src/library/scala/collection/mutable/LongMap.scala @@ -541,7 +541,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/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/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/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala index cc217d2f80..f853df0484 100755 --- a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala @@ -62,15 +62,15 @@ trait MemberLookupBase { syms.flatMap { case (sym, owner) => // reconstruct the original link def linkName(sym: Symbol) = { - def nameString(s: Symbol) = s.nameString + (if ((s.isModule || s.isModuleClass) && !s.isPackage) "$" else "") - val packageSuffix = if (sym.isPackage) ".package" else "" + def nameString(s: Symbol) = s.nameString + (if ((s.isModule || s.isModuleClass) && !s.hasPackageFlag) "$" else "") + val packageSuffix = if (sym.hasPackageFlag) ".package" else "" sym.ownerChain.reverse.filterNot(isRoot(_)).map(nameString(_)).mkString(".") + packageSuffix } - if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage) + if (sym.isClass || sym.isModule || sym.isTrait || sym.hasPackageFlag) findExternalLink(sym, linkName(sym)) - else if (owner.isClass || owner.isModule || owner.isTrait || owner.isPackage) + else if (owner.isClass || owner.isModule || owner.isTrait || owner.hasPackageFlag) findExternalLink(sym, linkName(owner) + "@" + externalSignature(sym)) else None 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/page/diagram/DotDiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala index 4ff436bdc6..dc823ab1e5 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala @@ -364,7 +364,7 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator { // add an id and class attribute to the SVG element case Elem(prefix, "svg", attribs, scope, child @ _*) => { val klass = if (isInheritanceDiagram) "class-diagram" else "package-diagram" - Elem(prefix, "svg", attribs, scope, child map(x => transform(x)) : _*) % + Elem(prefix, "svg", attribs, scope, true, child map(x => transform(x)) : _*) % new UnprefixedAttribute("id", "graph" + counter, Null) % new UnprefixedAttribute("class", klass, Null) } @@ -378,7 +378,7 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator { // assign id and class attributes to edges and nodes: // the id attribute generated by dot has the format: "{class}|{id}" case g @ Elem(prefix, "g", attribs, scope, children @ _*) if (List("edge", "node").contains((g \ "@class").toString)) => { - var res = new Elem(prefix, "g", attribs, scope, (children map(x => transform(x))): _*) + var res = new Elem(prefix, "g", attribs, scope, true, (children map(x => transform(x))): _*) val dotId = (g \ "@id").toString if (dotId.count(_ == '|') == 1) { val Array(klass, id) = dotId.toString.split("\\|") @@ -395,11 +395,11 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator { val imageNode = <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href={ ("./lib/" + kind + "_diagram.png") } width="16px" height="16px" preserveAspectRatio="xMinYMin meet" x={ xposition.get.toString } y={ yposition.get.toString }/> val anchorNode = (g \ "a") match { case Seq(Elem(prefix, "a", attribs, scope, children @ _*)) => - transform(new Elem(prefix, "a", attribs, scope, (children ++ imageNode): _*)) + transform(new Elem(prefix, "a", attribs, scope, true, (children ++ imageNode): _*)) case _ => g \ "a" } - res = new Elem(prefix, "g", attribs, scope, anchorNode: _*) + res = new Elem(prefix, "g", attribs, scope, true, anchorNode: _*) DiagramStats.addFixedImage() } } @@ -413,7 +413,7 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator { scala.xml.Text("") // apply recursively case Elem(prefix, label, attribs, scope, child @ _*) => - Elem(prefix, label, attribs, scope, child map(x => transform(x)) : _*) + Elem(prefix, label, attribs, scope, true, child map(x => transform(x)) : _*) case x => x } 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"); diff --git a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala index 64eb1adbea..20aaab29fc 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala @@ -40,7 +40,7 @@ trait MemberLookup extends base.MemberLookupBase { override def findExternalLink(sym: Symbol, name: String): Option[LinkToExternal] = { val sym1 = if (sym == AnyClass || sym == AnyRefClass || sym == AnyValClass || sym == NothingClass) ListClass - else if (sym.isPackage) + else if (sym.hasPackageFlag) /* Get package object which has associatedFile ne null */ sym.info.member(newTermName("package")) else sym diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala index ef84ac42ba..2993c4c4b9 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala @@ -89,10 +89,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { trait TemplateImpl extends EntityImpl with TemplateEntity { override def qualifiedName: String = if (inTemplate == null || inTemplate.isRootPackage) name else optimize(inTemplate.qualifiedName + "." + name) - def isPackage = sym.isPackage + def isPackage = sym.hasPackageFlag def isTrait = sym.isTrait def isClass = sym.isClass && !sym.isTrait - def isObject = sym.isModule && !sym.isPackage + def isObject = sym.isModule && !sym.hasPackageFlag def isCaseClass = sym.isCaseClass def isRootPackage = false def selfType = if (sym.thisSym eq sym) None else Some(makeType(sym.thisSym.typeOfThis, this)) @@ -250,7 +250,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def valueParams: List[List[ValueParam]] = Nil /** TODO, these are now only computed for DocTemplates */ def parentTypes = - if (sym.isPackage || sym == AnyClass) List() else { + if (sym.hasPackageFlag || sym == AnyClass) List() else { val tps = (this match { case a: AliasType => sym.tpe.dealias.parents case a: AbstractType => sym.info.bounds match { @@ -661,7 +661,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { s != EmptyPackage && s != RootPackage } }) - else if (bSym.isPackage) // (2) + else if (bSym.hasPackageFlag) // (2) if (settings.skipPackage(makeQualifiedName(bSym))) None else @@ -772,7 +772,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { Some(new MemberTemplateImpl(bSym, inTpl) with AliasImpl with AliasType { override def isAliasType = true }) - else if (!modelFinished && (bSym.isPackage || templateShouldDocument(bSym, inTpl))) + else if (!modelFinished && (bSym.hasPackageFlag || templateShouldDocument(bSym, inTpl))) modelCreation.createTemplate(bSym, inTpl) else None diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala index 2b7e2506d4..ea72fa6095 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala @@ -94,7 +94,7 @@ trait ModelFactoryTypeSupport { LinkToMember(bMbr, oTpl) case _ => val name = makeQualifiedName(bSym) - if (!bSym.owner.isPackage) + if (!bSym.owner.hasPackageFlag) Tooltip(name) else findExternalLink(bSym, name).getOrElse ( diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala index 86a7a67160..c1228e8735 100755 --- a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala @@ -49,7 +49,7 @@ trait TreeFactory { thisTreeFactory: ModelFactory with TreeFactory => case _ => } else if (asym.isTerm && asym.owner.isClass){ - if (asym.isSetter) asym = asym.getter(asym.owner) + if (asym.isSetter) asym = asym.getterIn(asym.owner) makeTemplate(asym.owner) match { case docTmpl: DocTemplateImpl => val mbrs: Option[MemberImpl] = findMember(asym, docTmpl) diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala index 44d8886e4e..bcb97639c6 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala @@ -177,7 +177,7 @@ trait DiagramDirectiveParser { def warning(message: String) = { // we need the position from the package object (well, ideally its comment, but yeah ...) - val sym = if (template.sym.isPackage) template.sym.info.member(global.nme.PACKAGE) else template.sym + val sym = if (template.sym.hasPackageFlag) template.sym.info.member(global.nme.PACKAGE) else template.sym assert((sym != global.NoSymbol) || (sym == global.rootMirror.RootPackage)) global.reporter.warning(sym.pos, message) } diff --git a/test/files/jvm/t8582.check b/test/files/jvm/t8582.check index 564f482ff8..1d19f1d6a8 100644 --- a/test/files/jvm/t8582.check +++ b/test/files/jvm/t8582.check @@ -1,3 +1,6 @@ +t8582.scala:17: warning: class BeanInfo in package beans is deprecated: the generation of BeanInfo classes is no longer supported + class C1 + ^ getClass on module gives module class class p1.p2.Singleton$Singleton$ diff --git a/test/files/jvm/t8582.flags b/test/files/jvm/t8582.flags new file mode 100644 index 0000000000..dcc59ebe32 --- /dev/null +++ b/test/files/jvm/t8582.flags @@ -0,0 +1 @@ +-deprecation diff --git a/test/files/neg/beanInfoDeprecation.check b/test/files/neg/beanInfoDeprecation.check new file mode 100644 index 0000000000..788b277818 --- /dev/null +++ b/test/files/neg/beanInfoDeprecation.check @@ -0,0 +1,6 @@ +beanInfoDeprecation.scala:2: warning: class BeanInfo in package beans is deprecated: the generation of BeanInfo classes is no longer supported +class C + ^ +error: No warnings can be incurred under -Xfatal-warnings. +one warning found +one error found diff --git a/test/files/neg/beanInfoDeprecation.flags b/test/files/neg/beanInfoDeprecation.flags new file mode 100644 index 0000000000..c6bfaf1f64 --- /dev/null +++ b/test/files/neg/beanInfoDeprecation.flags @@ -0,0 +1 @@ +-deprecation -Xfatal-warnings diff --git a/test/files/neg/beanInfoDeprecation.scala b/test/files/neg/beanInfoDeprecation.scala new file mode 100644 index 0000000000..c7e3a86202 --- /dev/null +++ b/test/files/neg/beanInfoDeprecation.scala @@ -0,0 +1,2 @@ +@scala.beans.BeanInfo +class C diff --git a/test/files/neg/t8764.check b/test/files/neg/t8764.check deleted file mode 100644 index 6d89ebe106..0000000000 --- a/test/files/neg/t8764.check +++ /dev/null @@ -1,6 +0,0 @@ -t8764.scala:8: error: type mismatch; - found : AnyVal - required: Double - val d: Double = a.productElement(0) - ^ -one error found diff --git a/test/files/neg/t8764.flags b/test/files/neg/t8764.flags deleted file mode 100644 index 48fd867160..0000000000 --- a/test/files/neg/t8764.flags +++ /dev/null @@ -1 +0,0 @@ --Xexperimental diff --git a/test/files/neg/t8764.scala b/test/files/neg/t8764.scala deleted file mode 100644 index dc5bfb0160..0000000000 --- a/test/files/neg/t8764.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Main { - - case class IntAndDouble(i: Int, d: Double) - - // a.productElement used to be Int => Double - // now: Int => AnyVal - val a = IntAndDouble(1, 5.0) - val d: Double = a.productElement(0) -} diff --git a/test/files/run/lub-visibility.check b/test/files/run/lub-visibility.check index 70734966f0..135cb3cb76 100644 --- a/test/files/run/lub-visibility.check +++ b/test/files/run/lub-visibility.check @@ -6,6 +6,6 @@ scala> // should infer List[scala.collection.immutable.Seq[Nothing]] scala> // but reverted that for SI-5534. scala> val x = List(List(), Vector()) -x: List[scala.collection.immutable.Seq[Nothing] with scala.collection.AbstractSeq[Nothing] with java.io.Serializable] = List(List(), Vector()) +x: List[scala.collection.immutable.Seq[Nothing] with scala.collection.AbstractSeq[Nothing] with Serializable] = List(List(), Vector()) scala> :quit diff --git a/test/files/run/t2251b.check b/test/files/run/t2251b.check index 4231fc6ea6..b60698d605 100644 --- a/test/files/run/t2251b.check +++ b/test/files/run/t2251b.check @@ -1,4 +1,4 @@ -TypeTag[List[scala.collection.immutable.LinearSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with scala.collection.AbstractSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with java.io.Serializable]] +TypeTag[List[scala.collection.immutable.LinearSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with scala.collection.AbstractSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with Serializable]] TypeTag[List[scala.collection.immutable.Iterable[B[_ >: F with E with D with C <: B[_ >: F with E with D with C <: A]]] with F with Int => Any]] TypeTag[List[scala.collection.immutable.Seq[B[_ >: D with C <: B[_ >: D with C <: A]]] with scala.collection.AbstractSeq[B[_ >: D with C <: B[_ >: D with C <: A]]] with Serializable]] TypeTag[List[scala.collection.Set[_ >: G with F <: B[_ >: G with F <: B[_ >: G with F <: A]]]]] @@ -6,6 +6,6 @@ TypeTag[List[scala.collection.Set[_ >: G with F <: B[_ >: G with F <: B[_ >: G w TypeTag[List[scala.collection.Set[_ >: G with F <: B[_ >: G with F <: B[_ >: G with F <: A]]]]] TypeTag[List[Seq[B[_ >: G with F <: B[_ >: G with F <: A]]]]] TypeTag[List[scala.collection.Map[_ >: F with C <: B[_ >: F with C <: B[_ >: F with C <: A]], B[_ >: G with D <: B[_ >: G with D <: A]]]]] -TypeTag[List[scala.collection.AbstractSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with scala.collection.LinearSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with java.io.Serializable]] +TypeTag[List[scala.collection.AbstractSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with scala.collection.LinearSeq[B[_ >: G with F <: B[_ >: G with F <: A]]] with Serializable]] TypeTag[List[Seq[B[_ >: G with F <: B[_ >: G with F <: A]]]]] TypeTag[List[Seq[B[_ >: G with F <: B[_ >: G with F <: A]]]]] diff --git a/test/files/run/t8710.scala b/test/files/run/t8710.scala new file mode 100644 index 0000000000..15aab5b8a4 --- /dev/null +++ b/test/files/run/t8710.scala @@ -0,0 +1,17 @@ +class Bar(val x: Int) extends AnyVal { + def f: String = f(0) + private def f(x: Int): String = "" +} + +class Baz(val x: Int) extends AnyVal { + def f: String = "123" + private def f(x: Int): String = "" +} +object Baz { + def x(b: Baz) = b.f(0) +} + +object Test extends App { + new Bar(23).f + new Baz(23).f +} diff --git a/test/files/run/t8764.check b/test/files/run/t8764.check deleted file mode 100644 index 6260069602..0000000000 --- a/test/files/run/t8764.check +++ /dev/null @@ -1,5 +0,0 @@ -IntOnly: should return an unboxed int -Int: int -IntAndDouble: should just box and return Anyval -Double: class java.lang.Double -Int: class java.lang.Integer diff --git a/test/files/run/t8764.flags b/test/files/run/t8764.flags deleted file mode 100644 index 48fd867160..0000000000 --- a/test/files/run/t8764.flags +++ /dev/null @@ -1 +0,0 @@ --Xexperimental diff --git a/test/files/run/t8764.scala b/test/files/run/t8764.scala deleted file mode 100644 index decc658f6e..0000000000 --- a/test/files/run/t8764.scala +++ /dev/null @@ -1,16 +0,0 @@ -object Test extends App { -case class IntOnly(i: Int, j: Int) - -println("IntOnly: should return an unboxed int") -val a = IntOnly(1, 2) -val i: Int = a.productElement(0) -println(s"Int: ${a.productElement(0).getClass}") - -case class IntAndDouble(i: Int, d: Double) - -println("IntAndDouble: should just box and return Anyval") -val b = IntAndDouble(1, 2.0) -val j: AnyVal = b.productElement(0) -println(s"Double: ${b.productElement(1).getClass}") -println(s"Int: ${b.productElement(0).getClass}") -} diff --git a/test/junit/scala/sys/process/t7350.scala b/test/junit/scala/sys/process/t7350.scala new file mode 100644 index 0000000000..7f3e8897f2 --- /dev/null +++ b/test/junit/scala/sys/process/t7350.scala @@ -0,0 +1,298 @@ + +package scala.sys.process + +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.Test +import java.io.{InputStream, OutputStream, PipedInputStream, PipedOutputStream, ByteArrayInputStream, + ByteArrayOutputStream, IOException, Closeable} +import java.lang.reflect.InvocationTargetException +import scala.concurrent.{Await, Future} +import scala.concurrent.duration.{Duration, SECONDS} +import scala.concurrent.ExecutionContext.Implicits.global +import scala.util.control.Exception.ignoring + +// Each test normally ends in a moment, but for failure cases, waits until one second. + +@RunWith(classOf[JUnit4]) +class PipedProcessTest { + class ProcessMock(error: Boolean) extends Process { + var destroyCount = 0 + def exitValue(): Int = { + if (error) { + throw new InterruptedException() + } + 0 + } + def destroy(): Unit = { destroyCount += 1 } + } + + class ProcessBuilderMock(process: Process, error: Boolean) extends ProcessBuilder.AbstractBuilder { + override def run(io: ProcessIO): Process = { + if (error) { + throw new IOException() + } + process + } + } + + class PipeSinkMock extends Process.PipeSink("PipeSinkMock") { + var releaseCount = 0 + override val pipe = null + override val sink = null + override def run(): Unit = {} + override def connectOut(out: OutputStream): Unit = {} + override def connectIn(pipeOut: PipedOutputStream): Unit = {} + override def release(): Unit = { releaseCount += 1 } + } + + class PipeSourceMock extends Process.PipeSource("PipeSourceMock") { + var releaseCount = 0 + override val pipe = null + override val source = null + override def run(): Unit = {} + override def connectIn(in: InputStream): Unit = {} + override def connectOut(sink: Process.PipeSink): Unit = {} + override def release(): Unit = { releaseCount += 1 } + } + + class PipedProcesses(a: ProcessBuilder, b: ProcessBuilder, defaultIO: ProcessIO, toError: Boolean) + extends Process.PipedProcesses(a, b, defaultIO, toError) { + def callRunAndExitValue(source: Process.PipeSource, sink: Process.PipeSink) = { + val m = classOf[Process.PipedProcesses].getDeclaredMethod("runAndExitValue", classOf[Process.PipeSource], classOf[Process.PipeSink]) + m.setAccessible(true) + try m.invoke(this, source, sink).asInstanceOf[Option[Int]] + catch { + case err: InvocationTargetException => throw err.getTargetException + } + } + } + + // PipedProcesses need not to release resources when it normally end + @Test + def normallyEnd() { + val io = BasicIO(false, ProcessLogger(_ => ())) + val source = new PipeSourceMock + val sink = new PipeSinkMock + val a = new ProcessMock(error = false) + val b = new ProcessMock(error = false) + val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = false), io, false) + val f = Future { + p.callRunAndExitValue(source, sink) + } + Await.result(f, Duration(1, SECONDS)) + assert(source.releaseCount == 0) + assert(sink.releaseCount == 0) + assert(a.destroyCount == 0) + assert(b.destroyCount == 0) + } + + // PipedProcesses must release resources when b.run() failed + @Test + def bFailed() { + val io = BasicIO(false, ProcessLogger(_ => ())) + val source = new PipeSourceMock + val sink = new PipeSinkMock + val a = new ProcessMock(error = false) + val b = new ProcessMock(error = false) + val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = true), io, false) + val f = Future { + ignoring(classOf[IOException]) { + p.callRunAndExitValue(source, sink) + } + } + Await.result(f, Duration(1, SECONDS)) + assert(source.releaseCount == 1) + assert(sink.releaseCount == 1) + assert(a.destroyCount == 0) + assert(b.destroyCount == 0) + } + + // PipedProcesses must release resources when a.run() failed + @Test + def aFailed() { + val io = BasicIO(false, ProcessLogger(_ => ())) + val source = new PipeSourceMock + val sink = new PipeSinkMock + val a = new ProcessMock(error = false) + val b = new ProcessMock(error = false) + val p = new PipedProcesses(new ProcessBuilderMock(a, error = true), new ProcessBuilderMock(b, error = false), io, false) + val f = Future { + ignoring(classOf[IOException]) { + p.callRunAndExitValue(source, sink) + } + } + Await.result(f, Duration(1, SECONDS)) + assert(source.releaseCount == 1) + assert(sink.releaseCount == 1) + assert(a.destroyCount == 0) + assert(b.destroyCount == 1) + } + + // PipedProcesses must release resources when interrupted during waiting for first.exitValue() + @Test + def firstInterrupted() { + val io = BasicIO(false, ProcessLogger(_ => ())) + val source = new PipeSourceMock + val sink = new PipeSinkMock + val a = new ProcessMock(error = true) + val b = new ProcessMock(error = false) + val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = false), io, false) + val f = Future { + p.callRunAndExitValue(source, sink) + } + Await.result(f, Duration(1, SECONDS)) + assert(source.releaseCount == 1) + assert(sink.releaseCount == 1) + assert(a.destroyCount == 1) + assert(b.destroyCount == 1) + } + + // PipedProcesses must release resources when interrupted during waiting for second.exitValue() + @Test + def secondInterrupted() { + val io = BasicIO(false, ProcessLogger(_ => ())) + val source = new PipeSourceMock + val sink = new PipeSinkMock + val a = new ProcessMock(error = false) + val b = new ProcessMock(error = true) + val p = new PipedProcesses(new ProcessBuilderMock(a, error = false), new ProcessBuilderMock(b, error = false), io, false) + val f = Future { + p.callRunAndExitValue(source, sink) + } + Await.result(f, Duration(1, SECONDS)) + assert(source.releaseCount == 1) + assert(sink.releaseCount == 1) + assert(a.destroyCount == 1) + assert(b.destroyCount == 1) + } +} + +@RunWith(classOf[JUnit4]) +class PipeSourceSinkTest { + def throwsIOException(f: => Unit) = { + try { f; false } + catch { case _: IOException => true } + } + + class PipeSink extends Process.PipeSink("TestPipeSink") { + def ensureRunloopStarted() = { + while (sink.size() > 0) { + Thread.sleep(1) + } + } + def isReleased = { + val field = classOf[Process.PipeSink].getDeclaredField("pipe") + field.setAccessible(true) + val pipe = field.get(this).asInstanceOf[PipedInputStream] + !this.isAlive && throwsIOException { pipe.read() } + } + } + + class PipeSource extends Process.PipeSource("TestPipeSource") { + def ensureRunloopStarted() = { + while (source.size() > 0) { + Thread.sleep(1) + } + } + def isReleased = { + val field = classOf[Process.PipeSource].getDeclaredField("pipe") + field.setAccessible(true) + val pipe = field.get(this).asInstanceOf[PipedOutputStream] + !this.isAlive && throwsIOException { pipe.write(1) } + } + } + + trait CloseChecking extends Closeable { + var closed = false + override def close() = closed = true + } + class DebugOutputStream extends ByteArrayOutputStream with CloseChecking + class DebugInputStream(s: String) extends ByteArrayInputStream(s.getBytes()) with CloseChecking + class DebugInfinityInputStream extends InputStream with CloseChecking { + def read() = 1 + } + + def sourceSink() = { + val source = new PipeSource + val sink = new PipeSink + source connectOut sink + source.start() + sink.start() + (source, sink) + } + + // PipeSource and PipeSink must release resources when it normally end + @Test + def normallyEnd() { + val in = new DebugInputStream("aaa") + val (source, sink) = sourceSink() + val out = new DebugOutputStream + source connectIn in + sink connectOut out + val f = Future { + source.join() + sink.join() + } + Await.result(f, Duration(1, SECONDS)) + assert(in.closed == true) + assert(out.closed == true) + assert(source.isReleased == true) + assert(sink.isReleased == true) + } + + // PipeSource and PipeSink must release resources when interrupted during waiting for source.take() + @Test + def sourceInterrupted() { + val (source, sink) = sourceSink() + val out = new DebugOutputStream + sink connectOut out + val f = Future { + sink.ensureRunloopStarted() + source.release() + sink.release() + } + Await.result(f, Duration(1, SECONDS)) + assert(out.closed == true) + assert(source.isReleased == true) + assert(sink.isReleased == true) + } + + // PipeSource and PipeSink must release resources when interrupted during waiting for sink.take() + @Test + def sinkInterrupted() { + val in = new DebugInputStream("aaa") + val (source, sink) = sourceSink() + source connectIn in + val f = Future { + source.ensureRunloopStarted() + source.release() + sink.release() + } + Await.result(f, Duration(1, SECONDS)) + assert(in.closed == true) + assert(source.isReleased == true) + assert(sink.isReleased == true) + } + + // PipeSource and PipeSink must release resources when interrupted during copy streams" + @Test + def runloopInterrupted() { + val in = new DebugInfinityInputStream + val (source, sink) = sourceSink() + val out = new DebugOutputStream + source connectIn in + sink connectOut out + val f = Future { + source.ensureRunloopStarted() + sink.ensureRunloopStarted() + source.release() + sink.release() + } + Await.result(f, Duration(1, SECONDS)) + assert(in.closed == true) + assert(out.closed == true) + assert(source.isReleased == true) + assert(sink.isReleased == true) + } +} diff --git a/test/scaladoc/run/t7905.check b/test/scaladoc/run/t7905.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/t7905.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/t7905.scala b/test/scaladoc/run/t7905.scala new file mode 100644 index 0000000000..8570724470 --- /dev/null +++ b/test/scaladoc/run/t7905.scala @@ -0,0 +1,36 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + override def code = """ + object A { + val foo = new B { + val bar = new C { + val baz: A.this.type = A.this + } + } + } + + trait B { + type E = bar.D + + val bar: C + } + + trait C { + trait D + } + + trait G { + type F = A.foo.E + + def m(f: F) = f match { + case _: A.foo.bar.D => // error here + } + } + """ + + def scaladocSettings = "" + + def testModel(root: Package) = () +} diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala index da0f253a37..fc190b188c 100644 --- a/test/scaladoc/scalacheck/HtmlFactoryTest.scala +++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala @@ -779,6 +779,11 @@ object Test extends Properties("HtmlFactory") { linkElement \@ "href" == expectedUrl && linkElement \@ "target" == "_top" } + def assertValuesLink(memberName: String, expectedUrl: String): Boolean = { + val linkElement: NodeSeq = node \\ "div" \@ ("class", "values members") \\ "li" \@ ("name", memberName) \\ "span" \@ ("class", "permalink") \ "a" + linkElement \@ "href" == expectedUrl && linkElement \@ "target" == "_top" + } + } val files = createTemplates("SI-8144.scala") @@ -791,12 +796,12 @@ object Test extends Properties("HtmlFactory") { property("SI-8144: Members' permalink - package") = check("some/package.html") { node => ("type link" |: node.assertTypeLink("../index.html#some.package")) && - ("member: some.pack" |: node.assertMemberLink("values")("some.pack", "../index.html#some.package@pack")) + ("member: some.pack" |: node.assertValuesLink("some.pack", "../index.html#some.package@pack")) } property("SI-8144: Members' permalink - inner package") = check("some/pack/package.html") { node => ("type link" |: node.assertTypeLink("../../index.html#some.pack.package")) && - ("member: SomeType (object)" |: node.assertMemberLink("values")("some.pack.SomeType", "../../index.html#some.pack.package@SomeType")) && + ("member: SomeType (object)" |: node.assertValuesLink("some.pack.SomeType", "../../index.html#some.pack.package@SomeType")) && ("member: SomeType (class)" |: node.assertMemberLink("types")("some.pack.SomeType", "../../index.html#some.pack.package@SomeTypeextendsAnyRef")) } @@ -809,8 +814,8 @@ object Test extends Properties("HtmlFactory") { ("type link" |: node.assertTypeLink("../../index.html#some.pack.SomeType")) && ("constructor " |: node.assertMemberLink("constructors")("some.pack.SomeType#<init>", "../../index.html#some.pack.SomeType@<init>(arg:String):some.pack.SomeType")) && ( "member: type TypeAlias" |: node.assertMemberLink("types")("some.pack.SomeType.TypeAlias", "../../index.html#some.pack.SomeType@TypeAlias=String")) && - ( "member: def >#<():Int " |: node.assertMemberLink("values")("some.pack.SomeType#>#<", "../../index.html#some.pack.SomeType@>#<():Int")) && - ( "member: def >@<():TypeAlias " |: node.assertMemberLink("values")("some.pack.SomeType#>@<", "../../index.html#some.pack.SomeType@>@<():SomeType.this.TypeAlias")) + ( "member: def >#<():Int " |: node.assertValuesLink("some.pack.SomeType#>#<", "../../index.html#some.pack.SomeType@>#<():Int")) && + ( "member: def >@<():TypeAlias " |: node.assertValuesLink("some.pack.SomeType#>@<", "../../index.html#some.pack.SomeType@>@<():SomeType.this.TypeAlias")) } } diff --git a/versions.properties b/versions.properties index 454df6b757..c334629d20 100644 --- a/versions.properties +++ b/versions.properties @@ -1,10 +1,10 @@ -#Wed, 23 Jul 2014 08:37:26 +0200 +#Tue, 20 May 2014 10:01:37 +0200 # NOTE: this file determines the content of the scala-distribution # via scala-dist-pom.xml and scala-library-all-pom.xml # when adding new properties that influence a release, # also add them to the update.versions mechanism in build.xml, # which is used by scala-release-2.11.x in scala/jenkins-scripts -starr.version=2.11.2 +starr.version=2.11.1 starr.use.released=1 # These are the versions of the modules that go with this release. @@ -14,21 +14,21 @@ starr.use.released=1 scala.binary.version=2.11 # e.g. 2.11.0-RC1, 2.11.0, 2.11.1-RC1, 2.11.1 # this defines the dependency on scala-continuations-plugin in scala-dist's pom -scala.full.version=2.11.2 +scala.full.version=2.11.1 # external modules shipped with distribution, as specified by scala-library-all's pom scala-xml.version.number=1.0.2 -scala-parser-combinators.version.number=1.0.2 +scala-parser-combinators.version.number=1.0.1 scala-continuations-plugin.version.number=1.0.2 scala-continuations-library.version.number=1.0.2 scala-swing.version.number=1.0.1 -akka-actor.version.number=2.3.4 +akka-actor.version.number=2.3.3 actors-migration.version.number=1.1.0 jline.version=2.12 # external modules, used internally (not shipped) -partest.version.number=1.0.1 -scalacheck.version.number=1.11.4 +partest.version.number=1.0.0 +scalacheck.version.number=1.11.3 # TODO: modularize the compiler #scala-compiler-doc.version.number=1.0.0-RC1 |