package scala.tools.nsc
package plugins
import io.{ File, Path }
trait Plugins {
self: Global =>
protected def loadRoughPluginsList(): List[Plugin] = {
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 map (Plugin.instantiate(_, this))
}
protected lazy val roughPluginsList: List[Plugin] = loadRoughPluginsList
protected def loadPlugins(): List[Plugin] = {
def pick(
plugins: List[Plugin],
plugNames: Set[String],
phaseNames: Set[String]): List[Plugin] =
{
if (plugins.isEmpty) return Nil
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(), phasesSet map (_.phaseName) toSet)
for (req <- settings.require.value ; if !(plugs exists (_.name == req)))
globalError("Missing required plugin: " + req)
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 (p <- plugs) {
val opts = doOpts(p)
if (!opts.isEmpty)
p.processOptions(opts, globalError)
}
for (opt <- settings.pluginOptions.value ; if plugs forall (p => optList(List(opt), p).isEmpty))
globalError("bad option: -P:" + opt)
plugs
}
lazy val plugins: List[Plugin] = loadPlugins
def pluginDescriptions: String =
roughPluginsList map (x => "%s - %s".format(x.name, x.description)) mkString "\n"
protected def computePluginPhases(): Unit =
phasesSet ++= (plugins flatMap (_.components))
def pluginOptionsHelp: String =
(for (plug <- roughPluginsList ; help <- plug.optionsHelp) yield {
"\nOptions for plugin '%s':\n%s\n".format(plug.name, help)
}) mkString
}