summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-25 07:42:04 -0700
committerPaul Phillips <paulp@improving.org>2012-04-25 09:11:04 -0700
commit4c6f64b708dc10b010e4da3aa05205ca3b04bcf9 (patch)
tree9abb9ec3a634c7ea2283dcd90e41cf8de26e0374
parentc22ec635c75170d1ac1cb0074e532b4186eed845 (diff)
downloadscala-4c6f64b708dc10b010e4da3aa05205ca3b04bcf9.tar.gz
scala-4c6f64b708dc10b010e4da3aa05205ca3b04bcf9.tar.bz2
scala-4c6f64b708dc10b010e4da3aa05205ca3b04bcf9.zip
Minor tweaks to reifier logic.
Nothing too major, please see the comment.
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Types.scala2
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reify.scala66
2 files changed, 39 insertions, 29 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala
index 841ec61e60..8fa24c5b00 100644
--- a/src/compiler/scala/reflect/reify/codegen/Types.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Types.scala
@@ -84,7 +84,7 @@ trait Types {
def spliceType(tpe: Type): Tree = {
// [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird!
- val quantified = currents collect { case ExistentialType(quantified, _) => quantified } flatMap identity
+ val quantified = currentQuantified
if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) {
if (reifyDebug) println("splicing " + tpe)
diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala
index a1ff486ed7..e03ff5832c 100644
--- a/src/compiler/scala/reflect/reify/phases/Reify.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reify.scala
@@ -19,37 +19,47 @@ trait Reify extends Symbols
import definitions._
import treeInfo._
+ // `reify` looked so nice, I wanted to push the last bit of orthogonal
+ // logic out of it so you can see the improvement. There is no cost to
+ // wrapper methods of this form because the inliner will eliminate them,
+ // but they are very good at separating concerns like pushing/popping
+ // a stack, and they are great for composition and reuse.
+ //
+ // Also, please avoid public vars whenever possible.
+ private object reifyStack {
+ var currents: List[Any] = reifee :: Nil
+
+ @inline final def push[T](reifee: Any)(body: => T): T = {
+ currents ::= reifee
+ try body
+ finally currents = currents.tail
+ }
+ }
+ def currentQuantified = flatCollect(reifyStack.currents)({ case ExistentialType(quantified, _) => quantified })
+ def current = reifyStack.currents.head
+
/**
* Reifies any supported value.
* For internal use only, use ``reified'' instead.
*/
- var currents: List[Any] = reifee :: Nil
- def current = currents.head
- def reify(reifee: Any): Tree = {
- currents = reifee :: currents
- try {
- reifee match {
- // before adding some case here, in global scope, please, consider
- // whether it can be localized like reifyAnnotationInfo or reifyScope
- // this will help reification stay as sane as possible
- case sym: Symbol => reifySymRef(sym)
- case tpe: Type => reifyType(tpe)
- case name: Name => reifyName(name)
- case tree: Tree => reifyTree(tree)
- // disabled because this is a very special case that I plan to remove later
- // why do I dislike annotations? see comments to `reifyAnnotationInfo`
+ def reify(reifee: Any): Tree = reifyStack.push(reifee)(reifee match {
+ // before adding some case here, in global scope, please, consider
+ // whether it can be localized like reifyAnnotationInfo or reifyScope
+ // this will help reification stay as sane as possible
+ case sym: Symbol => reifySymRef(sym)
+ case tpe: Type => reifyType(tpe)
+ case name: Name => reifyName(name)
+ case tree: Tree => reifyTree(tree)
+ // disabled because this is a very special case that I plan to remove later
+ // why do I dislike annotations? see comments to `reifyAnnotationInfo`
// case ann: AnnotationInfo => reifyAnnotationInfo(ann)
- case pos: Position => reifyPosition(pos)
- case mods: mirror.Modifiers => reifyModifiers(mods)
- case xs: List[_] => reifyList(xs)
- case s: String => Literal(Constant(s))
- case v if isAnyVal(v) => Literal(Constant(v))
- case null => Literal(Constant(null))
- case _ =>
- throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass))
- }
- } finally {
- currents = currents.tail
- }
- }
+ case pos: Position => reifyPosition(pos)
+ case mods: mirror.Modifiers => reifyModifiers(mods)
+ case xs: List[_] => reifyList(xs)
+ case s: String => Literal(Constant(s))
+ case v if isAnyVal(v) => Literal(Constant(v))
+ case null => Literal(Constant(null))
+ case _ =>
+ throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass))
+ })
} \ No newline at end of file