@@ -33,8 +33,18 @@ trait ExprBuilder {
33
33
34
34
var stats : List [Tree ]
35
35
36
+ def statsAnd (trees : List [Tree ]): List [Tree ] = {
37
+ val body = stats match {
38
+ case init :+ last if tpeOf(last) =:= definitions.NothingTpe =>
39
+ adaptToUnit(init :+ Typed (last, TypeTree (definitions.AnyTpe )))
40
+ case _ =>
41
+ adaptToUnit(stats)
42
+ }
43
+ Try (body, Nil , adaptToUnit(trees)) :: Nil
44
+ }
45
+
36
46
final def allStats : List [Tree ] = this match {
37
- case a : AsyncStateWithAwait => stats :+ a.awaitable.resultValDef
47
+ case a : AsyncStateWithAwait => statsAnd( a.awaitable.resultValDef :: Nil )
38
48
case _ => stats
39
49
}
40
50
@@ -51,8 +61,9 @@ trait ExprBuilder {
51
61
def nextStates : List [Int ] =
52
62
List (nextState)
53
63
54
- def mkHandlerCaseForState [T : WeakTypeTag ]: CaseDef =
55
- mkHandlerCase(state, stats :+ mkStateTree(nextState, symLookup))
64
+ def mkHandlerCaseForState [T : WeakTypeTag ]: CaseDef = {
65
+ mkHandlerCase(state, statsAnd(mkStateTree(nextState, symLookup) :: Nil ))
66
+ }
56
67
57
68
override val toString : String =
58
69
s " AsyncState # $state, next = $nextState"
@@ -86,10 +97,10 @@ trait ExprBuilder {
86
97
val tryGetOrCallOnComplete =
87
98
if (futureSystemOps.continueCompletedFutureOnSameThread)
88
99
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)))
100
+ adaptToUnit (ifIsFailureTree[T ](futureSystemOps.getCompleted[Any ](Expr [futureSystem.Fut [Any ]](awaitable.expr)).tree) :: Nil ),
101
+ Block (toList( callOnComplete) , Return (literalUnit)))
91
102
else
92
- Block (callOnComplete :: Nil , Return (literalUnit))
103
+ Block (toList( callOnComplete) , Return (literalUnit))
93
104
mkHandlerCase(state, stats ++ List (mkStateTree(onCompleteState, symLookup), tryGetOrCallOnComplete))
94
105
}
95
106
@@ -109,11 +120,11 @@ trait ExprBuilder {
109
120
*/
110
121
def ifIsFailureTree [T : WeakTypeTag ](tryReference : => Tree ) =
111
122
If (futureSystemOps.tryyIsFailure(Expr [futureSystem.Tryy [T ]](tryReference)).tree,
112
- Block (futureSystemOps.completeProm[T ](
123
+ Block (toList( futureSystemOps.completeProm[T ](
113
124
Expr [futureSystem.Prom [T ]](symLookup.memberRef(name.result)),
114
125
Expr [futureSystem.Tryy [T ]](
115
126
TypeApply (Select (tryReference, newTermName(" asInstanceOf" )),
116
- List (TypeTree (futureSystemOps.tryType[T ]))))).tree :: Nil ,
127
+ List (TypeTree (futureSystemOps.tryType[T ]))))).tree) ,
117
128
Return (literalUnit)),
118
129
Block (List (tryGetTree(tryReference)), mkStateTree(nextState, symLookup))
119
130
)
@@ -381,12 +392,12 @@ trait ExprBuilder {
381
392
val t = Expr [Throwable ](Ident (name.t))
382
393
val complete = futureSystemOps.completeProm[T ](
383
394
Expr [futureSystem.Prom [T ]](symLookup.memberRef(name.result)), futureSystemOps.tryyFailure[T ](t)).tree
384
- Block (complete :: Nil , Return (literalUnit))
395
+ Block (toList( complete) , Return (literalUnit))
385
396
})), EmptyTree )
386
397
387
398
def forever (t : Tree ): Tree = {
388
399
val labelName = name.fresh(" while$" )
389
- LabelDef (labelName, Nil , Block (t :: Nil , Apply (Ident (labelName), Nil )))
400
+ LabelDef (labelName, Nil , Block (toList(t) , Apply (Ident (labelName), Nil )))
390
401
}
391
402
392
403
/**
@@ -404,7 +415,7 @@ trait ExprBuilder {
404
415
def onCompleteHandler [T : WeakTypeTag ]: Tree = {
405
416
val onCompletes = initStates.flatMap(_.mkOnCompleteHandler[T ]).toList
406
417
forever {
407
- Block ( resumeFunTree :: Nil , literalUnit )
418
+ adaptToUnit(toList( resumeFunTree) )
408
419
}
409
420
}
410
421
}
@@ -421,12 +432,32 @@ trait ExprBuilder {
421
432
Assign (symLookup.memberRef(name.state), Literal (Constant (nextState)))
422
433
423
434
private def mkHandlerCase (num : Int , rhs : List [Tree ]): CaseDef =
424
- mkHandlerCase(num, Block (rhs, literalUnit))
435
+ mkHandlerCase(num, adaptToUnit(rhs))
436
+
437
+ private def tpeOf (t : Tree ): Type = t match {
438
+ case _ if t.tpe != null => t.tpe
439
+ case Try (body, Nil , _) => tpeOf(body)
440
+ case _ => NoType
441
+ }
442
+
443
+ private def adaptToUnit (rhs : List [Tree ]): Block = {
444
+ rhs match {
445
+ case init :+ last if tpeOf(last) <:< definitions.UnitTpe =>
446
+ Block (init, last)
447
+ case _ =>
448
+ Block (rhs, literalUnit)
449
+ }
450
+ }
425
451
426
452
private def mkHandlerCase (num : Int , rhs : Tree ): CaseDef =
427
453
CaseDef (Literal (Constant (num)), EmptyTree , rhs)
428
454
429
- def literalUnit = Literal (Constant (()))
455
+ def literalUnit = Literal (Constant (())) // a def to avoid sharing trees
456
+
457
+ def toList (tree : Tree ): List [Tree ] = tree match {
458
+ case Block (stats, Literal (Constant (value))) if value == () => stats
459
+ case _ => tree :: Nil
460
+ }
430
461
431
462
def literalNull = Literal (Constant (null ))
432
463
}
0 commit comments