aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-11-07 15:27:40 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-11-07 15:59:54 +0100
commit10f3c8db6163ebe3196173c1d87e69c1fb6a3a65 (patch)
treeb0043bf3feaea28eef36ed9548fa360213b1fd72
parent6a2b940ac6b7e511270079e1b6278c844a57f5d1 (diff)
downloadscala-async-10f3c8db6163ebe3196173c1d87e69c1fb6a3a65.tar.gz
scala-async-10f3c8db6163ebe3196173c1d87e69c1fb6a3a65.tar.bz2
scala-async-10f3c8db6163ebe3196173c1d87e69c1fb6a3a65.zip
Minimize the public API
- Remove the CPS fallback version of async. That was not intended to be part of 1.0. - Lookup the await method beside the macro, rather than requiring all calls to go to AsyncBase.await. - Create a minimal version of Async that just contains await/async and delegates to the macro implementation in internal._ - Add scaladoc.
-rw-r--r--build.sbt23
-rw-r--r--pending/run/fallback0/fallback0-manual.scala71
-rw-r--r--pending/run/fallback0/fallback0.scala48
-rw-r--r--src/main/scala/scala/async/Async.scala55
-rw-r--r--src/main/scala/scala/async/StateMachine.scala2
-rw-r--r--src/main/scala/scala/async/continuations/AsyncBaseWithCPSFallback.scala102
-rw-r--r--src/main/scala/scala/async/continuations/AsyncWithCPSFallback.scala25
-rw-r--r--src/main/scala/scala/async/continuations/CPSBasedAsync.scala24
-rw-r--r--src/main/scala/scala/async/continuations/CPSBasedAsyncBase.scala23
-rw-r--r--src/main/scala/scala/async/continuations/ScalaConcurrentCPSFallback.scala32
-rw-r--r--src/main/scala/scala/async/internal/AsyncAnalysis.scala9
-rw-r--r--src/main/scala/scala/async/internal/AsyncBase.scala5
-rw-r--r--src/main/scala/scala/async/internal/AsyncId.scala2
-rw-r--r--src/main/scala/scala/async/internal/AsyncTransform.scala2
-rw-r--r--src/main/scala/scala/async/internal/FutureSystem.scala7
-rw-r--r--src/main/scala/scala/async/internal/ScalaConcurrentAsync.scala (renamed from src/main/scala/scala/async/AsyncBase.scala)15
-rw-r--r--src/main/scala/scala/async/internal/TransformUtils.scala3
-rw-r--r--src/test/scala/scala/async/run/cps/CPSSpec.scala46
18 files changed, 74 insertions, 420 deletions
diff --git a/build.sbt b/build.sbt
index fc8edb8..c20da4a 100644
--- a/build.sbt
+++ b/build.sbt
@@ -28,27 +28,6 @@ testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s")
parallelExecution in Global := false
-autoCompilerPlugins := true
-
-scalacOptions ++= (scalaHome.value match {
- case Some(sh) =>
- // Use continuations plugin from the local scala instance
- val continuationsJar = sh / "misc" / "scala-devel" / "plugins" / "continuations.jar"
- ("-Xplugin:" + continuationsJar.getAbsolutePath) :: Nil
- case None =>
- Nil
-})
-
-libraryDependencies ++= (scalaHome.value match {
- case Some(sh) =>
- Nil
- case None =>
- // Use continuations plugin from the published artifact.
- compilerPlugin("org.scala-lang.plugins" % "continuations" % scalaVersion.value) :: Nil
-})
-
-scalacOptions += "-P:continuations:enable"
-
scalacOptions in compile ++= Seq("-optimize", "-deprecation", "-unchecked", "-Xlint", "-feature")
scalacOptions in Test ++= Seq("-Yrangepos")
@@ -133,4 +112,4 @@ packageOptions in packageSrc := Seq(Package.ManifestAttributes(
("Bundle-Name", s"${name.value} sources"),
("Bundle-Version", osgiVersion.value),
("Eclipse-SourceBundle", s"""${organization.value}.${name.value};version="${osgiVersion.value}";roots:="."""")
- )) \ No newline at end of file
+ ))
diff --git a/pending/run/fallback0/fallback0-manual.scala b/pending/run/fallback0/fallback0-manual.scala
deleted file mode 100644
index 9bc570d..0000000
--- a/pending/run/fallback0/fallback0-manual.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-import language.{ reflectiveCalls, postfixOps }
-import scala.concurrent.{ Future, ExecutionContext, future, Await, Promise }
-import scala.concurrent.duration._
-import scala.async.EndTaskException
-import scala.async.Async.{ async, await, awaitCps }
-import scala.util.continuations.reset
-
-object TestManual extends App {
-
- Fallback0ManualSpec.check()
-
-}
-
-class TestFallback0ManualClass {
- import ExecutionContext.Implicits.global
-
- def m1(x: Int): Future[Int] = future {
- x + 2
- }
-
- def m2(y: Int): Future[Int] = {
- val p = Promise[Int]()
- future { reset {
- val f = m1(y)
- var z = 0
- val res = awaitCps(f, p) + 5
- if (res > 0) {
- z = 2
- } else {
- z = 4
- }
- z
- } }
- p.future
- }
-
- /* that isn't even supported by current CPS plugin
- def m3(y: Int): Future[Int] = {
- val p = Promise[Int]()
- future { reset {
- val f = m1(y)
- var z = 0
- val res: Option[Int] = Some(5)
- res match {
- case None => z = 4
- case Some(a) => z = awaitCps(f, p) - 10
- }
- z
- } }
- p.future
- }
- */
-}
-
-
-object Fallback0ManualSpec extends MinimalScalaTest {
-
- "An async method" should {
- "support await in a simple if-else expression" in {
- val o = new TestFallback0ManualClass
- val fut = o.m2(10)
- val res = Await.result(fut, 2 seconds)
- res mustBe(2)
- }
- }
-
-}
diff --git a/pending/run/fallback0/fallback0.scala b/pending/run/fallback0/fallback0.scala
deleted file mode 100644
index fdb5568..0000000
--- a/pending/run/fallback0/fallback0.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-import language.{ reflectiveCalls, postfixOps }
-import scala.concurrent.{ Future, ExecutionContext, future, Await }
-import scala.concurrent.duration._
-import scala.async.Async.{ async, await, awaitCps }
-
-object Test extends App {
-
- Fallback0Spec.check()
-
-}
-
-class TestFallback0Class {
- import ExecutionContext.Implicits.global
-
- def m1(x: Int): Future[Int] = future {
- x + 2
- }
-
- def m2(y: Int): Future[Int] = async {
- val f = m1(y)
- var z = 0
- val res = await(f) + 5
- if (res > 0) {
- z = 2
- } else {
- z = 4
- }
- z
- }
-}
-
-
-object Fallback0Spec extends MinimalScalaTest {
-
- "An async method" should {
- "support await in a simple if-else expression" in {
- val o = new TestFallback0Class
- val fut = o.m2(10)
- val res = Await.result(fut, 2 seconds)
- res mustBe(2)
- }
- }
-
-}
diff --git a/src/main/scala/scala/async/Async.scala b/src/main/scala/scala/async/Async.scala
new file mode 100644
index 0000000..c45a9c6
--- /dev/null
+++ b/src/main/scala/scala/async/Async.scala
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.async
+
+import scala.language.experimental.macros
+import scala.concurrent.{Future, ExecutionContext}
+import scala.reflect.internal.annotations.compileTimeOnly
+
+/**
+ * Async blocks provide a direct means to work with [[scala.concurrent.Future]].
+ *
+ * For example, to use an API to that fetches as web page to fetch
+ * two pages and add their lengths:
+ *
+ * {{{
+ * import ExecutionContext.Implicits.global
+ * import scala.async.Async.{async, await}
+ *
+ * def fetchURL(url: URL): Future[String] = ...
+ *
+ * val sumLengths: Future[Int] = async {
+ * val body1 = fetchURL("http://scala-lang.org")
+ * val body2 = fetchURL("http://docs.scala-lang.org")
+ * await(body1).length + await(body2).length
+ * }
+ * }}}
+ *
+ * Note that the in the following program, the second fetch does *not* start
+ * until after the first. If you need to start tasks in parallel, you must do
+ * so before `await`-ing a result.
+ *
+ * {{{
+ * val sumLengths: Future[Int] = async {
+ * await(fetchURL("http://scala-lang.org")).length + await(fetchURL("http://docs.scala-lang.org")).length
+ * }
+ * }}}
+ */
+object Async {
+ /**
+ * Run the block of code `body` asynchronously. `body` may contain calls to `await` when the results of
+ * a `Future` are needed; this is translated into non-blocking code.
+ */
+ def async[T](body: T)(implicit execContext: ExecutionContext): Future[T] = macro internal.ScalaConcurrentAsync.asyncImpl[T]
+
+ /**
+ * Non-blocking await the on result of `awaitable`. This may only be used directly within an enclosing `await` block.
+ *
+ * Internally, this will register the remainder of the code in enclosing `async` block as a callback
+ * in the `onComplete` handler of `awaitable`, and will *not* block a thread.
+ */
+ @compileTimeOnly("`await` must be enclosed in an `async` block")
+ def await[T](awaitable: Future[T]): T = ??? // No implementation here, as calls to this are translated to `onComplete` by the macro.
+}
diff --git a/src/main/scala/scala/async/StateMachine.scala b/src/main/scala/scala/async/StateMachine.scala
index 823df71..cae8312 100644
--- a/src/main/scala/scala/async/StateMachine.scala
+++ b/src/main/scala/scala/async/StateMachine.scala
@@ -5,6 +5,8 @@
package scala.async
/** Internal class used by the `async` macro; should not be manually extended by client code */
+// NOTE: this is not in the `internal` package as we must keep this binary compatible as it extended
+// by the translated code.
abstract class StateMachine[Result, EC] extends (scala.util.Try[Any] => Unit) with (() => Unit) {
def result: Result
diff --git a/src/main/scala/scala/async/continuations/AsyncBaseWithCPSFallback.scala b/src/main/scala/scala/async/continuations/AsyncBaseWithCPSFallback.scala
deleted file mode 100644
index 20f5cce..0000000
--- a/src/main/scala/scala/async/continuations/AsyncBaseWithCPSFallback.scala
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-package scala.async
-package continuations
-
-import scala.language.experimental.macros
-
-import scala.reflect.macros.Context
-import scala.util.continuations._
-import scala.async.internal.{AsyncMacro, AsyncUtils}
-
-trait AsyncBaseWithCPSFallback extends internal.AsyncBase {
-
- /* Fall-back for `await` using CPS plugin.
- *
- * Note: This method is public, but is intended only for internal use.
- */
- def awaitFallback[T](awaitable: futureSystem.Fut[T]): T @cps[futureSystem.Fut[Any]]
-
- override protected[async] def fallbackEnabled = true
-
- /* Implements `async { ... }` using the CPS plugin.
- */
- protected def cpsBasedAsyncImpl[T: c.WeakTypeTag](c: Context)
- (body: c.Expr[T])
- (execContext: c.Expr[futureSystem.ExecContext]): c.Expr[futureSystem.Fut[T]] = {
- import c.universe._
-
- def lookupClassMember(clazz: String, name: String) = {
- val asyncTrait = c.mirror.staticClass(clazz)
- val tpe = asyncTrait.asType.toType
- tpe.member(newTermName(name)).ensuring(_ != NoSymbol, s"$clazz.$name")
- }
- def lookupObjectMember(clazz: String, name: String) = {
- val moduleClass = c.mirror.staticModule(clazz).moduleClass
- val tpe = moduleClass.asType.toType
- tpe.member(newTermName(name)).ensuring(_ != NoSymbol, s"$clazz.$name")
- }
-
- AsyncUtils.vprintln("AsyncBaseWithCPSFallback.cpsBasedAsyncImpl")
-
- val symTab = c.universe.asInstanceOf[reflect.internal.SymbolTable]
- val futureSystemOps = futureSystem.mkOps(symTab)
- val awaitSym = lookupObjectMember("scala.async.Async", "await")
- val awaitFallbackSym = lookupClassMember("scala.async.continuations.AsyncBaseWithCPSFallback", "awaitFallback")
-
- // replace `await` invocations with `awaitFallback` invocations
- val awaitReplacer = new Transformer {
- override def transform(tree: Tree): Tree = tree match {
- case Apply(fun @ TypeApply(_, List(futArgTpt)), args) if fun.symbol == awaitSym =>
- val typeApp = treeCopy.TypeApply(fun, atPos(tree.pos)(Ident(awaitFallbackSym)), List(atPos(tree.pos)(TypeTree(futArgTpt.tpe))))
- treeCopy.Apply(tree, typeApp, args.map(arg => c.resetAllAttrs(arg.duplicate)))
- case _ =>
- super.transform(tree)
- }
- }
- val bodyWithAwaitFallback = awaitReplacer.transform(body.tree)
-
- /* generate an expression that looks like this:
- reset {
- val f = future { ... }
- ...
- val x = awaitFallback(f)
- ...
- future { expr }
- }.asInstanceOf[Future[T]]
- */
-
- def spawn(expr: Tree) = futureSystemOps.spawn(expr.asInstanceOf[futureSystemOps.universe.Tree], execContext.tree.asInstanceOf[futureSystemOps.universe.Tree]).asInstanceOf[Tree]
-
- val bodyWithFuture = {
- val tree = bodyWithAwaitFallback match {
- case Block(stmts, expr) => Block(stmts, spawn(expr))
- case expr => spawn(expr)
- }
- c.Expr[futureSystem.Fut[Any]](c.resetAllAttrs(tree.duplicate))
- }
-
- val bodyWithReset: c.Expr[futureSystem.Fut[Any]] = reify {
- reset { bodyWithFuture.splice }
- }
- val bodyWithCast = futureSystemOps.castTo[T](bodyWithReset.asInstanceOf[futureSystemOps.universe.Expr[futureSystem.Fut[Any]]]).asInstanceOf[c.Expr[futureSystem.Fut[T]]]
-
- AsyncUtils.vprintln(s"CPS-based async transform expands to:\n${bodyWithCast.tree}")
- bodyWithCast
- }
-
- override def asyncImpl[T: c.WeakTypeTag](c: Context)
- (body: c.Expr[T])
- (execContext: c.Expr[futureSystem.ExecContext]): c.Expr[futureSystem.Fut[T]] = {
- AsyncUtils.vprintln("AsyncBaseWithCPSFallback.asyncImpl")
-
- val asyncMacro = AsyncMacro(c, this)
-
- if (!asyncMacro.reportUnsupportedAwaits(body.tree.asInstanceOf[asyncMacro.global.Tree], report = fallbackEnabled))
- super.asyncImpl[T](c)(body)(execContext) // no unsupported awaits
- else
- cpsBasedAsyncImpl[T](c)(body)(execContext) // fallback to CPS
- }
-}
diff --git a/src/main/scala/scala/async/continuations/AsyncWithCPSFallback.scala b/src/main/scala/scala/async/continuations/AsyncWithCPSFallback.scala
deleted file mode 100644
index e0da5aa..0000000
--- a/src/main/scala/scala/async/continuations/AsyncWithCPSFallback.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-package scala.async
-package continuations
-
-import scala.language.experimental.macros
-
-import scala.reflect.macros.Context
-import scala.concurrent.Future
-
-trait AsyncWithCPSFallback extends AsyncBaseWithCPSFallback with ScalaConcurrentCPSFallback
-
-object AsyncWithCPSFallback extends AsyncWithCPSFallback {
- import scala.concurrent.{ExecutionContext, Future}
-
- def async[T](body: T)(implicit execContext: ExecutionContext): Future[T] = macro asyncImpl[T]
-
- override def asyncImpl[T: c.WeakTypeTag](c: Context)
- (body: c.Expr[T])
- (execContext: c.Expr[ExecutionContext]): c.Expr[Future[T]] = {
- super.asyncImpl[T](c)(body)(execContext)
- }
-}
diff --git a/src/main/scala/scala/async/continuations/CPSBasedAsync.scala b/src/main/scala/scala/async/continuations/CPSBasedAsync.scala
deleted file mode 100644
index 2003082..0000000
--- a/src/main/scala/scala/async/continuations/CPSBasedAsync.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-package scala.async
-package continuations
-
-import scala.language.experimental.macros
-
-import scala.reflect.macros.Context
-import scala.concurrent.{ExecutionContext, Future}
-
-trait CPSBasedAsync extends CPSBasedAsyncBase with ScalaConcurrentCPSFallback
-
-object CPSBasedAsync extends CPSBasedAsync {
-
- def async[T](body: T)(implicit execContext: ExecutionContext): Future[T] = macro asyncImpl[T]
-
- override def asyncImpl[T: c.WeakTypeTag](c: Context)
- (body: c.Expr[T])
- (execContext: c.Expr[ExecutionContext]): c.Expr[Future[T]] = {
- super.asyncImpl[T](c)(body)(execContext)
- }
-}
diff --git a/src/main/scala/scala/async/continuations/CPSBasedAsyncBase.scala b/src/main/scala/scala/async/continuations/CPSBasedAsyncBase.scala
deleted file mode 100644
index a350704..0000000
--- a/src/main/scala/scala/async/continuations/CPSBasedAsyncBase.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-package scala.async
-package continuations
-
-import scala.language.experimental.macros
-
-import scala.reflect.macros.Context
-import scala.util.continuations._
-
-/* Specializes `AsyncBaseWithCPSFallback` to always fall back to CPS, yielding a purely CPS-based
- * implementation of async/await.
- */
-trait CPSBasedAsyncBase extends AsyncBaseWithCPSFallback {
-
- override def asyncImpl[T: c.WeakTypeTag](c: Context)
- (body: c.Expr[T])
- (execContext: c.Expr[futureSystem.ExecContext]): c.Expr[futureSystem.Fut[T]] = {
- super.cpsBasedAsyncImpl[T](c)(body)(execContext)
- }
-}
diff --git a/src/main/scala/scala/async/continuations/ScalaConcurrentCPSFallback.scala b/src/main/scala/scala/async/continuations/ScalaConcurrentCPSFallback.scala
deleted file mode 100644
index f864ad6..0000000
--- a/src/main/scala/scala/async/continuations/ScalaConcurrentCPSFallback.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-package scala.async
-package continuations
-
-import scala.util.continuations._
-import scala.concurrent.{Future, Promise, ExecutionContext}
-import scala.async.internal.ScalaConcurrentFutureSystem
-
-trait ScalaConcurrentCPSFallback {
- self: AsyncBaseWithCPSFallback =>
-
- import ExecutionContext.Implicits.global
-
- lazy val futureSystem = ScalaConcurrentFutureSystem
- type FS = ScalaConcurrentFutureSystem.type
-
- /* Fall-back for `await` when it is called at an unsupported position.
- */
- override def awaitFallback[T](awaitable: futureSystem.Fut[T]): T @cps[Future[Any]] =
- shift {
- (k: (T => Future[Any])) =>
- val fr = Promise[Any]()
- awaitable onComplete {
- case tr => fr completeWith k(tr.get)
- }
- fr.future
- }
-
-}
diff --git a/src/main/scala/scala/async/internal/AsyncAnalysis.scala b/src/main/scala/scala/async/internal/AsyncAnalysis.scala
index 122109e..69e4c3c 100644
--- a/src/main/scala/scala/async/internal/AsyncAnalysis.scala
+++ b/src/main/scala/scala/async/internal/AsyncAnalysis.scala
@@ -18,13 +18,13 @@ trait AsyncAnalysis {
*
* Must be called on the original tree, not on the ANF transformed tree.
*/
- def reportUnsupportedAwaits(tree: Tree, report: Boolean): Boolean = {
- val analyzer = new UnsupportedAwaitAnalyzer(report)
+ def reportUnsupportedAwaits(tree: Tree): Unit = {
+ val analyzer = new UnsupportedAwaitAnalyzer
analyzer.traverse(tree)
analyzer.hasUnsupportedAwaits
}
- private class UnsupportedAwaitAnalyzer(report: Boolean) extends AsyncTraverser {
+ private class UnsupportedAwaitAnalyzer extends AsyncTraverser {
var hasUnsupportedAwaits = false
override def nestedClass(classDef: ClassDef) {
@@ -87,8 +87,7 @@ trait AsyncAnalysis {
private def reportError(pos: Position, msg: String) {
hasUnsupportedAwaits = true
- if (report)
- abort(pos, msg)
+ abort(pos, msg)
}
}
}
diff --git a/src/main/scala/scala/async/internal/AsyncBase.scala b/src/main/scala/scala/async/internal/AsyncBase.scala
index e44c27f..89d5a4d 100644
--- a/src/main/scala/scala/async/internal/AsyncBase.scala
+++ b/src/main/scala/scala/async/internal/AsyncBase.scala
@@ -61,6 +61,11 @@ abstract class AsyncBase {
c.Expr[futureSystem.Fut[T]](code)
}
+ protected[async] def awaitMethod(u: Universe)(asyncMacroSymbol: u.Symbol): u.Symbol = {
+ import u._
+ asyncMacroSymbol.owner.typeSignature.member(newTermName("await"))
+ }
+
protected[async] def nullOut(u: Universe)(name: u.Expr[String], v: u.Expr[Any]): u.Expr[Unit] =
u.reify { () }
}
diff --git a/src/main/scala/scala/async/internal/AsyncId.scala b/src/main/scala/scala/async/internal/AsyncId.scala
index 7f7807f..c123675 100644
--- a/src/main/scala/scala/async/internal/AsyncId.scala
+++ b/src/main/scala/scala/async/internal/AsyncId.scala
@@ -78,7 +78,5 @@ object IdentityFutureSystem extends FutureSystem {
prom.splice.a = value.splice.get
Expr[Unit](Literal(Constant(()))).splice
}
-
- def castTo[A: WeakTypeTag](future: Expr[Fut[Any]]): Expr[Fut[A]] = ???
}
}
diff --git a/src/main/scala/scala/async/internal/AsyncTransform.scala b/src/main/scala/scala/async/internal/AsyncTransform.scala
index 27d95a4..cdae074 100644
--- a/src/main/scala/scala/async/internal/AsyncTransform.scala
+++ b/src/main/scala/scala/async/internal/AsyncTransform.scala
@@ -15,7 +15,7 @@ trait AsyncTransform {
// This implicit propagates the annotated type in the type tag.
implicit val uncheckedBoundsResultTag: WeakTypeTag[T] = WeakTypeTag[T](rootMirror, FixedMirrorTypeCreator(rootMirror, uncheckedBounds(resultType.tpe)))
- reportUnsupportedAwaits(body, report = !cpsFallbackEnabled)
+ reportUnsupportedAwaits(body)
// Transform to A-normal form:
// - no await calls in qualifiers or arguments,
diff --git a/src/main/scala/scala/async/internal/FutureSystem.scala b/src/main/scala/scala/async/internal/FutureSystem.scala
index f7fdc49..9fe88b4 100644
--- a/src/main/scala/scala/async/internal/FutureSystem.scala
+++ b/src/main/scala/scala/async/internal/FutureSystem.scala
@@ -51,9 +51,6 @@ trait FutureSystem {
def spawn(tree: Tree, execContext: Tree): Tree =
future(Expr[Unit](tree))(Expr[ExecContext](execContext)).tree
-
- // This is only needed in `AsyncBaseWithCPSFallback` and should be removed once CPS fall-back support is dropped.
- def castTo[A: WeakTypeTag](future: Expr[Fut[Any]]): Expr[Fut[A]]
}
def mkOps(c: SymbolTable): Ops { val universe: c.type }
@@ -96,9 +93,5 @@ object ScalaConcurrentFutureSystem extends FutureSystem {
prom.splice.complete(value.splice)
Expr[Unit](Literal(Constant(()))).splice
}
-
- def castTo[A: WeakTypeTag](future: Expr[Fut[Any]]): Expr[Fut[A]] = reify {
- future.splice.asInstanceOf[Fut[A]]
- }
}
}
diff --git a/src/main/scala/scala/async/AsyncBase.scala b/src/main/scala/scala/async/internal/ScalaConcurrentAsync.scala
index ff04a57..4e1a0af 100644
--- a/src/main/scala/scala/async/AsyncBase.scala
+++ b/src/main/scala/scala/async/internal/ScalaConcurrentAsync.scala
@@ -1,20 +1,15 @@
-/*
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-package scala.async
+package scala
+package async
+package internal
import scala.language.experimental.macros
import scala.reflect.macros.Context
-import scala.concurrent.{Future, ExecutionContext}
-import scala.async.internal.{AsyncBase, ScalaConcurrentFutureSystem}
+import scala.concurrent.Future
-object Async extends AsyncBase {
+object ScalaConcurrentAsync extends AsyncBase {
type FS = ScalaConcurrentFutureSystem.type
val futureSystem: FS = ScalaConcurrentFutureSystem
- def async[T](body: T)(implicit execContext: ExecutionContext): Future[T] = macro asyncImpl[T]
-
override def asyncImpl[T: c.WeakTypeTag](c: Context)
(body: c.Expr[T])
(execContext: c.Expr[futureSystem.ExecContext]): c.Expr[Future[T]] = {
diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala
index 663ca45..9722610 100644
--- a/src/main/scala/scala/async/internal/TransformUtils.scala
+++ b/src/main/scala/scala/async/internal/TransformUtils.scala
@@ -89,8 +89,7 @@ private[async] trait TransformUtils {
val Try_isFailure = TryClass.typeSignature.member(newTermName("isFailure")).ensuring(_ != NoSymbol)
val TryAnyType = appliedType(TryClass.toType, List(definitions.AnyTpe))
val NonFatalClass = rootMirror.staticModule("scala.util.control.NonFatal")
- val AsyncClass = rootMirror.staticClass("scala.async.internal.AsyncBase")
- val Async_await = AsyncClass.typeSignature.member(newTermName("await")).ensuring(_ != NoSymbol)
+ val Async_await = asyncBase.awaitMethod(global)(macroApplication.symbol).ensuring(_ != NoSymbol)
}
def isSafeToInline(tree: Tree) = {
diff --git a/src/test/scala/scala/async/run/cps/CPSSpec.scala b/src/test/scala/scala/async/run/cps/CPSSpec.scala
deleted file mode 100644
index 9476b22..0000000
--- a/src/test/scala/scala/async/run/cps/CPSSpec.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
- */
-
-package scala.async
-package run
-package cps
-
-import scala.concurrent.{Future, Promise, ExecutionContext, future, Await}
-import scala.concurrent.duration._
-import scala.async.continuations.CPSBasedAsync._
-import scala.util.continuations._
-
-import org.junit.Test
-
-class CPSSpec {
-
- import ExecutionContext.Implicits.global
-
- def m1(y: Int): Future[Int] = async {
- val f = future { y + 2 }
- val f2 = future { y + 3 }
- val x1 = await(f)
- val x2 = await(f2)
- x1 + x2
- }
-
- def m2(y: Int): Future[Int] = async {
- val f = future { y + 2 }
- val res = await(f)
- if (y > 0) res + 2
- else res - 2
- }
-
- @Test
- def testCPSFallback() {
- val fut1 = m1(10)
- val res1 = Await.result(fut1, 2.seconds)
- assert(res1 == 25, s"expected 25, got $res1")
-
- val fut2 = m2(10)
- val res2 = Await.result(fut2, 2.seconds)
- assert(res2 == 14, s"expected 14, got $res2")
- }
-
-}