Skip to content

Commit

Permalink
Merge pull request #42498 from lochana-chathura/fix-worker-on-fail
Browse files Browse the repository at this point in the history
[Master] Fix `error:NoMessage` for `worker-on-fail-clause`
  • Loading branch information
hasithaa committed Apr 8, 2024
2 parents fa2ff30 + 8aa4584 commit 55f7dc6
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1990,17 +1990,17 @@ private boolean isCommunicationAllowedContext(BLangFunctionBody enclInvokableBod
return false;
}

private boolean withinIf(BLangFunctionBody enclInvokableBody, BLangNode node) {
private boolean withinIfOrOnFail(BLangFunctionBody enclInvokableBody, BLangNode node) {
if (enclInvokableBody == node) {
return false;
}

BLangNode parentNode = node.parent;
if (parentNode.getKind() == NodeKind.IF) {
if (parentNode.getKind() == NodeKind.IF || parentNode.getKind() == NodeKind.ON_FAIL) {
return true;
}

return withinIf(enclInvokableBody, parentNode);
return withinIfOrOnFail(enclInvokableBody, parentNode);
}

private boolean isDefaultWorkerCommunication(String workerIdentifier) {
Expand Down Expand Up @@ -2058,15 +2058,15 @@ public void visit(BLangWorkerAsyncSendExpr asyncSendExpr, AnalyzerData data) {
was.hasErrors = true;
}

boolean withinIf = !invalidSendPos && withinIf(data.env.enclInvokable.body, data.env.node);
setWorkerSendSendTypeDetails(asyncSendExpr, asyncSendExpr.expr.getBType(), withinIf, data);
boolean withinIfOrOnFail = !invalidSendPos && withinIfOrOnFail(data.env.enclInvokable.body, data.env.node);
setWorkerSendSendTypeDetails(asyncSendExpr, asyncSendExpr.expr.getBType(), withinIfOrOnFail, data);
was.addWorkerAction(asyncSendExpr);
analyzeExpr(asyncSendExpr.expr, data);
validateActionParentNode(asyncSendExpr.pos, asyncSendExpr.expr);
}

private void setWorkerSendSendTypeDetails(BLangWorkerSendExpr workerSendExpr, BType exprType,
boolean withinIf, AnalyzerData data) {
boolean withinIfOrOnFail, AnalyzerData data) {
Set<BType> returnTypesUpToNow = data.returnTypes.peek();
LinkedHashSet<BType> returnTypeAndSendType = new LinkedHashSet<>() {
{
Expand All @@ -2091,7 +2091,7 @@ private void setWorkerSendSendTypeDetails(BLangWorkerSendExpr workerSendExpr, BT
}

BType sendType;
boolean noMessagePossible = withinIf || hasNonErrorReturn;
boolean noMessagePossible = withinIfOrOnFail || hasNonErrorReturn;
if (noMessagePossible) {
// There is a possibility that the send action may not be executed, thus adding NoMessageError type.
BSymbol noMsgErrSymbol = symTable.langErrorModuleSymbol.scope.
Expand Down Expand Up @@ -2144,8 +2144,8 @@ public void visit(BLangWorkerSyncSendExpr syncSendExpr, AnalyzerData data) {
}

syncSendExpr.setBType(BUnionType.create(null, symTable.nilType, symTable.errorType));
boolean withinIf = !invalidSendPos && withinIf(data.env.enclInvokable.body, data.env.node);
setWorkerSendSendTypeDetails(syncSendExpr, syncSendExpr.expr.getBType(), withinIf, data);
boolean withinIfOrOnFail = !invalidSendPos && withinIfOrOnFail(data.env.enclInvokable.body, data.env.node);
setWorkerSendSendTypeDetails(syncSendExpr, syncSendExpr.expr.getBType(), withinIfOrOnFail, data);
was.addWorkerAction(syncSendExpr);
analyzeExpr(syncSendExpr.expr, data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
import org.ballerinalang.test.BRunUtil;
import org.ballerinalang.test.CompileResult;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.util.Arrays;

import static org.ballerinalang.test.BAssertUtil.validateError;

/**
* Tests the worker on fail clause.
*
Expand All @@ -35,11 +38,13 @@
public class WorkerOnFailTest {

private CompileResult result;
private CompileResult resultNegative;

@BeforeClass
public void setup() {
this.result = BCompileUtil.compile("test-src/workers/worker-on-fail.bal");
result = BCompileUtil.compile("test-src/workers/worker-on-fail.bal");
Assert.assertEquals(result.getErrorCount(), 0, Arrays.asList(result.getDiagnostics()).toString());
resultNegative = BCompileUtil.compile("test-src/workers/worker-on-fail-negative.bal");
}

@Test
Expand Down Expand Up @@ -77,4 +82,37 @@ public void workerOnFailWithSend() {
Assert.assertEquals(ret, 1);
}

@Test
public void asyncSendInsideWorkerOnFail() {
Object returns = BRunUtil.invoke(result, "testAsyncSendInsideWorkerOnFail");
long ret = (long) returns;
Assert.assertEquals(ret, 17);
}

@Test
public void syncSendInsideWorkerOnFail() {
Object returns = BRunUtil.invoke(result, "testSyncSendInsideWorkerOnFail");
long ret = (long) returns;
Assert.assertEquals(ret, -8);
}

@Test
public void onFailNegative() {
String errMsg = "incompatible types: expected 'int', found '(int|ballerina/lang.error:0.0.0:NoMessage)'";
int index = 0;
validateError(resultNegative, index++, errMsg, 26, 17);
validateError(resultNegative, index++, errMsg, 41, 17);
validateError(resultNegative, index++, errMsg, 66, 17);
validateError(resultNegative, index++, errMsg, 67, 17);
validateError(resultNegative, index++, errMsg, 68, 17);
validateError(resultNegative, index++, errMsg, 69, 17);
validateError(resultNegative, index++, errMsg, 70, 17);
Assert.assertEquals(resultNegative.getErrorCount(), index);
}

@AfterClass
public void afterClass() {
result = null;
resultNegative = null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com).
//
// WSO2 LLC. licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except
// in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

public function testNoMessageErrorForOnFailAsyncSend() {
worker w1 {
0 -> w2;
} on fail {
1 -> w2;
}

worker w2 {
int _ = <- w1;
int _ = <- w1; // found 'int|error:NoMessage'
}

wait w2;
}

public function testNoMessageErrorForOnFailSyncSend() {
worker w1 {
0 ->> w2;
} on fail {
1 ->> w2;
}

worker w2 {
int _ = <- w1;
int _ = <- w1; // found 'int|error:NoMessage'
}

wait w1;
}

public function testNoMessageErrorWithWorkerOnFail() {
worker w1 {
boolean b = true;
check error("err");
0 -> w2;
if b {
1 -> w2;
}
} on fail {
boolean c = true;
2 -> w2;
if c {
3 ->> w2;
} else {
4 -> w2;
}
}

worker w2 {
int _ = <- w1; // found 'int|error:NoMessage'
int _ = <- w1; // found 'int|error:NoMessage'
int _ = <- w1; // found 'int|error:NoMessage'
int _ = <- w1; // found 'int|error:NoMessage'
int _ = <- w1; // found 'int|error:NoMessage'
}

wait w2;
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,33 @@ function testWorkerOnFailWithSend() returns int {
function returnOne() returns int => 1;

function returnIntArr() returns int[] => [2, 3, 4, 5];

public function testAsyncSendInsideWorkerOnFail() returns int|error {
worker w1 {
check error("err");
} on fail {
17 -> w2;
}

worker w2 returns int|error {
int x = check <- w1;
return x;
}

return wait w2;
}

public function testSyncSendInsideWorkerOnFail() returns int|error {
worker w1 {
check error("err");
} on fail {
-8 ->> w2;
}

worker w2 returns int|error {
int x = check <- w1;
return x;
}

return wait w2;
}

0 comments on commit 55f7dc6

Please sign in to comment.