aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-04-05 23:03:58 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-04-05 23:03:58 +0200
commit93898302564456f453a0cd283c89030a2b783e7f (patch)
treef56a252b2b3d03977e257c2078cac167fc7f850a /src
parentf53c3bb75be003c12fa6b999ed34eba2a2a38b41 (diff)
downloadscala-async-93898302564456f453a0cd283c89030a2b783e7f.tar.gz
scala-async-93898302564456f453a0cd283c89030a2b783e7f.tar.bz2
scala-async-93898302564456f453a0cd283c89030a2b783e7f.zip
Update to Scala 2.11.0-RC4, adapting to change in quasiquotes
Namely: https://github.com/scala/scala/pull/3656 I can't find a way to express a QQ that matches an constructor invocation *and* lets me bind a reference to the `New` tree. So I've dropped down to a borrowed version of `TreeInfo#Applied`.
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/scala/async/internal/AnfTransform.scala3
-rw-r--r--src/main/scala/scala/async/internal/TransformUtils.scala68
2 files changed, 69 insertions, 2 deletions
diff --git a/src/main/scala/scala/async/internal/AnfTransform.scala b/src/main/scala/scala/async/internal/AnfTransform.scala
index 0e58fa7..a0f722f 100644
--- a/src/main/scala/scala/async/internal/AnfTransform.scala
+++ b/src/main/scala/scala/async/internal/AnfTransform.scala
@@ -161,7 +161,7 @@ private[async] trait AnfTransform {
val stats :+ expr1 = linearize.transformToList(expr)
stats :+ treeCopy.Typed(tree, expr1, tpt)
- case q"$fun[..$targs](...$argss)" if argss.nonEmpty =>
+ case ap @ Applied(fun, targs, argss) if argss.nonEmpty =>
// we can assume that no await call appears in a by-name argument position,
// this has already been checked.
val funStats :+ simpleFun = linearize.transformToList(fun)
@@ -188,7 +188,6 @@ private[async] trait AnfTransform {
}
}
-
/** The depth of the nested applies: e.g. Apply(Apply(Apply(_, _), _), _)
* has depth 3. Continues through type applications (without counting them.)
*/
diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala
index 5d0a96f..a01a801 100644
--- a/src/main/scala/scala/async/internal/TransformUtils.scala
+++ b/src/main/scala/scala/async/internal/TransformUtils.scala
@@ -41,6 +41,74 @@ private[async] trait TransformUtils {
def isAwait(fun: Tree) =
fun.symbol == defn.Async_await
+ // Copy pasted from TreeInfo in the compiler.
+ // Using a quasiquote pattern like `case q"$fun[..$targs](...$args)" => is not
+ // sufficient since https://github.com/scala/scala/pull/3656 as it doesn't match
+ // constructor invocations.
+ class Applied(val tree: Tree) {
+ /** The tree stripped of the possibly nested applications.
+ * The original tree if it's not an application.
+ */
+ def callee: Tree = {
+ def loop(tree: Tree): Tree = tree match {
+ case Apply(fn, _) => loop(fn)
+ case tree => tree
+ }
+ loop(tree)
+ }
+
+ /** The `callee` unwrapped from type applications.
+ * The original `callee` if it's not a type application.
+ */
+ def core: Tree = callee match {
+ case TypeApply(fn, _) => fn
+ case AppliedTypeTree(fn, _) => fn
+ case tree => tree
+ }
+
+ /** The type arguments of the `callee`.
+ * `Nil` if the `callee` is not a type application.
+ */
+ def targs: List[Tree] = callee match {
+ case TypeApply(_, args) => args
+ case AppliedTypeTree(_, args) => args
+ case _ => Nil
+ }
+
+ /** (Possibly multiple lists of) value arguments of an application.
+ * `Nil` if the `callee` is not an application.
+ */
+ def argss: List[List[Tree]] = {
+ def loop(tree: Tree): List[List[Tree]] = tree match {
+ case Apply(fn, args) => loop(fn) :+ args
+ case _ => Nil
+ }
+ loop(tree)
+ }
+ }
+
+ /** Returns a wrapper that knows how to destructure and analyze applications.
+ */
+ def dissectApplied(tree: Tree) = new Applied(tree)
+
+ /** Destructures applications into important subparts described in `Applied` class,
+ * namely into: core, targs and argss (in the specified order).
+ *
+ * Trees which are not applications are also accepted. Their callee and core will
+ * be equal to the input, while targs and argss will be Nil.
+ *
+ * The provided extractors don't expose all the API of the `Applied` class.
+ * For advanced use, call `dissectApplied` explicitly and use its methods instead of pattern matching.
+ */
+ object Applied {
+ def apply(tree: Tree): Applied = new Applied(tree)
+
+ def unapply(applied: Applied): Option[(Tree, List[Tree], List[List[Tree]])] =
+ Some((applied.core, applied.targs, applied.argss))
+
+ def unapply(tree: Tree): Option[(Tree, List[Tree], List[List[Tree]])] =
+ unapply(dissectApplied(tree))
+ }
private lazy val Boolean_ShortCircuits: Set[Symbol] = {
import definitions.BooleanClass
def BooleanTermMember(name: String) = BooleanClass.typeSignature.member(newTermName(name).encodedName)