From 4cba60178d2f49f14b23039e47ac90612deb9046 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 23 May 2008 16:16:17 +0000 Subject: Added Scala compiler plugin Template. --- docs/examples/plugintemplate/.classpath | 11 + docs/examples/plugintemplate/.project | 18 ++ .../de.loskutov.anyedit.AnyEditTools.prefs | 15 ++ docs/examples/plugintemplate/build.xml | 265 +++++++++++++++++++++ docs/examples/plugintemplate/doc/README | 42 ++++ .../plugintemplate/examples/BasicExample.scala | 8 + .../plugintemplate/lib/scalatest.jar.desired.sha1 | 1 + .../examples/plugintemplate/misc/scalac-plugin.xml | 4 + docs/examples/plugintemplate/plugin.properties | 10 + .../src/plugintemplate/PluginProperties.scala | 61 +++++ .../src/plugintemplate/TemplateComponent.scala | 33 +++ .../src/plugintemplate/TemplatePlugin.scala | 24 ++ .../src/plugintemplate/standalone/Main.scala | 38 +++ .../plugintemplate/standalone/PluginRunner.scala | 30 +++ .../plugintemplate/PluginPropertiesSuite.scala | 14 ++ .../test/plugintemplate/TemplatePluginSuite.scala | 22 ++ 16 files changed, 596 insertions(+) create mode 100644 docs/examples/plugintemplate/.classpath create mode 100644 docs/examples/plugintemplate/.project create mode 100644 docs/examples/plugintemplate/.settings/de.loskutov.anyedit.AnyEditTools.prefs create mode 100644 docs/examples/plugintemplate/build.xml create mode 100644 docs/examples/plugintemplate/doc/README create mode 100644 docs/examples/plugintemplate/doc/examples/plugintemplate/examples/BasicExample.scala create mode 100644 docs/examples/plugintemplate/lib/scalatest.jar.desired.sha1 create mode 100644 docs/examples/plugintemplate/misc/scalac-plugin.xml create mode 100644 docs/examples/plugintemplate/plugin.properties create mode 100644 docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala create mode 100644 docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala create mode 100644 docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala create mode 100644 docs/examples/plugintemplate/src/plugintemplate/standalone/Main.scala create mode 100644 docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala create mode 100644 docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala create mode 100644 docs/examples/plugintemplate/test/plugintemplate/TemplatePluginSuite.scala (limited to 'docs') diff --git a/docs/examples/plugintemplate/.classpath b/docs/examples/plugintemplate/.classpath new file mode 100644 index 0000000000..e9069639ae --- /dev/null +++ b/docs/examples/plugintemplate/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/docs/examples/plugintemplate/.project b/docs/examples/plugintemplate/.project new file mode 100644 index 0000000000..075b0c580c --- /dev/null +++ b/docs/examples/plugintemplate/.project @@ -0,0 +1,18 @@ + + + plugintemplate + + + + + + ch.epfl.lamp.sdt.core.scalabuilder + + + + + + ch.epfl.lamp.sdt.core.scalanature + org.eclipse.jdt.core.javanature + + diff --git a/docs/examples/plugintemplate/.settings/de.loskutov.anyedit.AnyEditTools.prefs b/docs/examples/plugintemplate/.settings/de.loskutov.anyedit.AnyEditTools.prefs new file mode 100644 index 0000000000..2031891e97 --- /dev/null +++ b/docs/examples/plugintemplate/.settings/de.loskutov.anyedit.AnyEditTools.prefs @@ -0,0 +1,15 @@ +#Fri May 23 08:03:52 CEST 2008 +activeContentFilterList=*.makefile,makefile,*.Makefile,Makefile,Makefile.*,*.mk,MANIFEST.MF +convertActionOnSaave=AnyEdit.CnvrtTabToSpaces +eclipse.preferences.version=1 +inActiveContentFilterList= +javaTabWidthForJava=true +org.eclipse.jdt.ui.editor.tab.width=2 +projectPropsEnabled=false +removeTrailingSpaces=true +replaceAllSpaces=false +replaceAllTabs=false +saveAndAddLine=false +saveAndConvert=false +saveAndTrim=true +useModulo4Tabs=false diff --git a/docs/examples/plugintemplate/build.xml b/docs/examples/plugintemplate/build.xml new file mode 100644 index 0000000000..0ea47b4da8 --- /dev/null +++ b/docs/examples/plugintemplate/build.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/examples/plugintemplate/doc/README b/docs/examples/plugintemplate/doc/README new file mode 100644 index 0000000000..f3b9e15e97 --- /dev/null +++ b/docs/examples/plugintemplate/doc/README @@ -0,0 +1,42 @@ +Scala compiler plugin template +------------------------------ + +This project is a template that can be used for creating compiler +plugins for the Scala compiler. + + +Installation +------------ +To install the compiler plugin, run "ant install". This will create +an sbaz package for the template plugin and install it in the scala +installation available in your PATH. +The install command will also create a script for running the plugin +as standalone application. The command is called "runplugintemplate" +and available in your scala installation as well. +To uninstall the plugin again, run "and uninstall". + +Alternatively, copy the file build/pack/plugintemplate.jar, generated +by "ant pack", to the directory misc/scala-devel/plugins of your +scala distribution. The scala compiler will then find and integrate +the new plugin. + +Customization +------------- +The following files need to be edited when creating a new plugin +- plugin.properties +- misc/scalac-plugin.xml +- src / test / doc/examples: The source files of the template plugin + are located a package called "plugintemplate". This will most likely + be changed for new plugins. + +When using eclipse for development, make sure "scala-compiler.jar" is +in the Java Build Path: Right-Click the project and select "Properties". +Then go to "Java Build Path" -> "Libraries" and add the jar file +"eclipse/plugins/ch.epfl.lamp.sdt.core[..]/lib/scala-compiler.jar". + +Ant tasks +--------- +"build.xml" defines Ant tasks for building, testing and packing a +plugin. The tests are written using the ScalaTest framework +(http://www.artima.com/scalatest/). +Run the tests using "ant test", or "ant guitest". diff --git a/docs/examples/plugintemplate/doc/examples/plugintemplate/examples/BasicExample.scala b/docs/examples/plugintemplate/doc/examples/plugintemplate/examples/BasicExample.scala new file mode 100644 index 0000000000..d1f6c91cdc --- /dev/null +++ b/docs/examples/plugintemplate/doc/examples/plugintemplate/examples/BasicExample.scala @@ -0,0 +1,8 @@ +package plugintemplate.examples + +/** An example demonstrating the fancy features of the new + * compiler plugin. + */ +class BasicExample { + def foo = () +} diff --git a/docs/examples/plugintemplate/lib/scalatest.jar.desired.sha1 b/docs/examples/plugintemplate/lib/scalatest.jar.desired.sha1 new file mode 100644 index 0000000000..ab3c5ffd2c --- /dev/null +++ b/docs/examples/plugintemplate/lib/scalatest.jar.desired.sha1 @@ -0,0 +1 @@ +462624d9413123e32d073863fa8759457cf8721e ?scalatest.jar diff --git a/docs/examples/plugintemplate/misc/scalac-plugin.xml b/docs/examples/plugintemplate/misc/scalac-plugin.xml new file mode 100644 index 0000000000..bad4e87327 --- /dev/null +++ b/docs/examples/plugintemplate/misc/scalac-plugin.xml @@ -0,0 +1,4 @@ + + plugintemplate + plugintemplate.TemplatePlugin + diff --git a/docs/examples/plugintemplate/plugin.properties b/docs/examples/plugintemplate/plugin.properties new file mode 100644 index 0000000000..0db340cffa --- /dev/null +++ b/docs/examples/plugintemplate/plugin.properties @@ -0,0 +1,10 @@ +scala.home=/Users/luc/scala/dist + +plugin.name=plugintemplate +plugin.commandname=runplugintemplate +plugin.description=A template compiler plugin saying hello to the World +plugin.mainclass=plugintemplate.standalone.Main +plugin.sbazbaseurl=http://scala.epfl.ch/downloads/packages + +version.major=0 +version.minor=1 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 + ) +} diff --git a/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala b/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala new file mode 100644 index 0000000000..72b8ee66c3 --- /dev/null +++ b/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala @@ -0,0 +1,14 @@ +package plugintemplate.examples + +import org.scalatest.Suite + +class PluginPropertiesSuite extends Suite { + def testProperties() { + expect("A template compiler plugin saying hello to the World") { + PluginProperties.pluginDescription + } + expect("0.1") { + PluginProperties.versionString + } + } +} diff --git a/docs/examples/plugintemplate/test/plugintemplate/TemplatePluginSuite.scala b/docs/examples/plugintemplate/test/plugintemplate/TemplatePluginSuite.scala new file mode 100644 index 0000000000..06916f9dd3 --- /dev/null +++ b/docs/examples/plugintemplate/test/plugintemplate/TemplatePluginSuite.scala @@ -0,0 +1,22 @@ +package plugintemplate + +import org.scalatest.Suite +import org.scalatest.Ignore + +class TemplatePluginSuite extends Suite { + def testName() { + import scala.tools.nsc.{Global, Settings} + import scala.tools.nsc.reporters.ConsoleReporter + val settings = new Settings + val compiler = new Global(settings, new ConsoleReporter(settings)) + val plugin = new TemplatePlugin(compiler) + expect("plugintemplate") { + plugin.name + } + } + + @Ignore + def testFail() { + expect(1) { 2 } + } +} -- cgit v1.2.3