@@ -340,6 +340,7 @@ public class Desugar extends BLangNodeVisitor {
340
340
private BLangSimpleVariableDef onFailCallFuncDef ;
341
341
private BLangOnFailClause onFailClause ;
342
342
private BType forceCastReturnType = null ;
343
+ private boolean skipFailDesugaring = false ;
343
344
344
345
private SymbolEnv env ;
345
346
private int lambdaFunctionCount = 0 ;
@@ -2520,88 +2521,94 @@ public void visit(BLangRetry retryNode) {
2520
2521
BLangOnFailClause currentOnFailClause = this .onFailClause ;
2521
2522
BLangSimpleVariableDef currentOnFailCallDef = this .onFailCallFuncDef ;
2522
2523
if (retryNode .onFailClause != null ) {
2523
- rewrite (retryNode .onFailClause , env );
2524
- }
2525
- DiagnosticPos pos = retryNode .retryBody .pos ;
2526
- BLangBlockStmt retryBlockStmt = ASTBuilderUtil .createBlockStmt (retryNode .pos );
2527
- BLangSimpleVariableDef retryManagerVarDef = createRetryManagerDef (retryNode .retrySpec , retryNode .pos );
2528
- retryBlockStmt .stmts .add (retryManagerVarDef );
2529
-
2530
- // var $retryFunc$ = function () returns any|error {
2531
- // <"Content in retry block goes here">
2532
- // };
2533
- BLangType retryLambdaReturnType = ASTBuilderUtil .createTypeNode (symTable .anyOrErrorType );
2534
- BLangLambdaFunction retryFunc = createLambdaFunction (pos , "$retryFunc$" ,
2535
- Collections .emptyList (), retryLambdaReturnType ,
2536
- retryNode .retryBody .stmts , env ,
2537
- retryNode .retryBody .scope );
2538
- ((BLangBlockFunctionBody ) retryFunc .function .body ).isBreakable = this .onFailClause != null ;
2539
- BVarSymbol retryFuncVarSymbol = new BVarSymbol (0 , names .fromString ("$retryFunc$" ),
2540
- env .scope .owner .pkgID , retryFunc .type ,
2541
- retryFunc .function .symbol , pos , VIRTUAL );
2542
- BLangSimpleVariable retryLambdaVariable = ASTBuilderUtil .createVariable (pos , "$retryFunc$" ,
2543
- retryFunc .type , retryFunc ,
2544
- retryFuncVarSymbol );
2545
- BLangSimpleVariableDef retryLambdaVariableDef = ASTBuilderUtil .createVariableDef (pos ,
2546
- retryLambdaVariable );
2547
- BLangSimpleVarRef retryLambdaVarRef = new BLangSimpleVarRef .BLangLocalVarRef (retryLambdaVariable .symbol );
2548
- retryLambdaVarRef .type = retryFuncVarSymbol .type ;
2549
- retryBlockStmt .stmts .add (retryLambdaVariableDef );
2550
-
2551
- // Add lambda function call
2552
- //any|error $result$ = $retryFunc$();
2553
- BLangInvocation retryLambdaInvocation = new BLangInvocation .BFunctionPointerInvocation (pos ,
2554
- retryLambdaVarRef , retryLambdaVariable .symbol , retryLambdaReturnType .type );
2555
- retryLambdaInvocation .argExprs = new ArrayList <>();
2556
-
2557
- retryFunc .capturedClosureEnv = env .createClone ();
2558
-
2559
- BVarSymbol retryFunctionVarSymbol = new BVarSymbol (0 , new Name ("$result$" ),
2560
- env .scope .owner .pkgID , retryLambdaReturnType .type ,
2561
- env .scope .owner , pos , VIRTUAL );
2562
- BLangSimpleVariable retryFunctionVariable = ASTBuilderUtil .createVariable (pos , "$result$" ,
2563
- retryLambdaReturnType .type ,
2564
- retryLambdaInvocation ,
2565
- retryFunctionVarSymbol );
2566
- BLangSimpleVariableDef retryFunctionVariableDef = ASTBuilderUtil .createVariableDef (pos ,
2567
- retryFunctionVariable );
2568
- retryBlockStmt .stmts .add (retryFunctionVariableDef );
2569
-
2570
- // create while loop: while ($result$ is error && $retryManager$.shouldRetry($result$))
2571
- BLangSimpleVarRef retryFunctionVariableRef =
2572
- new BLangSimpleVarRef .BLangLocalVarRef (retryFunctionVariable .symbol );
2573
- retryFunctionVariableRef .type = retryFunctionVariable .symbol .type ;
2574
-
2575
- BLangWhile whileNode = createRetryWhileLoop (pos , retryManagerVarDef , retryLambdaInvocation ,
2576
- retryFunctionVariableRef );
2577
- retryBlockStmt .stmts .add (whileNode );
2578
- createErrorReturn (pos , retryBlockStmt , retryFunctionVariableRef );
2579
-
2580
- BLangStatementExpression retryTransactionStmtExpr ;
2581
- if (retryNode .retryBodyReturns ) {
2582
- // returns <TypeCast>$result$;
2583
- BLangInvokableNode encInvokable = env .enclInvokable ;
2584
- retryTransactionStmtExpr = ASTBuilderUtil .createStatementExpression (retryBlockStmt ,
2585
- addConversionExprIfRequired (retryFunctionVariableRef , encInvokable .returnTypeNode .type ));
2524
+ BLangOnFailClause onFailClause = retryNode .onFailClause ;
2525
+ retryNode .onFailClause = null ;
2526
+ BLangDo doStmt = wrapStatementWithinDo (retryNode .pos , retryNode , onFailClause );
2527
+ result = rewrite (doStmt , env );
2586
2528
} else {
2587
- retryTransactionStmtExpr = ASTBuilderUtil .createStatementExpression (retryBlockStmt ,
2588
- ASTBuilderUtil .createLiteral (pos , symTable .nilType , Names .NIL_VALUE ));
2529
+ boolean currentSkipFailDesugaring = this .skipFailDesugaring ;
2530
+ this .skipFailDesugaring = true ;
2531
+ DiagnosticPos pos = retryNode .retryBody .pos ;
2532
+ BLangBlockStmt retryBlockStmt = ASTBuilderUtil .createBlockStmt (retryNode .pos );
2533
+ BLangSimpleVariableDef retryManagerVarDef = createRetryManagerDef (retryNode .retrySpec , retryNode .pos );
2534
+ retryBlockStmt .stmts .add (retryManagerVarDef );
2535
+
2536
+ // var $retryFunc$ = function () returns any|error {
2537
+ // <"Content in retry block goes here">
2538
+ // };
2539
+ BLangType retryLambdaReturnType = ASTBuilderUtil .createTypeNode (symTable .anyOrErrorType );
2540
+ BLangLambdaFunction retryFunc = createLambdaFunction (pos , "$retryFunc$" ,
2541
+ Collections .emptyList (), retryLambdaReturnType ,
2542
+ retryNode .retryBody .stmts , env ,
2543
+ retryNode .retryBody .scope );
2544
+ BVarSymbol retryFuncVarSymbol = new BVarSymbol (0 , names .fromString ("$retryFunc$" ),
2545
+ env .scope .owner .pkgID , retryFunc .type ,
2546
+ retryFunc .function .symbol , pos , VIRTUAL );
2547
+ BLangSimpleVariable retryLambdaVariable = ASTBuilderUtil .createVariable (pos , "$retryFunc$" ,
2548
+ retryFunc .type , retryFunc ,
2549
+ retryFuncVarSymbol );
2550
+ BLangSimpleVariableDef retryLambdaVariableDef = ASTBuilderUtil .createVariableDef (pos ,
2551
+ retryLambdaVariable );
2552
+ BLangSimpleVarRef retryLambdaVarRef = new BLangSimpleVarRef .BLangLocalVarRef (retryLambdaVariable .symbol );
2553
+ retryLambdaVarRef .type = retryFuncVarSymbol .type ;
2554
+ retryBlockStmt .stmts .add (retryLambdaVariableDef );
2555
+
2556
+ // Add lambda function call
2557
+ //any|error $result$ = $retryFunc$();
2558
+ BLangInvocation retryLambdaInvocation = new BLangInvocation .BFunctionPointerInvocation (pos ,
2559
+ retryLambdaVarRef , retryLambdaVariable .symbol , retryLambdaReturnType .type );
2560
+ retryLambdaInvocation .argExprs = new ArrayList <>();
2561
+
2562
+ retryFunc .capturedClosureEnv = env .createClone ();
2563
+
2564
+ BVarSymbol retryFunctionVarSymbol = new BVarSymbol (0 , new Name ("$result$" ),
2565
+ env .scope .owner .pkgID , retryLambdaReturnType .type ,
2566
+ env .scope .owner , pos , VIRTUAL );
2567
+ BLangSimpleVariable retryFunctionVariable = ASTBuilderUtil .createVariable (pos , "$result$" ,
2568
+ retryLambdaReturnType .type ,
2569
+ retryLambdaInvocation ,
2570
+ retryFunctionVarSymbol );
2571
+ BLangSimpleVariableDef retryFunctionVariableDef = ASTBuilderUtil .createVariableDef (pos ,
2572
+ retryFunctionVariable );
2573
+ retryBlockStmt .stmts .add (retryFunctionVariableDef );
2574
+
2575
+ // create while loop: while ($result$ is error && $retryManager$.shouldRetry($result$))
2576
+ BLangSimpleVarRef retryFunctionVariableRef =
2577
+ new BLangSimpleVarRef .BLangLocalVarRef (retryFunctionVariable .symbol );
2578
+ retryFunctionVariableRef .type = retryFunctionVariable .symbol .type ;
2579
+
2580
+ BLangWhile whileNode = createRetryWhileLoop (pos , retryManagerVarDef , retryLambdaInvocation ,
2581
+ retryFunctionVariableRef );
2582
+ retryBlockStmt .stmts .add (whileNode );
2583
+ createErrorReturn (pos , retryBlockStmt , retryFunctionVariableRef );
2584
+
2585
+ BLangStatementExpression retryTransactionStmtExpr ;
2586
+ if (retryNode .retryBodyReturns ) {
2587
+ // returns <TypeCast>$result$;
2588
+ BLangInvokableNode encInvokable = env .enclInvokable ;
2589
+ retryTransactionStmtExpr = ASTBuilderUtil .createStatementExpression (retryBlockStmt ,
2590
+ addConversionExprIfRequired (retryFunctionVariableRef , encInvokable .returnTypeNode .type ));
2591
+ } else {
2592
+ retryTransactionStmtExpr = ASTBuilderUtil .createStatementExpression (retryBlockStmt ,
2593
+ ASTBuilderUtil .createLiteral (pos , symTable .nilType , Names .NIL_VALUE ));
2594
+ }
2595
+ this .skipFailDesugaring = currentSkipFailDesugaring ;
2596
+ // at this point;
2597
+ // RetryManager $retryManager$ = new();
2598
+ // var $retryFunc$ = function () returns any|error {
2599
+ // <"Content in retry block goes here">
2600
+ // };
2601
+ // any|error $result$ = $retryFunc$();
2602
+ //
2603
+ // while ($result$ is error && $retryManager$.shouldRetry($result$)) {
2604
+ // $result$ = $retryFunc$();
2605
+ // }
2606
+ // if($result$ is error) {
2607
+ // fail $result$;
2608
+ // }
2609
+ // returns <TypeCast>$result$;
2610
+ result = createExpressionStatement (pos , retryTransactionStmtExpr , retryNode .retryBodyReturns , env );
2589
2611
}
2590
- // at this point;
2591
- // RetryManager $retryManager$ = new();
2592
- // var $retryFunc$ = function () returns any|error {
2593
- // <"Content in retry block goes here">
2594
- // };
2595
- // any|error $result$ = $retryFunc$();
2596
- //
2597
- // while ($result$ is error && $retryManager$.shouldRetry($result$)) {
2598
- // $result$ = $retryFunc$();
2599
- // }
2600
- // if($result$ is error) {
2601
- // return $result$;
2602
- // }
2603
- // returns <TypeCast>$result$;
2604
- result = createExpressionStatement (pos , retryTransactionStmtExpr , retryNode .retryBodyReturns , env );
2605
2612
this .onFailClause = currentOnFailClause ;
2606
2613
this .onFailCallFuncDef = currentOnFailCallDef ;
2607
2614
}
@@ -2702,9 +2709,9 @@ protected void createErrorReturn(DiagnosticPos pos, BlockNode blockStmt, BLangSi
2702
2709
BLangIf returnError = ASTBuilderUtil .createIfStmt (pos , blockStmt );
2703
2710
returnError .expr = createTypeCheckExpr (pos , resultRef , getErrorTypeNode ());
2704
2711
returnError .body = ASTBuilderUtil .createBlockStmt (pos );
2705
- BLangReturn bLangReturn = ASTBuilderUtil . createReturnStmt ( pos ,
2706
- addConversionExprIfRequired (resultRef , symTable .errorType ) );
2707
- returnError .body .stmts .add (bLangReturn );
2712
+ BLangFail failExpressionNode = ( BLangFail ) TreeBuilder . createFailNode ();
2713
+ failExpressionNode . expr = addConversionExprIfRequired (resultRef , symTable .errorType );
2714
+ returnError .body .stmts .add (failExpressionNode );
2708
2715
}
2709
2716
2710
2717
@ Override
@@ -3320,13 +3327,28 @@ public void visit(BLangWhile whileNode) {
3320
3327
BLangOnFailClause currentOnFailClause = this .onFailClause ;
3321
3328
BLangSimpleVariableDef currentOnFailCallDef = this .onFailCallFuncDef ;
3322
3329
if (whileNode .onFailClause != null ) {
3323
- rewrite (whileNode .onFailClause , env );
3330
+ BLangOnFailClause onFailClause = whileNode .onFailClause ;
3331
+ whileNode .onFailClause = null ;
3332
+ BLangDo doStmt = wrapStatementWithinDo (whileNode .pos , whileNode , onFailClause );
3333
+ result = rewrite (doStmt , env );
3334
+ } else {
3335
+ whileNode .expr = rewriteExpr (whileNode .expr );
3336
+ whileNode .body = rewrite (whileNode .body , env );
3337
+ result = whileNode ;
3324
3338
}
3325
- whileNode .expr = rewriteExpr (whileNode .expr );
3326
- whileNode .body = rewrite (whileNode .body , env );
3327
3339
this .onFailClause = currentOnFailClause ;
3328
3340
this .onFailCallFuncDef = currentOnFailCallDef ;
3329
- result = whileNode ;
3341
+ }
3342
+
3343
+ private BLangDo wrapStatementWithinDo (DiagnosticPos pos , BLangStatement statement , BLangOnFailClause onFailClause ) {
3344
+ BLangDo bLDo = (BLangDo ) TreeBuilder .createDoNode ();
3345
+ BLangBlockStmt doBlock = ASTBuilderUtil .createBlockStmt (pos );
3346
+ bLDo .body = doBlock ;
3347
+ bLDo .pos = pos ;
3348
+ bLDo .onFailClause = onFailClause ;
3349
+ bLDo .body .isBreakable = true ;
3350
+ doBlock .stmts .add (statement );
3351
+ return bLDo ;
3330
3352
}
3331
3353
3332
3354
@ Override
@@ -4965,7 +4987,7 @@ public void visit(BLangXMLAttributeAccess xmlAttributeAccessExpr) {
4965
4987
4966
4988
@ Override
4967
4989
public void visit (BLangFail failNode ) {
4968
- if (this .onFailClause != null ) {
4990
+ if (this .onFailClause != null && ! skipFailDesugaring ) {
4969
4991
if (failNode .exprStmt == null ) {
4970
4992
BLangStatementExpression expression = createOnFailInvocation (onFailCallFuncDef , onFailClause ,
4971
4993
failNode .expr );
@@ -6036,20 +6058,12 @@ private BLangMatchTypedBindingPatternClause getSafeAssignErrorPattern(
6036
6058
6037
6059
BLangBlockStmt patternBlockFailureCase = (BLangBlockStmt ) TreeBuilder .createBlockNode ();
6038
6060
patternBlockFailureCase .pos = pos ;
6039
- if (!isCheckPanicExpr && this .onFailCallFuncDef != null ) {
6040
- BLangFail failExpressionNode = (BLangFail ) TreeBuilder .createFailNode ();
6041
- failExpressionNode .expr = patternFailureCaseVarRef ;
6042
- BLangStatementExpression expression = createOnFailInvocation (onFailCallFuncDef , onFailClause ,
6043
- patternFailureCaseVarRef );
6044
- failExpressionNode .exprStmt = createExpressionStatement (pos , expression ,
6045
- onFailClause .statementBlockReturns , env );;
6046
- patternBlockFailureCase .stmts .add (failExpressionNode );
6047
- } else if (!isCheckPanicExpr && returnOnError ) {
6048
- //return e;
6049
- BLangReturn returnStmt = (BLangReturn ) TreeBuilder .createReturnNode ();
6050
- returnStmt .pos = pos ;
6051
- returnStmt .expr = patternFailureCaseVarRef ;
6052
- patternBlockFailureCase .stmts .add (returnStmt );
6061
+ if (!isCheckPanicExpr && (returnOnError || this .onFailClause != null )) {
6062
+ //fail e;
6063
+ BLangFail failStmt = (BLangFail ) TreeBuilder .createFailNode ();
6064
+ failStmt .pos = pos ;
6065
+ failStmt .expr = patternFailureCaseVarRef ;
6066
+ patternBlockFailureCase .stmts .add (failStmt );
6053
6067
} else {
6054
6068
// throw e
6055
6069
BLangPanic panicNode = (BLangPanic ) TreeBuilder .createPanicNode ();
0 commit comments