summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-02-01 00:13:53 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-02-14 23:51:24 +0100
commit8c29132055845181a34ed9077d30fac87c284574 (patch)
tree29c5bb2ca8be67e324ee3e0f9d78bc62bf00d8b3 /src/compiler
parent73adf2d9de441e151a117a5b33ae707ad79a9f36 (diff)
downloadscala-8c29132055845181a34ed9077d30fac87c284574.tar.gz
scala-8c29132055845181a34ed9077d30fac87c284574.tar.bz2
scala-8c29132055845181a34ed9077d30fac87c284574.zip
adds internal.typingTransform
As per Jason’s request, this commit introduces a facility to perform tree transformations that know how to track current lexical context and how to typecheck trees in that lexical context. Interestingly enough, we can’t get away with the traditional “subclass the Transformer” approach, because the required base transformer class is declared in scala-compiler.jar, and our API is defined in scala-reflect.jar. This forced me to play with an idea that we’ve discussed with Denys today (actually, it’s already yesterday) - lightweight transformers that take contextful HOFs. This commit is a sketch in that direction. Turning `transform` and `typingTransform` into macros would make the API more elegant (see the comments), but I didn’t have time to experiment. I’m running short on time, so I haven’t had a chance to actually test this API, but I’m still submitting the pull request to ignite a discussion.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Internals.scala32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Internals.scala b/src/compiler/scala/reflect/macros/contexts/Internals.scala
index e0f7824cf3..e35a8ae034 100644
--- a/src/compiler/scala/reflect/macros/contexts/Internals.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Internals.scala
@@ -1,9 +1,39 @@
package scala.reflect.macros
package contexts
-trait Internals {
+trait Internals extends scala.tools.nsc.transform.TypingTransformers {
self: Context =>
+ import global._
+
lazy val internal: ContextInternalApi = new global.SymbolTableInternal with ContextInternalApi {
+ class HofTransformer(hof: (Tree, TransformApi) => Tree) extends Transformer {
+ val api = new TransformApi {
+ def recur(tree: Tree): Tree = hof(tree, this)
+ def default(tree: Tree): Tree = superTransform(tree)
+ }
+ def superTransform(tree: Tree) = super.transform(tree)
+ override def transform(tree: Tree): Tree = hof(tree, api)
+ }
+
+ def transform(tree: Tree)(transformer: (Tree, TransformApi) => Tree): Tree = new HofTransformer(transformer).transform(tree)
+
+ class HofTypingTransformer(hof: (Tree, TypingTransformApi) => Tree) extends TypingTransformer(callsiteTyper.context.unit) { self =>
+ currentOwner = callsiteTyper.context.owner
+ curTree = EmptyTree
+ localTyper = global.analyzer.newTyper(callsiteTyper.context.make(unit = callsiteTyper.context.unit))
+
+ val api = new TypingTransformApi {
+ def recur(tree: Tree): Tree = hof(tree, this)
+ def default(tree: Tree): Tree = superTransform(tree)
+ def atOwner[T](owner: Symbol)(op: => T): T = self.atOwner(owner)(op)
+ def currentOwner: Symbol = self.currentOwner
+ def typecheck(tree: Tree): Tree = localTyper.typed(tree)
+ }
+ def superTransform(tree: Tree) = super.transform(tree)
+ override def transform(tree: Tree): Tree = hof(tree, api)
+ }
+
+ def typingTransform(tree: Tree)(transformer: (Tree, TypingTransformApi) => Tree): Tree = new HofTypingTransformer(transformer).transform(tree)
}
} \ No newline at end of file