diff options
Diffstat (limited to 'src/compiler/scala')
8 files changed, 96 insertions, 34 deletions
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 9e59c1d509..9ba47c2d8b 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -119,7 +119,6 @@ abstract class SymbolTable extends api.Universe object perRunCaches { import java.lang.ref.WeakReference - import scala.tools.util.Signallable import scala.runtime.ScalaRunTime.stringOf // We can allow ourselves a structural type, these methods @@ -143,9 +142,9 @@ abstract class SymbolTable extends api.Universe )) } } - if (settings.debug.value) { - println(Signallable("dump compiler caches")(dumpCaches())) - } + // if (settings.debug.value) { + // println(Signallable("dump compiler caches")(dumpCaches())) + // } def recordCache[T <: Clearable](cache: T): T = { caches += new WeakReference(cache) diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index 457a34f9dc..e9d36e0bdb 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -66,7 +66,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) // Install a signal handler so we can be prodded. private val signallable = - if (isReplDebug) Signallable("Dump repl state.")(dumpCommand()) + if (isReplDebug && !settings.Yreplsync.value) + Signallable("Dump repl state.")(dumpCommand()) else null // classpath entries added via :cp @@ -95,19 +96,21 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) override lazy val formatting = new Formatting { def prompt = ILoop.this.prompt } - override protected def createLineManager() = new Line.Manager { - override def onRunaway(line: Line[_]): Unit = { - val template = """ - |// She's gone rogue, captain! Have to take her out! - |// Calling Thread.stop on runaway %s with offending code: - |// scala> %s""".stripMargin - - echo(template.format(line.thread, line.code)) - // XXX no way to suppress the deprecation warning - line.thread.stop() - in.redrawLine() + override protected def createLineManager(): Line.Manager = + if (ReplPropsKludge.noThreadCreation(settings)) null else new Line.Manager { + override def onRunaway(line: Line[_]): Unit = { + val template = """ + |// She's gone rogue, captain! Have to take her out! + |// Calling Thread.stop on runaway %s with offending code: + |// scala> %s""".stripMargin + + echo(template.format(line.thread, line.code)) + // XXX no way to suppress the deprecation warning + line.thread.stop() + in.redrawLine() + } } - } + override protected def parentClassLoader = settings.explicitParentLoader.getOrElse( classOf[ILoop].getClassLoader ) } diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala index a9c092861f..6ebe3f7362 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala @@ -47,7 +47,7 @@ trait ILoopInit { } ignoring(classOf[Exception]) { SignalManager("INT") = { - if (intp == null) + if (intp == null || intp.lineManager == null) onExit() else if (intp.lineManager.running) intp.lineManager.cancel() diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 0a5104f824..9d042f2401 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -265,7 +265,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** Create a line manager. Overridable. */ protected def createLineManager(): Line.Manager = - if (replProps.noThreads) null else new Line.Manager + if (ReplPropsKludge.noThreadCreation(settings)) null else new Line.Manager /** Instantiate a compiler. Overridable. */ protected def newCompiler(settings: Settings, reporter: Reporter) = { @@ -967,7 +967,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** load and run the code using reflection */ def loadAndRun: (String, Boolean) = { - if (replProps.noThreads) return { + if (lineManager == null) return { try { ("" + (lineRep call sessionNames.print), true) } catch { case ex => (lineRep.bindError(ex), false) } } diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplProps.scala b/src/compiler/scala/tools/nsc/interpreter/ReplProps.scala index 72bfb2eeff..99489b7c99 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplProps.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplProps.scala @@ -24,3 +24,9 @@ class ReplProps { val powerInitCode = Prop[JFile]("scala.repl.power.initcode") val powerBanner = Prop[JFile]("scala.repl.power.banner") } + +object ReplPropsKludge { + // !!! short term binary compatibility hack for 2.9.1 to put this + // here - needed a not previously existing object. + def noThreadCreation(settings: Settings) = replProps.noThreads || settings.Yreplsync.value +} diff --git a/src/compiler/scala/tools/reflect/WrappedProperties.scala b/src/compiler/scala/tools/reflect/WrappedProperties.scala new file mode 100644 index 0000000000..2ca374cf01 --- /dev/null +++ b/src/compiler/scala/tools/reflect/WrappedProperties.scala @@ -0,0 +1,39 @@ +/* NSC -- new Scala compiler + * Copyright 2006-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package reflect + +import scala.util.PropertiesTrait +import java.security.AccessControlException + +/** For placing a wrapper function around property functions. + * Motivated by places like google app engine throwing exceptions + * on property lookups. + */ +trait WrappedProperties extends PropertiesTrait { + def wrap[T](body: => T): Option[T] + + protected def propCategory = "wrapped" + protected def pickJarBasedOn = this.getClass + + override def propIsSet(name: String) = wrap(super.propIsSet(name)) exists (x => x) + override def propOrElse(name: String, alt: String) = wrap(super.propOrElse(name, alt)) getOrElse alt + override def setProp(name: String, value: String) = wrap(super.setProp(name, value)) orNull + override def clearProp(name: String) = wrap(super.clearProp(name)) orNull + override def envOrElse(name: String, alt: String) = wrap(super.envOrElse(name, alt)) getOrElse alt + override def envOrNone(name: String) = wrap(super.envOrNone(name)).flatten + + def systemProperties: Iterator[(String, String)] = { + import scala.collection.JavaConverters._ + wrap(System.getProperties.asScala.iterator) getOrElse Iterator.empty + } +} + +object WrappedProperties { + object AccessControl extends WrappedProperties { + def wrap[T](body: => T) = try Some(body) catch { case _: AccessControlException => None } + } +} diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala index 3ea5aa1703..c5d0e1edea 100644 --- a/src/compiler/scala/tools/util/PathResolver.scala +++ b/src/compiler/scala/tools/util/PathResolver.scala @@ -7,7 +7,7 @@ package scala.tools package util import java.net.{ URL, MalformedURLException } -import scala.util.Properties._ +import scala.tools.reflect.WrappedProperties.AccessControl import nsc.{ Settings, GenericRunnerSettings } import nsc.util.{ ClassPath, JavaClassPath, ScalaClassLoader } import nsc.io.{ File, Directory, Path, AbstractFile } @@ -18,6 +18,10 @@ import PartialFunction.condOpt // https://wiki.scala-lang.org/display/SW/Classpath object PathResolver { + // Imports property/environment functions which suppress + // security exceptions. + import AccessControl._ + def firstNonEmpty(xs: String*) = xs find (_ != "") getOrElse "" /** Map all classpath elements to absolute paths and reconstruct the classpath. @@ -34,10 +38,9 @@ object PathResolver { /** Values found solely by inspecting environment or property variables. */ object Environment { - private def searchForBootClasspath = { - import scala.collection.JavaConversions._ - System.getProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse "" - } + private def searchForBootClasspath = ( + systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse "" + ) /** Environment variables which java pays attention to so it * seems we do as well. diff --git a/src/compiler/scala/tools/util/Signallable.scala b/src/compiler/scala/tools/util/Signallable.scala index 2979e196e3..af98bfac83 100644 --- a/src/compiler/scala/tools/util/Signallable.scala +++ b/src/compiler/scala/tools/util/Signallable.scala @@ -6,11 +6,17 @@ package scala.tools package util +import java.security.AccessControlException + /** A class for things which are signallable. */ abstract class Signallable[T] private (val signal: String, val description: String) { private var last: Option[T] = None - private def lastString = last filterNot (_ == ()) map (_.toString) getOrElse "" + private def lastString = last match { + case Some(()) => "" + case Some(x) => "" + x + case _ => "" + } /** The most recent result from the signal handler. */ def lastResult: Option[T] = last @@ -29,8 +35,9 @@ abstract class Signallable[T] private (val signal: String, val description: Stri object Signallable { /** Same as the other apply, but an open signal is found for you. */ - def apply[T](description: String)(body: => T): Signallable[T] = + def apply[T](description: String)(body: => T): Signallable[T] = wrap { apply(SignalManager.findOpenSignal().name, description)(body) + } /** Given a signal name, a description, and a handler body, this * registers a signal handler and returns the Signallable instance. @@ -38,16 +45,21 @@ object Signallable { * SignalManager.info(), or sending SIGINFO to the manager will * dump it to console. */ - def apply[T](signal: String, description: String)(body: => T): Signallable[T] = { - val result = new Signallable[T](signal, description) { - def onSignal(): T = { + def apply[T](signal: String, description: String)(body: => T): Signallable[T] = wrap { + val result = create[T](signal, description, body) + SignalManager.public(signal, description)(result.onSignal()) + result + } + + private def wrap[T](body: => Signallable[T]): Signallable[T] = + try body catch { case _: AccessControlException => null } + + private def create[T](signal: String, description: String, body: => T): Signallable[T] = + new Signallable[T](signal, description) { + def onSignal = { val result = body last = Some(result) result } } - SignalManager.public(signal, description)(result.onSignal()) - result - } } - |