From af42446c3605fccf5a6d4446fcdb59b0578d1b28 Mon Sep 17 00:00:00 2001 From: Nadeeshan96 Date: Fri, 22 Sep 2023 14:15:05 +0530 Subject: [PATCH 01/11] Disallow pop on closed arrays --- .../main/java/org/ballerinalang/langlib/array/Pop.java | 9 ++++++++- .../ballerinalang/langlib/array/utils/ArrayUtils.java | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java index 84a25ee23bc9..df573d7c0e6b 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java @@ -18,10 +18,13 @@ package org.ballerinalang.langlib.array; +import io.ballerina.runtime.api.types.ArrayType; +import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; import static org.ballerinalang.langlib.array.utils.ArrayUtils.checkIsArrayOnlyOperation; +import static org.ballerinalang.langlib.array.utils.ArrayUtils.checkIsClosedArray; /** * Native implementation of lang.array:pop((any|error)[]). @@ -39,7 +42,11 @@ public class Pop { private static final String FUNCTION_SIGNATURE = "pop()"; public static Object pop(BArray arr) { - checkIsArrayOnlyOperation(TypeUtils.getImpliedType(arr.getType()), FUNCTION_SIGNATURE); + Type type = TypeUtils.getImpliedType(arr.getType()); + checkIsArrayOnlyOperation(type, FUNCTION_SIGNATURE); + checkIsClosedArray((ArrayType) type, FUNCTION_SIGNATURE); return arr.shift(arr.size() - 1); } + + private Pop() {} } diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java index 3b77683ca726..6f5c627b64b0 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java @@ -86,6 +86,12 @@ public static void checkIsArrayOnlyOperation(Type arrType, String op) { } } + public static void checkIsClosedArray(ArrayType arrType, String op) { + if (arrType.getState() == ArrayType.ArrayState.CLOSED) { + throw createOpNotSupportedError(arrType, op); + } + } + public static BError createOpNotSupportedError(Type type, String op) { return ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB, OPERATION_NOT_SUPPORTED_IDENTIFIER), From c5b57c18ee31e507d7f3ec1288c33c7434ef86b5 Mon Sep 17 00:00:00 2001 From: Nadeeshan96 Date: Mon, 25 Sep 2023 09:49:48 +0530 Subject: [PATCH 02/11] Fix incorrect error message given with setLength --- .../runtime/internal/values/AbstractArrayValue.java | 4 ++-- .../runtime/internal/values/ArrayValueImpl.java | 7 ++++--- .../runtime/internal/values/TupleValueImpl.java | 9 +++++---- .../java/org/ballerinalang/langlib/array/SetLength.java | 2 ++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java index 08c6734549fa..a7be264a10e6 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java @@ -151,7 +151,7 @@ public void setLength(long length) { int newLength = (int) length; checkFixedLength(length); rangeCheck(length, size); - fillerValueCheck(newLength, size); + fillerValueCheck(newLength, size, true); resizeInternalArray(newLength); fillValues(newLength); size = newLength; @@ -195,7 +195,7 @@ public Type getIteratorNextReturnType() { protected abstract void fillValues(int newLength); - protected abstract void fillerValueCheck(int newLength, int size2); + protected abstract void fillerValueCheck(int newLength, int size, boolean setLength); protected abstract void resizeInternalArray(int newLength); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java index a241fdede542..04d255a4a303 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java @@ -1105,15 +1105,16 @@ protected void rangeCheck(long index, int size) { } @Override - protected void fillerValueCheck(int index, int size) { + protected void fillerValueCheck(int index, int size, boolean setLength) { // if the elementType doesn't have an implicit initial value & if the insertion is not a consecutive append // to the array, then an exception will be thrown. if (arrayType.hasFillerValue()) { return; } if (index > size) { + int expectedLength = setLength ? index : index + 1; throw ErrorHelper.getRuntimeException(ErrorReasons.ILLEGAL_LIST_INSERTION_ERROR, - ErrorCodes.ILLEGAL_ARRAY_INSERTION, size, index + 1); + ErrorCodes.ILLEGAL_ARRAY_INSERTION, size, expectedLength); } } @@ -1172,7 +1173,7 @@ private void prepareForAdd(long index, Object value, Type sourceType, int curren int intIndex = (int) index; rangeCheck(index, size); - fillerValueCheck(intIndex, size); + fillerValueCheck(intIndex, size, false); ensureCapacity(intIndex + 1, currentArraySize); fillValues(intIndex); resetSize(intIndex); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java index a16a44309c8a..4bdefe2fd618 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java @@ -671,9 +671,9 @@ protected void rangeCheck(long index, int size) { } @Override - protected void fillerValueCheck(int index, int size) { + protected void fillerValueCheck(int index, int size, boolean setLength) { // if there has been values added beyond the current index, that means filler values - // has already been checked. Therefore no need to check again. + // has already been checked. Therefore, no need to check again. if (this.size >= index) { return; } @@ -681,8 +681,9 @@ protected void fillerValueCheck(int index, int size) { // if the elementType doesn't have an implicit initial value & if the insertion is not a consecutive append // to the array, then an exception will be thrown. if (!TypeChecker.hasFillerValue(this.tupleType.getRestType()) && (index > size)) { + int expectedLength = setLength ? index : index + 1; throw ErrorHelper.getRuntimeException(ErrorReasons.ILLEGAL_LIST_INSERTION_ERROR, - ErrorCodes.ILLEGAL_TUPLE_INSERTION, size, index + 1); + ErrorCodes.ILLEGAL_TUPLE_INSERTION, size, expectedLength); } } @@ -759,7 +760,7 @@ private void prepareForAdd(long index, Object value, int currentArraySize) { TypeChecker.getType(value))); } - fillerValueCheck(intIndex, size); + fillerValueCheck(intIndex, size, false); ensureCapacity(intIndex + 1, currentArraySize); fillValues(intIndex); resetSize(intIndex); diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java index cb67ee5006c5..d85908a7f2b8 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java @@ -35,4 +35,6 @@ public class SetLength { public static void setLength(BArray arr, long i) { arr.setLength(i); } + + private SetLength() {} } From e3d6fefb48f86ecdc53c307cb9727440f3439456 Mon Sep 17 00:00:00 2001 From: Nadeeshan96 Date: Mon, 25 Sep 2023 10:16:05 +0530 Subject: [PATCH 03/11] Add negative tests for setLength function --- .../langlib/test/LangLibArrayTest.java | 5 +++++ .../test/resources/test-src/arraylib_test.bal | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java index 9566cf30e95f..00669221a899 100644 --- a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java +++ b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java @@ -224,6 +224,11 @@ public void testForEach() { assertEquals(returns.toString(), "SunMonTues"); } + @Test + public void testSetLengthNegative() { + BRunUtil.invoke(compileResult, "testSetLengthNegative"); + } + @Test(dataProvider = "setLengthDataProvider") public void testSetLength(int setLengthTo, long lenAfterSet, String arrayAfterSet, String arrayLenPlusOneAfterSet) { Object returns = BRunUtil.invoke(compileResult, "testSetLength", new Object[] {(setLengthTo)}); diff --git a/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal b/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal index fc775c52bf20..c512b6709845 100644 --- a/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal +++ b/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal @@ -1788,3 +1788,23 @@ function testPushWithErrorConstructorExpr() { assertTrue(e is Error); assertValueEquality("e2", e.message()); } + +function testSetLengthNegative() { + string:Char[] arr = ["a","b"]; + error? result = trap arr.setLength(5); + assertTrue(result is error); + if (result is error) { + assertValueEquality("{ballerina/lang.array}IllegalListInsertion", result.message()); + assertValueEquality("array of length 2 cannot be expanded into array of length 5 without filler values", + checkpanic result.detail()["message"]); + } + + [string:Char...] tup = ["a","b"]; + result = trap tup.setLength(10); + assertTrue(result is error); + if (result is error) { + assertValueEquality("{ballerina/lang.array}IllegalListInsertion", result.message()); + assertValueEquality("tuple of length 2 cannot be expanded into tuple of length 10 without filler values", + checkpanic result.detail()["message"]); + } +} From d0d10e6a85bbbf47428e2536fa24df8cf7cf1df7 Mon Sep 17 00:00:00 2001 From: Nadeeshan96 Date: Mon, 25 Sep 2023 10:35:25 +0530 Subject: [PATCH 04/11] Add tests for array:pop function --- .../langlib/test/LangLibArrayTest.java | 5 ++++ .../test/resources/test-src/arraylib_test.bal | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java index 00669221a899..c7cf7cd3d106 100644 --- a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java +++ b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java @@ -229,6 +229,11 @@ public void testSetLengthNegative() { BRunUtil.invoke(compileResult, "testSetLengthNegative"); } + @Test + public void testArrayPop() { + BRunUtil.invoke(compileResult, "testArrayPop"); + } + @Test(dataProvider = "setLengthDataProvider") public void testSetLength(int setLengthTo, long lenAfterSet, String arrayAfterSet, String arrayLenPlusOneAfterSet) { Object returns = BRunUtil.invoke(compileResult, "testSetLength", new Object[] {(setLengthTo)}); diff --git a/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal b/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal index c512b6709845..e1810ae806b5 100644 --- a/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal +++ b/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal @@ -1789,6 +1789,30 @@ function testPushWithErrorConstructorExpr() { assertValueEquality("e2", e.message()); } +function testArrayPop() { + int[] arr1 = [1, 2]; + assertValueEquality(arr1.pop(), 2); + assertValueEquality(arr1, [1]); + + int[2] arr2 = [1, 2]; + int|error result = trap array:pop(arr2); + assertTrue(result is error); + if (result is error) { + assertValueEquality("{ballerina/lang.array}OperationNotSupported", result.message()); + assertValueEquality("pop() not supported on type 'int[2]'", + checkpanic result.detail()["message"]); + } + + int[] arr = arr2; + result = trap arr.pop(); + assertTrue(result is error); + if (result is error) { + assertValueEquality("{ballerina/lang.array}OperationNotSupported", result.message()); + assertValueEquality("pop() not supported on type 'int[2]'", + checkpanic result.detail()["message"]); + } +} + function testSetLengthNegative() { string:Char[] arr = ["a","b"]; error? result = trap arr.setLength(5); From 82f3efeac33dff3da17829e9f6adf714d4617b96 Mon Sep 17 00:00:00 2001 From: Nadeeshan96 Date: Mon, 25 Sep 2023 10:39:13 +0530 Subject: [PATCH 05/11] Refactor LangLibArrayTest --- .../langlib/test/LangLibArrayTest.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java index c7cf7cd3d106..f07bd8627f67 100644 --- a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java +++ b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java @@ -224,16 +224,6 @@ public void testForEach() { assertEquals(returns.toString(), "SunMonTues"); } - @Test - public void testSetLengthNegative() { - BRunUtil.invoke(compileResult, "testSetLengthNegative"); - } - - @Test - public void testArrayPop() { - BRunUtil.invoke(compileResult, "testArrayPop"); - } - @Test(dataProvider = "setLengthDataProvider") public void testSetLength(int setLengthTo, long lenAfterSet, String arrayAfterSet, String arrayLenPlusOneAfterSet) { Object returns = BRunUtil.invoke(compileResult, "testSetLength", new Object[] {(setLengthTo)}); @@ -610,7 +600,9 @@ public Object[] testFunctions() { "testModificationWithinEvery", "testArrSortWithNamedArgs1", "testArrSortWithNamedArgs2", - "testArrSortWithNamedArgs3" + "testArrSortWithNamedArgs3", + "testArrayPop", + "testSetLengthNegative" }; } } From 3adfbf0d6ea9434a8db88f5e30d7b4cf2cad33c7 Mon Sep 17 00:00:00 2001 From: Nadeeshan96 Date: Sun, 1 Oct 2023 22:42:44 +0530 Subject: [PATCH 06/11] Fix RecordAssignabilityTest to not compile always --- .../test/record/RecordAssignabilityTest.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java index f985d7c68353..56c42e8fe54b 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java @@ -20,6 +20,8 @@ import org.ballerinalang.test.BCompileUtil; import org.ballerinalang.test.BRunUtil; import org.ballerinalang.test.CompileResult; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -31,7 +33,12 @@ */ public class RecordAssignabilityTest { - private final CompileResult result = BCompileUtil.compile("test-src/record/record_assignability.bal"); + private CompileResult result; + + @BeforeClass + public void setup() { + result = BCompileUtil.compile("test-src/record/record_assignability.bal"); + } @DataProvider public static Object[] recordAssignabilityTestFunctions() { @@ -95,4 +102,9 @@ public void testRecordAssignabilityNegative() { "found 'record {| readonly int? b; int...; |}'", 70, 33); assertEquals(negativeResult.getErrorCount(), i); } + + @AfterClass + public void tearDown() { + result = null; + } } From c13231b748e8ae0404eec10e19728bcc075cd8e3 Mon Sep 17 00:00:00 2001 From: Nadeeshan96 Date: Mon, 2 Oct 2023 12:56:31 +0530 Subject: [PATCH 07/11] Change fillerValueCheck function signature --- .../runtime/internal/values/AbstractArrayValue.java | 6 +++--- .../ballerina/runtime/internal/values/ArrayValueImpl.java | 5 ++--- .../ballerina/runtime/internal/values/TupleValueImpl.java | 5 ++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java index a7be264a10e6..80c1ac6512f0 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java @@ -151,7 +151,7 @@ public void setLength(long length) { int newLength = (int) length; checkFixedLength(length); rangeCheck(length, size); - fillerValueCheck(newLength, size, true); + fillerValueCheck(newLength, size, newLength); resizeInternalArray(newLength); fillValues(newLength); size = newLength; @@ -193,9 +193,9 @@ public Type getIteratorNextReturnType() { * helper methods that are visible to the implementation classes. */ - protected abstract void fillValues(int newLength); + protected abstract void fillValues(int index); - protected abstract void fillerValueCheck(int newLength, int size, boolean setLength); + protected abstract void fillerValueCheck(int index, int size, int expectedLength); protected abstract void resizeInternalArray(int newLength); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java index 04d255a4a303..59543d47ce2b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java @@ -1105,14 +1105,13 @@ protected void rangeCheck(long index, int size) { } @Override - protected void fillerValueCheck(int index, int size, boolean setLength) { + protected void fillerValueCheck(int index, int size, int expectedLength) { // if the elementType doesn't have an implicit initial value & if the insertion is not a consecutive append // to the array, then an exception will be thrown. if (arrayType.hasFillerValue()) { return; } if (index > size) { - int expectedLength = setLength ? index : index + 1; throw ErrorHelper.getRuntimeException(ErrorReasons.ILLEGAL_LIST_INSERTION_ERROR, ErrorCodes.ILLEGAL_ARRAY_INSERTION, size, expectedLength); } @@ -1173,7 +1172,7 @@ private void prepareForAdd(long index, Object value, Type sourceType, int curren int intIndex = (int) index; rangeCheck(index, size); - fillerValueCheck(intIndex, size, false); + fillerValueCheck(intIndex, size, intIndex + 1); ensureCapacity(intIndex + 1, currentArraySize); fillValues(intIndex); resetSize(intIndex); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java index 4bdefe2fd618..1283cf5a11cc 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java @@ -671,7 +671,7 @@ protected void rangeCheck(long index, int size) { } @Override - protected void fillerValueCheck(int index, int size, boolean setLength) { + protected void fillerValueCheck(int index, int size, int expectedLength) { // if there has been values added beyond the current index, that means filler values // has already been checked. Therefore, no need to check again. if (this.size >= index) { @@ -681,7 +681,6 @@ protected void fillerValueCheck(int index, int size, boolean setLength) { // if the elementType doesn't have an implicit initial value & if the insertion is not a consecutive append // to the array, then an exception will be thrown. if (!TypeChecker.hasFillerValue(this.tupleType.getRestType()) && (index > size)) { - int expectedLength = setLength ? index : index + 1; throw ErrorHelper.getRuntimeException(ErrorReasons.ILLEGAL_LIST_INSERTION_ERROR, ErrorCodes.ILLEGAL_TUPLE_INSERTION, size, expectedLength); } @@ -760,7 +759,7 @@ private void prepareForAdd(long index, Object value, int currentArraySize) { TypeChecker.getType(value))); } - fillerValueCheck(intIndex, size, false); + fillerValueCheck(intIndex, size, intIndex + 1); ensureCapacity(intIndex + 1, currentArraySize); fillValues(intIndex); resetSize(intIndex); From 28aaa05e8248d016b05e7535cd4d27a78697b509 Mon Sep 17 00:00:00 2001 From: hindujaB Date: Wed, 4 Oct 2023 13:03:52 +0530 Subject: [PATCH 08/11] Fix getType usage for stop handler --- .../runtime/internal/scheduling/RuntimeRegistry.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java index 1a3ec5d602ca..9ce89176033f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java @@ -17,6 +17,7 @@ package io.ballerina.runtime.internal.scheduling; import io.ballerina.runtime.api.async.Callback; +import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BFunctionPointer; import io.ballerina.runtime.api.values.BObject; @@ -91,7 +92,8 @@ private synchronized void invokeStopHandlerFunction(Strand strand, Scheduler sch BFunctionPointer bFunctionPointer = stopHandlerStack.pop(); StopHandlerCallback callback = new StopHandlerCallback(strand, scheduler); final FutureValue future = scheduler.createFuture(strand, callback, null, - ((BFunctionType) bFunctionPointer.getType()).retType, null, strand.getMetadata()); + ((BFunctionType) TypeUtils.getImpliedType(bFunctionPointer.getType())).retType, null, + strand.getMetadata()); scheduler.scheduleLocal(new Object[]{strand}, bFunctionPointer, strand, future); } From 1d25cad088d1aecbc4a1f990b29dc62a1264cec2 Mon Sep 17 00:00:00 2001 From: hindujaB Date: Wed, 4 Oct 2023 13:04:35 +0530 Subject: [PATCH 09/11] Add unit test --- .../test-src/runtime/api/stop_handler/main.bal | 18 ++++++++++++------ .../api/stop_handler/modules/moduleA/main.bal | 3 +-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal index 5660560faa34..c789f0be1303 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal @@ -20,26 +20,27 @@ import ballerina/test; import stop_handler.moduleA; function stopHandlerFunc1() returns error? { - runtime:sleep(1); + runtime:sleep(2.5); moduleA:incrementCount(); - moduleA:assertCount(10); + moduleA:assertCount(11); } function stopHandlerFunc2() returns error? { + runtime:sleep(1); moduleA:incrementCount(); - moduleA:assertCount(9); + moduleA:assertCount(10); } function stopHandlerFunc3() returns error? { runtime:sleep(0.5); moduleA:incrementCount(); - moduleA:assertCount(7); + moduleA:assertCount(8); } function stopHandlerFunc4() returns error? { runtime:sleep(1.5); moduleA:incrementCount(); - moduleA:assertCount(8); + moduleA:assertCount(9); } function init() { @@ -57,7 +58,12 @@ public function main() { moduleA:assertCount(2); runtime:registerListener(lo); runtime:onGracefulStop(stopHandlerFunc3); - + runtime:StopHandler inlineStopHandler = function() returns error? { + runtime:sleep(2); + moduleA:incrementCount(); + moduleA:assertCount(7); + }; + runtime:onGracefulStop(inlineStopHandler); checkpanic lo.'start(); error? v = lo.gracefulStop(); if (v is error) { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal index 088aca81c2b2..a7231d21d255 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal @@ -13,7 +13,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. - import ballerina/lang.runtime; import ballerina/test; @@ -22,7 +21,7 @@ int count = 0; function stopHandlerFunc1() returns error? { runtime:sleep(1); incrementCount(); - assertCount(11); + assertCount(12); } function stopHandlerFunc2() returns error? { From 843d7e0d9b3fc6c1a07b8ff4e721a72c0a9f42e9 Mon Sep 17 00:00:00 2001 From: hindujaB Date: Wed, 4 Oct 2023 13:55:20 +0530 Subject: [PATCH 10/11] Move stop handler unit test to integration test --- .../packaging/ModuleExecutionFlowTests.java | 2 + .../packaging/stop_handler_execution/main.bal | 12 ++- .../test/runtime/api/RuntimeAPITest.java | 1 - .../runtime/api/stop_handler/Ballerina.toml | 4 - .../runtime/api/stop_handler/main.bal | 74 --------------- .../api/stop_handler/modules/moduleA/main.bal | 95 ------------------- 6 files changed, 11 insertions(+), 177 deletions(-) delete mode 100644 tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/Ballerina.toml delete mode 100644 tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal delete mode 100644 tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal diff --git a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java index dd9722b53eb8..e29f1801e14e 100644 --- a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java +++ b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java @@ -140,6 +140,8 @@ public void testStopHandlerExecution() throws BallerinaTestException { LogLeecher infoLeecher1 = new LogLeecher("Stopped stopHandlerFunc3"); LogLeecher infoLeecher2 = new LogLeecher("Stopped stopHandlerFunc2"); LogLeecher infoLeecher3 = new LogLeecher("Stopped stopHandlerFunc1"); + LogLeecher infoLeecher4 = new LogLeecher("Stopped inlineStopHandler"); + serverInstance.addLogLeecher(infoLeecher4); serverInstance.addLogLeecher(infoLeecher1); serverInstance.addLogLeecher(infoLeecher2); serverInstance.addLogLeecher(infoLeecher3); diff --git a/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal b/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal index 41637860fe75..54bd4a2819be 100644 --- a/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal +++ b/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal @@ -22,19 +22,19 @@ int count = 0; function stopHandlerFunc1() returns error? { incrementCount(); - assertCount(5); + assertCount(6); println("Stopped stopHandlerFunc1"); } function stopHandlerFunc2() returns error? { incrementCount(); - assertCount(4); + assertCount(5); println("Stopped stopHandlerFunc2"); } function stopHandlerFunc3() returns error? { incrementCount(); - assertCount(3); + assertCount(4); println("Stopped stopHandlerFunc3"); } @@ -49,6 +49,12 @@ public function main() { incrementCount(); assertCount(2); runtime:onGracefulStop(stopHandlerFunc3); + runtime:StopHandler inlineStopHandler = function() returns error? { + incrementCount(); + assertCount(3); + println("Stopped inlineStopHandler"); + }; + runtime:onGracefulStop(inlineStopHandler); runtime:sleep(3); } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java index 19480a6932ef..7ca9edaca1d8 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java @@ -45,7 +45,6 @@ public Object[] packageNameProvider() { "invalid_values", "async", "utils", - "stop_handler", "identifier_utils", "environment" }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/Ballerina.toml b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/Ballerina.toml deleted file mode 100644 index 1b09d3767f68..000000000000 --- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/Ballerina.toml +++ /dev/null @@ -1,4 +0,0 @@ -[package] -org= "testorg" -name="stop_handler" -version= "1.0.0" diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal deleted file mode 100644 index c789f0be1303..000000000000 --- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2022 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. 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. - -import ballerina/lang.runtime; -import ballerina/test; - -import stop_handler.moduleA; - -function stopHandlerFunc1() returns error? { - runtime:sleep(2.5); - moduleA:incrementCount(); - moduleA:assertCount(11); -} - -function stopHandlerFunc2() returns error? { - runtime:sleep(1); - moduleA:incrementCount(); - moduleA:assertCount(10); -} - -function stopHandlerFunc3() returns error? { - runtime:sleep(0.5); - moduleA:incrementCount(); - moduleA:assertCount(8); -} - -function stopHandlerFunc4() returns error? { - runtime:sleep(1.5); - moduleA:incrementCount(); - moduleA:assertCount(9); -} - -function init() { - moduleA:incrementCount(); - moduleA:assertCount(1); - runtime:onGracefulStop(stopHandlerFunc1); - runtime:onGracefulStop(stopHandlerFunc2); - runtime:onGracefulStop(stopHandlerFunc4); -} - -final moduleA:ListenerObj lo = new moduleA:ListenerObj("ModDyncListener"); - -public function main() { - moduleA:incrementCount(); - moduleA:assertCount(2); - runtime:registerListener(lo); - runtime:onGracefulStop(stopHandlerFunc3); - runtime:StopHandler inlineStopHandler = function() returns error? { - runtime:sleep(2); - moduleA:incrementCount(); - moduleA:assertCount(7); - }; - runtime:onGracefulStop(inlineStopHandler); - checkpanic lo.'start(); - error? v = lo.gracefulStop(); - if (v is error) { - test:assertEquals(v.message(), "listener in main stopped"); - } - runtime:deregisterListener(lo); - moduleA:main(); -} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal deleted file mode 100644 index a7231d21d255..000000000000 --- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2022 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. 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. -import ballerina/lang.runtime; -import ballerina/test; - -int count = 0; - -function stopHandlerFunc1() returns error? { - runtime:sleep(1); - incrementCount(); - assertCount(12); -} - -function stopHandlerFunc2() returns error? { - incrementCount(); - assertCount(6); -} - -function init() { - runtime:onGracefulStop(stopHandlerFunc1); -} - -public class ListenerObj { - - *runtime:DynamicListener; - private string name = ""; - - public function init(string name) { - self.name = name; - } - - public function 'start() returns error? { - if (self.name == "ModDyncListener") { - incrementCount(); - assertCount(3); - } - } - - public function gracefulStop() returns error? { - if (self.name == "ModDyncListener") { - runtime:sleep(1.5); - incrementCount(); - assertCount(4); - return error("listener in main stopped"); - } else if (self.name == "ModDyncListenerA") { - return error("listener in moduleA stopped"); - } - } - - public function immediateStop() { - } - - public function attach(service object {} s, string[]|string? name = ()) returns error? { - } - - public function detach(service object {} s) returns error? { - } -} - -final ListenerObj lo = new ListenerObj("ModDyncListenerA"); - -public function main() { - incrementCount(); - assertCount(5); - runtime:registerListener(lo); - runtime:onGracefulStop(stopHandlerFunc2); - - checkpanic lo.'start(); - error? v = lo.gracefulStop(); - if (v is error) { - test:assertEquals(v.message(), "listener in moduleA stopped"); - } - runtime:deregisterListener(lo); -} - -public function incrementCount() { - count += 1; -} - -public function assertCount(int val) { - test:assertEquals(count, val); -} From ea8465da7c743f750db58d88e31758482a2485f0 Mon Sep 17 00:00:00 2001 From: Charuka Tharindu Date: Thu, 5 Oct 2023 08:05:26 +0530 Subject: [PATCH 11/11] Fix the path for JRE-17 --- distribution/zip/jballerina/bin/bal.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/zip/jballerina/bin/bal.bat b/distribution/zip/jballerina/bin/bal.bat index c87ace5a0322..4108114a6540 100644 --- a/distribution/zip/jballerina/bin/bal.bat +++ b/distribution/zip/jballerina/bin/bal.bat @@ -34,7 +34,7 @@ rem ----- if JAVA_HOME is not set we're not happy ------------------------------ :checkJava set BALLERINA_HOME=%~sdp0.. -if exist %BALLERINA_HOME%\..\..\dependencies\jdk-17.0.7+7-jree ( +if exist %BALLERINA_HOME%\..\..\dependencies\jdk-17.0.7+7-jre ( set "JAVA_HOME=%BALLERINA_HOME%\..\..\dependencies\jdk-17.0.7+7-jre" )