summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-09-07 17:48:09 +0000
committerPaul Phillips <paulp@improving.org>2010-09-07 17:48:09 +0000
commit6dfcae30bfcdc93509755185f814c8e318a64012 (patch)
tree713036c0fa3b3504fd7ca8e9d991f33cc9dbeae0 /src
parentb5c20527352085b01457e9104137de7b28eafdff (diff)
downloadscala-6dfcae30bfcdc93509755185f814c8e318a64012.tar.gz
scala-6dfcae30bfcdc93509755185f814c8e318a64012.tar.bz2
scala-6dfcae30bfcdc93509755185f814c8e318a64012.zip
Some modifications to repl classloading to make...
Some modifications to repl classloading to make it usable in managed classloader environments. Contributed by mark harrah. Review by rytz.
Diffstat (limited to 'src')
-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