Skip to content

Commit dc5ee63

Browse files
committed
Merge pull request #71 from retronym/topic/quasiquote-applied
Update to Scala 2.11.0-RC4, adapting to change in quasiquotes
2 parents f53c3bb + 92ab5b7 commit dc5ee63

File tree

3 files changed

+71
-17
lines changed

3 files changed

+71
-17
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
scalaVersion := "2.11.0-RC3"
1+
scalaVersion := "2.11.0-RC4"
22

33
// Uncomment to test with a locally built copy of Scala.
44
// scalaHome := Some(file("/code/scala2/build/pack"))

src/main/scala/scala/async/internal/AnfTransform.scala

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ private[async] trait AnfTransform {
161161
val stats :+ expr1 = linearize.transformToList(expr)
162162
stats :+ treeCopy.Typed(tree, expr1, tpt)
163163

164-
case q"$fun[..$targs](...$argss)" if argss.nonEmpty =>
164+
case Applied(fun, targs, argss) if argss.nonEmpty =>
165165
// we can assume that no await call appears in a by-name argument position,
166166
// this has already been checked.
167167
val funStats :+ simpleFun = linearize.transformToList(fun)
@@ -188,21 +188,7 @@ private[async] trait AnfTransform {
188188
}
189189
}
190190

191-
192-
/** The depth of the nested applies: e.g. Apply(Apply(Apply(_, _), _), _)
193-
* has depth 3. Continues through type applications (without counting them.)
194-
*/
195-
def applyDepth: Int = {
196-
def loop(tree: Tree): Int = tree match {
197-
case Apply(fn, _) => 1 + loop(fn)
198-
case TypeApply(fn, _) => loop(fn)
199-
case AppliedTypeTree(fn, _) => loop(fn)
200-
case _ => 0
201-
}
202-
loop(tree)
203-
}
204-
205-
val typedNewApply = copyApplied(tree, applyDepth)
191+
val typedNewApply = copyApplied(tree, argss.length)
206192

207193
funStats ++ argStatss.flatten.flatten :+ typedNewApply
208194

src/main/scala/scala/async/internal/TransformUtils.scala

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,74 @@ private[async] trait TransformUtils {
4141
def isAwait(fun: Tree) =
4242
fun.symbol == defn.Async_await
4343

44+
// Copy pasted from TreeInfo in the compiler.
45+
// Using a quasiquote pattern like `case q"$fun[..$targs](...$args)" => is not
46+
// sufficient since https://github.com/scala/scala/pull/3656 as it doesn't match
47+
// constructor invocations.
48+
class Applied(val tree: Tree) {
49+
/** The tree stripped of the possibly nested applications.
50+
* The original tree if it's not an application.
51+
*/
52+
def callee: Tree = {
53+
def loop(tree: Tree): Tree = tree match {
54+
case Apply(fn, _) => loop(fn)
55+
case tree => tree
56+
}
57+
loop(tree)
58+
}
59+
60+
/** The `callee` unwrapped from type applications.
61+
* The original `callee` if it's not a type application.
62+
*/
63+
def core: Tree = callee match {
64+
case TypeApply(fn, _) => fn
65+
case AppliedTypeTree(fn, _) => fn
66+
case tree => tree
67+
}
68+
69+
/** The type arguments of the `callee`.
70+
* `Nil` if the `callee` is not a type application.
71+
*/
72+
def targs: List[Tree] = callee match {
73+
case TypeApply(_, args) => args
74+
case AppliedTypeTree(_, args) => args
75+
case _ => Nil
76+
}
77+
78+
/** (Possibly multiple lists of) value arguments of an application.
79+
* `Nil` if the `callee` is not an application.
80+
*/
81+
def argss: List[List[Tree]] = {
82+
def loop(tree: Tree): List[List[Tree]] = tree match {
83+
case Apply(fn, args) => loop(fn) :+ args
84+
case _ => Nil
85+
}
86+
loop(tree)
87+
}
88+
}
89+
90+
/** Returns a wrapper that knows how to destructure and analyze applications.
91+
*/
92+
def dissectApplied(tree: Tree) = new Applied(tree)
93+
94+
/** Destructures applications into important subparts described in `Applied` class,
95+
* namely into: core, targs and argss (in the specified order).
96+
*
97+
* Trees which are not applications are also accepted. Their callee and core will
98+
* be equal to the input, while targs and argss will be Nil.
99+
*
100+
* The provided extractors don't expose all the API of the `Applied` class.
101+
* For advanced use, call `dissectApplied` explicitly and use its methods instead of pattern matching.
102+
*/
103+
object Applied {
104+
def apply(tree: Tree): Applied = new Applied(tree)
105+
106+
def unapply(applied: Applied): Option[(Tree, List[Tree], List[List[Tree]])] =
107+
Some((applied.core, applied.targs, applied.argss))
108+
109+
def unapply(tree: Tree): Option[(Tree, List[Tree], List[List[Tree]])] =
110+
unapply(dissectApplied(tree))
111+
}
44112
private lazy val Boolean_ShortCircuits: Set[Symbol] = {
45113
import definitions.BooleanClass
46114
def BooleanTermMember(name: String) = BooleanClass.typeSignature.member(newTermName(name).encodedName)

0 commit comments

Comments
 (0)