aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-11-09 18:33:13 +0100
committerJason Zaugg <jzaugg@gmail.com>2012-11-09 18:33:13 +0100
commit6226c3583b742e0576e5c598fba4e64622c99165 (patch)
treee54878ce719641166bb13c36bd9ec2f1d5047489 /src
parent566102b23cd08f2b6af60121feb28013288a0951 (diff)
downloadscala-async-6226c3583b742e0576e5c598fba4e64622c99165.tar.gz
scala-async-6226c3583b742e0576e5c598fba4e64622c99165.tar.bz2
scala-async-6226c3583b742e0576e5c598fba4e64622c99165.zip
Avoid hygiene problems by suffixing result/result/state.
Perhaps we should freshen them, but that will be a little awkward in our reify block.
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/scala/async/Async.scala14
-rw-r--r--src/main/scala/scala/async/ExprBuilder.scala9
-rw-r--r--src/test/scala/scala/async/run/hygiene/Hygiene.scala52
3 files changed, 67 insertions, 8 deletions
diff --git a/src/main/scala/scala/async/Async.scala b/src/main/scala/scala/async/Async.scala
index e8f5263..0a3bbbf 100644
--- a/src/main/scala/scala/async/Async.scala
+++ b/src/main/scala/scala/async/Async.scala
@@ -129,19 +129,25 @@ abstract class AsyncBase extends AsyncUtils {
val prom: Expr[futureSystem.Prom[T]] = reify {
- val result = futureSystemOps.createProm[T].splice
- var state = 0
+ val result$async = futureSystemOps.createProm[T].splice
+ var state$async = 0
futureSystemOps.future[Unit] {
c.Expr[Unit](Block(
localVarTrees :+ resumeFunTree,
Apply(Ident(name.resume), List())))
}(futureSystemOps.execContext).splice
- result
+ result$async
}
val result = futureSystemOps.promiseToFuture(prom)
- // println(s"${c.macroApplication} \nexpands to:\n ${result.tree}")
+// println(s"${c.macroApplication} \nexpands to:\n ${result.tree}")
+// val positions = result.tree.collect {
+// case t => (t.toString.take(10).replaceAll("\n", "\\n"), t.pos)
+// }
+// println(positions.mkString("\n"))
+
result
+
case tree =>
c.abort(c.macroApplication.pos, s"expression not supported by async: ${tree}")
}
diff --git a/src/main/scala/scala/async/ExprBuilder.scala b/src/main/scala/scala/async/ExprBuilder.scala
index 65e98e0..b563869 100644
--- a/src/main/scala/scala/async/ExprBuilder.scala
+++ b/src/main/scala/scala/async/ExprBuilder.scala
@@ -21,9 +21,10 @@ final class ExprBuilder[C <: Context, FS <: FutureSystem](val c: C, val futureSy
object name {
// TODO do we need to freshen any of these?
- val resume = newTermName("resume")
- val state = newTermName("state")
- val result = newTermName("result")
+ def expanded(prefix: String) = newTermName(prefix + "$async")
+ val resume = expanded("resume")
+ val state = expanded("state")
+ val result = expanded("result")
val tr = newTermName("tr")
val any = newTermName("any")
val x1 = newTermName("x$1")
@@ -256,7 +257,7 @@ final class ExprBuilder[C <: Context, FS <: FutureSystem](val c: C, val futureSy
* case any if any == num =>
* stats
* awaitable.onComplete {
- * (try: Try[A]) =>
+ * (tr: Try[A]) =>
* resultName = tr.get
* resume()
* }
diff --git a/src/test/scala/scala/async/run/hygiene/Hygiene.scala b/src/test/scala/scala/async/run/hygiene/Hygiene.scala
new file mode 100644
index 0000000..0cc68a4
--- /dev/null
+++ b/src/test/scala/scala/async/run/hygiene/Hygiene.scala
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.async
+package run
+package hygiene
+
+import language.{reflectiveCalls, postfixOps}
+import concurrent._
+import scala.concurrent.{Future, ExecutionContext, future, Await}
+import scala.concurrent.duration._
+import scala.async.Async.{async, await}
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+
+class HygieneClass {
+
+ import ExecutionContext.Implicits.global
+
+ def m1(x: Int): Future[Int] = future {
+ x + 2
+ }
+
+ def m2(y: Int) = {
+ val state = 23
+ val result: Any = "result"
+ def resume(): Any = "resume"
+ async {
+ val f1 = m1(state)
+ val x = await(f1)
+ val y = await(future(result))
+ val z = await(future(resume()))
+ (x, y, z)
+ }
+ }
+}
+
+@RunWith(classOf[JUnit4])
+class HygieneSpec {
+
+ @Test def `is hygenic`() {
+ val o = new HygieneClass
+ val fut = o.m2(10)
+ val res = Await.result(fut, 2 seconds)
+ res._1 mustBe (25)
+ res._2 mustBe ("result")
+ res._3 mustBe ("resume")
+ }
+}