summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/util
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-05-20 11:29:10 +0200
committerEugene Burmako <xeno.by@gmail.com>2013-05-20 11:40:41 +0200
commit8f6b4743a0fac93f671e9eff3fca2b4dec4bf935 (patch)
treec49f6d0997ca9799535ffc311ae2c07f531c432c /src/compiler/scala/tools/nsc/util
parent01dec25425cefb6acc147d8341893eb70ca76245 (diff)
downloadscala-8f6b4743a0fac93f671e9eff3fca2b4dec4bf935.tar.gz
scala-8f6b4743a0fac93f671e9eff3fca2b4dec4bf935.tar.bz2
scala-8f6b4743a0fac93f671e9eff3fca2b4dec4bf935.zip
Moves AbstractFileClassLoader to scala-reflect.jar
Its string name was used in ReflectionUtils and became broken after repl got factored out. This hints that that classloader belongs to where it is used, i.e. to scala-reflect.jar. Moreover AbstractFile is defined in scala-reflect.jar, so it's only logical to also define a derived classloader in scala-reflect.jar.
Diffstat (limited to 'src/compiler/scala/tools/nsc/util')
-rw-r--r--src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala122
-rw-r--r--src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala124
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala9
3 files changed, 9 insertions, 246 deletions
diff --git a/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala b/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala
deleted file mode 100644
index b204c39e9c..0000000000
--- a/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala
+++ /dev/null
@@ -1,122 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- */
-
-package scala.tools.nsc
-package util
-
-import scala.tools.nsc.io.AbstractFile
-import java.security.cert.Certificate
-import java.security.{ ProtectionDomain, CodeSource }
-import java.net.{ URL, URLConnection, URLStreamHandler }
-import scala.collection.{ mutable, immutable }
-
-/**
- * A class loader that loads files from a {@link scala.tools.nsc.io.AbstractFile}.
- *
- * @author Lex Spoon
- */
-class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader)
- extends ClassLoader(parent)
- with ScalaClassLoader
-{
- protected def classNameToPath(name: String): String =
- if (name endsWith ".class") name
- else name.replace('.', '/') + ".class"
-
- protected def findAbstractFile(name: String): AbstractFile = {
- var file: AbstractFile = root
- val pathParts = name split '/'
-
- for (dirPart <- pathParts.init) {
- file = file.lookupName(dirPart, directory = true)
- if (file == null)
- return null
- }
-
- file.lookupName(pathParts.last, directory = false) match {
- case null => null
- case file => file
- }
- }
-
- protected def dirNameToPath(name: String): String =
- name.replace('.', '/')
-
- protected def findAbstractDir(name: String): AbstractFile = {
- var file: AbstractFile = root
- val pathParts = dirNameToPath(name) split '/'
-
- for (dirPart <- pathParts) {
- file = file.lookupName(dirPart, directory = true)
- if (file == null)
- return null
- }
-
- file
- }
-
- // parent delegation in JCL uses getResource; so either add parent.getResAsStream
- // or implement findResource, which we do here as a study in scarlet (my complexion
- // after looking at CLs and URLs)
- override def findResource(name: String): URL = findAbstractFile(name) match {
- case null => null
- case file => new URL(null, "repldir:" + file.path, new URLStreamHandler {
- override def openConnection(url: URL): URLConnection = new URLConnection(url) {
- override def connect() { }
- override def getInputStream = file.input
- }
- })
- }
-
- // this inverts delegation order: super.getResAsStr calls parent.getRes if we fail
- override def getResourceAsStream(name: String) = findAbstractFile(name) match {
- case null => super.getResourceAsStream(name)
- case file => file.input
- }
- // ScalaClassLoader.classBytes uses getResAsStream, so we'll try again before delegating
- override def classBytes(name: String): Array[Byte] = findAbstractFile(classNameToPath(name)) match {
- case null => super.classBytes(name)
- case file => file.toByteArray
- }
- override def findClass(name: String): Class[_] = {
- val bytes = classBytes(name)
- if (bytes.length == 0)
- throw new ClassNotFoundException(name)
- else
- defineClass(name, bytes, 0, bytes.length, protectionDomain)
- }
-
- lazy val protectionDomain = {
- val cl = Thread.currentThread().getContextClassLoader()
- val resource = cl.getResource("scala/runtime/package.class")
- if (resource == null || resource.getProtocol != "jar") null else {
- val s = resource.getPath
- val n = s.lastIndexOf('!')
- if (n < 0) null else {
- val path = s.substring(0, n)
- new ProtectionDomain(new CodeSource(new URL(path), null.asInstanceOf[Array[Certificate]]), null, this, null)
- }
- }
- }
-
- private val packages = mutable.Map[String, Package]()
-
- override def definePackage(name: String, specTitle: String, specVersion: String, specVendor: String, implTitle: String, implVersion: String, implVendor: String, sealBase: URL): Package = {
- throw new UnsupportedOperationException()
- }
-
- override def getPackage(name: String): Package = {
- findAbstractDir(name) match {
- case null => super.getPackage(name)
- case file => packages.getOrElseUpdate(name, {
- val ctor = classOf[Package].getDeclaredConstructor(classOf[String], classOf[String], classOf[String], classOf[String], classOf[String], classOf[String], classOf[String], classOf[URL], classOf[ClassLoader])
- ctor.setAccessible(true)
- ctor.newInstance(name, null, null, null, null, null, null, null, this)
- })
- }
- }
-
- override def getPackages(): Array[Package] =
- root.iterator.filter(_.isDirectory).map(dir => getPackage(dir.name)).toArray
-}
diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
deleted file mode 100644
index 3899ef24c7..0000000000
--- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
+++ /dev/null
@@ -1,124 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Paul Phillips
- */
-
-package scala.tools.nsc
-package util
-
-import java.lang.{ ClassLoader => JClassLoader }
-import java.lang.reflect.{ Constructor, Modifier, Method }
-import java.io.{ File => JFile }
-import java.net.{ URLClassLoader => JURLClassLoader }
-import java.net.URL
-import scala.reflect.runtime.ReflectionUtils.unwrapHandler
-import ScalaClassLoader._
-import scala.util.control.Exception.{ catching }
-import scala.language.implicitConversions
-import scala.reflect.{ ClassTag, classTag }
-
-trait HasClassPath {
- def classPathURLs: Seq[URL]
-}
-
-/** A wrapper around java.lang.ClassLoader to lower the annoyance
- * of java reflection.
- */
-trait ScalaClassLoader extends JClassLoader {
- /** Executing an action with this classloader as context classloader */
- def asContext[T](action: => T): T = {
- val saved = contextLoader
- try { setContext(this) ; action }
- finally setContext(saved)
- }
- def setAsContext() { setContext(this) }
-
- /** Load and link a class with this classloader */
- def tryToLoadClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, initialize = false)
- /** Load, link and initialize a class with this classloader */
- def tryToInitializeClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, initialize = 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[AnyRef](path) map (_.newInstance()) orNull
-
- /** The actual bytes for a class file, or an empty array if it can't be found. */
- def classBytes(className: String): Array[Byte] = classAsStream(className) match {
- case null => Array()
- case stream => io.Streamable.bytes(stream)
- }
-
- /** An InputStream representing the given class name, or null if not found. */
- def classAsStream(className: String) =
- getResourceAsStream(className.replaceAll("""\.""", "/") + ".class")
-
- /** 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")
-
- try asContext(method.invoke(null, Array(arguments.toArray: AnyRef): _*)) // !!! : AnyRef shouldn't be necessary
- catch unwrapHandler({ case ex => throw ex })
- }
-}
-
-/** Methods for obtaining various classloaders.
- * appLoader: the application classloader. (Also called the java system classloader.)
- * extLoader: the extension classloader.
- * bootLoader: the boot classloader.
- * contextLoader: the context classloader.
- */
-object ScalaClassLoader {
- /** Returns loaders which are already ScalaClassLoaders unaltered,
- * and translates java.net.URLClassLoaders into scala URLClassLoaders.
- * Otherwise creates a new wrapper.
- */
- implicit def apply(cl: JClassLoader): ScalaClassLoader = cl match {
- case cl: ScalaClassLoader => cl
- case cl: JURLClassLoader => new URLClassLoader(cl.getURLs.toSeq, cl.getParent)
- case _ => new JClassLoader(cl) with ScalaClassLoader
- }
- def contextLoader = apply(Thread.currentThread.getContextClassLoader)
- def appLoader = apply(JClassLoader.getSystemClassLoader)
- def setContext(cl: JClassLoader) =
- Thread.currentThread.setContextClassLoader(cl)
- def savingContextLoader[T](body: => T): T = {
- val saved = contextLoader
- try body
- finally setContext(saved)
- }
-
- class URLClassLoader(urls: Seq[URL], parent: JClassLoader)
- extends JURLClassLoader(urls.toArray, parent)
- with ScalaClassLoader
- with HasClassPath {
-
- private var classloaderURLs: Seq[URL] = urls
- def classPathURLs: Seq[URL] = classloaderURLs
-
- /** Override to widen to public */
- override def addURL(url: URL) = {
- classloaderURLs :+= url
- super.addURL(url)
- }
- }
-
- def fromURLs(urls: Seq[URL], parent: ClassLoader = null): URLClassLoader =
- new URLClassLoader(urls, parent)
-
- /** True if supplied class exists in supplied path */
- def classExists(urls: Seq[URL], name: String): Boolean =
- fromURLs(urls) tryToLoadClass name isDefined
-
- /** Finding what jar a clazz or instance came from */
- def originOfClass(x: Class[_]): Option[URL] =
- Option(x.getProtectionDomain.getCodeSource) flatMap (x => Option(x.getLocation))
-}
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala
index 5faa2f7513..1e43d18900 100644
--- a/src/compiler/scala/tools/nsc/util/package.scala
+++ b/src/compiler/scala/tools/nsc/util/package.scala
@@ -133,4 +133,13 @@ package object util {
@deprecated("Moved to scala.reflect.internal.util.BatchSourceFile", "2.10.0")
type BatchSourceFile = scala.reflect.internal.util.BatchSourceFile
+
+ @deprecated("Moved to scala.reflect.internal.util.AbstractFileClassLoader", "2.11.0")
+ type AbstractFileClassLoader = scala.reflect.internal.util.AbstractFileClassLoader
+
+ @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0")
+ val ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader
+
+ @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0")
+ type ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader
}