summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Sabin <miles@milessabin.com>2009-07-15 13:01:43 +0000
committerMiles Sabin <miles@milessabin.com>2009-07-15 13:01:43 +0000
commit69e1ddb55a7f122715dbed337de73f595ae00dc3 (patch)
treec545190e2d2a79070ac49e76886bdca34f94bdba
parent370817ac9736f67775a150f679bb5a4c01356ecb (diff)
downloadscala-69e1ddb55a7f122715dbed337de73f595ae00dc3.tar.gz
scala-69e1ddb55a7f122715dbed337de73f595ae00dc3.tar.bz2
scala-69e1ddb55a7f122715dbed337de73f595ae00dc3.zip
Added ControlException marker trait and update ...
Added ControlException marker trait and update various exceptions to mix it in; the typer now correctly propagates ControlExceptions rather than reporting them; the IDE reports attempts to log ControlExceptions; Global.signalDone no longer leaks ValidateErrors back into the typer; the set of compiler options offered by the IDE has been updated.
-rw-r--r--src/actors/scala/actors/Actor.scala3
-rw-r--r--src/actors/scala/actors/Reaction.scala3
-rw-r--r--src/actors/scala/actors/SchedulerService.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala7
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/Global.scala22
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
-rw-r--r--src/library/scala/runtime/NonLocalReturnException.scala3
-rwxr-xr-xsrc/library/scala/util/control/Breaks.scala2
-rw-r--r--src/library/scala/util/control/ControlException.scala39
11 files changed, 76 insertions, 21 deletions
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala
index 015ec917b6..43d1f7c707 100644
--- a/src/actors/scala/actors/Actor.scala
+++ b/src/actors/scala/actors/Actor.scala
@@ -11,6 +11,7 @@
package scala.actors
import scala.compat.Platform
+import scala.util.control.ControlException
import java.util.{Timer, TimerTask}
import java.util.concurrent.ExecutionException
@@ -881,7 +882,7 @@ case class Exit(from: AbstractActor, reason: AnyRef)
* @version 0.9.8
* @author Philipp Haller
*/
-private[actors] class SuspendActorException extends Throwable {
+private[actors] class SuspendActorException extends Throwable with ControlException {
/*
* For efficiency reasons we do not fill in
* the execution stack trace.
diff --git a/src/actors/scala/actors/Reaction.scala b/src/actors/scala/actors/Reaction.scala
index fee697b6cb..c8e19400eb 100644
--- a/src/actors/scala/actors/Reaction.scala
+++ b/src/actors/scala/actors/Reaction.scala
@@ -11,9 +11,10 @@
package scala.actors
+import scala.util.control.ControlException
import java.lang.{InterruptedException, Runnable}
-private[actors] class KillActorException extends Throwable {
+private[actors] class KillActorException extends Throwable with ControlException {
/*
* For efficiency reasons we do not fill in
* the execution stack trace.
diff --git a/src/actors/scala/actors/SchedulerService.scala b/src/actors/scala/actors/SchedulerService.scala
index 1826a153da..78abb97962 100644
--- a/src/actors/scala/actors/SchedulerService.scala
+++ b/src/actors/scala/actors/SchedulerService.scala
@@ -10,6 +10,7 @@
package scala.actors
+import scala.util.control.ControlException
import java.lang.{Runnable, Thread, InterruptedException}
/**
@@ -95,7 +96,7 @@ abstract class SchedulerService(daemon: Boolean) extends Thread with ActorGC {
* @version 0.9.8
* @author Philipp Haller
*/
-private[actors] class QuitException extends Throwable {
+private[actors] class QuitException extends Throwable with ControlException {
/*
For efficiency reasons we do not fill in
the execution stack trace.
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index a8f6853853..d247134fd6 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
@@ -7,6 +7,7 @@
package scala.tools.nsc.ast.parser
import scala.collection.mutable
+import scala.util.control.ControlException
import scala.tools.nsc.util.{Position,NoPosition,SourceFile,CharArrayReader}
import scala.xml.{Text, TextBuffer}
import SourceFile.{SU,LF}
@@ -18,15 +19,15 @@ import scala.annotation.switch
* @version 1.0
*/
trait MarkupParsers {self: Parsers =>
- case object MissingEndTagException extends RuntimeException {
+ case object MissingEndTagException extends RuntimeException with ControlException {
override def getMessage = "start tag was here: "
}
- case object ConfusedAboutBracesException extends RuntimeException {
+ case object ConfusedAboutBracesException extends RuntimeException with ControlException {
override def getMessage = " I encountered a '}' where I didn't expect one, maybe this tag isn't closed <"
}
- case object TruncatedXML extends RuntimeException {
+ case object TruncatedXML extends RuntimeException with ControlException {
override def getMessage = "input ended while parsing XML"
}
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index d264632bd5..0782639ac5 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -1,6 +1,7 @@
package scala.tools.nsc.interactive
import scala.concurrent.SyncVar
+import scala.util.control.ControlException
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.util.{SourceFile, Position, WorkScheduler}
import scala.tools.nsc.symtab._
@@ -104,8 +105,8 @@ trait CompilerControl { self: Global =>
// ---------------- Interpreted exeptions -------------------
- class CancelActionReq extends Exception
- class FreshRunReq extends Exception
- class ShutdownReq extends Exception
+ class CancelActionReq extends Exception with ControlException
+ class FreshRunReq extends Exception with ControlException
+ class ShutdownReq extends Exception with ControlException
}
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 51ba19951e..72415b5d7b 100755
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -4,6 +4,7 @@ import java.io.{ PrintWriter, StringWriter }
import scala.collection.mutable.{LinkedHashMap, SynchronizedMap}
import scala.concurrent.SyncVar
+import scala.util.control.ControlException
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler}
import scala.tools.nsc.reporters._
@@ -77,11 +78,19 @@ self =>
throw new TyperResult(located)
}
val typerRun = currentTyperRun
- pollForWork()
- if (typerRun != currentTyperRun) {
- integrateNew()
- throw new FreshRunReq
- }
+
+ while(true)
+ try {
+ pollForWork()
+ if (typerRun == currentTyperRun)
+ return
+
+ integrateNew()
+ throw new FreshRunReq
+ } catch {
+ case ex : ValidateError => // Ignore, this will have been reported elsewhere
+ case t : Throwable => throw t
+ }
}
}
@@ -421,9 +430,8 @@ self =>
}
}
- class TyperResult(val tree: Tree) extends Exception
+ class TyperResult(val tree: Tree) extends Exception with ControlException
assert(globalPhase.id == 0)
-
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 7565b20c56..ce16b55001 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -7,6 +7,7 @@
package scala.tools.nsc.typechecker
import scala.tools.nsc.util.{Position, NoPosition}
import scala.collection.mutable.ListBuffer
+import scala.util.control.ControlException
import symtab.Flags._
/** This trait ...
@@ -77,7 +78,7 @@ trait Infer {
//todo: remove comments around following privates; right now they cause an IllegalAccess
// error when built with scalac
- /*private*/ class NoInstance(msg: String) extends RuntimeException(msg)
+ /*private*/ class NoInstance(msg: String) extends RuntimeException(msg) with ControlException
/*private*/ class DeferredNoInstance(getmsg: () => String) extends NoInstance("") {
override def getMessage(): String = getmsg()
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index f576c17ad1..b1ed6da208 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -11,7 +11,9 @@
package scala.tools.nsc.typechecker
import scala.collection.mutable.{HashMap, ListBuffer}
+import scala.util.control.ControlException
import scala.compat.Platform.currentTime
+import scala.tools.nsc.interactive.RangePositions
import scala.tools.nsc.util.{HashSet, Position, Set, NoPosition, SourceFile}
import symtab.Flags._
import util.HashSet
@@ -3735,7 +3737,6 @@ trait Typers { self: Analyzer =>
* @return ...
*/
def typed(tree: Tree, mode: Int, pt: Type): Tree = {
- import scala.tools.nsc.interactive.CompilerControl
def dropExistential(tp: Type): Type = tp match {
case ExistentialType(tparams, tpe) =>
@@ -3767,7 +3768,7 @@ trait Typers { self: Analyzer =>
if (phase.id <= currentRun.typerPhase.id) signalDone(context.asInstanceOf[analyzer.Context], tree, result)
result
} catch {
- case ex: CompilerControl#FreshRunReq => throw ex
+ case ex: ControlException => throw ex
case ex: TypeError =>
tree.tpe = null
//Console.println("caught "+ex+" in typed");//DEBUG
diff --git a/src/library/scala/runtime/NonLocalReturnException.scala b/src/library/scala/runtime/NonLocalReturnException.scala
index 7bb7b99341..2884a0ce9f 100644
--- a/src/library/scala/runtime/NonLocalReturnException.scala
+++ b/src/library/scala/runtime/NonLocalReturnException.scala
@@ -13,8 +13,9 @@ package scala.runtime
import Predef.RuntimeException
+import scala.util.control.ControlException
-class NonLocalReturnException[T](val key: AnyRef, val value: T) extends RuntimeException {
+class NonLocalReturnException[T](val key: AnyRef, val value: T) extends RuntimeException with ControlException {
/*
* For efficiency reasons we do not fill in
* the execution stack trace.
diff --git a/src/library/scala/util/control/Breaks.scala b/src/library/scala/util/control/Breaks.scala
index 3315140b6b..25adf80573 100755
--- a/src/library/scala/util/control/Breaks.scala
+++ b/src/library/scala/util/control/Breaks.scala
@@ -44,5 +44,5 @@ class Breaks {
/** A singleton object providing the Break functionality */
object Breaks extends Breaks
-private class BreakException extends RuntimeException
+private class BreakException extends RuntimeException with ControlException
diff --git a/src/library/scala/util/control/ControlException.scala b/src/library/scala/util/control/ControlException.scala
new file mode 100644
index 0000000000..4ac7b0ceeb
--- /dev/null
+++ b/src/library/scala/util/control/ControlException.scala
@@ -0,0 +1,39 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.util.control
+
+/**
+ * A marker trait indicating that the <code>Throwable</code> it is mixed
+ * into is intended for flow control.
+ *
+ * <p>Note that <code>Throwable</code> subclasses which extend this trait
+ * may extend any other <code>Throwable</code> subclass (eg.
+ * <code>RuntimeException</code>) and are not required to extend
+ * <code>Throwable</code> directly.</p>
+ *
+ * <p>Instances of <code>Throwable</code> subclasses marked in
+ * this way should not normally be caught. Where catch-all behaviour is
+ * required <code>ControlException</code>s should be propagated, for
+ * example,</p>
+ *
+ * <pre>
+ * import scala.util.control.ControlException
+ *
+ * try {
+ * // Body might throw arbitrarily
+ * } catch {
+ * case ce : ControlException => throw ce // propagate
+ * case t : Exception => log(t) // log and suppress
+ * </pre>
+ *
+ * @author Miles Sabin
+ */
+trait ControlException extends Throwable