From 447288060a3d057a220ed4f53b7a164c651271f1 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 10 Aug 2017 16:31:53 +1000 Subject: Support future systems that perform external failure handling --- .../scala/scala/async/internal/ExprBuilder.scala | 28 +++++++++++++--------- .../scala/scala/async/internal/FutureSystem.scala | 1 + .../scala/async/internal/TransformUtils.scala | 2 ++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/scala/scala/async/internal/ExprBuilder.scala b/src/main/scala/scala/async/internal/ExprBuilder.scala index 002e5cc..bb5e06a 100644 --- a/src/main/scala/scala/async/internal/ExprBuilder.scala +++ b/src/main/scala/scala/async/internal/ExprBuilder.scala @@ -117,16 +117,22 @@ trait ExprBuilder { * * } */ - def ifIsFailureTree[T: WeakTypeTag](tryReference: => Tree) = - If(futureSystemOps.tryyIsFailure(c.Expr[futureSystem.Tryy[T]](tryReference)).tree, - Block(toList(futureSystemOps.completeProm[T]( - c.Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), - c.Expr[futureSystem.Tryy[T]]( - TypeApply(Select(tryReference, newTermName("asInstanceOf")), - List(TypeTree(futureSystemOps.tryType[T]))))).tree), - Return(literalUnit)), - Block(List(tryGetTree(tryReference)), mkStateTree(nextState, symLookup)) - ) + def ifIsFailureTree[T: WeakTypeTag](tryReference: => Tree) = { + val getAndUpdateState = Block(List(tryGetTree(tryReference)), mkStateTree(nextState, symLookup)) + if (asyncBase.futureSystem.emitTryCatch) { + If(futureSystemOps.tryyIsFailure(c.Expr[futureSystem.Tryy[T]](tryReference)).tree, + Block(toList(futureSystemOps.completeProm[T]( + c.Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), + c.Expr[futureSystem.Tryy[T]]( + TypeApply(Select(tryReference, newTermName("asInstanceOf")), + List(TypeTree(futureSystemOps.tryType[T]))))).tree), + Return(literalUnit)), + getAndUpdateState + ) + } else { + getAndUpdateState + } + } override def mkOnCompleteHandler[T: WeakTypeTag]: Option[CaseDef] = { Some(mkHandlerCase(onCompleteState, List(ifIsFailureTree[T](Ident(symLookup.applyTrParam))))) @@ -402,7 +408,7 @@ trait ExprBuilder { val stateMemberRef = symLookup.memberRef(name.state) val body = Match(stateMemberRef, mkCombinedHandlerCases[T] ++ initStates.flatMap(_.mkOnCompleteHandler[T]) ++ List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Throw(Apply(Select(New(Ident(defn.IllegalStateExceptionClass)), termNames.CONSTRUCTOR), List()))))) - Try( + maybeTry( body, List( CaseDef( diff --git a/src/main/scala/scala/async/internal/FutureSystem.scala b/src/main/scala/scala/async/internal/FutureSystem.scala index aad5b92..b248744 100644 --- a/src/main/scala/scala/async/internal/FutureSystem.scala +++ b/src/main/scala/scala/async/internal/FutureSystem.scala @@ -76,6 +76,7 @@ trait FutureSystem { def mkOps(c0: Context): Ops { val c: c0.type } def freshenAllNames: Boolean = false + def emitTryCatch: Boolean = true } object ScalaConcurrentFutureSystem extends FutureSystem { diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala index 4c16dd7..1c0b625 100644 --- a/src/main/scala/scala/async/internal/TransformUtils.scala +++ b/src/main/scala/scala/async/internal/TransformUtils.scala @@ -56,6 +56,8 @@ private[async] trait TransformUtils { def fresh(name: String): String = c.freshName(name) } + def maybeTry(block: Tree, catches: List[CaseDef], finalizer: Tree) = if (asyncBase.futureSystem.emitTryCatch) Try(block, catches, finalizer) else block + def isAsync(fun: Tree) = fun.symbol == defn.Async_async -- cgit v1.2.3