summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/plugins
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-09-11 18:12:33 +0000
committerPaul Phillips <paulp@improving.org>2009-09-11 18:12:33 +0000
commite604abb25c1c95aa75b969519aea3a915ba11798 (patch)
tree05081680122b722e0d62c2b34cbc18cc7c5019ed /src/compiler/scala/tools/nsc/plugins
parentf9394a4d472887c4563e768467170a9b1677d5c1 (diff)
downloadscala-e604abb25c1c95aa75b969519aea3a915ba11798.tar.gz
scala-e604abb25c1c95aa75b969519aea3a915ba11798.tar.bz2
scala-e604abb25c1c95aa75b969519aea3a915ba11798.zip
Resurrected the former contents of scala.io in ...
Resurrected the former contents of scala.io in their new home, scala.tools.nsc.io, and equipped them with fake beards and handlebar moustaches. Also restored the reverted bits of the compiler which had been taking advantage of them.
Diffstat (limited to 'src/compiler/scala/tools/nsc/plugins')
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala91
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugins.scala146
2 files changed, 96 insertions, 141 deletions
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index 3013199c36..2b61724c49 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
@@ -7,7 +7,7 @@
package scala.tools.nsc
package plugins
-import java.io.File
+import io.{ File, Path }
import java.net.URLClassLoader
import java.util.jar.JarFile
import java.util.zip.ZipException
@@ -63,39 +63,44 @@ abstract class Plugin {
* @author Lex Spoon
* @version 1.0, 2007-5-21
*/
-object Plugin {
+object Plugin
+{
+ private val PluginXML = "scalac-plugin.xml"
+
/** Create a class loader with the specified file plus
* the loader that loaded the Scala compiler.
*/
- private def loaderFor(jarfiles: Seq[File]): ClassLoader = {
+ private def loaderFor(jarfiles: Seq[Path]): ClassLoader = {
val compilerLoader = classOf[Plugin].getClassLoader
- val jarurls = jarfiles.map(_.toURL).toArray
- new URLClassLoader(jarurls, compilerLoader)
+ val jarurls = jarfiles map (_.toURL)
+
+ new URLClassLoader(jarurls.toArray, compilerLoader)
}
/** Try to load a plugin description from the specified
* file, returning None if it does not work. */
- private def loadDescription(jarfile: File): Option[PluginDescription] = {
- if (!jarfile.exists) return None
+ private def loadDescription(jarfile: Path): Option[PluginDescription] =
+ // XXX Return to this once we have some ARM support
+ if (!jarfile.exists) None
+ else try {
+ val jar = new JarFile(jarfile.jfile)
- try {
- val jar = new JarFile(jarfile)
try {
- val ent = jar.getEntry("scalac-plugin.xml")
- if (ent == null) return None
-
- val inBytes = jar.getInputStream(ent)
- val packXML = XML.load(inBytes)
- inBytes.close()
-
- PluginDescription.fromXML(packXML)
- } finally {
- jar.close()
+ (jar getEntry PluginXML) match {
+ case null => None
+ case entry =>
+ val in = jar getInputStream entry
+ val packXML = XML load in
+ in.close()
+
+ PluginDescription fromXML packXML
+ }
}
- } catch {
+ finally jar.close()
+ }
+ catch {
case _: ZipException => None
}
- }
type AnyClass = Class[_]
@@ -103,16 +108,13 @@ object Plugin {
* if the jar file has no plugin in it or if the plugin
* is badly formed.
*/
- def loadFrom(jarfile: File, loader: ClassLoader): Option[AnyClass] = {
+ def loadFrom(jarfile: Path, loader: ClassLoader): Option[AnyClass] = {
val pluginInfo = loadDescription(jarfile).get
- try {
- Some(loader.loadClass(pluginInfo.classname))
- } catch {
- case _:ClassNotFoundException =>
- println("Warning: class not found for plugin in " + jarfile +
- " (" + pluginInfo.classname + ")")
- None
+ try Some(loader loadClass pluginInfo.classname) catch {
+ case _: ClassNotFoundException =>
+ println("Warning: class not found for plugin in %s (%s)".format(jarfile, pluginInfo.classname))
+ None
}
}
@@ -121,35 +123,28 @@ object Plugin {
* directories specified. Skips all plugins in <code>ignoring</code>.
* A single classloader is created and used to load all of them.
*/
- def loadAllFrom(jars: List[File],
- dirs: List[File],
- ignoring: List[String]): List[AnyClass] =
+ def loadAllFrom(
+ jars: List[Path],
+ dirs: List[Path],
+ ignoring: List[String]): List[AnyClass] =
{
- val alljars = new ListBuffer[File]
-
- alljars ++= jars
-
- for {
+ val alljars = jars ::: (for {
dir <- dirs if dir.isDirectory
- entries = dir.listFiles
- if entries ne null
- entry <- entries.toList.sort(_.getName <= _.getName)
- if entry.toString.toLowerCase endsWith ".jar"
+ entry <- dir.toDirectory.files.toList sortWith (_.name <= _.name)
+ if entry.name.toLowerCase endsWith ".jar"
pdesc <- loadDescription(entry)
if !(ignoring contains pdesc.name)
- } alljars += entry
+ } yield entry)
- val loader = loaderFor(alljars.toList)
- alljars.toList.map(f => loadFrom(f,loader)).flatMap(x => x)
+ val loader = loaderFor(alljars)
+ alljars map (loadFrom(_, loader)) flatten
}
/** Instantiate a plugin class, given the class and
* the compiler it is to be used in.
*/
def instantiate(clazz: AnyClass, global: Global): Plugin = {
- //println("instantiating "+clazz)
- //println(clazz.getDeclaredConstructors)
- val constructor = clazz.getConstructor(classOf[Global])
- constructor.newInstance(global).asInstanceOf[Plugin]
+ val constructor = clazz getConstructor classOf[Global]
+ (constructor newInstance global).asInstanceOf[Plugin]
}
}
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
index 1163ae5a6a..93a3f46ac2 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
@@ -8,7 +8,7 @@
package scala.tools.nsc
package plugins
-import java.io.File
+import io.{ File, Path }
/** Support for run-time loading of compiler plugins.
*
@@ -16,7 +16,9 @@ import java.io.File
* @version 1.1, 2009/1/2
* Updated 2009/1/2 by Anders Bach Nielsen: Added features to implement SIP 00002
*/
-trait Plugins { self: Global =>
+trait Plugins
+{
+ self: Global =>
/** Load a rough list of the plugins. For speed, it
* does not instantiate a compiler run. Therefore it cannot
@@ -24,24 +26,17 @@ trait Plugins { self: Global =>
* filtered from the final list of plugins.
*/
protected def loadRoughPluginsList(): List[Plugin] = {
- val jars = settings.plugin.value.map(new File(_))
- val dirs =
- for (name <- settings.pluginsDir.value.split(File.pathSeparator).toList)
- yield new File(name)
+ val jars = settings.plugin.value map Path.apply
+ val dirs = (settings.pluginsDir.value split File.pathSeparator).toList map Path.apply
+ val classes = Plugin.loadAllFrom(jars, dirs, settings.disable.value)
+
+ classes foreach (c => Plugin.instantiate(c, this))
for (plugClass <- Plugin.loadAllFrom(jars, dirs, settings.disable.value))
yield Plugin.instantiate(plugClass, this)
}
- private var roughPluginsListCache: Option[List[Plugin]] = None
-
- protected def roughPluginsList: List[Plugin] =
- roughPluginsListCache match {
- case Some(list) => list
- case None =>
- roughPluginsListCache = Some(loadRoughPluginsList)
- roughPluginsListCache.get
- }
+ protected lazy val roughPluginsList: List[Plugin] = loadRoughPluginsList
/** Load all available plugins. Skips plugins that
* either have the same name as another one, or which
@@ -54,105 +49,70 @@ trait Plugins { self: Global =>
plugNames: Set[String],
phaseNames: Set[String]): List[Plugin] =
{
- plugins match {
- case Nil => Nil
- case plug :: rest =>
- val plugPhaseNames = Set.empty ++ plug.components.map(_.phaseName)
- def withoutPlug = pick(rest, plugNames, plugPhaseNames)
- def withPlug =
- (plug ::
- pick(rest,
- plugNames+plug.name,
- phaseNames++plugPhaseNames))
-
- if (plugNames.contains(plug.name)) {
- if (settings.verbose.value)
- inform("[skipping a repeated plugin: " + plug.name + "]")
- withoutPlug
- } else if (settings.disable.value contains(plug.name)) {
- if (settings.verbose.value)
- inform("[disabling plugin: " + plug.name + "]")
- withoutPlug
- } else {
- val commonPhases = phaseNames.intersect(plugPhaseNames)
- if (!commonPhases.isEmpty) {
- if (settings.verbose.value)
- inform("[skipping plugin " + plug.name +
- "because it repeats phase names: " +
- commonPhases.mkString(", ") + "]")
- withoutPlug
- } else {
- if (settings.verbose.value)
- inform("[loaded plugin " + plug.name + "]")
- withPlug
- }
- }
+ if (plugins.isEmpty) return Nil // early return
+
+ val plug :: tail = plugins
+ val plugPhaseNames = Set(plug.components map (_.phaseName): _*)
+ def withoutPlug = pick(tail, plugNames, plugPhaseNames)
+ def withPlug = plug :: pick(tail, plugNames + plug.name, phaseNames ++ plugPhaseNames)
+ lazy val commonPhases = phaseNames intersect plugPhaseNames
+
+ def note(msg: String): Unit = if (settings.verbose.value) inform(msg format plug.name)
+ def fail(msg: String) = { note(msg) ; withoutPlug }
+
+ if (plugNames contains plug.name)
+ fail("[skipping a repeated plugin: %s]")
+ else if (settings.disable.value contains plug.name)
+ fail("[disabling plugin: %s]")
+ else if (!commonPhases.isEmpty)
+ fail("[skipping plugin %s because it repeats phase names: " + (commonPhases mkString ", ") + "]")
+ else {
+ note("[loaded plugin %s]")
+ withPlug
}
}
- val plugs =
- pick(roughPluginsList,
- Set.empty,
- Set.empty ++ phasesSet.map(_.phaseName))
+ val plugs = pick(roughPluginsList, Set(), phasesSet map (_.phaseName) toSet)
- for (req <- settings.require.value; if !plugs.exists(p => p.name==req))
+ /** Verify requirements are present. */
+ for (req <- settings.require.value ; if !(plugs exists (_.name == req)))
error("Missing required plugin: " + req)
+ /** Process plugin options. */
+ def namec(plug: Plugin) = plug.name + ":"
+ def optList(xs: List[String], p: Plugin) = xs filter (_ startsWith namec(p))
+ def doOpts(p: Plugin): List[String] =
+ optList(settings.pluginOptions.value, p) map (_ stripPrefix namec(p))
- for (plug <- plugs) {
- val nameColon = plug.name + ":"
- val opts = for {
- raw <- settings.pluginOptions.value
- if raw.startsWith(nameColon)
- } yield raw.substring(nameColon.length)
-
+ for (p <- plugs) {
+ val opts = doOpts(p)
if (!opts.isEmpty)
- plug.processOptions(opts, error)
+ p.processOptions(opts, error)
}
- for {
- opt <- settings.pluginOptions.value
- if !plugs.exists(p => opt.startsWith(p.name + ":"))
- } error("bad option: -P:" + opt)
+ /** Verify no non-existent plugin given with -P */
+ for (opt <- settings.pluginOptions.value ; if plugs forall (p => optList(List(opt), p).isEmpty))
+ error("bad option: -P:" + opt)
plugs
}
- private var pluginsCache: Option[List[Plugin]] = None
-
- def plugins: List[Plugin] = {
- if (pluginsCache.isEmpty)
- pluginsCache = Some(loadPlugins)
- pluginsCache.get
- }
+ lazy val plugins: List[Plugin] = loadPlugins
/** A description of all the plugins that are loaded */
- def pluginDescriptions: String = {
- val messages =
- for (plugin <- roughPluginsList)
- yield plugin.name + " - " + plugin.description
- messages.mkString("\n")
- }
+ def pluginDescriptions: String =
+ roughPluginsList map (x => "%s - %s".format(x.name, x.description)) mkString "\n"
/**
* Extract all phases supplied by plugins and add them to the phasesSet.
* @see phasesSet
*/
- protected def computePluginPhases() {
- val plugPhases = plugins.flatMap(_.components)
- for (pPhase <- plugPhases) {
- phasesSet += pPhase
- }
- }
+ protected def computePluginPhases(): Unit =
+ phasesSet ++= (plugins flatMap (_.components))
/** Summary of the options for all loaded plugins */
- def pluginOptionsHelp: String = {
- val buf = new StringBuffer
- for (plug <- roughPluginsList; help <- plug.optionsHelp) {
- buf append ("Options for plugin " + plug.name + ":\n")
- buf append help
- buf append "\n"
- }
- buf.toString
- }
+ def pluginOptionsHelp: String =
+ (for (plug <- roughPluginsList ; help <- plug.optionsHelp) yield {
+ "Options for plugin %s:\n%s\n".format(plug.name, help)
+ }) mkString
}