summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala15
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterLoop.scala3
-rw-r--r--src/compiler/scala/tools/nsc/settings/MutableSettings.scala28
3 files changed, 39 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index 7dd6d3ba04..3be1b44a4c 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -229,7 +229,9 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
private def methodByName(c: Class[_], name: String): reflect.Method =
c.getMethod(name, classOf[Object])
- protected def parentClassLoader: ClassLoader = this.getClass.getClassLoader()
+ protected def parentClassLoader: ClassLoader =
+ settings.explicitParentLoader.getOrElse( this.getClass.getClassLoader() )
+
def getInterpreterClassLoader() = classLoader
// Set the current Java "context" class loader to this interpreter's class loader
@@ -1267,15 +1269,16 @@ object Interpreter {
}
}
}
- def breakIf(assertion: => Boolean, args: DebugParam[_]*): Unit =
- if (assertion) break(args.toList)
+ // provide the enclosing type T
+ // in order to set up the interpreter's classpath and parent class loader properly
+ def breakIf[T: Manifest](assertion: => Boolean, args: DebugParam[_]*): Unit =
+ if (assertion) break[T](args.toList)
// start a repl, binding supplied args
- def break(args: List[DebugParam[_]]): Unit = {
+ def break[T: Manifest](args: List[DebugParam[_]]): Unit = {
val intLoop = new InterpreterLoop
intLoop.settings = new Settings(Console.println)
- // XXX come back to the dot handling
- intLoop.settings.classpath.value = "."
+ intLoop.settings.embeddedDefaults[T]
intLoop.createInterpreter
intLoop.in = InteractiveReader.createDefault(intLoop.interpreter)
diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
index f68ce4a5b4..bdcd7b9f58 100644
--- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
@@ -117,7 +117,8 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
settings.classpath append addedClasspath
interpreter = new Interpreter(settings, out) {
- override protected def parentClassLoader = classOf[InterpreterLoop].getClassLoader
+ override protected def parentClassLoader =
+ settings.explicitParentLoader.getOrElse( classOf[InterpreterLoop].getClassLoader )
}
interpreter.setContextClassLoader()
// interpreter.quietBind("settings", "scala.tools.nsc.InterpreterSettings", interpreter.isettings)
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
index 1e0e00e01d..c15a4279fb 100644
--- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
@@ -11,6 +11,7 @@ package settings
import io.{AbstractFile, VirtualDirectory}
import scala.tools.util.StringOps
import scala.collection.mutable.ListBuffer
+import scala.io.Source
/** A mutable Settings object.
*/
@@ -160,6 +161,33 @@ class MutableSettings(val errorFn: String => Unit) extends AbsSettings with Scal
doArgs(args)
}
+ /** Initializes these settings for embedded use by type `T`.
+ * The class loader defining `T` should provide resources `app.class.path`
+ * and `boot.class.path`. These resources should contain the application
+ * and boot classpaths in the same form as would be passed on the command line.*/
+ def embeddedDefaults[T: Manifest]: Unit =
+ embeddedDefaults(implicitly[Manifest[T]].erasure.getClassLoader)
+
+ /** Initializes these settings for embedded use by a class from the given class loader.
+ * The class loader for `T` should provide resources `app.class.path`
+ * and `boot.class.path`. These resources should contain the application
+ * and boot classpaths in the same form as would be passed on the command line.*/
+ def embeddedDefaults(loader: ClassLoader) {
+ explicitParentLoader = Option(loader) // for the Interpreter parentClassLoader
+ getClasspath("app", loader) foreach { classpath.value = _ }
+ getClasspath("boot", loader) foreach { bootclasspath append _ }
+ }
+
+ /** The parent loader to use for the interpreter.*/
+ private[nsc] var explicitParentLoader: Option[ClassLoader] = None
+
+ /** Retrieves the contents of resource "${id}.class.path" from `loader`
+ * (wrapped in Some) or None if the resource does not exist.*/
+ private def getClasspath(id: String, loader: ClassLoader): Option[String] =
+ Option(loader).flatMap(ld => Option(ld.getResource(id + ".class.path"))).map { cp =>
+ Source.fromURL(cp).mkString
+ }
+
// a wrapper for all Setting creators to keep our list up to date
private def add[T <: Setting](s: T): T = {
allSettings += s