summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala41
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala72
2 files changed, 90 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 43902d1c65..b6387fd56b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -379,18 +379,37 @@ trait NamesDefaults { self: Analyzer =>
def makeNamedTypes(syms: List[Symbol]) = syms map (sym => NamedType(sym.name, sym.tpe))
- def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name] = nameOfNamedArg _): (List[Symbol], Boolean) = {
- val namedArgs = args.dropWhile(arg => {
- val n = argName(arg)
- n.isEmpty || params.forall(p => p.name != n.get)
- })
- val namedParams = params.drop(args.length - namedArgs.length)
- // missing: keep those with a name which doesn't exist in namedArgs
- val missingParams = namedParams.filter(p => namedArgs.forall(arg => {
+ /**
+ * Returns the parameter symbols of an invocation expression that are not defined by the list
+ * of arguments.
+ *
+ * @param args The list of arguments
+ * @param params The list of parameter sybols of the invoked method
+ * @param argName A function that extracts the name of an argument expression, if it is a named argument.
+ */
+ def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name]): (List[Symbol], Boolean) = {
+ // The argument list contains first a mix of positional args and named args that are on the
+ // right parameter position, and then a number or named args on different positions.
+
+ // collect all named arguments whose position does not match the parameter they define
+ val namedArgsOnChangedPosition = args.zip(params) dropWhile {
+ case (arg, param) =>
+ val n = argName(arg)
+ // drop the argument if
+ // - it's not named, or
+ // - it's named, but defines the parameter on its current position, or
+ // - it's named, but none of the parameter names matches (treated as a positional argument, an assignment expression)
+ n.isEmpty || n.get == param.name || params.forall(_.name != n.get)
+ } map (_._1)
+
+ val paramsWithoutPositionalArg = params.drop(args.length - namedArgsOnChangedPosition.length)
+
+ // missing parameters: those with a name which is not specified in one of the namedArgsOnChangedPosition
+ val missingParams = paramsWithoutPositionalArg.filter(p => namedArgsOnChangedPosition.forall { arg =>
val n = argName(arg)
n.isEmpty || n.get != p.name
- }))
- val allPositional = missingParams.length == namedParams.length
+ })
+ val allPositional = missingParams.length == paramsWithoutPositionalArg.length
(missingParams, allPositional)
}
@@ -407,7 +426,7 @@ trait NamesDefaults { self: Analyzer =>
previousArgss: List[List[Tree]], params: List[Symbol],
pos: scala.reflect.internal.util.Position, context: Context): (List[Tree], List[Symbol]) = {
if (givenArgs.length < params.length) {
- val (missing, positional) = missingParams(givenArgs, params)
+ val (missing, positional) = missingParams(givenArgs, params, nameOfNamedArg)
if (missing forall (_.hasDefault)) {
val defaultArgs = missing flatMap (p => {
val defGetter = defaultGetter(p, context)
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index 4674c9174b..11d3bb8b02 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -61,28 +61,44 @@ or import scala.concurrent.ExecutionContext.Implicits.global.""")
trait ExecutionContext {
/** Runs a block of code on this execution context.
+ *
+ * @param runnable the task to execute
*/
def execute(runnable: Runnable): Unit
/** Reports that an asynchronous computation failed.
+ *
+ * @param cause the cause of the failure
*/
def reportFailure(@deprecatedName('t) cause: Throwable): Unit
- /** Prepares for the execution of a task. Returns the prepared
- * execution context. A valid implementation of `prepare` is one
- * that simply returns `this`.
+ /** Prepares for the execution of a task. Returns the prepared execution context.
+ *
+ * `prepare` should be called at the site where an `ExecutionContext` is received (for
+ * example, through an implicit method parameter). The returned execution context may
+ * then be used to execute tasks. The role of `prepare` is to save any context relevant
+ * to an execution's ''call site'', so that this context may be restored at the
+ * ''execution site''. (These are often different: for example, execution may be
+ * suspended through a `Promise`'s future until the `Promise` is completed, which may
+ * be done in another thread, on another stack.)
+ *
+ * Note: a valid implementation of `prepare` is one that simply returns `this`.
+ *
+ * @return the prepared execution context
*/
def prepare(): ExecutionContext = this
}
/**
- * An [[ExecutionContext]] that is also a Java [[Executor]].
+ * An [[ExecutionContext]] that is also a
+ * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html Executor]].
*/
trait ExecutionContextExecutor extends ExecutionContext with Executor
/**
- * An [[ExecutionContext]] that is also a Java [[ExecutorService]].
+ * An [[ExecutionContext]] that is also a
+ * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html ExecutorService]].
*/
trait ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService
@@ -91,38 +107,70 @@ trait ExecutionContextExecutorService extends ExecutionContextExecutor with Exec
*/
object ExecutionContext {
/**
- * This is the explicit global ExecutionContext,
- * call this when you want to provide the global ExecutionContext explicitly
+ * The explicit global `ExecutionContext`. Invoke `global` when you want to provide the global
+ * `ExecutionContext` explicitly.
+ *
+ * The default `ExecutionContext` implementation is backed by a port of
+ * [[http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166-4jdk7docs/java/util/concurrent/ForkJoinPool.html java.util.concurrent.ForkJoinPool]].
+ *
+ * @return the global `ExecutionContext`
*/
def global: ExecutionContextExecutor = Implicits.global
object Implicits {
/**
- * This is the implicit global ExecutionContext,
- * import this when you want to provide the global ExecutionContext implicitly
+ * The implicit global `ExecutionContext`. Import `global` when you want to provide the global
+ * `ExecutionContext` implicitly.
+ *
+ * The default `ExecutionContext` implementation is backed by a port of
+ * [[http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166-4jdk7docs/java/util/concurrent/ForkJoinPool.html java.util.concurrent.ForkJoinPool]].
*/
implicit lazy val global: ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(null: Executor)
}
/** Creates an `ExecutionContext` from the given `ExecutorService`.
+ *
+ * @param e the `ExecutorService` to use
+ * @param reporter a function for error reporting
+ * @return the `ExecutionContext` using the given `ExecutorService`
*/
def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService =
impl.ExecutionContextImpl.fromExecutorService(e, reporter)
- /** Creates an `ExecutionContext` from the given `ExecutorService` with the default Reporter.
+ /** Creates an `ExecutionContext` from the given `ExecutorService` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]].
+ *
+ * If it is guaranteed that none of the executed tasks are blocking, a single-threaded `ExecutorService`
+ * can be used to create an `ExecutionContext` as follows:
+ *
+ * {{{
+ * import java.util.concurrent.Executors
+ * val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor())
+ * }}}
+ *
+ * @param e the `ExecutorService` to use
+ * @return the `ExecutionContext` using the given `ExecutorService`
*/
def fromExecutorService(e: ExecutorService): ExecutionContextExecutorService = fromExecutorService(e, defaultReporter)
/** Creates an `ExecutionContext` from the given `Executor`.
+ *
+ * @param e the `Executor` to use
+ * @param reporter a function for error reporting
+ * @return the `ExecutionContext` using the given `Executor`
*/
def fromExecutor(e: Executor, reporter: Throwable => Unit): ExecutionContextExecutor =
impl.ExecutionContextImpl.fromExecutor(e, reporter)
- /** Creates an `ExecutionContext` from the given `Executor` with the default Reporter.
+ /** Creates an `ExecutionContext` from the given `Executor` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]].
+ *
+ * @param e the `Executor` to use
+ * @return the `ExecutionContext` using the given `Executor`
*/
def fromExecutor(e: Executor): ExecutionContextExecutor = fromExecutor(e, defaultReporter)
- /** The default reporter simply prints the stack trace of the `Throwable` to System.err.
+ /** The default reporter simply prints the stack trace of the `Throwable` to [[http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#err System.err]].
+ *
+ * @return the function for error reporting
*/
def defaultReporter: Throwable => Unit = _.printStackTrace()
}