@@ -33,8 +33,13 @@ trait ExprBuilder {
3333
3434 var stats : List [Tree ]
3535
36+ def statsAnd (trees : List [Tree ]): List [Tree ] = {
37+ val body = adaptToUnit(stats)
38+ Try (body, Nil , adaptToUnit(trees)) :: Nil
39+ }
40+
3641 final def allStats : List [Tree ] = this match {
37- case a : AsyncStateWithAwait => stats :+ a.awaitable.resultValDef
42+ case a : AsyncStateWithAwait => statsAnd( a.awaitable.resultValDef :: Nil )
3843 case _ => stats
3944 }
4045
@@ -51,8 +56,9 @@ trait ExprBuilder {
5156 def nextStates : List [Int ] =
5257 List (nextState)
5358
54- def mkHandlerCaseForState [T : WeakTypeTag ]: CaseDef =
55- mkHandlerCase(state, stats :+ mkStateTree(nextState, symLookup))
59+ def mkHandlerCaseForState [T : WeakTypeTag ]: CaseDef = {
60+ mkHandlerCase(state, statsAnd(mkStateTree(nextState, symLookup) :: Nil ))
61+ }
5662
5763 override val toString : String =
5864 s " AsyncState # $state, next = $nextState"
@@ -86,10 +92,10 @@ trait ExprBuilder {
8692 val tryGetOrCallOnComplete =
8793 if (futureSystemOps.continueCompletedFutureOnSameThread)
8894 If (futureSystemOps.isCompleted(Expr [futureSystem.Fut [_]](awaitable.expr)).tree,
89- Block (ifIsFailureTree[T ](futureSystemOps.getCompleted[Any ](Expr [futureSystem.Fut [Any ]](awaitable.expr)).tree) :: Nil , literalUnit ),
90- Block (callOnComplete :: Nil , Return (literalUnit)))
95+ adaptToUnit (ifIsFailureTree[T ](futureSystemOps.getCompleted[Any ](Expr [futureSystem.Fut [Any ]](awaitable.expr)).tree) :: Nil ),
96+ Block (toList( callOnComplete) , Return (literalUnit)))
9197 else
92- Block (callOnComplete :: Nil , Return (literalUnit))
98+ Block (toList( callOnComplete) , Return (literalUnit))
9399 mkHandlerCase(state, stats ++ List (mkStateTree(onCompleteState, symLookup), tryGetOrCallOnComplete))
94100 }
95101
@@ -109,11 +115,11 @@ trait ExprBuilder {
109115 */
110116 def ifIsFailureTree [T : WeakTypeTag ](tryReference : => Tree ) =
111117 If (futureSystemOps.tryyIsFailure(Expr [futureSystem.Tryy [T ]](tryReference)).tree,
112- Block (futureSystemOps.completeProm[T ](
118+ Block (toList( futureSystemOps.completeProm[T ](
113119 Expr [futureSystem.Prom [T ]](symLookup.memberRef(name.result)),
114120 Expr [futureSystem.Tryy [T ]](
115121 TypeApply (Select (tryReference, newTermName(" asInstanceOf" )),
116- List (TypeTree (futureSystemOps.tryType[T ]))))).tree :: Nil ,
122+ List (TypeTree (futureSystemOps.tryType[T ]))))).tree) ,
117123 Return (literalUnit)),
118124 Block (List (tryGetTree(tryReference)), mkStateTree(nextState, symLookup))
119125 )
@@ -381,12 +387,12 @@ trait ExprBuilder {
381387 val t = Expr [Throwable ](Ident (name.t))
382388 val complete = futureSystemOps.completeProm[T ](
383389 Expr [futureSystem.Prom [T ]](symLookup.memberRef(name.result)), futureSystemOps.tryyFailure[T ](t)).tree
384- Block (complete :: Nil , Return (literalUnit))
390+ Block (toList( complete) , Return (literalUnit))
385391 })), EmptyTree )
386392
387393 def forever (t : Tree ): Tree = {
388394 val labelName = name.fresh(" while$" )
389- LabelDef (labelName, Nil , Block (t :: Nil , Apply (Ident (labelName), Nil )))
395+ LabelDef (labelName, Nil , Block (toList(t) , Apply (Ident (labelName), Nil )))
390396 }
391397
392398 /**
@@ -404,7 +410,7 @@ trait ExprBuilder {
404410 def onCompleteHandler [T : WeakTypeTag ]: Tree = {
405411 val onCompletes = initStates.flatMap(_.mkOnCompleteHandler[T ]).toList
406412 forever {
407- Block ( resumeFunTree :: Nil , literalUnit )
413+ adaptToUnit(toList( resumeFunTree) )
408414 }
409415 }
410416 }
@@ -421,12 +427,32 @@ trait ExprBuilder {
421427 Assign (symLookup.memberRef(name.state), Literal (Constant (nextState)))
422428
423429 private def mkHandlerCase (num : Int , rhs : List [Tree ]): CaseDef =
424- mkHandlerCase(num, Block (rhs, literalUnit))
430+ mkHandlerCase(num, adaptToUnit(rhs))
431+
432+ private def tpeOf (t : Tree ): Type = t match {
433+ case _ if t.tpe != null => t.tpe
434+ case Try (body, Nil , _) => tpeOf(body)
435+ case _ => NoType
436+ }
437+
438+ private def adaptToUnit (rhs : List [Tree ]): Block = {
439+ rhs match {
440+ case init :+ last if tpeOf(last) <:< definitions.UnitTpe =>
441+ Block (init, last)
442+ case _ =>
443+ Block (rhs, literalUnit)
444+ }
445+ }
425446
426447 private def mkHandlerCase (num : Int , rhs : Tree ): CaseDef =
427448 CaseDef (Literal (Constant (num)), EmptyTree , rhs)
428449
429- def literalUnit = Literal (Constant (()))
450+ def literalUnit = Literal (Constant (())) // a def to avoid sharing trees
451+
452+ def toList (tree : Tree ): List [Tree ] = tree match {
453+ case Block (stats, Literal (Constant (value))) if value == () => stats
454+ case _ => tree :: Nil
455+ }
430456
431457 def literalNull = Literal (Constant (null ))
432458}
0 commit comments