diff options
author | Martin Odersky <odersky@gmail.com> | 2013-05-22 18:02:24 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-05-22 18:30:23 +0200 |
commit | fd079d2f3335db7b54b0f78a4d884d9948a7beea (patch) | |
tree | cee19b71a9a077880e8d7ab1738891f55ce5bd85 /src/dotty/tools/dotc/ast/PluggableTransformers.scala | |
parent | 0ebdcc7ed2d2024d93ba7d24b88187d4c502eb4b (diff) | |
download | dotty-fd079d2f3335db7b54b0f78a4d884d9948a7beea.tar.gz dotty-fd079d2f3335db7b54b0f78a4d884d9948a7beea.tar.bz2 dotty-fd079d2f3335db7b54b0f78a4d884d9948a7beea.zip |
More tree refactorings.
1) Getting rid of ugen in favor of untpd.
2) Eliminating some unused methods
3) Splitting out CheckTrees from TypedTrees.
4) Moving trees and related classes into separate package dotc.ast
Diffstat (limited to 'src/dotty/tools/dotc/ast/PluggableTransformers.scala')
-rw-r--r-- | src/dotty/tools/dotc/ast/PluggableTransformers.scala | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/ast/PluggableTransformers.scala b/src/dotty/tools/dotc/ast/PluggableTransformers.scala new file mode 100644 index 000000000..8c64feb21 --- /dev/null +++ b/src/dotty/tools/dotc/ast/PluggableTransformers.scala @@ -0,0 +1,105 @@ +package dotty.tools.dotc +package ast + + +object PluggableTransformers { +/* + import Trees._, Contexts._ + + abstract class PluggableTransformer[T] extends TreeTransformer[T, Context] { + type PluginOp[-N <: Tree[T]] = N => Tree[T] + + private[this] var _ctx: Context = _ + private[this] var _oldTree: Tree[T] = _ + + protected implicit def ctx: Context = _ctx + protected def oldTree: Tree[T] = _oldTree + protected def thisTransformer: PluggableTransformer[T] = this + + class PluginOps[-N <: Tree[T]](op: PluginOp[N], val next: Plugins) { + def apply(tree: N, old: Tree[T], c: Context): Tree[T] = { + val savedCtx = _ctx + val savedOld = _oldTree + try { + op(tree) + } finally { + _oldTree = savedOld + _ctx = savedCtx + } + } + } + + val NoOp: PluginOp[Tree[T]] = identity + val NoOps = new PluginOps(NoOp, null) + + class Plugins { + def next: Plugins = null + + def processIdent: PluginOp[Ident[T]] = NoOp + def processSelect: PluginOp[Select[T]] = NoOp + + val IdentOps: PluginOps[Ident[T]] = NoOps + val SelectOps: PluginOps[Select[T]] = NoOps + } + + val EmptyPlugin = new Plugins + + private[this] var _plugins: Plugins = EmptyPlugin + + override def plugins: Plugins = _plugins + + class Plugin extends Plugins { + override val next = _plugins + _plugins = this + + private def push[N <: Tree[T]](op: PluginOp[N], ops: => PluginOps[N]): PluginOps[N] = + if (op == NoOp) ops else new PluginOps(op, next) + + override val IdentOps: PluginOps[Ident[T]] = push(processIdent, next.IdentOps) + override val SelectOps: PluginOps[Select[T]] = push(processSelect, next.SelectOps) + } + + def postIdent(tree: Ident[T], old: Tree[T], c: Context, ops: PluginOps[Ident[T]]) = + if (ops eq NoOps) tree + else finishIdent(ops(tree, old, c), old, c, ops.next) + + override def finishIdent(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match { + case tree: Ident[_] => postIdent(tree, old, c, plugins.IdentOps) + case _ => postProcess(tree, old, c, plugins) + } + + def postSelect(tree: Select[T], old: Tree[T], c: Context, ops: PluginOps[Select[T]]) = + if (ops eq NoOps) tree + else finishSelect(ops(tree, old, c), old, c, ops.next) + + override def finishSelect(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match { + case tree: Select[_] => postSelect(tree, old, c, plugins.SelectOps) + case _ => postProcess(tree, old, c, plugins) + } + + protected def postProcess(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match { + case tree: Ident[_] => finishIdent(tree, old, c, plugins) + case tree: Select[_] => finishSelect(tree, old, c, plugins) + } + } +} + +import PluggableTransformers._, Types._, Trees._, Contexts._, TypedTrees.tpd + +class ExampleTransformer extends PluggableTransformer[Type] { + + object ExamplePlugin extends Plugin { + override def processIdent = { + case tree @ Ident(x) if x.isTypeName => tree.derivedSelect(tree, x) + case tree => tpd.Ident(???) + } + override def processSelect = { tree => + if (tree.isType) tree.derivedIdent(tree.name) + else tpd.EmptyTree + } + } + + override def transform(tree: tpd.Tree, ctx: Context) = + super.transform(tree, ctx) +*/ +}
\ No newline at end of file |