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