diff options
Diffstat (limited to 'docs/examples/plugintemplate/src')
5 files changed, 186 insertions, 0 deletions
diff --git a/docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala b/docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala new file mode 100644 index 0000000000..e9c2050a29 --- /dev/null +++ b/docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala @@ -0,0 +1,61 @@ +package plugintemplate + +import java.util.Properties + +/** A utility to load properties of this plugin via the property + * file "plugin.properties" + */ +object PluginProperties { + private val propFilename = "plugin.properties" + + val pluginName = getOrElse("plugin.name", "(name_unknown)") + val pluginDescription = getOrElse("plugin.description", "(plugin description not found)") + val pluginCommand = getOrElse("plugin.commandname", "(command_unknown)") + val versionString = { + val default = "(version_unknown)" + props match { + case Some(p) => + val major = p.getProperty("version.major") + val minor = p.getProperty("version.minor") + if ((major eq null) || (minor eq null)) default + else major +"."+ minor + case None => default + } + } + + private def getOrElse(property: String, default: String) = { + props match { + case Some(p) if (p.getProperty(property) != null) => + p.getProperty(property) + case _ => + default + } + } + + private lazy val props: Option[Properties] = { + /** Running from JAR file: the properties file should be in the + * jar as well + */ + var stream = this.getClass.getResourceAsStream("/"+ propFilename) + if (stream == null) { + /** Running from .class files: expect classfiles to be in + * directory [...]/build/build.main, and [...] to contain + * the properties file. + */ + try { + val current = this.getClass.getClassLoader.getResource(".") + val dir = new java.io.File(current.toURI) + // dir will be [...]/build/build.main/ + stream = new java.io.FileInputStream(dir.getParentFile.getParent +"/"+ propFilename) + } catch { + case _ => () + } + } + if (stream == null) None + else { + val p = new Properties + p.load(stream) + Some(p) + } + } +}
\ No newline at end of file diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala new file mode 100644 index 0000000000..b6e405dcef --- /dev/null +++ b/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala @@ -0,0 +1,33 @@ +package plugintemplate + +import scala.tools.nsc._ +import scala.tools.nsc.plugins.PluginComponent + +/** This class shows how to implement a compiler component that + * can be used in a compiler plugin. + * + * @todo Adapt the name of this class to the plugin, and implement it. + */ +class TemplateComponent(val global: Global) extends PluginComponent { + import global._ + import global.definitions._ + + val runsAfter = "refchecks" + /** The phase name of the compiler plugin + * @todo Adapt to specific plugin. + */ + val phaseName = "plugintemplate" + + def newPhase(prev: Phase) = new Phase(prev) { + def name = phaseName + + /** This method contains the implementation of the compiler + * component + * + * @todo Implementation. + */ + def run { + println("Hello from phase "+ name) + } + } +} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala new file mode 100644 index 0000000000..e79608fe59 --- /dev/null +++ b/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala @@ -0,0 +1,24 @@ +package plugintemplate + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.Plugin + +/** A class describing the compiler plugin + * + * @todo Adapt the name of this class to the plugin being + * implemented + */ +class TemplatePlugin(val global: Global) extends Plugin { + /** The name of this plugin. Extracted from the properties file. */ + val name = PluginProperties.pluginName + + /** A short description of the plugin, read from the properties file */ + val description = PluginProperties.pluginDescription + + /** The compiler components that will be applied when running + * this plugin + * + * @todo Adapt to the plugin being implemented + */ + val components=List(new TemplateComponent(global)) +} diff --git a/docs/examples/plugintemplate/src/plugintemplate/standalone/Main.scala b/docs/examples/plugintemplate/src/plugintemplate/standalone/Main.scala new file mode 100644 index 0000000000..6eec249ed7 --- /dev/null +++ b/docs/examples/plugintemplate/src/plugintemplate/standalone/Main.scala @@ -0,0 +1,38 @@ +package plugintemplate.standalone + +import scala.tools.nsc.CompilerCommand +import scala.tools.nsc.Settings + +/** An object for running the plugin as standalone application. + */ +object Main { + def main(args: Array[String]) { + val settings = new Settings + + val command = new CompilerCommand(args.toList, settings, println, false) { + /** The command name that will be printed in in the usage message. + * This is autmatically set to the value of 'plugin.commandname' in the + * file build.properties. + */ + override val cmdName = PluginProperties.pluginCommand + } + + if (!command.ok) + return() + + /** The version number of this plugin is read from the porperties file + */ + if (settings.version.value) { + println(command.cmdName +" version "+ PluginProperties.versionString) + return() + } + if (settings.help.value) { + println(command.usageMsg) + return() + } + + val runner = new PluginRunner(settings) + val run = new runner.Run + run.compile(command.files) + } +} diff --git a/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala b/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala new file mode 100644 index 0000000000..b385581778 --- /dev/null +++ b/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala @@ -0,0 +1,30 @@ +package plugintemplate.standalone + +import scala.tools.nsc.{Global, Settings, SubComponent} +import scala.tools.nsc.reporters.{ConsoleReporter, Reporter} + +/** This class is a compiler that will be used for running + * the plugin in standalone mode. + * + * @todo Adapt to specific plugin. + */ +class PluginRunner(settings: Settings, reporter: Reporter) +extends Global(settings, reporter) { + def this(settings: Settings) = this(settings, new ConsoleReporter(settings)) + + /** The plugin component that should will executed. + * + * @todo Adapt to specific plugin. It is possible to add multiple + * plugin components to run. + */ + val pluginComponent = new TemplateComponent(this) + + override def phaseDescriptors: List[SubComponent] = List( + analyzer.namerFactory, + analyzer.typerFactory, + superAccessors, + pickler, + refchecks, + pluginComponent + ) +} |