summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2013-07-25 19:52:15 -0700
committerSom Snytt <som.snytt@gmail.com>2013-08-21 17:03:03 -0700
commitf3731f9ace5d3d5e213ea786fe0027ea66c5358b (patch)
treefb068e41ba1e2aabf0cff642e1d3b47590ef4d12
parent79d619127bb84ef858476252ace53b730d2e38cd (diff)
downloadscala-f3731f9ace5d3d5e213ea786fe0027ea66c5358b.tar.gz
scala-f3731f9ace5d3d5e213ea786fe0027ea66c5358b.tar.bz2
scala-f3731f9ace5d3d5e213ea786fe0027ea66c5358b.zip
SI-7622 Plugins can be not enabled
Plugins can interrogate options and declare themselves not enabled. The plugin itself can return false from its init if the options do not compute. A plugin phase component can declare itself not enabled, same as an internal phase. No one exploits this facility at this commit.
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala29
-rw-r--r--src/compiler/scala/tools/nsc/plugins/PluginComponent.scala6
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugins.scala25
-rw-r--r--test/files/neg/t7494-no-options.check2
4 files changed, 35 insertions, 27 deletions
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index 4fd6ba7d9d..1578caff26 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
@@ -41,12 +41,31 @@ abstract class Plugin {
*/
val global: Global
- /** Handle any plugin-specific options. The `-P:plugname:` part
- * will not be present.
+ def options: List[String] = {
+ // Process plugin options of form plugin:option
+ def namec = name + ":"
+ global.settings.pluginOptions.value filter (_ startsWith namec) map (_ stripPrefix namec)
+ }
+
+ /** Handle any plugin-specific options.
+ * The user writes `-P:plugname:opt1,opt2`,
+ * but the plugin sees `List(opt1, opt2)`.
+ * The plugin can opt out of further processing
+ * by returning false. For example, if the plugin
+ * has an "enable" flag, now would be a good time
+ * to sit on the bench.
+ * @param options plugin arguments
+ * @param error error function
+ * @return true to continue, or false to opt out
*/
- def processOptions(options: List[String], error: String => Unit) {
- if (!options.isEmpty)
- error("Error: " + name + " has no options")
+ def init(options: List[String], error: String => Unit): Boolean = {
+ processOptions(options, error)
+ true
+ }
+
+ @deprecated("use Plugin#init instead", since="2.11")
+ def processOptions(options: List[String], error: String => Unit): Unit = {
+ if (!options.isEmpty) error(s"Error: $name takes no options")
}
/** A description of this plugin's options, suitable as a response
diff --git a/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala b/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala
index c6e1af7ea4..a6df08c331 100644
--- a/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala
+++ b/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala
@@ -15,12 +15,10 @@ package plugins
*/
abstract class PluginComponent extends SubComponent {
- /** Internal flag to tell external from internal phases */
+ /** By definition, plugin phases are externally provided. */
final override val internal = false
- /** Phases supplied by plugins should not have to supply the
- * runsRightAfter constraint, but can override it.
- */
+ /** Only plugins are granted a reprieve from specifying whether they follow. */
val runsRightAfter: Option[String] = None
/** Useful for -Xshow-phases. */
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
index 8f7794fa90..4769705404 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
@@ -78,27 +78,18 @@ trait Plugins {
val plugs = pick(roughPluginsList, Set(), (phasesSet map (_.phaseName)).toSet)
- /* Verify requirements are present. */
+ // Verify required plugins are present.
for (req <- settings.require.value ; if !(plugs exists (_.name == req)))
globalError("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))
+ // Verify no non-existent plugin given with -P
+ for {
+ opt <- settings.pluginOptions.value
+ if !(plugs exists (opt startsWith _.name + ":"))
+ } globalError("bad option: -P:" + opt)
- for (p <- plugs) {
- val opts = doOpts(p)
- if (!opts.isEmpty)
- p.processOptions(opts, globalError)
- }
-
- /* Verify no non-existent plugin given with -P */
- for (opt <- settings.pluginOptions.value ; if plugs forall (p => optList(List(opt), p).isEmpty))
- globalError("bad option: -P:" + opt)
-
- plugs
+ // Plugins may opt out, unless we just want to show info
+ plugs filter (p => p.init(p.options, globalError) || (settings.debug && settings.isInfo))
}
lazy val plugins: List[Plugin] = loadPlugins()
diff --git a/test/files/neg/t7494-no-options.check b/test/files/neg/t7494-no-options.check
index efc91a6215..04fbf0ec72 100644
--- a/test/files/neg/t7494-no-options.check
+++ b/test/files/neg/t7494-no-options.check
@@ -1,4 +1,4 @@
-error: Error: ploogin has no options
+error: Error: ploogin takes no options
phase name id description
---------- -- -----------
parser 1 parse source into ASTs, perform simple desugaring