diff options
author | Lukas Rytz <lukas.rytz@epfl.ch> | 2008-06-06 08:49:43 +0000 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@epfl.ch> | 2008-06-06 08:49:43 +0000 |
commit | e4e5d2a93d6ce8a4a91cb1168501dd6541c72a7c (patch) | |
tree | 00b31140bce66442129d6a126174f4d322640e26 /docs/examples/plugintemplate/src | |
parent | 8c06a1a54516bbbeed907da3446b372b732c4329 (diff) | |
download | scala-e4e5d2a93d6ce8a4a91cb1168501dd6541c72a7c.tar.gz scala-e4e5d2a93d6ce8a4a91cb1168501dd6541c72a7c.tar.bz2 scala-e4e5d2a93d6ce8a4a91cb1168501dd6541c72a7c.zip |
updated plugin template to use Transform and In...
updated plugin template to use Transform and InfoTransform
Diffstat (limited to 'docs/examples/plugintemplate/src')
5 files changed, 186 insertions, 17 deletions
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) } |