summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-09-06 02:32:14 +0000
committerPaul Phillips <paulp@improving.org>2009-09-06 02:32:14 +0000
commitc980b574ba8747d7f0adbeaf1e53fb3850dae840 (patch)
tree938fb2e462421de1be0c936d7779abf52d493a82 /src
parent822b93ac9baa48e510a12f2eae81a290926e06e6 (diff)
downloadscala-c980b574ba8747d7f0adbeaf1e53fb3850dae840.tar.gz
scala-c980b574ba8747d7f0adbeaf1e53fb3850dae840.tar.bz2
scala-c980b574ba8747d7f0adbeaf1e53fb3850dae840.zip
Converts some "lazy vals by hand" (probably pre...
Converts some "lazy vals by hand" (probably predating the availability of lazy vals) to lazy vals. Streamlined some Plugin(s) logic and took minor advantage of scala.io.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala10
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala91
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugins.scala146
-rw-r--r--src/library/scala/io/File.scala2
4 files changed, 100 insertions, 149 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 02d65d7e05..56b8253fa7 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -623,18 +623,12 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
buildCompilerFromPhasesSet() // PhaseAssembly.scala
}
- /* Simple option value to hold the compiler phase chain */
- private var phasesCache: Option[List[SubComponent]] = None
+ /* The phase descriptor list */
+ lazy val phaseDescriptors: List[SubComponent] = computePhaseDescriptors
/* The set of phase objects that is the basis for the compiler phase chain */
protected val phasesSet : HashSet[SubComponent] = new HashSet[SubComponent]
- /** A accessor for the phase descriptor list (List of SubComponents), Only calculate the list once */
- def phaseDescriptors = {
- if (phasesCache.isEmpty) phasesCache = Some(computePhaseDescriptors)
- phasesCache.get
- }
-
/** A description of the phases that will run */
def phaseDescriptions: String = {
new Run // force some initialization
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index 3013199c36..a7b686e750 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 scala.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..a67218ee01 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 scala.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
}
diff --git a/src/library/scala/io/File.scala b/src/library/scala/io/File.scala
index b4131d7e57..74a66492ec 100644
--- a/src/library/scala/io/File.scala
+++ b/src/library/scala/io/File.scala
@@ -18,6 +18,8 @@ import collection.Traversable
object File
{
+ def pathSeparator = JFile.pathSeparator
+
def apply(path: Path)(implicit codec: Codec = null) =
if (codec != null) new File(path.jfile)(codec)
else path.toFile