@@ -34,8 +34,13 @@ trait ExprBuilder {
34
34
35
35
var stats : List [Tree ]
36
36
37
+ def statsAnd (trees : List [Tree ]): List [Tree ] = {
38
+ val body = adaptToUnit(stats)
39
+ Try (body, Nil , adaptToUnit(trees)) :: Nil
40
+ }
41
+
37
42
final def allStats : List [Tree ] = this match {
38
- case a : AsyncStateWithAwait => stats :+ a.awaitable.resultValDef
43
+ case a : AsyncStateWithAwait => statsAnd( a.awaitable.resultValDef :: Nil )
39
44
case _ => stats
40
45
}
41
46
@@ -52,8 +57,9 @@ trait ExprBuilder {
52
57
def nextStates : List [Int ] =
53
58
List (nextState)
54
59
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
+ }
57
63
58
64
override val toString : String =
59
65
s " AsyncState # $state, next = $nextState"
@@ -87,10 +93,10 @@ trait ExprBuilder {
87
93
val tryGetOrCallOnComplete =
88
94
if (futureSystemOps.continueCompletedFutureOnSameThread)
89
95
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)))
92
98
else
93
- Block (callOnComplete :: Nil , Return (literalUnit))
99
+ Block (toList( callOnComplete) , Return (literalUnit))
94
100
mkHandlerCase(state, stats ++ List (mkStateTree(onCompleteState, symLookup), tryGetOrCallOnComplete))
95
101
}
96
102
@@ -110,11 +116,11 @@ trait ExprBuilder {
110
116
*/
111
117
def ifIsFailureTree [T : WeakTypeTag ](tryReference : => Tree ) =
112
118
If (futureSystemOps.tryyIsFailure(c.Expr [futureSystem.Tryy [T ]](tryReference)).tree,
113
- Block (futureSystemOps.completeProm[T ](
119
+ Block (toList( futureSystemOps.completeProm[T ](
114
120
c.Expr [futureSystem.Prom [T ]](symLookup.memberRef(name.result)),
115
121
c.Expr [futureSystem.Tryy [T ]](
116
122
TypeApply (Select (tryReference, newTermName(" asInstanceOf" )),
117
- List (TypeTree (futureSystemOps.tryType[T ]))))).tree :: Nil ,
123
+ List (TypeTree (futureSystemOps.tryType[T ]))))).tree) ,
118
124
Return (literalUnit)),
119
125
Block (List (tryGetTree(tryReference)), mkStateTree(nextState, symLookup))
120
126
)
@@ -382,12 +388,12 @@ trait ExprBuilder {
382
388
val t = c.Expr [Throwable ](Ident (name.t))
383
389
val complete = futureSystemOps.completeProm[T ](
384
390
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))
386
392
})), EmptyTree )
387
393
388
394
def forever (t : Tree ): Tree = {
389
395
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 )))
391
397
}
392
398
393
399
/**
@@ -405,7 +411,7 @@ trait ExprBuilder {
405
411
def onCompleteHandler [T : WeakTypeTag ]: Tree = {
406
412
val onCompletes = initStates.flatMap(_.mkOnCompleteHandler[T ]).toList
407
413
forever {
408
- Block ( resumeFunTree :: Nil , literalUnit )
414
+ adaptToUnit(toList( resumeFunTree) )
409
415
}
410
416
}
411
417
}
@@ -422,12 +428,32 @@ trait ExprBuilder {
422
428
Assign (symLookup.memberRef(name.state), Literal (Constant (nextState)))
423
429
424
430
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
+ }
426
447
427
448
private def mkHandlerCase (num : Int , rhs : Tree ): CaseDef =
428
449
CaseDef (Literal (Constant (num)), EmptyTree , rhs)
429
450
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
+ }
431
457
432
458
def literalNull = Literal (Constant (null ))
433
459
}
0 commit comments