diff options
10 files changed, 191 insertions, 22 deletions
diff --git a/docs/examples/plugintemplate/build.xml b/docs/examples/plugintemplate/build.xml index 0ea47b4da8..37c8441ce3 100644 --- a/docs/examples/plugintemplate/build.xml +++ b/docs/examples/plugintemplate/build.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="plugintemplate" default="build"> +<project name="plugintemplate" default="pack"> <!-- Edit the file plugin.properties to set - scala.home - plugin.name diff --git a/docs/examples/plugintemplate/plugin.properties b/docs/examples/plugintemplate/plugin.properties index 0db340cffa..44e4900f8a 100644 --- a/docs/examples/plugintemplate/plugin.properties +++ b/docs/examples/plugintemplate/plugin.properties @@ -1,4 +1,4 @@ -scala.home=/Users/luc/scala/dist +scala.home=/Users/luc/scala/trunk/build/pack plugin.name=plugintemplate plugin.commandname=runplugintemplate diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala index b6e405dcef..d740395cc8 100644 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala +++ b/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala @@ -4,16 +4,19 @@ 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. + * can be used in a compiler plugin. If the plugin uses a tree + * transformer and / or an InfoTransformer, look at the two + * classes <code>TemplateTransformComponent</code> and + * <code>TemplateInfoTransformComponent</code>. * * @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 + + /** The name of this plugin phase * @todo Adapt to specific plugin. */ val phaseName = "plugintemplate" @@ -21,8 +24,7 @@ class TemplateComponent(val global: Global) extends PluginComponent { def newPhase(prev: Phase) = new Phase(prev) { def name = phaseName - /** This method contains the implementation of the compiler - * component + /** The implementation of this Phase's behavior * * @todo Implementation. */ diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateInfoTransformComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateInfoTransformComponent.scala new file mode 100644 index 0000000000..7185717e6d --- /dev/null +++ b/docs/examples/plugintemplate/src/plugintemplate/TemplateInfoTransformComponent.scala @@ -0,0 +1,70 @@ +package plugintemplate + +import scala.tools.nsc._ +import scala.tools.nsc.plugins.PluginComponent +import scala.tools.nsc.transform.InfoTransform +// import scala.tools.nsc.transform.TypingTransformers + +/** This class implements a plugin component using tree transformers and + * InfoTransformer. An InfoTransformer will be automatically created + * and registered in <code>SymbolTable.infoTransformers</code>. If + * a <code>Typer</code> is needed during transformation, the component + * should mix in <code>TypingTransformers</code>. This provides a local + * variable <code>localTyper: Typer</code> that is always updated to + * the current context. + * + * @todo Adapt the name of this class to the plugin, and implement it. + */ +class TemplateInfoTransformComponent(val global: Global) extends PluginComponent + // with TypingTransformers + with InfoTransform { + + import global._ + import global.definitions._ + + val runsAfter = "refchecks" + /** The phase name of the compiler plugin + * @todo Adapt to specific plugin. + */ + val phaseName = "plugintemplateinfotransform" + + def transformInfo(sym: Symbol, tp: Type): Type = infoTransformer(tp) + + def newTransformer(unit: CompilationUnit) = new TemplateTransformer + + /** The type transformation applied by this component + * + * @todo Implement. + */ + private val infoTransformer = new TypeMap { + def apply(tp: Type): Type = tp match { + case _ => tp + } + } + + /** The tree transformer that implements the behavior of this + * component. Change the superclass to <code>TypingTransformer</code> + * to make a local typechecker <code>localTyper</code> available. + * + * @todo Implement. + */ + class TemplateTransformer extends /*Typing*/ Transformer { + /** When using <code>preTransform</code>, each node is + * visited before its children. + */ + def preTransform(tree: Tree): Tree = tree match { + case _ => tree + } + + /** When using <code>postTransform</code>, each node is + * visited after its children. + */ + def postTransform(tree: Tree): Tree = tree match { + case _ => tree + } + + override def transform(tree: Tree): Tree = { + postTransform(super.transform(preTransform(tree))) + } + } +} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala index e79608fe59..5c4780d247 100644 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala +++ b/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala @@ -20,5 +20,34 @@ class TemplatePlugin(val global: Global) extends Plugin { * * @todo Adapt to the plugin being implemented */ - val components=List(new TemplateComponent(global)) + val components = TemplatePlugin.components(global) + val runsAfter = "refchecks" + + /* TODO: include annotationChecker + import global._ + + println("adding annotationchecker...") + addAnnotationChecker(new AnnotationChecker { + def annotationsConform(tpe1: Type, tpe2: Type): Boolean = { + println("checking: "+ tpe1 +" <: "+ tpe2) + true + } + + override def addAnnotations(tree: Tree, tpe: Type): Type = { + //println("adding annot to "+ tree.symbol) + tpe + } + }) + */ +} + +object TemplatePlugin { + /** Yields the list of Components to be executed in this plugin + * + * @todo: Adapt to specific implementation. + */ + def components(global: Global) = + List(new TemplateComponent(global), + new TemplateTransformComponent(global), + new TemplateInfoTransformComponent(global)) } diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateTransformComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateTransformComponent.scala new file mode 100644 index 0000000000..4156f262ee --- /dev/null +++ b/docs/examples/plugintemplate/src/plugintemplate/TemplateTransformComponent.scala @@ -0,0 +1,55 @@ +package plugintemplate + +import scala.tools.nsc._ +import scala.tools.nsc.plugins.PluginComponent +import scala.tools.nsc.transform.Transform +// import scala.tools.nsc.transform.TypingTransformers + +/** This class implements a plugin component using tree transformers. If + * a <code>Typer</code> is needed during transformation, the component + * should mix in <code>TypingTransformers</code>. This provides a local + * variable <code>localTyper: Typer</code> that is always updated to + * the current context. + * + * @todo Adapt the name of this class to the plugin, and implement it. + */ +class TemplateTransformComponent(val global: Global) extends PluginComponent + // with TypingTransformers + with Transform { + import global._ + import global.definitions._ + + val runsAfter = "refchecks" + /** The phase name of the compiler plugin + * @todo Adapt to specific plugin. + */ + val phaseName = "plugintemplatetransform" + + def newTransformer(unit: CompilationUnit) = new TemplateTransformer + + /** The tree transformer that implements the behavior of this + * component. Change the superclass to <code>TypingTransformer</code> + * to make a local typechecker <code>localTyper</code> available. + * + * @todo Implement. + */ + class TemplateTransformer extends /*Typing*/ Transformer { + /** When using <code>preTransform</code>, each node is + * visited before its children. + */ + def preTransform(tree: Tree): Tree = tree match { + case _ => tree + } + + /** When using <code>postTransform</code>, each node is + * visited after its children. + */ + def postTransform(tree: Tree): Tree = tree match { + case _ => tree + } + + override def transform(tree: Tree): Tree = { + postTransform(super.transform(preTransform(tree))) + } + } +} diff --git a/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala b/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala index b385581778..a4481829c5 100644 --- a/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala +++ b/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala @@ -5,26 +5,39 @@ 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) + /* TODO: include AnnotationChecker + println("adding annotationchecker...") + addAnnotationChecker(new AnnotationChecker { + def annotationsConform(tpe1: Type, tpe2: Type): Boolean = { + def getAnnTpe(t: Type) = t match { + case AnnotatedType(attrs, underlying, selfsym) => + attrs match { + case x :: xs => Some(x.atp) + case _ => None + } + case _ => None + } + val ta1 = getAnnTpe(tpe1) + val ta2 = getAnnTpe(tpe2) + ta1 == ta2 + } + + override def addAnnotations(tree: Tree, tpe: Type): Type = { + //println("adding annot to "+ tree.symbol) + tpe + } + }) + */ override def phaseDescriptors: List[SubComponent] = List( analyzer.namerFactory, analyzer.typerFactory, superAccessors, pickler, - refchecks, - pluginComponent - ) + refchecks) ::: TemplatePlugin.components(this) } diff --git a/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala b/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala index 72b8ee66c3..a07796a7f2 100644 --- a/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala +++ b/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala @@ -1,4 +1,4 @@ -package plugintemplate.examples +package plugintemplate import org.scalatest.Suite diff --git a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala index 2183218c82..d130abb336 100644 --- a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala +++ b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala @@ -13,7 +13,7 @@ package scala.tools.nsc.transform * A transform contains a compiler phase which applies a tree transformer. * </p> */ -abstract class InfoTransform extends Transform { +trait InfoTransform extends Transform { import global.{Symbol, Type, InfoTransformer, infoTransformers} def transformInfo(sym: Symbol, tpe: Type): Type diff --git a/src/compiler/scala/tools/nsc/transform/Transform.scala b/src/compiler/scala/tools/nsc/transform/Transform.scala index b447aaca2d..f683c7c5e3 100644 --- a/src/compiler/scala/tools/nsc/transform/Transform.scala +++ b/src/compiler/scala/tools/nsc/transform/Transform.scala @@ -16,7 +16,7 @@ package scala.tools.nsc.transform * @author Martin Odersky * @version 1.0 */ -abstract class Transform extends SubComponent { +trait Transform extends SubComponent { /** The transformer factory */ protected def newTransformer(unit: global.CompilationUnit): global.Transformer |