summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-06-10 13:02:50 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-06-10 13:02:50 +0200
commitcf8902907756cca2c5b8367c898ca0e9698c6521 (patch)
tree4b880aac09cf5cfc5a682ff3cf97ef805db6a9cd /src
parented3df58ab167f660825e675b6b45eb454fc9869b (diff)
parentddb29a8105bc3b692bc129cbd8ed111baae7076d (diff)
downloadscala-cf8902907756cca2c5b8367c898ca0e9698c6521.tar.gz
scala-cf8902907756cca2c5b8367c898ca0e9698c6521.tar.bz2
scala-cf8902907756cca2c5b8367c898ca0e9698c6521.zip
Merge remote-tracking branch 'origin/2.11.x' into merge/2.11.x-to-2.12.x
Diffstat (limited to 'src')
-rw-r--r--src/build/maven/scala-dist-pom.xml5
-rw-r--r--src/compiler/scala/tools/nsc/CompilerCommand.scala11
-rw-r--r--src/compiler/scala/tools/nsc/Driver.scala21
-rw-r--r--src/compiler/scala/tools/nsc/GenericRunnerCommand.scala27
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala3
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala48
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala4
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala1
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Main.scala7
-rwxr-xr-xsrc/library/scala/collection/IndexedSeqOptimized.scala2
-rw-r--r--src/library/scala/collection/Iterator.scala13
-rw-r--r--src/library/scala/collection/mutable/AVLTree.scala2
-rw-r--r--src/library/scala/concurrent/Channel.scala17
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala4
-rw-r--r--src/library/scala/concurrent/Lock.scala2
-rw-r--r--src/library/scala/concurrent/SyncVar.scala16
-rw-r--r--src/library/scala/concurrent/package.scala5
-rw-r--r--src/library/scala/util/Properties.scala7
-rw-r--r--src/reflect/scala/reflect/internal/util/SourceFile.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/package.scala3
-rw-r--r--src/repl/scala/tools/nsc/MainGenericRunner.scala128
23 files changed, 193 insertions, 144 deletions
diff --git a/src/build/maven/scala-dist-pom.xml b/src/build/maven/scala-dist-pom.xml
index 22a24dea21..9477e14285 100644
--- a/src/build/maven/scala-dist-pom.xml
+++ b/src/build/maven/scala-dist-pom.xml
@@ -40,6 +40,11 @@
<version>@VERSION@</version>
</dependency>
<dependency>
+ <groupId>org.scala-lang</groupId>
+ <artifactId>scalap</artifactId>
+ <version>@VERSION@</version>
+ </dependency>
+ <dependency>
<groupId>org.scala-lang.plugins</groupId>
<!-- plugins are fully cross-versioned. But, we don't publish with 2.11.0-SNAPSHOT, instead use full version of the last non-snapshot version -->
<artifactId>scala-continuations-plugin_@SCALA_FULL_VERSION@</artifactId>
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala
index bab0768ca9..a1d0d52dcf 100644
--- a/src/compiler/scala/tools/nsc/CompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala
@@ -20,9 +20,12 @@ class CompilerCommand(arguments: List[String], val settings: Settings) {
def ok = processArgumentsResult._1
def files = processArgumentsResult._2
- /** The name of the command */
+ /** The name of the command. */
def cmdName = "scalac"
+ /** A descriptive alias for version and help messages. */
+ def cmdDesc = "compiler"
+
private def explainAdvanced = "\n" + """
|-- Notes on option parsing --
|Boolean settings are always false unless set.
@@ -85,7 +88,11 @@ class CompilerCommand(arguments: List[String], val settings: Settings) {
def getInfoMessage(global: Global): String = {
import settings._
- if (help) usageMsg + global.pluginOptionsHelp
+ import Properties.{ versionString, copyrightString } //versionFor
+ def versionFor(command: String) = f"Scala $command $versionString -- $copyrightString"
+
+ if (version) versionFor(cmdDesc)
+ else if (help) usageMsg + global.pluginOptionsHelp
else if (Xhelp) xusageMsg
else if (Yhelp) yusageMsg
else if (showPlugins) global.pluginDescriptions
diff --git a/src/compiler/scala/tools/nsc/Driver.scala b/src/compiler/scala/tools/nsc/Driver.scala
index 3ac27a42e8..6befa76b3f 100644
--- a/src/compiler/scala/tools/nsc/Driver.scala
+++ b/src/compiler/scala/tools/nsc/Driver.scala
@@ -2,26 +2,24 @@ package scala
package tools.nsc
import scala.tools.nsc.reporters.ConsoleReporter
-import Properties.{ versionString, copyrightString, residentPromptString }
+import Properties.{ versionMsg, residentPromptString }
import scala.reflect.internal.util.FakePos
abstract class Driver {
val prompt = residentPromptString
- val versionMsg = "Scala compiler " +
- versionString + " -- " +
- copyrightString
-
var reporter: ConsoleReporter = _
protected var command: CompilerCommand = _
protected var settings: Settings = _
- protected def scalacError(msg: String) {
+ protected def scalacError(msg: String): Unit = {
reporter.error(FakePos("scalac"), msg + "\n scalac -help gives more information")
}
- protected def processSettingsHook(): Boolean = true
+ protected def processSettingsHook(): Boolean = {
+ if (settings.version) { reporter echo versionMsg ; false } else true
+ }
protected def newCompiler(): Global
@@ -37,14 +35,12 @@ abstract class Driver {
}
def process(args: Array[String]) {
- val ss = new Settings(scalacError)
- reporter = new ConsoleReporter(ss)
+ val ss = new Settings(scalacError)
+ reporter = new ConsoleReporter(ss)
command = new CompilerCommand(args.toList, ss)
settings = command.settings
- if (settings.version) {
- reporter.echo(versionMsg)
- } else if (processSettingsHook()) {
+ if (processSettingsHook()) {
val compiler = newCompiler()
try {
if (reporter.hasErrors)
@@ -68,5 +64,4 @@ abstract class Driver {
process(args)
sys.exit(if (reporter.hasErrors) 1 else 0)
}
-
}
diff --git a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
index e710222285..dbdeec809f 100644
--- a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
+++ b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
@@ -19,9 +19,10 @@ extends CompilerCommand(args, settings) {
def this(args: List[String]) =
this(args, str => Console.println("Error: " + str))
- /** name of the associated compiler command */
override def cmdName = "scala"
- def compCmdName = "scalac"
+ override def cmdDesc = "code runner"
+
+ def compCmdName = "scalac" // super.cmdName
// change CompilerCommand behavior
override def shouldProcessArguments: Boolean = false
@@ -50,17 +51,16 @@ extends CompilerCommand(args, settings) {
case Nil => AsRepl
case hd :: _ => waysToRun find (_.name == settings.howtorun.value) getOrElse guessHowToRun(hd)
}
- private def interpolate(s: String) = s.trim.replaceAll("@cmd@", cmdName).replaceAll("@compileCmd@", compCmdName) + "\n"
-
- def shortUsageMsg = interpolate("""
-Usage: @cmd@ <options> [<script|class|object|jar> <arguments>]
- or @cmd@ -help
-All options to @compileCmd@ (see @compileCmd@ -help) are also allowed.
-""")
+ def shortUsageMsg =
+s"""|Usage: $cmdName <options> [<script|class|object|jar> <arguments>]
+ | or $cmdName -help
+ |
+ |All options to $compCmdName (see $compCmdName -help) are also allowed.
+""".stripMargin
- override def usageMsg = shortUsageMsg + interpolate("""
-The first given argument other than options to @cmd@ designates
+ override def usageMsg = f"""$shortUsageMsg
+The first given argument other than options to $cmdName designates
what to run. Runnable targets are:
- a file containing scala source
@@ -68,7 +68,7 @@ what to run. Runnable targets are:
- a runnable jar file with a valid Main-Class attribute
- or if no argument is given, the repl (interactive shell) is started
-Options to @cmd@ which reach the java runtime:
+Options to $cmdName which reach the java runtime:
-Dname=prop passed directly to java to set system properties
-J<arg> -J is stripped and <arg> passed to java as-is
@@ -86,8 +86,7 @@ A file argument will be run as a scala script unless it contains only
self-contained compilation units (classes and objects) and exactly one
runnable main method. In that case the file will be compiled and the
main method invoked. This provides a bridge between scripts and standard
-scala source.
- """) + "\n"
+scala source.%n"""
}
object GenericRunnerCommand {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 1285ca6862..bffa4bc51d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -686,7 +686,12 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
case _ =>
}
if ((targetTypeKind != null) && (sym == definitions.Array_clone) && invokeStyle.isDynamic) {
- val target: String = targetTypeKind.asClassBType.internalName
+ // An invokevirtual points to a CONSTANT_Methodref_info which in turn points to a
+ // CONSTANT_Class_info of the receiver type.
+ // The JVMS is not explicit about this, but that receiver type may be an array type
+ // descriptor (instead of a class internal name):
+ // invokevirtual #2; //Method "[I".clone:()Ljava/lang/Object
+ val target: String = targetTypeKind.asRefBType.classOrArrayType
bc.invokevirtual(target, "clone", "()Ljava/lang/Object;")
}
else {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
index 9aedc7f8b4..5b0fa6f7a8 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
@@ -217,7 +217,8 @@ abstract class BTypes[G <: Global](val __global_dont_use: G) {
sealed trait RefBType extends BType {
/**
* The class or array type of this reference type. Used for ANEWARRAY, MULTIANEWARRAY,
- * INSTANCEOF and CHECKCAST instructions.
+ * INSTANCEOF and CHECKCAST instructions. Also used for emitting invokevirtual calls to
+ * (a: Array[T]).clone() for any T, see genApply.
*
* In contrast to the descriptor, this string does not contain the surrounding 'L' and ';' for
* class types, for example "java/lang/String".
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 20ccc30ff6..d22dcacad6 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -42,7 +42,7 @@ trait ScalaSettings extends AbsScalaSettings
def optimiseSettings = List[BooleanSetting](inline, inlineHandlers, Xcloselim, Xdce, YconstOptimization)
/** If any of these settings is enabled, the compiler should print a message and exit. */
- def infoSettings = List[Setting](help, Xhelp, Yhelp, showPlugins, showPhases, genPhaseGraph)
+ def infoSettings = List[Setting](version, help, Xhelp, Yhelp, showPlugins, showPhases, genPhaseGraph)
/** Is an info setting set? */
def isInfo = infoSettings exists (_.isSetByUser)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 6ca2205881..149b4fe446 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -780,32 +780,40 @@ abstract class ICodeReader extends ClassfileParser {
bb = otherBlock
// Console.println("\t> entering bb: " + bb)
}
- instr match {
- case LJUMP(target) =>
- otherBlock = blocks(target)
- bb.emitOnly(JUMP(otherBlock))
- case LCJUMP(success, failure, cond, kind) =>
- otherBlock = blocks(success)
- val failBlock = blocks(failure)
- bb.emitOnly(CJUMP(otherBlock, failBlock, cond, kind))
+ if (bb.closed) {
+ // the basic block is closed, i.e. the previous instruction was a jump, return or throw,
+ // but the next instruction is not a jump target. this means that the next instruction is
+ // dead code. we can therefore advance until the next jump target.
+ debuglog(s"ICode reader skipping dead instruction $instr in classfile $instanceCode")
+ } else {
+ instr match {
+ case LJUMP(target) =>
+ otherBlock = blocks(target)
+ bb.emitOnly(JUMP(otherBlock))
+
+ case LCJUMP(success, failure, cond, kind) =>
+ otherBlock = blocks(success)
+ val failBlock = blocks(failure)
+ bb.emitOnly(CJUMP(otherBlock, failBlock, cond, kind))
- case LCZJUMP(success, failure, cond, kind) =>
- otherBlock = blocks(success)
- val failBlock = blocks(failure)
- bb.emitOnly(CZJUMP(otherBlock, failBlock, cond, kind))
+ case LCZJUMP(success, failure, cond, kind) =>
+ otherBlock = blocks(success)
+ val failBlock = blocks(failure)
+ bb.emitOnly(CZJUMP(otherBlock, failBlock, cond, kind))
- case LSWITCH(tags, targets) =>
- bb.emitOnly(SWITCH(tags, targets map blocks))
+ case LSWITCH(tags, targets) =>
+ bb.emitOnly(SWITCH(tags, targets map blocks))
- case RETURN(_) =>
- bb emitOnly instr
+ case RETURN(_) =>
+ bb emitOnly instr
- case THROW(clasz) =>
- bb emitOnly instr
+ case THROW(clasz) =>
+ bb emitOnly instr
- case _ =>
- bb emit instr
+ case _ =>
+ bb emit instr
+ }
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index dceb0a47d8..284ab2f6f9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -174,8 +174,8 @@ trait NamesDefaults { self: Analyzer =>
// assigning the correct method symbol, typedSelect will just assign the type. the reason
// to still call 'typed' is to correctly infer singleton types, SI-5259.
val selectPos =
- if(qual.pos.isRange && baseFun.pos.isRange) qual.pos.union(baseFun.pos).withStart(Math.min(qual.pos.end, baseFun.pos.end))
- else baseFun.pos
+ if(qual.pos.isRange && baseFun1.pos.isRange) qual.pos.union(baseFun1.pos).withStart(Math.min(qual.pos.end, baseFun1.pos.end))
+ else baseFun1.pos
val f = blockTyper.typedOperator(Select(newQual, selected).setSymbol(baseFun1.symbol).setPos(selectPos))
if (funTargs.isEmpty) f
else TypeApply(f, funTargs).setType(baseFun.tpe)
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 3b12086cc7..923297bafb 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -141,6 +141,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val run = new Run
run.symSource(ownerClass) = NoAbstractFile // need to set file to something different from null, so that currentRun.defines works
phase = run.typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled
+ globalPhase = run.typerPhase // amazing... looks like phase and globalPhase are different things, so we need to set them separately
currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions
reporter.reset()
diff --git a/src/interactive/scala/tools/nsc/interactive/Main.scala b/src/interactive/scala/tools/nsc/interactive/Main.scala
index c838606f02..7796c65670 100644
--- a/src/interactive/scala/tools/nsc/interactive/Main.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Main.scala
@@ -12,7 +12,7 @@ package interactive
*/
object Main extends nsc.MainClass {
override def processSettingsHook(): Boolean = {
- if (this.settings.Yidedebug) {
+ def run(): Unit = {
this.settings.Xprintpos.value = true
this.settings.Yrangepos.value = true
val compiler = new interactive.Global(this.settings, this.reporter)
@@ -27,8 +27,9 @@ object Main extends nsc.MainClass {
case None => reporter.reset() // Causes other compiler errors to be ignored
}
askShutdown
- false
}
- else true
+ super.processSettingsHook() && (
+ if (this.settings.Yidedebug) { run() ; false } else true
+ )
}
}
diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala
index ade04e4de8..42cb37aa24 100755
--- a/src/library/scala/collection/IndexedSeqOptimized.scala
+++ b/src/library/scala/collection/IndexedSeqOptimized.scala
@@ -206,7 +206,7 @@ trait IndexedSeqOptimized[+A, +Repr] extends Any with IndexedSeqLike[A, Repr] {
override /*SeqLike*/
def lastIndexWhere(p: A => Boolean, end: Int): Int = {
- var i = end
+ var i = math.min(end, length - 1)
while (i >= 0 && !p(this(i))) i -= 1
i
}
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index e321a6adba..f6f46e158f 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -922,6 +922,9 @@ trait Iterator[+A] extends TraversableOnce[A] {
/** For reasons which remain to be determined, calling
* self.take(n).toSeq cause an infinite loop, so we have
* a slight variation on take for local usage.
+ * NB: self.take.toSeq is slice.toStream, lazily built on self,
+ * so a subsequent self.hasNext would not test self after the
+ * group was consumed.
*/
private def takeDestructively(size: Int): Seq[A] = {
val buf = new ArrayBuffer[A]
@@ -945,12 +948,10 @@ trait Iterator[+A] extends TraversableOnce[A] {
// so the rest of the code can be oblivious
val xs: Seq[B] = {
val res = takeDestructively(count)
- // extra checks so we don't calculate length unless there's reason
- if (pad.isDefined && !self.hasNext) {
- val shortBy = count - res.length
- if (shortBy > 0) res ++ padding(shortBy) else res
- }
- else res
+ // was: extra checks so we don't calculate length unless there's reason
+ // but since we took the group eagerly, just use the fast length
+ val shortBy = count - res.length
+ if (shortBy > 0 && pad.isDefined) res ++ padding(shortBy) else res
}
lazy val len = xs.length
lazy val incomplete = len < count
diff --git a/src/library/scala/collection/mutable/AVLTree.scala b/src/library/scala/collection/mutable/AVLTree.scala
index de09bb2040..cc2acb74d4 100644
--- a/src/library/scala/collection/mutable/AVLTree.scala
+++ b/src/library/scala/collection/mutable/AVLTree.scala
@@ -14,8 +14,8 @@ package mutable
* An immutable AVL Tree implementation formerly used by mutable.TreeSet
*
* @author Lucien Pereira
- * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11.0")
*/
+@deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11.2")
private[mutable] sealed trait AVLTree[+A] extends Serializable {
def balance: Int
diff --git a/src/library/scala/concurrent/Channel.scala b/src/library/scala/concurrent/Channel.scala
index 067244bd1c..89ad7d8c0e 100644
--- a/src/library/scala/concurrent/Channel.scala
+++ b/src/library/scala/concurrent/Channel.scala
@@ -10,8 +10,10 @@
package scala.concurrent
-/** This class ...
+/** This class provides a simple FIFO queue of data objects,
+ * which are read by one or more reader threads.
*
+ * @tparam A type of data exchanged
* @author Martin Odersky
* @version 1.0, 10/03/2003
*/
@@ -20,11 +22,14 @@ class Channel[A] {
var elem: A = _
var next: LinkedList[A] = null
}
- private var written = new LinkedList[A] // FIFO buffer, realized through
+ private var written = new LinkedList[A] // FIFO queue, realized through
private var lastWritten = written // aliasing of a linked list
private var nreaders = 0
- /**
+ /** Append a value to the FIFO queue to be read by `read`.
+ * This operation is nonblocking and can be executed by any thread.
+ *
+ * @param x object to enqueue to this channel
*/
def write(x: A) = synchronized {
lastWritten.elem = x
@@ -33,6 +38,11 @@ class Channel[A] {
if (nreaders > 0) notify()
}
+ /** Retrieve the next waiting object from the FIFO queue,
+ * blocking if necessary until an object is available.
+ *
+ * @return next object dequeued from this channel
+ */
def read: A = synchronized {
while (written.next == null) {
try {
@@ -45,5 +55,4 @@ class Channel[A] {
written = written.next
x
}
-
}
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index a1e94c8876..4674c9174b 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -77,12 +77,12 @@ trait ExecutionContext {
}
/**
- * Union interface since Java does not support union types
+ * An [[ExecutionContext]] that is also a Java [[Executor]].
*/
trait ExecutionContextExecutor extends ExecutionContext with Executor
/**
- * Union interface since Java does not support union types
+ * An [[ExecutionContext]] that is also a Java [[ExecutorService]].
*/
trait ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService
diff --git a/src/library/scala/concurrent/Lock.scala b/src/library/scala/concurrent/Lock.scala
index 1c00c0e91f..8d18da2d38 100644
--- a/src/library/scala/concurrent/Lock.scala
+++ b/src/library/scala/concurrent/Lock.scala
@@ -14,8 +14,8 @@ package scala.concurrent
*
* @author Martin Odersky
* @version 1.0, 10/03/2003
- * @deprecated("Use java.util.concurrent.locks.Lock", "2.11.0")
*/
+@deprecated("Use java.util.concurrent.locks.Lock", "2.11.2")
class Lock {
var available = true
diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala
index d5dc3d7e3f..494c955833 100644
--- a/src/library/scala/concurrent/SyncVar.scala
+++ b/src/library/scala/concurrent/SyncVar.scala
@@ -13,6 +13,7 @@ import java.util.concurrent.TimeUnit
/** A class to provide safe concurrent access to a mutable cell.
* All methods are synchronized.
*
+ * @tparam A type of the contained value
* @author Martin Odersky
* @version 1.0, 10/03/2003
*/
@@ -20,6 +21,12 @@ class SyncVar[A] {
private var isDefined: Boolean = false
private var value: Option[A] = None
+ /**
+ * Waits for this SyncVar to become defined and returns
+ * the result, without modifying the stored value.
+ *
+ * @return value that is held in this container
+ */
def get: A = synchronized {
while (!isDefined) wait()
value.get
@@ -57,8 +64,12 @@ class SyncVar[A] {
value
}
- /** Waits for this SyncVar to become defined and returns
- * the result */
+ /**
+ * Waits for this SyncVar to become defined and returns
+ * the result, unsetting the stored value before returning.
+ *
+ * @return value that was held in this container
+ */
def take(): A = synchronized {
try get
finally unsetVal()
@@ -129,4 +140,3 @@ class SyncVar[A] {
}
}
-
diff --git a/src/library/scala/concurrent/package.scala b/src/library/scala/concurrent/package.scala
index cc1350f5a9..4d88253de4 100644
--- a/src/library/scala/concurrent/package.scala
+++ b/src/library/scala/concurrent/package.scala
@@ -55,6 +55,11 @@ package object concurrent {
}
package concurrent {
+ /**
+ * This marker trait is used by [[Await]] to ensure that [[Awaitable.ready]] and [[Awaitable.result]]
+ * are not directly called by user code. An implicit instance of this trait is only available when
+ * user code is currently calling the methods on [[Await]].
+ */
@implicitNotFound("Don't call `Awaitable` methods directly, use the `Await` object.")
sealed trait CanAwait
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index d597feb898..2daa4de9a6 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -155,9 +155,12 @@ private[scala] trait PropertiesTrait {
// This is looking for javac, tools.jar, etc.
// Tries JDK_HOME first, then the more common but likely jre JAVA_HOME,
// and finally the system property based javaHome.
- def jdkHome = envOrElse("JDK_HOME", envOrElse("JAVA_HOME", javaHome))
+ def jdkHome = envOrElse("JDK_HOME", envOrElse("JAVA_HOME", javaHome))
- def versionMsg = "Scala %s %s -- %s".format(propCategory, versionString, copyrightString)
+ // private[scala] for 2.12
+ private[this] def versionFor(command: String) = f"Scala $command $versionString -- $copyrightString"
+
+ def versionMsg = versionFor(propCategory)
def scalaCmd = if (isWin) "scala.bat" else "scala"
def scalacCmd = if (isWin) "scalac.bat" else "scalac"
diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala
index 4fccad74ac..a2642628a4 100644
--- a/src/reflect/scala/reflect/internal/util/SourceFile.scala
+++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala
@@ -40,7 +40,7 @@ abstract class SourceFile {
def lineToString(index: Int): String = {
val start = lineToOffset(index)
var end = start
- while (!isEndOfLine(end) && end <= length) end += 1
+ while (end < length && !isEndOfLine(end)) end += 1
new String(content, start, end - start)
}
diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala
index 3c9bbccba3..e240bed0a7 100644
--- a/src/reflect/scala/reflect/runtime/package.scala
+++ b/src/reflect/scala/reflect/runtime/package.scala
@@ -30,7 +30,8 @@ package runtime {
import c.universe._
val runtimeClass = c.reifyEnclosingRuntimeClass
if (runtimeClass.isEmpty) c.abort(c.enclosingPosition, "call site does not have an enclosing class")
- val runtimeUniverse = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("runtime")), newTermName("universe"))
+ val scalaPackage = Select(Ident(newTermName("_root_")), newTermName("scala"))
+ val runtimeUniverse = Select(Select(Select(scalaPackage, newTermName("reflect")), newTermName("runtime")), newTermName("universe"))
val currentMirror = Apply(Select(runtimeUniverse, newTermName("runtimeMirror")), List(Select(runtimeClass, newTermName("getClassLoader"))))
c.Expr[Nothing](currentMirror)(c.WeakTypeTag.Nothing)
}
diff --git a/src/repl/scala/tools/nsc/MainGenericRunner.scala b/src/repl/scala/tools/nsc/MainGenericRunner.scala
index 43f0ea1256..34057ed341 100644
--- a/src/repl/scala/tools/nsc/MainGenericRunner.scala
+++ b/src/repl/scala/tools/nsc/MainGenericRunner.scala
@@ -8,7 +8,6 @@ package tools.nsc
import io.{ File }
import util.{ ClassPath, ScalaClassLoader }
-import Properties.{ versionString, copyrightString }
import GenericRunnerCommand._
object JarRunner extends CommonRunner {
@@ -28,79 +27,78 @@ object JarRunner extends CommonRunner {
}
/** An object that runs Scala code. It has three possible
- * sources for the code to run: pre-compiled code, a script file,
- * or interactive entry.
- */
+ * sources for the code to run: pre-compiled code, a script file,
+ * or interactive entry.
+ */
class MainGenericRunner {
- def errorFn(ex: Throwable): Boolean = {
- ex.printStackTrace()
- false
- }
- def errorFn(str: String): Boolean = {
- Console.err println str
- false
+ def errorFn(str: String, e: Option[Throwable] = None, isFailure: Boolean = true): Boolean = {
+ if (str.nonEmpty) Console.err println str
+ e foreach (_.printStackTrace())
+ !isFailure
}
def process(args: Array[String]): Boolean = {
val command = new GenericRunnerCommand(args.toList, (x: String) => errorFn(x))
- import command.{ settings, howToRun, thingToRun }
- def sampleCompiler = new Global(settings) // def so its not created unless needed
-
- if (!command.ok) return errorFn("\n" + command.shortUsageMsg)
- else if (settings.version) return errorFn("Scala code runner %s -- %s".format(versionString, copyrightString))
- else if (command.shouldStopWithInfo) return errorFn(command getInfoMessage sampleCompiler)
-
- def isE = !settings.execute.isDefault
- def dashe = settings.execute.value
-
- def isI = !settings.loadfiles.isDefault
- def dashi = settings.loadfiles.value
-
- // Deadlocks on startup under -i unless we disable async.
- if (isI)
- settings.Yreplsync.value = true
-
- def combinedCode = {
- val files = if (isI) dashi map (file => File(file).slurp()) else Nil
- val str = if (isE) List(dashe) else Nil
-
- files ++ str mkString "\n\n"
- }
-
- def runTarget(): Either[Throwable, Boolean] = howToRun match {
- case AsObject =>
- ObjectRunner.runAndCatch(settings.classpathURLs, thingToRun, command.arguments)
- case AsScript =>
- ScriptRunner.runScriptAndCatch(settings, thingToRun, command.arguments)
- case AsJar =>
- JarRunner.runJar(settings, thingToRun, command.arguments)
- case Error =>
- Right(false)
- case _ =>
- // We start the repl when no arguments are given.
- Right(new interpreter.ILoop process settings)
+ import command.{ settings, howToRun, thingToRun, shortUsageMsg, shouldStopWithInfo }
+ def sampleCompiler = new Global(settings) // def so it's not created unless needed
+
+ def run(): Boolean = {
+ def isE = !settings.execute.isDefault
+ def dashe = settings.execute.value
+
+ def isI = !settings.loadfiles.isDefault
+ def dashi = settings.loadfiles.value
+
+ // Deadlocks on startup under -i unless we disable async.
+ if (isI)
+ settings.Yreplsync.value = true
+
+ def combinedCode = {
+ val files = if (isI) dashi map (file => File(file).slurp()) else Nil
+ val str = if (isE) List(dashe) else Nil
+
+ files ++ str mkString "\n\n"
+ }
+
+ def runTarget(): Either[Throwable, Boolean] = howToRun match {
+ case AsObject =>
+ ObjectRunner.runAndCatch(settings.classpathURLs, thingToRun, command.arguments)
+ case AsScript =>
+ ScriptRunner.runScriptAndCatch(settings, thingToRun, command.arguments)
+ case AsJar =>
+ JarRunner.runJar(settings, thingToRun, command.arguments)
+ case Error =>
+ Right(false)
+ case _ =>
+ // We start the repl when no arguments are given.
+ Right(new interpreter.ILoop process settings)
+ }
+
+ /** If -e and -i were both given, we want to execute the -e code after the
+ * -i files have been included, so they are read into strings and prepended to
+ * the code given in -e. The -i option is documented to only make sense
+ * interactively so this is a pretty reasonable assumption.
+ *
+ * This all needs a rewrite though.
+ */
+ if (isE) {
+ ScriptRunner.runCommand(settings, combinedCode, thingToRun +: command.arguments)
+ }
+ else runTarget() match {
+ case Left(ex) => errorFn("", Some(ex)) // there must be a useful message of hope to offer here
+ case Right(b) => b
+ }
}
- /** If -e and -i were both given, we want to execute the -e code after the
- * -i files have been included, so they are read into strings and prepended to
- * the code given in -e. The -i option is documented to only make sense
- * interactively so this is a pretty reasonable assumption.
- *
- * This all needs a rewrite though.
- */
- if (isE) {
- ScriptRunner.runCommand(settings, combinedCode, thingToRun +: command.arguments)
- }
- else runTarget() match {
- case Left(ex) => errorFn(ex)
- case Right(b) => b
- }
+ if (!command.ok)
+ errorFn(f"%n$shortUsageMsg")
+ else if (shouldStopWithInfo)
+ errorFn(command getInfoMessage sampleCompiler, isFailure = false)
+ else
+ run()
}
}
object MainGenericRunner extends MainGenericRunner {
- def main(args: Array[String]) {
- if (!process(args))
- sys.exit(1)
- }
+ def main(args: Array[String]): Unit = if (!process(args)) sys.exit(1)
}