@@ -34,8 +34,13 @@ trait ExprBuilder {
3434
3535 var stats : List [Tree ]
3636
37+ def statsAnd (trees : List [Tree ]): List [Tree ] = {
38+ val body = adaptToUnit(stats)
39+ Try (body, Nil , adaptToUnit(trees)) :: Nil
40+ }
41+
3742 final def allStats : List [Tree ] = this match {
38- case a : AsyncStateWithAwait => stats :+ a.awaitable.resultValDef
43+ case a : AsyncStateWithAwait => statsAnd( a.awaitable.resultValDef :: Nil )
3944 case _ => stats
4045 }
4146
@@ -52,8 +57,9 @@ trait ExprBuilder {
5257 def nextStates : List [Int ] =
5358 List (nextState)
5459
55- def mkHandlerCaseForState [T : WeakTypeTag ]: CaseDef =
56- mkHandlerCase(state, stats :+ mkStateTree(nextState, symLookup))
60+ def mkHandlerCaseForState [T : WeakTypeTag ]: CaseDef = {
61+ mkHandlerCase(state, statsAnd(mkStateTree(nextState, symLookup) :: Nil ))
62+ }
5763
5864 override val toString : String =
5965 s " AsyncState # $state, next = $nextState"
@@ -87,10 +93,10 @@ trait ExprBuilder {
8793 val tryGetOrCallOnComplete =
8894 if (futureSystemOps.continueCompletedFutureOnSameThread)
8995 If (futureSystemOps.isCompleted(c.Expr [futureSystem.Fut [_]](awaitable.expr)).tree,
90- Block (ifIsFailureTree[T ](futureSystemOps.getCompleted[Any ](c.Expr [futureSystem.Fut [Any ]](awaitable.expr)).tree) :: Nil , literalUnit ),
91- Block (callOnComplete :: Nil , Return (literalUnit)))
96+ adaptToUnit (ifIsFailureTree[T ](futureSystemOps.getCompleted[Any ](c.Expr [futureSystem.Fut [Any ]](awaitable.expr)).tree) :: Nil ),
97+ Block (toList( callOnComplete) , Return (literalUnit)))
9298 else
93- Block (callOnComplete :: Nil , Return (literalUnit))
99+ Block (toList( callOnComplete) , Return (literalUnit))
94100 mkHandlerCase(state, stats ++ List (mkStateTree(onCompleteState, symLookup), tryGetOrCallOnComplete))
95101 }
96102
@@ -110,11 +116,11 @@ trait ExprBuilder {
110116 */
111117 def ifIsFailureTree [T : WeakTypeTag ](tryReference : => Tree ) =
112118 If (futureSystemOps.tryyIsFailure(c.Expr [futureSystem.Tryy [T ]](tryReference)).tree,
113- Block (futureSystemOps.completeProm[T ](
119+ Block (toList( futureSystemOps.completeProm[T ](
114120 c.Expr [futureSystem.Prom [T ]](symLookup.memberRef(name.result)),
115121 c.Expr [futureSystem.Tryy [T ]](
116122 TypeApply (Select (tryReference, newTermName(" asInstanceOf" )),
117- List (TypeTree (futureSystemOps.tryType[T ]))))).tree :: Nil ,
123+ List (TypeTree (futureSystemOps.tryType[T ]))))).tree) ,
118124 Return (literalUnit)),
119125 Block (List (tryGetTree(tryReference)), mkStateTree(nextState, symLookup))
120126 )
@@ -382,12 +388,12 @@ trait ExprBuilder {
382388 val t = c.Expr [Throwable ](Ident (name.t))
383389 val complete = futureSystemOps.completeProm[T ](
384390 c.Expr [futureSystem.Prom [T ]](symLookup.memberRef(name.result)), futureSystemOps.tryyFailure[T ](t)).tree
385- Block (complete :: Nil , Return (literalUnit))
391+ Block (toList( complete) , Return (literalUnit))
386392 })), EmptyTree )
387393
388394 def forever (t : Tree ): Tree = {
389395 val labelName = name.fresh(" while$" )
390- LabelDef (labelName, Nil , Block (t :: Nil , Apply (Ident (labelName), Nil )))
396+ LabelDef (labelName, Nil , Block (toList(t) , Apply (Ident (labelName), Nil )))
391397 }
392398
393399 /**
@@ -405,7 +411,7 @@ trait ExprBuilder {
405411 def onCompleteHandler [T : WeakTypeTag ]: Tree = {
406412 val onCompletes = initStates.flatMap(_.mkOnCompleteHandler[T ]).toList
407413 forever {
408- Block ( resumeFunTree :: Nil , literalUnit )
414+ adaptToUnit(toList( resumeFunTree) )
409415 }
410416 }
411417 }
@@ -422,12 +428,32 @@ trait ExprBuilder {
422428 Assign (symLookup.memberRef(name.state), Literal (Constant (nextState)))
423429
424430 private def mkHandlerCase (num : Int , rhs : List [Tree ]): CaseDef =
425- mkHandlerCase(num, Block (rhs, literalUnit))
431+ mkHandlerCase(num, adaptToUnit(rhs))
432+
433+ private def tpeOf (t : Tree ): Type = t match {
434+ case _ if t.tpe != null => t.tpe
435+ case Try (body, Nil , _) => tpeOf(body)
436+ case _ => NoType
437+ }
438+
439+ private def adaptToUnit (rhs : List [Tree ]): c.universe.Block = {
440+ rhs match {
441+ case init :+ last if tpeOf(last) <:< definitions.UnitTpe =>
442+ Block (init, last)
443+ case _ =>
444+ Block (rhs, literalUnit)
445+ }
446+ }
426447
427448 private def mkHandlerCase (num : Int , rhs : Tree ): CaseDef =
428449 CaseDef (Literal (Constant (num)), EmptyTree , rhs)
429450
430- def literalUnit = Literal (Constant (()))
451+ def literalUnit = Literal (Constant (())) // a def to avoid sharing trees
452+
453+ def toList (tree : Tree ): List [Tree ] = tree match {
454+ case Block (stats, Literal (Constant (value))) if value == () => stats
455+ case _ => tree :: Nil
456+ }
431457
432458 def literalNull = Literal (Constant (null ))
433459}
0 commit comments