diff options
author | Paul Phillips <paulp@improving.org> | 2012-04-25 07:42:04 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-04-25 09:11:04 -0700 |
commit | 4c6f64b708dc10b010e4da3aa05205ca3b04bcf9 (patch) | |
tree | 9abb9ec3a634c7ea2283dcd90e41cf8de26e0374 | |
parent | c22ec635c75170d1ac1cb0074e532b4186eed845 (diff) | |
download | scala-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.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/reflect/reify/phases/Reify.scala | 66 |
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 |