aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-11-11 22:12:50 +0100
committerJason Zaugg <jzaugg@gmail.com>2012-11-11 22:12:50 +0100
commit40da520a74fbb13b0ed1c5acb7ddf5c521fd8acc (patch)
treef39a3f1882103e78329637408a08dc509012bc1e
parent23e24fc738e2d4ad967090c375cd356cf45745ce (diff)
downloadscala-async-40da520a74fbb13b0ed1c5acb7ddf5c521fd8acc.tar.gz
scala-async-40da520a74fbb13b0ed1c5acb7ddf5c521fd8acc.tar.bz2
scala-async-40da520a74fbb13b0ed1c5acb7ddf5c521fd8acc.zip
Add a test to interrogate the expanded tree.
- checks that only one function is synthesized - checks the set of vars created (TODO minimize these) - use x$1 rather than x1 for the freshened names for lifted vars. - make execContext a val, not a var.
-rw-r--r--src/main/scala/scala/async/Async.scala2
-rw-r--r--src/main/scala/scala/async/ExprBuilder.scala6
-rw-r--r--src/test/scala/scala/async/TestUtils.scala9
-rw-r--r--src/test/scala/scala/async/TreeInterrogation.scala38
4 files changed, 49 insertions, 6 deletions
diff --git a/src/main/scala/scala/async/Async.scala b/src/main/scala/scala/async/Async.scala
index 9f43b0b..4f7fa01 100644
--- a/src/main/scala/scala/async/Async.scala
+++ b/src/main/scala/scala/async/Async.scala
@@ -139,7 +139,7 @@ abstract class AsyncBase {
// Initialize the state
var state$async = 0
// Resolve the execution context
- var execContext$async = futureSystemOps.execContext.splice
+ val execContext$async = futureSystemOps.execContext.splice
var onCompleteHandler$async: util.Try[Any] => Unit = null
// Spawn a future to:
diff --git a/src/main/scala/scala/async/ExprBuilder.scala b/src/main/scala/scala/async/ExprBuilder.scala
index 09489d4..1a3f866 100644
--- a/src/main/scala/scala/async/ExprBuilder.scala
+++ b/src/main/scala/scala/async/ExprBuilder.scala
@@ -34,6 +34,8 @@ final class ExprBuilder[C <: Context, FS <: FutureSystem](val c: C, val futureSy
val x1 = newTermName("x$1")
val tr = newTermName("tr")
val onCompleteHandler = suffixedName("onCompleteHandler")
+
+ def fresh(name: TermName) = newTermName(c.fresh("" + name + "$"))
}
private val execContext = futureSystemOps.execContext
@@ -295,7 +297,7 @@ final class ExprBuilder[C <: Context, FS <: FutureSystem](val c: C, val futureSy
for (stat <- stats) stat match {
// the val name = await(..) pattern
case ValDef(mods, name, tpt, Apply(fun, args)) if fun.symbol == Async_await =>
- val newName = c.fresh(name)
+ val newName = builder.name.fresh(name)
toRename += (stat.symbol -> newName)
asyncStates += stateBuilder.complete(args.head, newName, tpt, toRename).result // complete with await
@@ -309,7 +311,7 @@ final class ExprBuilder[C <: Context, FS <: FutureSystem](val c: C, val futureSy
case ValDef(mods, name, tpt, rhs) =>
checkForUnsupportedAwait(rhs)
- val newName = c.fresh(name)
+ val newName = builder.name.fresh(name)
toRename += (stat.symbol -> newName)
// when adding assignment need to take `toRename` into account
stateBuilder.addVarDef(mods, newName, tpt, rhs, toRename)
diff --git a/src/test/scala/scala/async/TestUtils.scala b/src/test/scala/scala/async/TestUtils.scala
index 0920659..bac22a3 100644
--- a/src/test/scala/scala/async/TestUtils.scala
+++ b/src/test/scala/scala/async/TestUtils.scala
@@ -40,11 +40,14 @@ trait TestUtils {
}
def eval(code: String, compileOptions: String = ""): Any = {
+ val tb = mkToolbox(compileOptions)
+ tb.eval(tb.parse(code))
+ }
+
+ def mkToolbox(compileOptions: String = "") = {
val m = scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
- val tb = m.mkToolBox(options = compileOptions)
- val result = tb.eval(tb.parse(code))
- result
+ m.mkToolBox(options = compileOptions)
}
def expectError(errorSnippet: String, compileOptions: String = "")(code: String) {
diff --git a/src/test/scala/scala/async/TreeInterrogation.scala b/src/test/scala/scala/async/TreeInterrogation.scala
new file mode 100644
index 0000000..7c277b1
--- /dev/null
+++ b/src/test/scala/scala/async/TreeInterrogation.scala
@@ -0,0 +1,38 @@
+package scala.async
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Test
+import AsyncId._
+
+@RunWith(classOf[JUnit4])
+class TreeInterrogation {
+ @Test
+ def `a minimal set of vals are lifted to vars`() {
+ val cm = reflect.runtime.currentMirror
+ val tb = mkToolbox()
+ val tree = mkToolbox().parse(
+ """| import _root_.scala.async.AsyncId._
+ | async {
+ | val x = await(1)
+ | val y = x * 2
+ | val z = await(x * 3)
+ | z
+ | }""".stripMargin)
+ val tree1 = tb.typeCheck(tree)
+
+ // println(cm.universe.showRaw(tree1))
+
+ import tb.mirror.universe._
+ val functions = tree1.collect {
+ case f: Function => f
+ }
+ functions.size mustBe 1
+
+ val varDefs = tree1.collect {
+ case ValDef(mods, name, _, _) if mods.hasFlag(Flag.MUTABLE) => name
+ }
+ // TODO no need to lift `y` as it is only accessed from a single state.
+ varDefs.map(_.decoded).toSet mustBe(Set("state$async", "onCompleteHandler$async", "x$1", "z$1", "y$1"))
+ }
+}