Skip to content

Commit a10e3a8

Browse files
committed
Merge branch 'master' of https://github.com/ballerina-platform/ballerina-lang into jdk_11_sync
2 parents c11c977 + 8f925da commit a10e3a8

File tree

32 files changed

+1015
-157
lines changed

32 files changed

+1015
-157
lines changed

.github/workflows/CD_publish_snapshot.yml

-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ name: Publish Ballerina Snapshot
22

33
on:
44
push:
5-
paths-ignore:
6-
- 'stdlib/release/**'
7-
- '.github/workflows/**'
85
branchs:
96
- master
107
workflow_dispatch:

.github/workflows/CI_push_build.yml

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ name: Build merged PR changes on Ubuntu
22

33
on:
44
push:
5-
paths-ignore:
6-
- 'stdlib/release/**'
75
branches:
86
- master
97
- next-release

.github/workflows/CI_ubuntu.yml

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ name: CI Ubuntu
22

33
on:
44
pull_request:
5-
paths-ignore:
6-
- 'stdlib/release/**'
75
branches:
86
- master
97
- next-release

.github/workflows/CI_ubuntu_windows.yml

+4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ name: CI Ubuntu/Windows
22

33
on:
44
push:
5+
paths-ignore:
6+
- 'stdlib/release/**'
57
branches-ignore:
68
- master
79
- next-release
810
- release-stage
911
- stage
1012
- ballerina-1.2.x
1113
pull_request:
14+
paths-ignore:
15+
- 'stdlib/release/**'
1216
branches-ignore:
1317
- master
1418
- next-release

.github/workflows/CI_windows.yml

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ name: CI Windows
22

33
on:
44
pull_request:
5-
paths-ignore:
6-
- 'stdlib/release/**'
75
branches:
86
- master
97
- next-release

compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java

+2
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ public enum DiagnosticCode {
162162
TRANSACTION_CANNOT_BE_USED_WITHIN_HANDLER("transaction.cannot.be.used.within.handler"),
163163
TRANSACTION_CANNOT_BE_USED_WITHIN_TRANSACTIONAL_SCOPE("transaction.cannot.be.used.within.transactional.scope"),
164164
TRANSACTIONAL_FUNC_INVOKE_PROHIBITED("transactional.function.prohibited.outside.transactional.scope"),
165+
TRANSACTIONAL_WORKER_OUT_OF_TRANSACTIONAL_SCOPE("transactional.worker.prohibited.outside.transactional.scope"),
166+
165167
NESTED_TRANSACTIONS_ARE_INVALID("nested.transactions.are.invalid"),
166168
INVALID_FUNCTION_POINTER_ASSIGNMENT_FOR_HANDLER("invalid.function.pointer.assignment.for.handler"),
167169
USAGE_OF_START_WITHIN_TRANSACTION_IS_PROHIBITED("usage.of.start.within.transaction.is.prohibited"),

compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java

+116-102
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ public class Desugar extends BLangNodeVisitor {
340340
private BLangSimpleVariableDef onFailCallFuncDef;
341341
private BLangOnFailClause onFailClause;
342342
private BType forceCastReturnType = null;
343+
private boolean skipFailDesugaring = false;
343344

344345
private SymbolEnv env;
345346
private int lambdaFunctionCount = 0;
@@ -2520,88 +2521,94 @@ public void visit(BLangRetry retryNode) {
25202521
BLangOnFailClause currentOnFailClause = this.onFailClause;
25212522
BLangSimpleVariableDef currentOnFailCallDef = this.onFailCallFuncDef;
25222523
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);
25862528
} 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);
25892611
}
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);
26052612
this.onFailClause = currentOnFailClause;
26062613
this.onFailCallFuncDef = currentOnFailCallDef;
26072614
}
@@ -2702,9 +2709,9 @@ protected void createErrorReturn(DiagnosticPos pos, BlockNode blockStmt, BLangSi
27022709
BLangIf returnError = ASTBuilderUtil.createIfStmt(pos, blockStmt);
27032710
returnError.expr = createTypeCheckExpr(pos, resultRef, getErrorTypeNode());
27042711
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);
27082715
}
27092716

27102717
@Override
@@ -3320,13 +3327,28 @@ public void visit(BLangWhile whileNode) {
33203327
BLangOnFailClause currentOnFailClause = this.onFailClause;
33213328
BLangSimpleVariableDef currentOnFailCallDef = this.onFailCallFuncDef;
33223329
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;
33243338
}
3325-
whileNode.expr = rewriteExpr(whileNode.expr);
3326-
whileNode.body = rewrite(whileNode.body, env);
33273339
this.onFailClause = currentOnFailClause;
33283340
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;
33303352
}
33313353

