diff options
author | Paul Phillips <paulp@improving.org> | 2009-11-18 00:18:58 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-11-18 00:18:58 +0000 |
commit | ac3931a11d681a35fd4b96717aabe1258067edfc (patch) | |
tree | a173580a819208533a2810c055271a56bc7565f1 /src/compiler | |
parent | 32b04c2801b1eb24e28fe4deafe62c995472e957 (diff) | |
download | scala-ac3931a11d681a35fd4b96717aabe1258067edfc.tar.gz scala-ac3931a11d681a35fd4b96717aabe1258067edfc.tar.bz2 scala-ac3931a11d681a35fd4b96717aabe1258067edfc.zip |
Removing bits from the library which shouldn't ...
Removing bits from the library which shouldn't make the 2.8 cut. Removed
outright:
util.Hashable: unused and I have a better plan for this net.Utility:
class created to accomodate expansion which never materialized
reflect.Invocation: doesn't go far enough, needs love it won't find
right now reflect.RichClass: same as Invocation
Moved into compiler:
util.ScalaClassLoader: too useful to lose, not done enough to ship
Diffstat (limited to 'src/compiler')
6 files changed, 104 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/ant/sabbus/Compiler.scala b/src/compiler/scala/tools/ant/sabbus/Compiler.scala index 787c6af870..f6372f741a 100644 --- a/src/compiler/scala/tools/ant/sabbus/Compiler.scala +++ b/src/compiler/scala/tools/ant/sabbus/Compiler.scala @@ -13,7 +13,7 @@ package scala.tools.ant.sabbus import java.io.File import java.net.URL import java.lang.reflect.InvocationTargetException -import scala.util.ScalaClassLoader +import scala.tools.nsc.util.ScalaClassLoader class Compiler(classpath: Array[URL], val settings: Settings) { diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index 489ab1a3e0..77436fe55f 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -15,7 +15,8 @@ import reflect.InvocationTargetException import scala.collection.immutable.ListSet import scala.collection.mutable import scala.collection.mutable.{ ListBuffer, HashSet, ArrayBuffer } -import scala.util.{ ScalaClassLoader, URLClassLoader } +import scala.tools.nsc.util.ScalaClassLoader +import ScalaClassLoader.URLClassLoader import scala.util.control.Exception.{ Catcher, catching, ultimately, unwrapping } import io.{ PlainFile, VirtualDirectory } @@ -119,11 +120,14 @@ class Interpreter(val settings: Settings, out: PrintWriter) /** the compiler's classpath, as URL's */ val compilerClasspath: List[URL] = { - import scala.net.Utility.parseURL + def parseURL(s: String): Option[URL] = + catching(classOf[MalformedURLException]) opt new URL(s) + val classpathPart = ClassPath.expandPath(compiler.settings.classpath.value).map(s => new File(s).toURL) + val codebasePart = + (compiler.settings.Xcodebase.value.split(" ")).toList flatMap parseURL - val codebasePart = (compiler.settings.Xcodebase.value.split(" ")).toList flatMap parseURL classpathPart ::: codebasePart } diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala index 9cd9cdbd43..0365f28dc3 100644 --- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala +++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala @@ -11,9 +11,8 @@ import java.io.{ File, IOException } import java.lang.{ClassNotFoundException, NoSuchMethodException} import java.lang.reflect.InvocationTargetException import java.net.{ URL, MalformedURLException } -import scala.util.ScalaClassLoader -import util.ClassPath +import util.{ ClassPath, ScalaClassLoader } import File.pathSeparator import Properties.{ versionString, copyrightString } diff --git a/src/compiler/scala/tools/nsc/ObjectRunner.scala b/src/compiler/scala/tools/nsc/ObjectRunner.scala index e4e0826d32..282cff4987 100644 --- a/src/compiler/scala/tools/nsc/ObjectRunner.scala +++ b/src/compiler/scala/tools/nsc/ObjectRunner.scala @@ -8,7 +8,7 @@ package scala.tools.nsc import java.net.URL -import scala.util.ScalaClassLoader +import util.ScalaClassLoader /** An object that runs another object specified by name. * diff --git a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala index cf41852652..02df1d7318 100644 --- a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package interpreter import scala.tools.nsc.io.AbstractFile -import scala.util.ScalaClassLoader +import util.ScalaClassLoader /** * A class loader that loads files from a {@link scala.tools.nsc.io.AbstractFile}. diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala new file mode 100644 index 0000000000..fa1227a859 --- /dev/null +++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala @@ -0,0 +1,93 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2009 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package util + +import java.lang.{ ClassLoader => JavaClassLoader } +import java.lang.reflect.{ Constructor, Modifier, Method } +import java.net.URL +import ScalaClassLoader._ +import scala.util.control.Exception.{ catching } + +trait ScalaClassLoader extends JavaClassLoader +{ + /** Executing an action with this classloader as context classloader */ + def asContext[T](action: => T): T = { + val oldLoader = getContextLoader + try { + setContextLoader(this) + action + } + finally setContextLoader(oldLoader) + } + def setAsContext() { setContextLoader(this) } + + /** Load and link a class with this classloader */ + def tryToLoadClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, false) + /** Load, link and initialize a class with this classloader */ + def tryToInitializeClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, true) + + private def tryClass[T <: AnyRef](path: String, initialize: Boolean): Option[Class[T]] = + catching(classOf[ClassNotFoundException], classOf[SecurityException]) opt + Class.forName(path, initialize, this).asInstanceOf[Class[T]] + + /** Create an instance of a class with this classloader */ + def create(path: String): AnyRef = { + tryToInitializeClass(path) match { + case Some(clazz) => clazz.newInstance() + case None => null + } + } + + /** Run the main method of a class to be loaded by this classloader */ + def run(objectName: String, arguments: Seq[String]) { + val clsToRun = tryToInitializeClass(objectName) getOrElse ( + throw new ClassNotFoundException(objectName) + ) + + val method = clsToRun.getMethod("main", classOf[Array[String]]) + if (!Modifier.isStatic(method.getModifiers)) + throw new NoSuchMethodException(objectName + ".main is not static") + + asContext(method.invoke(null, Array(arguments.toArray: AnyRef): _*)) // !!! : AnyRef shouldn't be necessary + } +} + + +object ScalaClassLoader { + class URLClassLoader(urls: Seq[URL], parent: JavaClassLoader) + extends java.net.URLClassLoader(urls.toArray, parent) + with ScalaClassLoader { + /** Override to widen to public */ + override def addURL(url: URL) = super.addURL(url) + } + + def setContextLoader(cl: JavaClassLoader) = Thread.currentThread.setContextClassLoader(cl) + def getContextLoader() = Thread.currentThread.getContextClassLoader() + def getSystemLoader() = JavaClassLoader.getSystemClassLoader() + def defaultParentClassLoader() = findExtClassLoader() + + def fromURLs(urls: Seq[URL]): URLClassLoader = + new URLClassLoader(urls.toList, defaultParentClassLoader()) + + /** True if supplied class exists in supplied path */ + def classExists(urls: Seq[URL], name: String): Boolean = + (fromURLs(urls) tryToLoadClass name).isDefined + + // we cannot use the app classloader here or we get what looks to + // be classloader deadlock, but if we pass null we bypass the extension + // classloader and our extensions, so we search the hierarchy to find + // the classloader whose parent is null. Resolves bug #857. + def findExtClassLoader(): JavaClassLoader = { + def search(cl: JavaClassLoader): JavaClassLoader = { + if (cl == null) null + else if (cl.getParent == null) cl + else search(cl.getParent) + } + + search(getContextLoader()) + } +} |