aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-11-13 18:28:45 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-11-13 19:17:12 +0100
commit32500577c34c2eff39e06620a7027c27be31b9e4 (patch)
treea4d5b4ecf37640e0b628a01a4901af3d3529c794
parent2eba82f8b7687dd898b89496451ebb3ae9519692 (diff)
downloadscala-async-32500577c34c2eff39e06620a7027c27be31b9e4.tar.gz
scala-async-32500577c34c2eff39e06620a7027c27be31b9e4.tar.bz2
scala-async-32500577c34c2eff39e06620a7027c27be31b9e4.zip
Abstract over use of scala.util.Try
Custom implementation of the async macro may choose to use a different data type to represent `Throwable | A`.
-rw-r--r--src/main/scala/scala/async/internal/AsyncId.scala20
-rw-r--r--src/main/scala/scala/async/internal/AsyncTransform.scala2
-rw-r--r--src/main/scala/scala/async/internal/ExprBuilder.scala12
-rw-r--r--src/main/scala/scala/async/internal/FutureSystem.scala29
4 files changed, 52 insertions, 11 deletions
diff --git a/src/main/scala/scala/async/internal/AsyncId.scala b/src/main/scala/scala/async/internal/AsyncId.scala
index a794f93..5343a82 100644
--- a/src/main/scala/scala/async/internal/AsyncId.scala
+++ b/src/main/scala/scala/async/internal/AsyncId.scala
@@ -50,6 +50,7 @@ object IdentityFutureSystem extends FutureSystem {
type Fut[A] = A
type ExecContext = Unit
+ type Tryy[A] = scala.util.Try[A]
def mkOps(c: SymbolTable): Ops {val universe: c.type} = new Ops {
val universe: c.type = c
@@ -59,6 +60,7 @@ object IdentityFutureSystem extends FutureSystem {
def execContext: Expr[ExecContext] = Expr[Unit](Literal(Constant(())))
def promType[A: WeakTypeTag]: Type = weakTypeOf[Prom[A]]
+ def tryType[A: WeakTypeTag]: Type = weakTypeOf[scala.util.Try[A]]
def execContextType: Type = weakTypeOf[Unit]
def createProm[A: WeakTypeTag]: Expr[Prom[A]] = reify {
@@ -71,15 +73,29 @@ object IdentityFutureSystem extends FutureSystem {
def future[A: WeakTypeTag](t: Expr[A])(execContext: Expr[ExecContext]) = t
- def onComplete[A, U](future: Expr[Fut[A]], fun: Expr[scala.util.Try[A] => U],
+ def onComplete[A, U](future: Expr[Fut[A]], fun: Expr[Tryy[A] => U],
execContext: Expr[ExecContext]): Expr[Unit] = reify {
fun.splice.apply(util.Success(future.splice))
Expr[Unit](Literal(Constant(()))).splice
}
- def completeProm[A](prom: Expr[Prom[A]], value: Expr[scala.util.Try[A]]): Expr[Unit] = reify {
+ def completeProm[A](prom: Expr[Prom[A]], value: Expr[Tryy[A]]): Expr[Unit] = reify {
prom.splice.a = value.splice.get
Expr[Unit](Literal(Constant(()))).splice
}
+
+ def tryyIsFailure[A](tryy: Expr[Tryy[A]]): Expr[Boolean] = reify {
+ tryy.splice.isFailure
+ }
+
+ def tryyGet[A](tryy: Expr[Tryy[A]]): Expr[A] = reify {
+ tryy.splice.get
+ }
+ def tryySuccess[A: WeakTypeTag](a: Expr[A]): Expr[Tryy[A]] = reify {
+ scala.util.Success[A](a.splice)
+ }
+ def tryyFailure[A: WeakTypeTag](a: Expr[Throwable]): Expr[Tryy[A]] = reify {
+ scala.util.Failure[A](a.splice)
+ }
}
}
diff --git a/src/main/scala/scala/async/internal/AsyncTransform.scala b/src/main/scala/scala/async/internal/AsyncTransform.scala
index 043822b..352ef71 100644
--- a/src/main/scala/scala/async/internal/AsyncTransform.scala
+++ b/src/main/scala/scala/async/internal/AsyncTransform.scala
@@ -27,7 +27,7 @@ trait AsyncTransform {
val resumeFunTreeDummyBody = DefDef(Modifiers(), name.resume, Nil, List(Nil), Ident(definitions.UnitClass), Literal(Constant(())))
val applyDefDefDummyBody: DefDef = {
- val applyVParamss = List(List(ValDef(Modifiers(Flag.PARAM), name.tr, TypeTree(defn.TryAnyType), EmptyTree)))
+ val applyVParamss = List(List(ValDef(Modifiers(Flag.PARAM), name.tr, TypeTree(futureSystemOps.tryType[Any]), EmptyTree)))
DefDef(NoMods, name.apply, Nil, applyVParamss, TypeTree(definitions.UnitTpe), Literal(Constant(())))
}
diff --git a/src/main/scala/scala/async/internal/ExprBuilder.scala b/src/main/scala/scala/async/internal/ExprBuilder.scala
index 16e95dd..85e0953 100644
--- a/src/main/scala/scala/async/internal/ExprBuilder.scala
+++ b/src/main/scala/scala/async/internal/ExprBuilder.scala
@@ -89,7 +89,7 @@ trait ExprBuilder {
val tryGetTree =
Assign(
Ident(awaitable.resultName),
- TypeApply(Select(Select(Ident(symLookup.applyTrParam), Try_get), newTermName("asInstanceOf")), List(TypeTree(awaitable.resultType)))
+ TypeApply(Select(futureSystemOps.tryyGet[T](Expr[futureSystem.Tryy[T]](Ident(symLookup.applyTrParam))).tree, newTermName("asInstanceOf")), List(TypeTree(awaitable.resultType)))
)
/* if (tr.isFailure)
@@ -101,12 +101,12 @@ trait ExprBuilder {
* }
*/
val ifIsFailureTree =
- If(Select(Ident(symLookup.applyTrParam), Try_isFailure),
+ If(futureSystemOps.tryyIsFailure(Expr[futureSystem.Tryy[T]](Ident(symLookup.applyTrParam))).tree,
futureSystemOps.completeProm[T](
Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)),
- Expr[scala.util.Try[T]](
+ Expr[futureSystem.Tryy[T]](
TypeApply(Select(Ident(symLookup.applyTrParam), newTermName("asInstanceOf")),
- List(TypeTree(weakTypeOf[scala.util.Try[T]]))))).tree,
+ List(TypeTree(futureSystemOps.tryType[T]))))).tree,
Block(List(tryGetTree, mkStateTree(nextState, symLookup)), mkResumeApply(symLookup))
)
@@ -325,7 +325,7 @@ trait ExprBuilder {
val lastState = asyncStates.last
val lastStateBody = Expr[T](lastState.body)
val rhs = futureSystemOps.completeProm(
- Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), reify(scala.util.Success[T](lastStateBody.splice)))
+ Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), futureSystemOps.tryySuccess[T](lastStateBody))
mkHandlerCase(lastState.state, rhs.tree)
}
asyncStates.toList match {
@@ -368,7 +368,7 @@ trait ExprBuilder {
Apply(Ident(defn.NonFatalClass), List(Ident(name.t))), {
val t = Expr[Throwable](Ident(name.t))
futureSystemOps.completeProm[T](
- Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), reify(scala.util.Failure(t.splice))).tree
+ Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), futureSystemOps.tryyFailure[T](t)).tree
})), EmptyTree))
/**
diff --git a/src/main/scala/scala/async/internal/FutureSystem.scala b/src/main/scala/scala/async/internal/FutureSystem.scala
index c064474..166affe 100644
--- a/src/main/scala/scala/async/internal/FutureSystem.scala
+++ b/src/main/scala/scala/async/internal/FutureSystem.scala
@@ -23,6 +23,8 @@ trait FutureSystem {
type Fut[A]
/** An execution context, required to create or register an on completion callback on a Future. */
type ExecContext
+ /** Any data type isomorphic to scala.util.Try. */
+ type Tryy[T]
trait Ops {
val universe: reflect.internal.SymbolTable
@@ -31,6 +33,7 @@ trait FutureSystem {
def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](rootMirror, universe.FixedMirrorTreeCreator(rootMirror, tree))
def promType[A: WeakTypeTag]: Type
+ def tryType[A: WeakTypeTag]: Type
def execContextType: Type
/** Create an empty promise */
@@ -43,15 +46,21 @@ trait FutureSystem {
def future[A: WeakTypeTag](a: Expr[A])(execContext: Expr[ExecContext]): Expr[Fut[A]]
/** Register an call back to run on completion of the given future */
- def onComplete[A, U](future: Expr[Fut[A]], fun: Expr[scala.util.Try[A] => U],
+ def onComplete[A, U](future: Expr[Fut[A]], fun: Expr[Tryy[A] => U],
execContext: Expr[ExecContext]): Expr[Unit]
/** Complete a promise with a value */
- def completeProm[A](prom: Expr[Prom[A]], value: Expr[scala.util.Try[A]]): Expr[Unit]
+ def completeProm[A](prom: Expr[Prom[A]], value: Expr[Tryy[A]]): Expr[Unit]
def spawn(tree: Tree, execContext: Tree): Tree =
future(Expr[Unit](tree))(Expr[ExecContext](execContext)).tree
+ def tryyIsFailure[A](tryy: Expr[Tryy[A]]): Expr[Boolean]
+
+ def tryyGet[A](tryy: Expr[Tryy[A]]): Expr[A]
+ def tryySuccess[A: WeakTypeTag](a: Expr[A]): Expr[Tryy[A]]
+ def tryyFailure[A: WeakTypeTag](a: Expr[Throwable]): Expr[Tryy[A]]
+
/** A hook for custom macros to transform the tree post-ANF transform */
def postAnfTransform(tree: Block): Block = tree
}
@@ -66,6 +75,7 @@ object ScalaConcurrentFutureSystem extends FutureSystem {
type Prom[A] = Promise[A]
type Fut[A] = Future[A]
type ExecContext = ExecutionContext
+ type Tryy[A] = scala.util.Try[A]
def mkOps(c: SymbolTable): Ops {val universe: c.type} = new Ops {
val universe: c.type = c
@@ -73,6 +83,7 @@ object ScalaConcurrentFutureSystem extends FutureSystem {
import universe._
def promType[A: WeakTypeTag]: Type = weakTypeOf[Promise[A]]
+ def tryType[A: WeakTypeTag]: Type = weakTypeOf[scala.util.Try[A]]
def execContextType: Type = weakTypeOf[ExecutionContext]
def createProm[A: WeakTypeTag]: Expr[Prom[A]] = reify {
@@ -96,5 +107,19 @@ object ScalaConcurrentFutureSystem extends FutureSystem {
prom.splice.complete(value.splice)
Expr[Unit](Literal(Constant(()))).splice
}
+
+ def tryyIsFailure[A](tryy: Expr[scala.util.Try[A]]): Expr[Boolean] = reify {
+ tryy.splice.isFailure
+ }
+
+ def tryyGet[A](tryy: Expr[Tryy[A]]): Expr[A] = reify {
+ tryy.splice.get
+ }
+ def tryySuccess[A: WeakTypeTag](a: Expr[A]): Expr[Tryy[A]] = reify {
+ scala.util.Success[A](a.splice)
+ }
+ def tryyFailure[A: WeakTypeTag](a: Expr[Throwable]): Expr[Tryy[A]] = reify {
+ scala.util.Failure[A](a.splice)
+ }
}
}