33323354
@Override
@@ -4965,7 +4987,7 @@ public void visit(BLangXMLAttributeAccess xmlAttributeAccessExpr) {
49654987

49664988
@Override
49674989
public void visit(BLangFail failNode) {
4968-
if (this.onFailClause != null) {
4990+
if (this.onFailClause != null && !skipFailDesugaring) {
49694991
if (failNode.exprStmt == null) {
49704992
BLangStatementExpression expression = createOnFailInvocation(onFailCallFuncDef, onFailClause,
49714993
failNode.expr);
@@ -6036,20 +6058,12 @@ private BLangMatchTypedBindingPatternClause getSafeAssignErrorPattern(
60366058

60376059
BLangBlockStmt patternBlockFailureCase = (BLangBlockStmt) TreeBuilder.createBlockNode();
60386060
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);
60536067
} else {
60546068
// throw e
60556069
BLangPanic panicNode = (BLangPanic) TreeBuilder.createPanicNode();

compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeTransformer.java

+8
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,10 @@ public BLangNode transform(NamedWorkerDeclarationNode namedWorkerDeclNode) {
14861486
bLFunction.addFlag(Flag.ANONYMOUS);
14871487
bLFunction.addFlag(Flag.WORKER);
14881488

1489+
if (namedWorkerDeclNode.transactionalKeyword().isPresent()) {
1490+
bLFunction.addFlag(Flag.TRANSACTIONAL);
1491+
}
1492+
14891493
// change default worker name
14901494
String workerName = namedWorkerDeclNode.workerName().text();
14911495
if (workerName.startsWith(IDENTIFIER_LITERAL_PREFIX)) {
@@ -1528,6 +1532,10 @@ public BLangNode transform(NamedWorkerDeclarationNode namedWorkerDeclNode) {
15281532
.isFinal()
15291533
.build();
15301534

1535+
if (namedWorkerDeclNode.transactionalKeyword().isPresent()) {
1536+
var.addFlag(Flag.TRANSACTIONAL);
1537+
}
1538+
15311539
BLangSimpleVariableDef lamdaWrkr = (BLangSimpleVariableDef) TreeBuilder.createSimpleVariableDefinitionNode();
15321540
lamdaWrkr.pos = workerBodyPos;
15331541
var.pos = workerBodyPos;

compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/CodeAnalyzer.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ public void visit(BLangRetry retryNode) {
679679
retryNode.retryBodyReturns = this.returnWithinLambdaWrappingCheckStack.peek();
680680
this.returnWithinLambdaWrappingCheckStack.pop();
681681
this.resetLastStatement();
682+
this.resetErrorThrown();
682683
retryNode.retryBody.isBreakable = retryNode.onFailClause != null;
683684
analyzeOnFailClause(retryNode.onFailClause);
684685
this.errorTypes.pop();
@@ -1527,7 +1528,6 @@ public void visit(BLangWhile whileNode) {
15271528
this.resetLastStatement();
15281529
this.loopWithinTransactionCheckStack.pop();
15291530
analyzeExpr(whileNode.expr);
1530-
whileNode.body.isBreakable = whileNode.onFailClause != null;
15311531
analyzeOnFailClause(whileNode.onFailClause);
15321532
this.errorTypes.pop();
15331533
}
@@ -2724,6 +2724,13 @@ public void visit(BLangRawTemplateLiteral rawTemplateLiteral) {
27242724

27252725
public void visit(BLangLambdaFunction bLangLambdaFunction) {
27262726
boolean isWorker = false;
2727+
2728+
if (bLangLambdaFunction.function.flagSet.contains(Flag.TRANSACTIONAL) &&
2729+
bLangLambdaFunction.function.flagSet.contains(Flag.WORKER) && !withinTransactionScope) {
2730+
dlog.error(bLangLambdaFunction.pos, DiagnosticCode.TRANSACTIONAL_WORKER_OUT_OF_TRANSACTIONAL_SCOPE,
2731+
bLangLambdaFunction);
2732+
return;
2733+
}
27272734
if (bLangLambdaFunction.parent.getKind() == NodeKind.VARIABLE) {
27282735
String workerVarName = ((BLangSimpleVariable) bLangLambdaFunction.parent).name.value;
27292736
if (workerVarName.startsWith(WORKER_LAMBDA_VAR_PREFIX)) {
@@ -2734,11 +2741,8 @@ public void visit(BLangLambdaFunction bLangLambdaFunction) {
27342741
bLangLambdaFunction.function);
27352742
}
27362743
}
2737-
27382744
boolean statementReturn = this.statementReturns;
2739-
27402745
this.visitFunction(bLangLambdaFunction.function);
2741-
27422746
this.statementReturns = statementReturn;
27432747

27442748
if (isWorker) {

0 commit comments

Comments
 (0)