From f460632e8517d472dcf7e62852431bf94e33a245 Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Thu, 15 Aug 2024 10:16:31 +0530 Subject: [PATCH 01/11] Add orderedType check and tests for tuples --- .../ballerina/runtime/api/values/BArray.java | 3 + .../internal/values/TupleValueImpl.java | 34 +- .../src/main/java/module-info.java | 2 +- .../lang.array/src/main/java/module-info.java | 1 + .../org/ballerinalang/langlib/array/Sort.java | 35 +- .../langlib/array/utils/SortUtils.java | 161 +++++++ .../langlib/array/utils/TypePair.java | 47 +++ .../langlib/test/LangLibArrayTest.java | 1 + .../langlib/test/LangLibTupleTest.java | 3 +- .../test/resources/test-src/arraylib_test.bal | 398 ++++++++++++++++++ 10 files changed, 660 insertions(+), 25 deletions(-) create mode 100644 langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java create mode 100644 langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java index efc1e70cb995..5d786140dc9c 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java @@ -237,3 +237,6 @@ public interface BArray extends BRefValue, BCollection { long getLength(); } + + + 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 2bdc52b627bb..f6b4ae374d6c 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 @@ -23,28 +23,19 @@ import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; -import io.ballerina.runtime.api.values.BArray; -import io.ballerina.runtime.api.values.BIterator; -import io.ballerina.runtime.api.values.BLink; -import io.ballerina.runtime.api.values.BListInitialValueEntry; -import io.ballerina.runtime.api.values.BRefValue; -import io.ballerina.runtime.api.values.BString; -import io.ballerina.runtime.api.values.BTypedesc; -import io.ballerina.runtime.api.values.BValue; +import io.ballerina.runtime.api.values.*; import io.ballerina.runtime.internal.CycleUtils; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.ValueConverter; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; +import io.ballerina.runtime.internal.types.BType; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; +import java.util.*; import java.util.stream.IntStream; import static io.ballerina.runtime.api.constants.RuntimeConstants.ARRAY_LANG_LIB; @@ -324,6 +315,25 @@ public void addRefValue(long index, Object value) { refValues[(int) index] = value; } + public boolean checkSortCompatibility(BArray arr, BFunctionPointer function, Set typeList, Integer[] orderedTypeList) { + Type memberType; + for(int i = 0; i < arr.getLength(); i++) { + memberType = TypeUtils.getReferredType(this.tupleType.getTupleTypes().get(i)); + if( memberType != this.tupleType.getTupleTypes().get(0) && function == null) { + return false; + } + typeList.add(memberType); + } + return (Arrays.stream(orderedTypeList).toList().contains(typeList.stream().toList().get(0).getTag()) && + typeList.size() == 1); + } + + public List getElementTypeList() { + List typeList = this.tupleType.getTupleTypes(); + typeList.add(this.tupleType.getRestType()); + return typeList; + } + public void convertStringAndAddRefValue(long index, BString value) { rangeCheck(index, size); int intIndex = (int) index; diff --git a/bvm/ballerina-runtime/src/main/java/module-info.java b/bvm/ballerina-runtime/src/main/java/module-info.java index 385a49becba8..de5947b17a93 100644 --- a/bvm/ballerina-runtime/src/main/java/module-info.java +++ b/bvm/ballerina-runtime/src/main/java/module-info.java @@ -68,7 +68,7 @@ io.ballerina.lang.function, io.ballerina.lang.regexp, io.ballerina.lang.value, io.ballerina.lang.internal; exports io.ballerina.runtime.internal.configurable to io.ballerina.lang.internal; exports io.ballerina.runtime.internal.types to io.ballerina.lang.typedesc, io.ballerina.testerina.runtime, - org.ballerinalang.debugadapter.runtime, io.ballerina.lang.function, io.ballerina.lang.regexp, io.ballerina.testerina.core; + org.ballerinalang.debugadapter.runtime, io.ballerina.lang.function, io.ballerina.lang.regexp, io.ballerina.testerina.core, io.ballerina.lang.array; exports io.ballerina.runtime.observability.metrics.noop; exports io.ballerina.runtime.observability.tracer.noop; exports io.ballerina.runtime.internal.regexp; diff --git a/langlib/lang.array/src/main/java/module-info.java b/langlib/lang.array/src/main/java/module-info.java index 627916960435..25c102fb02d0 100644 --- a/langlib/lang.array/src/main/java/module-info.java +++ b/langlib/lang.array/src/main/java/module-info.java @@ -1,4 +1,5 @@ module io.ballerina.lang.array { requires io.ballerina.runtime; + requires io.ballerina.lang; exports org.ballerinalang.langlib.array; } diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java index 750706c1c0ec..9473bb44b404 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java @@ -18,21 +18,26 @@ package org.ballerinalang.langlib.array; +import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; -import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BFunctionPointer; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.internal.ValueComparisonUtils; import io.ballerina.runtime.internal.scheduling.Scheduler; +import io.ballerina.runtime.internal.types.*; + +import java.util.*; import static io.ballerina.runtime.api.constants.RuntimeConstants.ARRAY_LANG_LIB; import static io.ballerina.runtime.internal.errors.ErrorReasons.INVALID_TYPE_TO_SORT; import static io.ballerina.runtime.internal.errors.ErrorReasons.getModulePrefixedReason; -import static org.ballerinalang.langlib.array.utils.ArrayUtils.checkIsArrayOnlyOperation; +import static org.ballerinalang.langlib.array.utils.SortUtils.isOrderedType; /** * Native implementation of lang.array:sort((any|error)[], direction, function). @@ -42,12 +47,21 @@ public class Sort { public static BArray sort(BArray arr, Object direction, Object func) { - checkIsArrayOnlyOperation(TypeUtils.getImpliedType(arr.getType()), "sort()"); + BArray sortedArray; BFunctionPointer function = (BFunctionPointer) func; - + Set typeList = new HashSet<>(); + if(arr.getType().getTag() == TypeTags.TUPLE_TAG) { + if(!isOrderedType(arr.getType()) && function == null) { + throw ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB, INVALID_TYPE_TO_SORT), + StringUtils.fromString("Valid Key function needed")); + } + typeList = new HashSet<>(((BTupleType)arr.getType()).getTupleTypes()); + if(((BTupleType)arr.getType()).getRestType() != null) { + typeList.add(((BTupleType)arr.getType()).getRestType()); + } + } Object[][] sortArr = new Object[arr.size()][2]; Object[][] sortArrClone = new Object[arr.size()][2]; - if (function != null) { for (int i = 0; i < arr.size(); i++) { sortArr[i][0] = function.call(new Object[]{Scheduler.getStrand(), arr.get(i), true}); @@ -58,15 +72,16 @@ public static BArray sort(BArray arr, Object direction, Object func) { sortArr[i][0] = sortArr[i][1] = arr.get(i); } } - mergesort(sortArr, sortArrClone, 0, sortArr.length - 1, direction.toString()); - - BArray sortedArray = ValueCreator.createArrayValue(TypeCreator.createArrayType(arr.getElementType())); - + if(arr.getType().getTag() == TypeTags.TUPLE_TAG) { + sortedArray = ValueCreator.createArrayValue(TypeCreator.createArrayType( + TypeCreator.createUnionType(typeList.stream().toList()))); + } else { + sortedArray = ValueCreator.createArrayValue(TypeCreator.createArrayType(arr.getElementType())); + } for (int k = 0; k < sortArr.length; k++) { sortedArray.add(k, sortArr[k][1]); } - return sortedArray; } diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java new file mode 100644 index 000000000000..5c707e5f7bca --- /dev/null +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2024, 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. + */ + +package org.ballerinalang.langlib.array.utils; + +import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.creators.TypeCreator; +import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.UnionType; +import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.internal.TypeChecker; +import io.ballerina.runtime.internal.types.BArrayType; +import io.ballerina.runtime.internal.types.BFiniteType; +import io.ballerina.runtime.internal.types.BTupleType; + +import java.util.*; + +public class SortUtils { + + public static boolean isOrderedType(Type type) { + type = TypeUtils.getImpliedType(type); + switch (type.getTag()) { + case TypeTags.UNION_TAG: + UnionType unionType = (UnionType) type; + if (unionType.isCyclic()) { + return true; + } + Set memberTypes = new HashSet<>(unionType.getMemberTypes()); + Type firstTypeInUnion = getTypeWithEffectiveIntersectionTypes(TypeUtils.getImpliedType( + memberTypes.stream().filter(m -> m.getTag() != TypeTags.NULL_TAG).findFirst(). + orElse(memberTypes.iterator().next()))); + if (firstTypeInUnion.getTag() == TypeTags.NULL_TAG) { + // Union contains only the nil type. + return true; + } + if(!isOrderedType(firstTypeInUnion)) { + return false; + } + for (Type memType : memberTypes) { + memType = TypeUtils.getImpliedType(memType); + if(!isOrderedType(memType) || isDifferentOrderedType(memType, firstTypeInUnion)) { + return false; + } + } + return true; + case TypeTags.ARRAY_TAG: + return isOrderedType(((BArrayType) type).getElementType()); + case TypeTags.TUPLE_TAG: + List tupleTypes = ((BTupleType) type).getTupleTypes(); + if (((BTupleType) type).getRestType() != null) tupleTypes.add(((BTupleType) type).getRestType()); + if(!isOrderedType(tupleTypes.get(0))) { + return false; + } + for (Type memType : tupleTypes) { + if (!isOrderedType(memType) || isDifferentOrderedType(memType, tupleTypes.get(0))) { + return false; + } + } + return true; + case TypeTags.FINITE_TYPE_TAG: + Set valSpace = ((BFiniteType) type).getValueSpace(); + Type baseExprType = TypeUtils.getType(valSpace.iterator().next()); + if (!checkValueSpaceHasSameType((BFiniteType) type, baseExprType)) { + return false; + } + return isOrderedType(baseExprType); + default: + return isSimpleBasicType(type.getTag()); + } + } + + public static Type getTypeWithEffectiveIntersectionTypes(Type bType) { + Type type = TypeUtils.getReferredType(bType); + Type effectiveType = null; + if (type.getTag() == TypeTags.INTERSECTION_TAG) { + effectiveType = ((IntersectionType)type).getEffectiveType(); + type = effectiveType; + } + + if (type.getTag() != TypeTags.UNION_TAG) { + return Objects.requireNonNullElse(effectiveType, bType); + } + + LinkedHashSet members = new LinkedHashSet<>(); + boolean hasDifferentMember = false; + + for (Type memberType : ((UnionType) type).getMemberTypes()) { + effectiveType = getTypeWithEffectiveIntersectionTypes(memberType); + effectiveType = TypeUtils.getImpliedType(effectiveType); + if (effectiveType != memberType) { + hasDifferentMember = true; + } + members.add(effectiveType); + } + + if (hasDifferentMember) { + return TypeCreator.createUnionType(members.stream().toList()); + } + return bType; + } + + public static boolean checkValueSpaceHasSameType(BFiniteType finiteType, Type type) { + Type baseType = TypeUtils.getImpliedType(type); + if (baseType.getTag() == TypeTags.FINITE_TYPE_TAG) { + return checkValueSpaceHasSameType((BFiniteType) baseType, + TypeUtils.getType(finiteType.getValueSpace().iterator().next())); + } + for (Object expr : finiteType.getValueSpace()) { + if(isDifferentOrderedType(TypeUtils.getType(expr), baseType)) { + return false; + } + } + return true; + } + + public static boolean isDifferentOrderedType(Type source, Type target) { + source = TypeUtils.getImpliedType(source); + target = TypeUtils.getImpliedType(target); + if (source.getTag() == TypeTags.NULL_TAG || target.getTag() == TypeTags.NULL_TAG) { + return false; + } + if(checkIfDifferent(source)) { + return true; + } + return !TypeChecker.checkIsType(source, target); + } + + public static boolean isSimpleBasicType(int tag) { + return switch (tag) { + case TypeTags.BYTE_TAG, TypeTags.FLOAT_TAG, TypeTags.DECIMAL_TAG, TypeTags.BOOLEAN_TAG, TypeTags.NULL_TAG -> + true; + default -> tag >= TypeTags.INT_TAG && tag <= TypeTags.CHAR_STRING_TAG; + }; + } + + public static boolean checkIfDifferent(Type s) { + return switch (s.getTag()) { + case TypeTags.TYPE_REFERENCED_TYPE_TAG, TypeTags.ANY_TAG, TypeTags.ANYDATA_TAG, TypeTags.MAP_TAG, + TypeTags.FUTURE_TAG, TypeTags.XML_TAG, TypeTags.JSON_TAG, TypeTags.OBJECT_TYPE_TAG, + TypeTags.RECORD_TYPE_TAG, TypeTags.STREAM_TAG, TypeTags.TABLE_TAG, TypeTags.INVOKABLE_TAG, + TypeTags.ERROR_TAG -> true; + default -> false; + }; + } +} diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java new file mode 100644 index 000000000000..3b0b130c3cba --- /dev/null +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024, 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. + */ + +package org.ballerinalang.langlib.array.utils; + +import io.ballerina.runtime.api.types.Type; + +import java.util.Objects; + +public class TypePair { + Type sourceType; + Type targetType; + + public TypePair(Type sourceType, Type targetType) { + this.sourceType = sourceType; + this.targetType = targetType; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof TypePair other)) { + return false; + } + + return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType); + } + + @Override + public int hashCode() { + return Objects.hash(sourceType, targetType); + } +} 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 f8dc94bbf0e0..925abb141f5e 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 @@ -562,6 +562,7 @@ public Object[] testFunctions() { "testSort8", "testSort9", "testSort10", + "testSortNegative", "testReadOnlyArrayFilter", "testTupleFilter", "testTupleReverse", diff --git a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibTupleTest.java b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibTupleTest.java index 96e425c14df6..0baa6a41c5fa 100644 --- a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibTupleTest.java +++ b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibTupleTest.java @@ -113,8 +113,7 @@ public void testRemove() { BRunUtil.invoke(compileResult, "testRemove"); } - @Test(expectedExceptions = RuntimeException.class, - expectedExceptionsMessageRegExp = ".*error: \\{ballerina/lang.array\\}OperationNotSupported.*") + @Test public void testSort() { BRunUtil.invoke(compileResult, "testSort"); } 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 3a7ceb07f9a2..5a20a41350d7 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 @@ -906,13 +906,30 @@ function getStudentList() returns Student[] { return studentList; } +function getStudentListForTuples() returns [Student...] { + Student s1 = {id: 1, fname: "Amber", fee: 10000.56, impact: 0.127, isUndergrad: true}; + Student s2 = {id: 20, fname: (), fee: 2000.56, impact: 0.45, isUndergrad: false}; + Student s3 = {id: 2, fname: "Dan", fee: (), impact: 0.3, isUndergrad: true}; + Student s4 = {id: 10, fname: "Kate", fee: (0.0 / 0.0), impact: 0.146, isUndergrad: false}; + Student s5 = {id: 3, fname: "Kate", fee: 5000.56, impact: 0.4, isUndergrad: false}; + + [Student...] studentList = [s1, s2, s3, s4, s5]; + + return studentList; +} + function testSort1() { Student[] studentArr = getStudentList(); + [Student...] studentTup = getStudentListForTuples(); Student[] sortedArr = studentArr.sort(array:DESCENDING, isolated function(Student s) returns int { return s.id; }); + Student[] sortedTup = studentTup.sort(array:DESCENDING, isolated function(Student s) returns int { + return s.id; + }); + assertValueEquality(sortedArr[0].toString(), "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); assertValueEquality(sortedArr[1].toString(), @@ -925,10 +942,26 @@ function testSort1() { "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); assertFalse(studentArr == sortedArr); + assertValueEquality(sortedTup[0].toString(), + "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedTup[1].toString(), + "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(sortedTup[2].toString(), + "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); + assertValueEquality(sortedTup[3].toString(), + "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedTup[4].toString(), + "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertFalse(studentArr == sortedTup); + Student[] sortedArr2 = studentArr.sort(array:DESCENDING, isolated function(Student s) returns string? { return s.fname; }); + Student[] sortedTup2 = studentTup.sort(array:DESCENDING, isolated function(Student s) returns string? { + return s.fname; + }); + assertValueEquality(sortedArr2[0].toString(), "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); assertValueEquality(sortedArr2[1].toString(), @@ -941,10 +974,26 @@ function testSort1() { "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); assertFalse(studentArr == sortedArr2); + assertValueEquality(sortedTup2[0].toString(), + "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(sortedTup2[1].toString(), + "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); + assertValueEquality(sortedTup2[2].toString(), + "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedTup2[3].toString(), + "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertValueEquality(sortedTup2[4].toString(), + "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertFalse(studentArr == sortedArr2); + Student[] sortedArr3 = studentArr.sort(array:ASCENDING, isolated function(Student s) returns float? { return s.fee; }); + Student[] sortedTup3 = studentTup.sort(array:ASCENDING, isolated function(Student s) returns float? { + return s.fee; + }); + assertValueEquality(sortedArr3[0].toString(), "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); assertValueEquality(sortedArr3[1].toString(), @@ -956,10 +1005,25 @@ function testSort1() { assertValueEquality(sortedArr3[4].toString(), "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedTup3[0].toString(), + "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedTup3[1].toString(), + "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); + assertValueEquality(sortedTup3[2].toString(), + "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertValueEquality(sortedTup3[3].toString(), + "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(sortedTup3[4].toString(), + "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + Student[] sortedArr4 = studentArr.sort(array:ASCENDING, isolated function(Student s) returns decimal { return s.impact; }); + Student[] sortedTup4 = studentTup.sort(array:ASCENDING, isolated function(Student s) returns decimal { + return s.impact; + }); + assertValueEquality(sortedArr4[0].toString(), "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); assertValueEquality(sortedArr4[1].toString(), @@ -971,6 +1035,17 @@ function testSort1() { assertValueEquality(sortedArr4[4].toString(), "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedTup4[0].toString(), + "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertValueEquality(sortedTup4[1].toString(), + "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(sortedTup4[2].toString(), + "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedTup4[3].toString(), + "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); + assertValueEquality(sortedTup4[4].toString(), + "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + Student[] sortedArr5 = sortedArr4.sort(array:ASCENDING, isolated function(Student s) returns boolean { return s.isUndergrad; }); @@ -988,6 +1063,7 @@ function testSort1() { assertFalse(sortedArr4 == sortedArr5); assertValueEquality(getStudentList(), studentArr); // no change to original array + assertValueEquality(getStudentListForTuples(), studentTup); } function testSort2() { @@ -1118,6 +1194,7 @@ function testSort3() returns int[] { function testSort4() { [Grade, int][] grades = [["A+", 2], ["A-", 3], ["B", 3], ["C", 2]]; + [[Grade, int]...] gradesTup = [["A+", 2], ["A-", 3], ["B", 3], ["C", 2]]; [Grade, int][] sortedArr = grades.sort(array:ASCENDING, isolated function([Grade, int] val) returns float[] { if (val[0] == "A+") { @@ -1126,20 +1203,38 @@ function testSort4() { return [val[1], 5.2]; }); + [Grade, int][] sortedTup = gradesTup.sort(array:ASCENDING, isolated function([Grade, int] val) returns float[] { + if (val[0] == "A+") { + return [val[1], 6.5]; + } + return [val[1], 5.2]; + }); + assertValueEquality(sortedArr[0].toString(), "[\"C\",2]"); assertValueEquality(sortedArr[1].toString(), "[\"A+\",2]"); assertValueEquality(sortedArr[2].toString(), "[\"A-\",3]"); assertValueEquality(sortedArr[3].toString(), "[\"B\",3]"); assertValueEquality([["A+", 2], ["A-", 3], ["B", 3], ["C", 2]], grades); // no change to original array + + assertValueEquality(sortedTup[0].toString(), "[\"C\",2]"); + assertValueEquality(sortedTup[1].toString(), "[\"A+\",2]"); + assertValueEquality(sortedTup[2].toString(), "[\"A-\",3]"); + assertValueEquality(sortedTup[3].toString(), "[\"B\",3]"); + assertValueEquality([["A+", 2], ["A-", 3], ["B", 3], ["C", 2]], gradesTup); // no change to original array } function testSort5() { Student[] studentArr = getStudentList(); + [Student...] studentTup = getStudentListForTuples(); Student[] sortedArr = studentArr.sort(array:DESCENDING, isolated function(Student s) returns string? { return getFullName(s.id, s.fname); }); + Student[] sortedTup = studentTup.sort(array:DESCENDING, isolated function(Student s) returns string? { + return getFullName(s.id, s.fname); + }); + assertValueEquality(sortedArr[0].toString(), "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); assertValueEquality(sortedArr[1].toString(), @@ -1151,6 +1246,18 @@ function testSort5() { assertValueEquality(sortedArr[4].toString(), "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); assertValueEquality(getStudentList(), studentArr); // no change to original array + + assertValueEquality(sortedTup[0].toString(), + "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); + assertValueEquality(sortedTup[1].toString(), + "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(sortedTup[2].toString(), + "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedTup[3].toString(), + "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertValueEquality(sortedTup[4].toString(), + "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(getStudentListForTuples(), studentTup); // no change to original array } isolated function getFullName(int id, string? name) returns string? { @@ -1167,6 +1274,7 @@ type StringOrStudent string|Student; function testSort6() { anydata[] arr = [90, 2.0, 1, true, 32, "AA", 12.09, 100, 3, >{"k": "Bar"}, ["BB", true]]; + [anydata...] tup = [90, 2.0, 1, true, 32, "AA", 12.09, 100, 3, >{"k": "Bar"}, ["BB", true]]; anydata[] sortedArr = arr.sort(array:ASCENDING, isolated function(anydata a) returns int? { if (a is int) { @@ -1181,40 +1289,79 @@ function testSort6() { return (); }); + anydata[] sortedTup = tup.sort(array:ASCENDING, isolated function(anydata a) returns int? { + if (a is int) { + return a; + } else if (a is float) { + return a; + } else if (a is boolean) { + return 0; + } else if (a is map) { + return -1; + } + return (); + }); + assertValueEquality(sortedArr.toString(), "[{\"k\":\"Bar\"},true,1,2.0,3,12.09,32,90,100,\"AA\",[\"BB\",true]]"); assertValueEquality([90, 2.0, 1, true, 32, "AA", 12.09, 100, 3, >{"k": "Bar"}, ["BB", true]], arr); + assertValueEquality(sortedTup.toString(), + "[{\"k\":\"Bar\"},true,1,2.0,3,12.09,32,90,100,\"AA\",[\"BB\",true]]"); + assertValueEquality([90, 2.0, 1, true, 32, "AA", 12.09, 100, 3, >{"k": "Bar"}, ["BB", true]], tup); + string?[] arr2 = ["Hello", "World!", (), "from", "Ballerina"]; + [(string?)...] tup2 = ["Hello", "World!", (), "from", "Ballerina"]; string?[] sortedArr2 = arr2.sort(); assertValueEquality(sortedArr2.toString(), "[\"Ballerina\",\"Hello\",\"World!\",\"from\",null]"); + string?[] sortedTup2 = tup2.sort(); + assertValueEquality(sortedTup2.toString(), "[\"Ballerina\",\"Hello\",\"World!\",\"from\",null]"); + Obj obj1 = new Obj(1, 1); Obj obj2 = new Obj(1, 2); Obj obj3 = new Obj(1, 10); Obj[] arr3 = [obj1, obj2, obj3]; + [Obj...] tup3 = [obj1, obj2, obj3]; Obj[] sortedArr3 = arr3.sort(array:DESCENDING, isolated function(Obj obj) returns int { return obj.j; }); + Obj[] sortedTup3 = tup3.sort(array:DESCENDING, isolated function(Obj obj) returns int { + return obj.j; + }); + assertValueEquality(sortedArr3[0].j, 10); assertValueEquality(sortedArr3[1].j, 2); assertValueEquality(sortedArr3[2].j, 1); + assertValueEquality(sortedTup3[0].j, 10); + assertValueEquality(sortedTup3[1].j, 2); + assertValueEquality(sortedTup3[2].j, 1); + int[2]|int[] arr4 = [1, 9, 3, 21, 0, 7]; + [int, int]|[int...] tup4 = [1, 9, 3, 21, 0, 7]; int[2]|int[] sortedArr4 = arr4.sort(array:ASCENDING, isolated function(int i) returns int { return i; }); + int[2]|int[] sortedTup4 = tup4.sort(array:ASCENDING, isolated function(int i) returns int { + return i; + }); + assertValueEquality(sortedArr4.toString(), "[0,1,3,7,9,21]"); + assertValueEquality(sortedTup4.toString(), "[0,1,3,7,9,21]"); int[] arr5 = [2, 0, 12, 1, 23, 3, 100, 55]; + [int...] tup5 = [2, 0, 12, 1, 23, 3, 100, 55]; int[] sortedArr5 = arr5.sort(array:DESCENDING); + int[] sortedTup5 = tup5.sort(array:DESCENDING); assertValueEquality(sortedArr5.toString(), "[100,55,23,12,3,2,1,0]"); + assertValueEquality(sortedTup5.toString(), "[100,55,23,12,3,2,1,0]"); string?[] sortedArr6 = arr2.sort(array:DESCENDING, isolated function(string? s) returns string?[]? { if (s is string) { @@ -1223,7 +1370,15 @@ function testSort6() { return (); }); + string?[] sortedTup6 = tup2.sort(array:DESCENDING, isolated function(string? s) returns string?[]? { + if (s is string) { + return [s, "A"]; + } + return (); + }); + assertValueEquality(sortedArr6.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); + assertValueEquality(sortedTup6.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); string?[] sortedArr7 = arr2.sort(array:ASCENDING, isolated function(string? s) returns string?[] { if (s is string) { @@ -1232,25 +1387,43 @@ function testSort6() { return ["W", "A"]; }); + string?[] sortedTup7 = tup2.sort(array:ASCENDING, isolated function(string? s) returns string?[] { + if (s is string) { + return [s, "A"]; + } + return ["W", "A"]; + }); + assertValueEquality(sortedArr7.toString(), "[\"Ballerina\",\"Hello\",null,\"World!\",\"from\"]"); + assertValueEquality(sortedTup7.toString(), "[\"Ballerina\",\"Hello\",null,\"World!\",\"from\"]"); int[] sortedArr8 = arr5.sort(array:ASCENDING, ()); + int[] sortedTup8 = tup5.sort(array:ASCENDING, ()); assertValueEquality(sortedArr8.toString(), "[0,1,2,3,12,23,55,100]"); + assertValueEquality(sortedTup8.toString(), "[0,1,2,3,12,23,55,100]"); Grade[] arr6 = ["A+", "B+", "C", "F", "A-", "C", "A+", "B"]; + [Grade...] tup6 = ["A+", "B+", "C", "F", "A-", "C", "A+", "B"]; Grade[] sortedArr9 = arr6.sort(array:DESCENDING, isolated function(Grade grade) returns string { return grade; }); + Grade[] sortedTup9 = arr6.sort(array:DESCENDING, isolated function(Grade grade) returns string { + return grade; + }); + assertValueEquality(sortedArr9.toString(), "[\"F\",\"C\",\"C\",\"B+\",\"B\",\"A-\",\"A+\",\"A+\"]"); assertValueEquality(["A+", "B+", "C", "F", "A-", "C", "A+", "B"], arr6); // no change to arr6 + assertValueEquality(sortedTup9.toString(), "[\"F\",\"C\",\"C\",\"B+\",\"B\",\"A-\",\"A+\",\"A+\"]"); + assertValueEquality(["A+", "B+", "C", "F", "A-", "C", "A+", "B"], arr6); // no change to tup6 Student s1 = {id: 1, fname: "Amber", fee: 10000.56, impact: 0.127, isUndergrad: true}; Student s2 = {id: 2, fname: "Dan", fee: (), impact: 0.3, isUndergrad: true}; Student s3 = {id: 10, fname: "Kate", fee: (0.0 / 0.0), impact: 0.146, isUndergrad: false}; StringOrStudent[] arr7 = ["Anne", s3, s1, "James", "Frank", s2]; + [StringOrStudent...] tup7 = ["Anne", s3, s1, "James", "Frank", s2]; StringOrStudent[] sortedArr10 = arr7.sort(array:ASCENDING, isolated function(StringOrStudent sp) returns string? { if (sp is Student) { @@ -1260,6 +1433,14 @@ function testSort6() { } }); + StringOrStudent[] sortedTup10 = tup7.sort(array:ASCENDING, isolated function(StringOrStudent sp) returns string? { + if (sp is Student) { + return sp.fname; + } else { + return sp; + } + }); + assertValueEquality(sortedArr10[0].toString(), "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); assertValueEquality(sortedArr10[1].toString(), "Anne"); @@ -1271,20 +1452,45 @@ function testSort6() { "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); assertValueEquality(["Anne", s3, s1, "James", "Frank", s2], arr7); // no change to arr7 + assertValueEquality(sortedTup10[0].toString(), + "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertValueEquality(sortedTup10[1].toString(), "Anne"); + assertValueEquality(sortedTup10[2].toString(), + "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedTup10[3].toString(), "Frank"); + assertValueEquality(sortedTup10[4].toString(), "James"); + assertValueEquality(sortedTup10[5].toString(), + "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(["Anne", s3, s1, "James", "Frank", s2], tup7); // no change to tup7 + int[] sortedArr11 = array:sort(arr5); + [int...] sortedTup11 = array:sort(tup5); assertValueEquality(sortedArr11.toString(), "[0,1,2,3,12,23,55,100]"); assertValueEquality([2, 0, 12, 1, 23, 3, 100, 55], arr5); // no change to arr5 assertValueEquality([0, 1, 2, 3, 12, 23, 55, 100], sortedArr8); // no change to sortedArr8 + assertValueEquality(sortedTup11.toString(), "[0,1,2,3,12,23,55,100]"); + assertValueEquality([2, 0, 12, 1, 23, 3, 100, 55], tup5); // no change to tup5 + assertValueEquality([0, 1, 2, 3, 12, 23, 55, 100], sortedTup8); // no change to sortedTup8 + int[2]|int[] sortedArr12 = array:sort(arr4, array:DESCENDING, isolated function(int i) returns int { return i; }); + int[2]|int[] sortedTup12 = array:sort(tup4, array:DESCENDING, isolated function(int i) returns int { + return i; + }); + assertValueEquality(sortedArr12.toString(), "[21,9,7,3,1,0]"); assertValueEquality([1, 9, 3, 21, 0, 7], arr4); // no change to arr4 + assertValueEquality(sortedTup12.toString(), "[21,9,7,3,1,0]"); + assertValueEquality([1, 9, 3, 21, 0, 7], tup4); // no change to tup4 + string?[] sortedArr13 = array:sort(arr2, array:DESCENDING); + string?[] sortedTup13 = array:sort(tup2, array:DESCENDING); assertValueEquality(sortedArr13.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); + assertValueEquality(sortedTup13.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); } function testSort7() { @@ -1309,7 +1515,29 @@ function testSort7() { [1.8, (0.0 / 0.0)] ]; + [(float?[])...] tup = [ + [1.8, 2.89, 5, 70, 90], + [(), 4], + [1.8, 2.89, 5, 70], + [(0.0 / 0.0), 9, 8, 10], + [ + 1.8, + 2.89, + 5, + 70, + () + ], + [1.8, 2.89, 5], + [1.8, 2.89, 4], + [1.8, 2.89], + [2.8, 2.89, 5, 70, 90], + [3], + [1.8, 2.89, 5, 70, (0.0 / 0.0)], + [1.8, (0.0 / 0.0)] + ]; + float?[][] sortedArr = arr.sort(array:DESCENDING); + float?[][] sortedTup = tup.sort(array:DESCENDING); assertValueEquality(sortedArr[0], [3.0]); assertValueEquality(sortedArr[1], [2.8, 2.89, 5.0, 70.0, 90.0]); @@ -1324,10 +1552,27 @@ function testSort7() { assertValueEquality(sortedArr[10], [(0.0 / 0.0), 9.0, 8.0, 10.0]); assertValueEquality(sortedArr[11], [(), 4.0]); + assertValueEquality(sortedTup[0], [3.0]); + assertValueEquality(sortedTup[1], [2.8, 2.89, 5.0, 70.0, 90.0]); + assertValueEquality(sortedTup[2], [1.8, 2.89, 5.0, 70.0, 90.0]); + assertValueEquality(sortedTup[3], [1.8, 2.89, 5.0, 70.0, (0.0 / 0.0)]); + assertValueEquality(sortedTup[4], [1.8, 2.89, 5.0, 70.0, ()]); + assertValueEquality(sortedTup[5], [1.8, 2.89, 5.0, 70.0]); + assertValueEquality(sortedTup[6], [1.8, 2.89, 5.0]); + assertValueEquality(sortedTup[7], [1.8, 2.89, 4.0]); + assertValueEquality(sortedTup[8], [1.8, 2.89]); + assertValueEquality(sortedTup[9], [1.8, (0.0 / 0.0)]); + assertValueEquality(sortedTup[10], [(0.0 / 0.0), 9.0, 8.0, 10.0]); + assertValueEquality(sortedTup[11], [(), 4.0]); + float?[][] sortedArr2 = arr.sort(array:ASCENDING, isolated function(float?[] x) returns float?[] { return x; }); + float?[][] sortedTup2 = tup.sort(array:ASCENDING, isolated function(float?[] x) returns float?[] { + return x; + }); + assertValueEquality(sortedArr2[0], [1.8, 2.89]); assertValueEquality(sortedArr2[1], [1.8, 2.89, 4.0]); assertValueEquality(sortedArr2[2], [1.8, 2.89, 5.0]); @@ -1341,24 +1586,50 @@ function testSort7() { assertValueEquality(sortedArr2[10], [(0.0 / 0.0), 9.0, 8.0, 10.0]); assertValueEquality(sortedArr2[11], [(), 4.0]); + assertValueEquality(sortedTup2[0], [1.8, 2.89]); + assertValueEquality(sortedTup2[1], [1.8, 2.89, 4.0]); + assertValueEquality(sortedTup2[2], [1.8, 2.89, 5.0]); + assertValueEquality(sortedTup2[3], [1.8, 2.89, 5.0, 70.0]); + assertValueEquality(sortedTup2[4], [1.8, 2.89, 5.0, 70.0, 90.0]); + assertValueEquality(sortedTup2[5], [1.8, 2.89, 5.0, 70.0, (0.0 / 0.0)]); + assertValueEquality(sortedTup2[6], [1.8, 2.89, 5.0, 70.0, ()]); + assertValueEquality(sortedTup2[7], [1.8, (0.0 / 0.0)]); + assertValueEquality(sortedTup2[8], [2.8, 2.89, 5.0, 70.0, 90.0]); + assertValueEquality(sortedTup2[9], [3.0]); + assertValueEquality(sortedTup2[10], [(0.0 / 0.0), 9.0, 8.0, 10.0]); + assertValueEquality(sortedTup2[11], [(), 4.0]); + int[][] arr2 = [[1, 9, 2], [0, 9, 1], [1, 7, 5], [9, 8, 2], [9, 8, 1]]; + [(int[])...] tup2 = [[1, 9, 2], [0, 9, 1], [1, 7, 5], [9, 8, 2], [9, 8, 1]]; int[][] sortedArr3 = arr2.sort(); + int[][] sortedTup3 = tup2.sort(); assertValueEquality(sortedArr3[0], [0, 9, 1]); assertValueEquality(sortedArr3[1], [1, 7, 5]); assertValueEquality(sortedArr3[2], [1, 9, 2]); assertValueEquality(sortedArr3[3], [9, 8, 1]); assertValueEquality(sortedArr3[4], [9, 8, 2]); + + assertValueEquality(sortedTup3[0], [0, 9, 1]); + assertValueEquality(sortedTup3[1], [1, 7, 5]); + assertValueEquality(sortedTup3[2], [1, 9, 2]); + assertValueEquality(sortedTup3[3], [9, 8, 1]); + assertValueEquality(sortedTup3[4], [9, 8, 2]); } function testSort8() { [int...][] arr = [[10, 2, 0], [1, 2, 0, 7], [1, 2, 5], [0, 9, 5], [1, 2, 0], [1, 1, 0]]; + [([int...])...] tup = [[10, 2, 0], [1, 2, 0, 7], [1, 2, 5], [0, 9, 5], [1, 2, 0], [1, 1, 0]]; [int...][] sortedArr = arr.sort(array:ASCENDING, isolated function([int...] x) returns int[] { return x; }); + [int...][] sortedTup = tup.sort(array:ASCENDING, isolated function([int...] x) returns int[] { + return x; + }); + assertValueEquality(sortedArr[0], [0, 9, 5]); assertValueEquality(sortedArr[1], [1, 1, 0]); assertValueEquality(sortedArr[2], [1, 2, 0]); @@ -1366,12 +1637,24 @@ function testSort8() { assertValueEquality(sortedArr[4], [1, 2, 5]); assertValueEquality(sortedArr[5], [10, 2, 0]); + assertValueEquality(sortedTup[0], [0, 9, 5]); + assertValueEquality(sortedTup[1], [1, 1, 0]); + assertValueEquality(sortedTup[2], [1, 2, 0]); + assertValueEquality(sortedTup[3], [1, 2, 0, 7]); + assertValueEquality(sortedTup[4], [1, 2, 5]); + assertValueEquality(sortedTup[5], [10, 2, 0]); + [int?...][] arr2 = [[(), 2, 0], [1, 2, 0, 7], [1, 2, 5], [0, 9, 5], [1, 2, 0], [1, 1, 0], [0, (), 9]]; + [([int?...])...] tup2 = [[(), 2, 0], [1, 2, 0, 7], [1, 2, 5], [0, 9, 5], [1, 2, 0], [1, 1, 0], [0, (), 9]]; [int?...][] sortedArr2 = arr2.sort(array:DESCENDING, isolated function(int?[] x) returns int?[] { return x; }); + [int?...][] sortedTup2 = tup2.sort(array:DESCENDING, isolated function(int?[] x) returns int?[] { + return x; + }); + assertValueEquality(sortedArr2[0], [1, 2, 5]); assertValueEquality(sortedArr2[1], [1, 2, 0, 7]); assertValueEquality(sortedArr2[2], [1, 2, 0]); @@ -1380,32 +1663,58 @@ function testSort8() { assertValueEquality(sortedArr2[5], [0, (), 9]); assertValueEquality(sortedArr2[6], [(), 2, 0]); + assertValueEquality(sortedTup2[0], [1, 2, 5]); + assertValueEquality(sortedTup2[1], [1, 2, 0, 7]); + assertValueEquality(sortedTup2[2], [1, 2, 0]); + assertValueEquality(sortedTup2[3], [1, 1, 0]); + assertValueEquality(sortedTup2[4], [0, 9, 5]); + assertValueEquality(sortedTup2[5], [0, (), 9]); + assertValueEquality(sortedTup2[6], [(), 2, 0]); + [int, boolean...][] arr3 = [[3, true, true, true], [5, true, false, true], [1, false, false]]; + [([int, boolean...])...] tup3 = [[3, true, true, true], [5, true, false, true], [1, false, false]]; [int, boolean...][] sortedArr3 = arr3.sort(array:ASCENDING, isolated function([int, boolean...] x) returns boolean[] { return [x[1], x[2]]; }); + [int, boolean...][] sortedTup3 = tup3.sort(array:ASCENDING, isolated function([int, boolean...] x) returns boolean[] { + return [x[1], x[2]]; + }); + assertValueEquality(sortedArr3[0], [1, false, false]); assertValueEquality(sortedArr3[1], [5, true, false, true]); assertValueEquality(sortedArr3[2], [3, true, true, true]); + + assertValueEquality(sortedTup3[0], [1, false, false]); + assertValueEquality(sortedTup3[1], [5, true, false, true]); + assertValueEquality(sortedTup3[2], [3, true, true, true]); } function testSort9() { strings:Char[] arr = ["s", "a", "b", "M", "Z"]; + [strings:Char...] tup = ["s", "a", "b", "M", "Z"]; strings:Char[] sortedArr = arr.sort(array:DESCENDING); + strings:Char[] sortedTup = tup.sort(array:DESCENDING); assertValueEquality(sortedArr.toString(), "[\"s\",\"b\",\"a\",\"Z\",\"M\"]"); + assertValueEquality(sortedTup.toString(), "[\"s\",\"b\",\"a\",\"Z\",\"M\"]"); int[] arr2 = [4294967295, 4194967295, 4294967290, 4284967295, 3294967295, 1294967295]; + [int...] tup2 = [4294967295, 4194967295, 4294967290, 4284967295, 3294967295, 1294967295]; int[] sortedArr2 = arr2.sort(); + int[] sortedTup2 = tup2.sort(); assertValueEquality(sortedArr2.toString(), "[1294967295,3294967295,4194967295,4284967295,4294967290,4294967295]"); + assertValueEquality(sortedTup2.toString(), + "[1294967295,3294967295,4194967295,4284967295,4294967290,4294967295]"); ints:Signed32[] arr3 = [2147483647, -2147483648, 2147483637, -1147483648, -2137483648, 1147483647]; + [ints:Signed32...] tup3 = [2147483647, -2147483648, 2147483637, -1147483648, -2137483648, 1147483647]; ints:Signed32[] sortedArr3 = arr3.sort(); + ints:Signed32[] sortedTup3 = tup3.sort(); assertValueEquality(sortedArr3[0], -2147483648); assertValueEquality(sortedArr3[1], -2137483648); @@ -1414,9 +1723,18 @@ function testSort9() { assertValueEquality(sortedArr3[4], 2147483637); assertValueEquality(sortedArr3[5], 2147483647); + assertValueEquality(sortedTup3[0], -2147483648); + assertValueEquality(sortedTup3[1], -2137483648); + assertValueEquality(sortedTup3[2], -1147483648); + assertValueEquality(sortedTup3[3], 1147483647); + assertValueEquality(sortedTup3[4], 2147483637); + assertValueEquality(sortedTup3[5], 2147483647); + ints:Signed16[] arr4 = [32765, -32768, 32767, -32668, -30768, 32567]; + [ints:Signed16...] tup4 = [32765, -32768, 32767, -32668, -30768, 32567]; ints:Signed16[] sortedArr4 = arr4.sort(array:DESCENDING); + ints:Signed16[] sortedTup4 = tup4.sort(array:DESCENDING); assertValueEquality(sortedArr4[0], 32767); assertValueEquality(sortedArr4[1], 32765); @@ -1425,9 +1743,18 @@ function testSort9() { assertValueEquality(sortedArr4[4], -32668); assertValueEquality(sortedArr4[5], -32768); + assertValueEquality(sortedTup4[0], 32767); + assertValueEquality(sortedTup4[1], 32765); + assertValueEquality(sortedTup4[2], 32567); + assertValueEquality(sortedTup4[3], -30768); + assertValueEquality(sortedTup4[4], -32668); + assertValueEquality(sortedTup4[5], -32768); + ints:Signed8[] arr5 = [-100, -123, 100, 67, -34, 52]; + [ints:Signed8...] tup5 = [-100, -123, 100, 67, -34, 52]; ints:Signed8[] sortedArr5 = arr5.sort(); + ints:Signed8[] sortedTup5 = tup5.sort(); assertValueEquality(sortedArr5[0], -123); assertValueEquality(sortedArr5[1], -100); @@ -1436,12 +1763,24 @@ function testSort9() { assertValueEquality(sortedArr5[4], 67); assertValueEquality(sortedArr5[5], 100); + assertValueEquality(sortedTup5[0], -123); + assertValueEquality(sortedTup5[1], -100); + assertValueEquality(sortedTup5[2], -34); + assertValueEquality(sortedTup5[3], 52); + assertValueEquality(sortedTup5[4], 67); + assertValueEquality(sortedTup5[5], 100); + ints:Unsigned32[] arr6 = [50, 4294967295, 0, 4294957295, 4294967294, 123, 214967295]; + [ints:Unsigned32...] tup6 = [50, 4294967295, 0, 4294957295, 4294967294, 123, 214967295]; ints:Unsigned32[] sortedArr6 = arr6.sort(array:ASCENDING, isolated function(ints:Unsigned32 x) returns ints:Unsigned32 { return x; }); + ints:Unsigned32[] sortedTup6 = tup6.sort(array:ASCENDING, isolated function(ints:Unsigned32 x) returns ints:Unsigned32 { + return x; + }); + assertValueEquality(sortedArr6[0], 0); assertValueEquality(sortedArr6[1], 50); assertValueEquality(sortedArr6[2], 123); @@ -1450,9 +1789,19 @@ function testSort9() { assertValueEquality(sortedArr6[5], 4294967294); assertValueEquality(sortedArr6[6], 4294967295); + assertValueEquality(sortedTup6[0], 0); + assertValueEquality(sortedTup6[1], 50); + assertValueEquality(sortedTup6[2], 123); + assertValueEquality(sortedTup6[3], 214967295); + assertValueEquality(sortedTup6[4], 4294957295); + assertValueEquality(sortedTup6[5], 4294967294); + assertValueEquality(sortedTup6[6], 4294967295); + ints:Unsigned16[] arr7 = [450, 65335, 0, 12, 65535, 12500, 4]; + [ints:Unsigned16...] tup7 = [450, 65335, 0, 12, 65535, 12500, 4]; ints:Unsigned16[] sortedArr7 = arr7.sort(array:DESCENDING); + ints:Unsigned16[] sortedTup7 = arr7.sort(array:DESCENDING); assertValueEquality(sortedArr7[0], 65535); assertValueEquality(sortedArr7[1], 65335); @@ -1462,9 +1811,19 @@ function testSort9() { assertValueEquality(sortedArr7[5], 4); assertValueEquality(sortedArr7[6], 0); + assertValueEquality(sortedTup7[0], 65535); + assertValueEquality(sortedTup7[1], 65335); + assertValueEquality(sortedTup7[2], 12500); + assertValueEquality(sortedTup7[3], 450); + assertValueEquality(sortedTup7[4], 12); + assertValueEquality(sortedTup7[5], 4); + assertValueEquality(sortedTup7[6], 0); + ints:Unsigned8[] arr8 = [221, 100, 0, 255, 24, 9, 2]; + [ints:Unsigned8...] tup8 = [221, 100, 0, 255, 24, 9, 2]; ints:Unsigned8[] sortedArr8 = arr8.sort(); + ints:Unsigned8[] sortedTup8 = tup8.sort(); assertValueEquality(sortedArr8[0], 0); assertValueEquality(sortedArr8[1], 2); @@ -1473,14 +1832,25 @@ function testSort9() { assertValueEquality(sortedArr8[4], 100); assertValueEquality(sortedArr8[5], 221); assertValueEquality(sortedArr8[6], 255); + + assertValueEquality(sortedTup8[0], 0); + assertValueEquality(sortedTup8[1], 2); + assertValueEquality(sortedTup8[2], 9); + assertValueEquality(sortedTup8[3], 24); + assertValueEquality(sortedTup8[4], 100); + assertValueEquality(sortedTup8[5], 221); + assertValueEquality(sortedTup8[6], 255); } function testSort10() { int[] arr = [10, 1, 3, 2, 0, 6]; + [int...] tup = [10, 1, 3, 2, 0, 6]; int[] sortedArr = arr.sort(array:ASCENDING, (i) => i); + int[] sortedTup = tup.sort(array:ASCENDING, (i) => i); assertValueEquality(sortedArr.toString(), "[0,1,2,3,6,10]"); + assertValueEquality(sortedTup.toString(), "[0,1,2,3,6,10]"); final int methodInt1 = 2; var addFunc1 = isolated function(int funcInt1) returns (int) { @@ -1494,27 +1864,55 @@ function testSort10() { }; int[] sortedArr2 = arr.sort(array:DESCENDING, addFunc1); + int[] sortedTup2 = tup.sort(array:DESCENDING, addFunc1); assertValueEquality(sortedArr2.toString(), "[10,6,3,2,1,0]"); + assertValueEquality(sortedTup2.toString(), "[10,6,3,2,1,0]"); int[] sortedArr3 = array:sort(arr, array:ASCENDING, isolated function(int x) returns string[] => [x.toString(), "World"]); + int[] sortedTup3 = array:sort(tup, array:ASCENDING, isolated function(int x) returns string[] => [x.toString(), "World"]); assertValueEquality(sortedArr3.toString(), "[0,1,10,2,3,6]"); + assertValueEquality(sortedTup3.toString(), "[0,1,10,2,3,6]"); int[] sortedArr4 = arr.sort(array:DESCENDING, (i) => i.toString()); + int[] sortedTup4 = tup.sort(array:DESCENDING, (i) => i.toString()); assertValueEquality(sortedArr4, [6, 3, 2, 10, 1, 0]); + assertValueEquality(sortedTup4, [6, 3, 2, 10, 1, 0]); int?[] arr2 = [(), 1, 3, 10, 0, 6]; + [int?...] tup2 = [(), 1, 3, 10, 0, 6]; int?[] sortedArr5 = arr2.sort(array:DESCENDING, (i) => i); + int?[] sortedTup5 = tup2.sort(array:DESCENDING, (i) => i); assertValueEquality(sortedArr5, [10, 6, 3, 1, 0, ()]); + assertValueEquality(sortedTup5, [10, 6, 3, 1, 0, ()]); int[] arr3 = []; + [int...] tup3 = []; int[] sortedArr6 = arr3.sort(array:DESCENDING, (i) => i); + int[] sortedTup6 = tup3.sort(array:DESCENDING, (i) => i); assertValueEquality(sortedArr6, []); + assertValueEquality(sortedTup6, []); +} + +function testSortNegative() { + [int, float] tup1 = [5, 7.3]; + [int|float, float] tup2 = [5, 7.3]; + [Grade, Student] tup3 = ["A", {id: 1, fname: "Amber", fee: 10000.56, impact: 0.127, isUndergrad: true}]; + [15|17, 15|17|21, 15|17|"hello"] tup4 = [15, 21, 17]; + anydata[][] items = [tup1, tup2, tup3, tup4]; + foreach anydata[] item in items { + any|error res = trap function:call(array:sort, item); + assertTrue(res is error); + if(res is error) { + assertValueEquality("{ballerina/lang.array}SortOperationError", res.message()); + assertValueEquality("Valid Key function needed", checkpanic res.detail()["message"]); + } + } } function testTupleReverse() { From 3921949e228014e180ff786f0abf5a218026d7c9 Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Thu, 15 Aug 2024 11:28:47 +0530 Subject: [PATCH 02/11] Remove unused methods --- .../ballerina/runtime/api/values/BArray.java | 5 +---- .../internal/values/TupleValueImpl.java | 19 ------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java index 5d786140dc9c..02d729122639 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java @@ -236,7 +236,4 @@ public interface BArray extends BRefValue, BCollection { void setLength(long i); long getLength(); -} - - - +} \ No newline at end of file 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 c1b7e3cfad45..b5fc11d92692 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 @@ -315,25 +315,6 @@ public void addRefValue(long index, Object value) { refValues[(int) index] = value; } - public boolean checkSortCompatibility(BArray arr, BFunctionPointer function, Set typeList, Integer[] orderedTypeList) { - Type memberType; - for(int i = 0; i < arr.getLength(); i++) { - memberType = TypeUtils.getReferredType(this.tupleType.getTupleTypes().get(i)); - if( memberType != this.tupleType.getTupleTypes().get(0) && function == null) { - return false; - } - typeList.add(memberType); - } - return (Arrays.stream(orderedTypeList).toList().contains(typeList.stream().toList().get(0).getTag()) && - typeList.size() == 1); - } - - public List getElementTypeList() { - List typeList = this.tupleType.getTupleTypes(); - typeList.add(this.tupleType.getRestType()); - return typeList; - } - public void convertStringAndAddRefValue(long index, BString value) { rangeCheck(index, size); int intIndex = (int) index; From 4a55addb5272da9dccbeefd2cbb0be654e20464c Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Thu, 15 Aug 2024 11:31:12 +0530 Subject: [PATCH 03/11] Add newline to EOF --- .../src/main/java/io/ballerina/runtime/api/values/BArray.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java index 02d729122639..efc1e70cb995 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BArray.java @@ -236,4 +236,4 @@ public interface BArray extends BRefValue, BCollection { void setLength(long i); long getLength(); -} \ No newline at end of file +} From f0a1e779b2a86bc778bec884c7906bcec6582596 Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Thu, 15 Aug 2024 11:43:33 +0530 Subject: [PATCH 04/11] Refactor code --- .../runtime/internal/values/TupleValueImpl.java | 15 ++++++++++++--- langlib/lang.array/src/main/java/module-info.java | 1 - 2 files changed, 12 insertions(+), 4 deletions(-) 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 b5fc11d92692..baf8b1029ff4 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 @@ -23,19 +23,28 @@ import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; -import io.ballerina.runtime.api.values.*; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BIterator; +import io.ballerina.runtime.api.values.BLink; +import io.ballerina.runtime.api.values.BListInitialValueEntry; +import io.ballerina.runtime.api.values.BRefValue; +import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.runtime.api.values.BValue; import io.ballerina.runtime.internal.CycleUtils; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.ValueConverter; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; -import io.ballerina.runtime.internal.types.BType; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; -import java.util.*; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; import java.util.stream.IntStream; import static io.ballerina.runtime.api.constants.RuntimeConstants.ARRAY_LANG_LIB; diff --git a/langlib/lang.array/src/main/java/module-info.java b/langlib/lang.array/src/main/java/module-info.java index 25c102fb02d0..627916960435 100644 --- a/langlib/lang.array/src/main/java/module-info.java +++ b/langlib/lang.array/src/main/java/module-info.java @@ -1,5 +1,4 @@ module io.ballerina.lang.array { requires io.ballerina.runtime; - requires io.ballerina.lang; exports org.ballerinalang.langlib.array; } From e0837715fa7ace3a67e0fa0e29cc6ae6a478f82f Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Thu, 15 Aug 2024 13:54:03 +0530 Subject: [PATCH 05/11] Fix checkstyle issue --- .../org/ballerinalang/langlib/array/Sort.java | 17 +++++++------- .../langlib/array/utils/SortUtils.java | 22 ++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java index 9473bb44b404..fe0f4feb327c 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java @@ -30,9 +30,10 @@ import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.internal.ValueComparisonUtils; import io.ballerina.runtime.internal.scheduling.Scheduler; -import io.ballerina.runtime.internal.types.*; +import io.ballerina.runtime.internal.types.BTupleType; -import java.util.*; +import java.util.HashSet; +import java.util.Set; import static io.ballerina.runtime.api.constants.RuntimeConstants.ARRAY_LANG_LIB; import static io.ballerina.runtime.internal.errors.ErrorReasons.INVALID_TYPE_TO_SORT; @@ -50,14 +51,14 @@ public static BArray sort(BArray arr, Object direction, Object func) { BArray sortedArray; BFunctionPointer function = (BFunctionPointer) func; Set typeList = new HashSet<>(); - if(arr.getType().getTag() == TypeTags.TUPLE_TAG) { - if(!isOrderedType(arr.getType()) && function == null) { + if (arr.getType().getTag() == TypeTags.TUPLE_TAG) { + if (!isOrderedType(arr.getType()) && function == null) { throw ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB, INVALID_TYPE_TO_SORT), StringUtils.fromString("Valid Key function needed")); } - typeList = new HashSet<>(((BTupleType)arr.getType()).getTupleTypes()); - if(((BTupleType)arr.getType()).getRestType() != null) { - typeList.add(((BTupleType)arr.getType()).getRestType()); + typeList = new HashSet<>(((BTupleType) arr.getType()).getTupleTypes()); + if (((BTupleType) arr.getType()).getRestType() != null) { + typeList.add(((BTupleType) arr.getType()).getRestType()); } } Object[][] sortArr = new Object[arr.size()][2]; @@ -73,7 +74,7 @@ public static BArray sort(BArray arr, Object direction, Object func) { } } mergesort(sortArr, sortArrClone, 0, sortArr.length - 1, direction.toString()); - if(arr.getType().getTag() == TypeTags.TUPLE_TAG) { + if (arr.getType().getTag() == TypeTags.TUPLE_TAG) { sortedArray = ValueCreator.createArrayValue(TypeCreator.createArrayType( TypeCreator.createUnionType(typeList.stream().toList()))); } else { diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java index 5c707e5f7bca..b67db20b69b4 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java @@ -29,7 +29,11 @@ import io.ballerina.runtime.internal.types.BFiniteType; import io.ballerina.runtime.internal.types.BTupleType; -import java.util.*; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; public class SortUtils { @@ -49,12 +53,12 @@ public static boolean isOrderedType(Type type) { // Union contains only the nil type. return true; } - if(!isOrderedType(firstTypeInUnion)) { + if (!isOrderedType(firstTypeInUnion)) { return false; } for (Type memType : memberTypes) { memType = TypeUtils.getImpliedType(memType); - if(!isOrderedType(memType) || isDifferentOrderedType(memType, firstTypeInUnion)) { + if (!isOrderedType(memType) || isDifferentOrderedType(memType, firstTypeInUnion)) { return false; } } @@ -63,8 +67,10 @@ public static boolean isOrderedType(Type type) { return isOrderedType(((BArrayType) type).getElementType()); case TypeTags.TUPLE_TAG: List tupleTypes = ((BTupleType) type).getTupleTypes(); - if (((BTupleType) type).getRestType() != null) tupleTypes.add(((BTupleType) type).getRestType()); - if(!isOrderedType(tupleTypes.get(0))) { + if (((BTupleType) type).getRestType() != null) { + tupleTypes.add(((BTupleType) type).getRestType()); + } + if (!isOrderedType(tupleTypes.get(0))) { return false; } for (Type memType : tupleTypes) { @@ -89,7 +95,7 @@ public static Type getTypeWithEffectiveIntersectionTypes(Type bType) { Type type = TypeUtils.getReferredType(bType); Type effectiveType = null; if (type.getTag() == TypeTags.INTERSECTION_TAG) { - effectiveType = ((IntersectionType)type).getEffectiveType(); + effectiveType = ((IntersectionType) type).getEffectiveType(); type = effectiveType; } @@ -122,7 +128,7 @@ public static boolean checkValueSpaceHasSameType(BFiniteType finiteType, Type ty TypeUtils.getType(finiteType.getValueSpace().iterator().next())); } for (Object expr : finiteType.getValueSpace()) { - if(isDifferentOrderedType(TypeUtils.getType(expr), baseType)) { + if (isDifferentOrderedType(TypeUtils.getType(expr), baseType)) { return false; } } @@ -135,7 +141,7 @@ public static boolean isDifferentOrderedType(Type source, Type target) { if (source.getTag() == TypeTags.NULL_TAG || target.getTag() == TypeTags.NULL_TAG) { return false; } - if(checkIfDifferent(source)) { + if (checkIfDifferent(source)) { return true; } return !TypeChecker.checkIsType(source, target); From bafd0e9b8d75122e570174d22d24ca67f57c87cb Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Tue, 20 Aug 2024 15:51:41 +0530 Subject: [PATCH 06/11] Refactor code and add additional tests --- .../org/ballerinalang/langlib/array/Sort.java | 2 +- .../langlib/array/utils/SortUtils.java | 52 +------------------ .../test/resources/test-src/arraylib_test.bal | 16 +++++- 3 files changed, 17 insertions(+), 53 deletions(-) diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java index fe0f4feb327c..9fd06104e25d 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java @@ -54,7 +54,7 @@ public static BArray sort(BArray arr, Object direction, Object func) { if (arr.getType().getTag() == TypeTags.TUPLE_TAG) { if (!isOrderedType(arr.getType()) && function == null) { throw ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB, INVALID_TYPE_TO_SORT), - StringUtils.fromString("Valid Key function needed")); + StringUtils.fromString("Valid key function required")); } typeList = new HashSet<>(((BTupleType) arr.getType()).getTupleTypes()); if (((BTupleType) arr.getType()).getRestType() != null) { diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java index b67db20b69b4..b75e23f38a63 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java @@ -19,8 +19,6 @@ package org.ballerinalang.langlib.array.utils; import io.ballerina.runtime.api.TypeTags; -import io.ballerina.runtime.api.creators.TypeCreator; -import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.TypeUtils; @@ -30,9 +28,7 @@ import io.ballerina.runtime.internal.types.BTupleType; import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Objects; import java.util.Set; public class SortUtils { @@ -46,9 +42,8 @@ public static boolean isOrderedType(Type type) { return true; } Set memberTypes = new HashSet<>(unionType.getMemberTypes()); - Type firstTypeInUnion = getTypeWithEffectiveIntersectionTypes(TypeUtils.getImpliedType( - memberTypes.stream().filter(m -> m.getTag() != TypeTags.NULL_TAG).findFirst(). - orElse(memberTypes.iterator().next()))); + Type firstTypeInUnion = TypeUtils.getImpliedType(memberTypes.stream().findFirst(). + orElse(memberTypes.iterator().next())); if (firstTypeInUnion.getTag() == TypeTags.NULL_TAG) { // Union contains only the nil type. return true; @@ -91,36 +86,6 @@ public static boolean isOrderedType(Type type) { } } - public static Type getTypeWithEffectiveIntersectionTypes(Type bType) { - Type type = TypeUtils.getReferredType(bType); - Type effectiveType = null; - if (type.getTag() == TypeTags.INTERSECTION_TAG) { - effectiveType = ((IntersectionType) type).getEffectiveType(); - type = effectiveType; - } - - if (type.getTag() != TypeTags.UNION_TAG) { - return Objects.requireNonNullElse(effectiveType, bType); - } - - LinkedHashSet members = new LinkedHashSet<>(); - boolean hasDifferentMember = false; - - for (Type memberType : ((UnionType) type).getMemberTypes()) { - effectiveType = getTypeWithEffectiveIntersectionTypes(memberType); - effectiveType = TypeUtils.getImpliedType(effectiveType); - if (effectiveType != memberType) { - hasDifferentMember = true; - } - members.add(effectiveType); - } - - if (hasDifferentMember) { - return TypeCreator.createUnionType(members.stream().toList()); - } - return bType; - } - public static boolean checkValueSpaceHasSameType(BFiniteType finiteType, Type type) { Type baseType = TypeUtils.getImpliedType(type); if (baseType.getTag() == TypeTags.FINITE_TYPE_TAG) { @@ -141,9 +106,6 @@ public static boolean isDifferentOrderedType(Type source, Type target) { if (source.getTag() == TypeTags.NULL_TAG || target.getTag() == TypeTags.NULL_TAG) { return false; } - if (checkIfDifferent(source)) { - return true; - } return !TypeChecker.checkIsType(source, target); } @@ -154,14 +116,4 @@ public static boolean isSimpleBasicType(int tag) { default -> tag >= TypeTags.INT_TAG && tag <= TypeTags.CHAR_STRING_TAG; }; } - - public static boolean checkIfDifferent(Type s) { - return switch (s.getTag()) { - case TypeTags.TYPE_REFERENCED_TYPE_TAG, TypeTags.ANY_TAG, TypeTags.ANYDATA_TAG, TypeTags.MAP_TAG, - TypeTags.FUTURE_TAG, TypeTags.XML_TAG, TypeTags.JSON_TAG, TypeTags.OBJECT_TYPE_TAG, - TypeTags.RECORD_TYPE_TAG, TypeTags.STREAM_TAG, TypeTags.TABLE_TAG, TypeTags.INVOKABLE_TAG, - TypeTags.ERROR_TAG -> true; - default -> false; - }; - } } 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 0a276f2c8e77..08a11fd2eb3b 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 @@ -1957,18 +1957,30 @@ function testSort10() { assertValueEquality(sortedTup6, []); } +type Grade2 1|15|"B"; +type Grade3 15|17|Grade3[]; +type Grade4 (Grade2|int)|Grade3; + function testSortNegative() { [int, float] tup1 = [5, 7.3]; [int|float, float] tup2 = [5, 7.3]; [Grade, Student] tup3 = ["A", {id: 1, fname: "Amber", fee: 10000.56, impact: 0.127, isUndergrad: true}]; [15|17, 15|17|21, 15|17|"hello"] tup4 = [15, 21, 17]; - anydata[][] items = [tup1, tup2, tup3, tup4]; + [int, Grade2] tup5 = [56, 1]; + [Student|int, int] tup6 = [{id: 1, fname: "Amber", fee: 10000.56, impact: 0.127, isUndergrad: true}, 7]; + [Grade3, int] tup7 = [17, 15]; + [Grade4, Grade3] tup8 = [1, 15]; + [(readonly & Person2 & Student2)|int, int] tup9 = [{id: 16158, name: "Arun", age: 12, average: 89.9, school: "JHC"}, 15]; + [((int|byte)|float), int] tup10 = [1, 15]; + [()|(), int] tup11 = [(),67]; + [json, json] tup12 = [{"abc":"defg"}, {"abc":"hello"}]; + anydata[][] items = [tup1, tup2, tup3, tup4, tup5, tup6, tup7, tup8, tup9, tup10, tup11, tup12]; foreach anydata[] item in items { any|error res = trap function:call(array:sort, item); assertTrue(res is error); if(res is error) { assertValueEquality("{ballerina/lang.array}SortOperationError", res.message()); - assertValueEquality("Valid Key function needed", checkpanic res.detail()["message"]); + assertValueEquality("Valid key function required", checkpanic res.detail()["message"]); } } } From a24620d966c835f29fd0f70ef2ca8ae260c92298 Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Tue, 20 Aug 2024 16:05:43 +0530 Subject: [PATCH 07/11] Remove unused TypePair class --- .../langlib/array/utils/TypePair.java | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java deleted file mode 100644 index 3b0b130c3cba..000000000000 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/TypePair.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2024, 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. - */ - -package org.ballerinalang.langlib.array.utils; - -import io.ballerina.runtime.api.types.Type; - -import java.util.Objects; - -public class TypePair { - Type sourceType; - Type targetType; - - public TypePair(Type sourceType, Type targetType) { - this.sourceType = sourceType; - this.targetType = targetType; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof TypePair other)) { - return false; - } - - return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType); - } - - @Override - public int hashCode() { - return Objects.hash(sourceType, targetType); - } -} From c5daaea654d92b306868ce09652d183a764da99f Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Fri, 23 Aug 2024 11:04:38 +0530 Subject: [PATCH 08/11] Add additional tests and refactor code --- .../org/ballerinalang/langlib/array/Sort.java | 21 +- .../langlib/array/utils/SortUtils.java | 27 ++ .../langlib/test/LangLibArrayTest.java | 1 + .../test/resources/test-src/arraylib_test.bal | 316 ++++++++---------- 4 files changed, 179 insertions(+), 186 deletions(-) diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java index 9fd06104e25d..8f6f9864b2b3 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java @@ -49,17 +49,12 @@ public class Sort { public static BArray sort(BArray arr, Object direction, Object func) { BArray sortedArray; + Type arrType = arr.getType(); BFunctionPointer function = (BFunctionPointer) func; - Set typeList = new HashSet<>(); - if (arr.getType().getTag() == TypeTags.TUPLE_TAG) { - if (!isOrderedType(arr.getType()) && function == null) { - throw ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB, INVALID_TYPE_TO_SORT), - StringUtils.fromString("Valid key function required")); - } - typeList = new HashSet<>(((BTupleType) arr.getType()).getTupleTypes()); - if (((BTupleType) arr.getType()).getRestType() != null) { - typeList.add(((BTupleType) arr.getType()).getRestType()); - } + // Check if the array type is an Ordered type, otherwise a key function is mandatory + if (!isOrderedType(arrType) && function == null) { + throw ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB, INVALID_TYPE_TO_SORT), + StringUtils.fromString("Valid key function required")); } Object[][] sortArr = new Object[arr.size()][2]; Object[][] sortArrClone = new Object[arr.size()][2]; @@ -74,7 +69,11 @@ public static BArray sort(BArray arr, Object direction, Object func) { } } mergesort(sortArr, sortArrClone, 0, sortArr.length - 1, direction.toString()); - if (arr.getType().getTag() == TypeTags.TUPLE_TAG) { + if (arrType.getTag() == TypeTags.TUPLE_TAG) { + Set typeList = new HashSet<>(((BTupleType) arrType).getTupleTypes()); + if (((BTupleType) arrType).getRestType() != null) { + typeList.add(((BTupleType) arrType).getRestType()); + } sortedArray = ValueCreator.createArrayValue(TypeCreator.createArrayType( TypeCreator.createUnionType(typeList.stream().toList()))); } else { diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java index b75e23f38a63..bbc4d101f09e 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java @@ -31,8 +31,18 @@ import java.util.List; import java.util.Set; +/** + * A utility class containing methods needed for the sort operation on tuples and arrays + * + * @since 2201.10.0 + */ public class SortUtils { + /** + * Check if the provided type is an Ordered type. + * @param type type to be checked. + * @return true if type is Ordered, false otherwise. + */ public static boolean isOrderedType(Type type) { type = TypeUtils.getImpliedType(type); switch (type.getTag()) { @@ -86,6 +96,12 @@ public static boolean isOrderedType(Type type) { } } + /** + * Check if the values space of the provided finite type belongs to the value space of the given type + * @param finiteType finite type to be checked. + * @param type type to be checked against. + * @return true if the finite type belongs to the same value space, false otherwise. + */ public static boolean checkValueSpaceHasSameType(BFiniteType finiteType, Type type) { Type baseType = TypeUtils.getImpliedType(type); if (baseType.getTag() == TypeTags.FINITE_TYPE_TAG) { @@ -100,6 +116,12 @@ public static boolean checkValueSpaceHasSameType(BFiniteType finiteType, Type ty return true; } + /** + * Check whether a given type is different to a target type. + * @param source type to check. + * @param target type to compare with. + * @return true if the source type does not belong to the target type, false otherwise. + */ public static boolean isDifferentOrderedType(Type source, Type target) { source = TypeUtils.getImpliedType(source); target = TypeUtils.getImpliedType(target); @@ -109,6 +131,11 @@ public static boolean isDifferentOrderedType(Type source, Type target) { return !TypeChecker.checkIsType(source, target); } + /** + * Check whether the given type tag belongs to a simple basic type. + * @param tag type tag to check. + * @return true if the tag belongs to a simple basic type, false otherwise. + */ public static boolean isSimpleBasicType(int tag) { return switch (tag) { case TypeTags.BYTE_TAG, TypeTags.FLOAT_TAG, TypeTags.DECIMAL_TAG, TypeTags.BOOLEAN_TAG, TypeTags.NULL_TAG -> 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 4d45141c2969..2f9335e8127a 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 @@ -563,6 +563,7 @@ public Object[] testFunctions() { "testSort8", "testSort9", "testSort10", + "testSort11", "testSortNegative", "testReadOnlyArrayFilter", "testTupleFilter", 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 08a11fd2eb3b..e460ef601899 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 @@ -988,28 +988,18 @@ function testSort1() { return s.id; }); - assertValueEquality(sortedArr[0].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); - assertValueEquality(sortedArr[1].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedArr[2].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedArr[3].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedArr[4].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertValueEquality(sortedArr[0], studentArr[1]); + assertValueEquality(sortedArr[1], studentArr[3]); + assertValueEquality(sortedArr[2], studentArr[4]); + assertValueEquality(sortedArr[3], studentArr[2]); + assertValueEquality(sortedArr[4], studentArr[0]); assertFalse(studentArr == sortedArr); - assertValueEquality(sortedTup[0].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); - assertValueEquality(sortedTup[1].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedTup[2].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedTup[3].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedTup[4].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); + assertValueEquality(sortedTup[0], studentTup[1]); + assertValueEquality(sortedTup[1], studentTup[3]); + assertValueEquality(sortedTup[2], studentTup[4]); + assertValueEquality(sortedTup[3], studentTup[2]); + assertValueEquality(sortedTup[4], studentTup[0]); assertFalse(studentArr == sortedTup); Student[] sortedArr2 = studentArr.sort(array:DESCENDING, isolated function(Student s) returns string? { @@ -1020,28 +1010,18 @@ function testSort1() { return s.fname; }); - assertValueEquality(sortedArr2[0].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedArr2[1].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedArr2[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedArr2[3].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedArr2[4].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedArr2[0], studentArr[3]); + assertValueEquality(sortedArr2[1], studentArr[4]); + assertValueEquality(sortedArr2[2], studentArr[2]); + assertValueEquality(sortedArr2[3], studentArr[0]); + assertValueEquality(sortedArr2[4], studentArr[1]); assertFalse(studentArr == sortedArr2); - assertValueEquality(sortedTup2[0].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedTup2[1].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedTup2[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedTup2[3].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedTup2[4].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedTup2[0], studentTup[3]); + assertValueEquality(sortedTup2[1], studentTup[4]); + assertValueEquality(sortedTup2[2], studentTup[2]); + assertValueEquality(sortedTup2[3], studentTup[0]); + assertValueEquality(sortedTup2[4], studentTup[1]); assertFalse(studentArr == sortedArr2); Student[] sortedArr3 = studentArr.sort(array:ASCENDING, isolated function(Student s) returns float? { @@ -1052,27 +1032,17 @@ function testSort1() { return s.fee; }); - assertValueEquality(sortedArr3[0].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); - assertValueEquality(sortedArr3[1].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedArr3[2].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedArr3[3].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedArr3[4].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - - assertValueEquality(sortedTup3[0].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); - assertValueEquality(sortedTup3[1].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedTup3[2].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedTup3[3].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedTup3[4].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedArr3[0], studentArr[1]); + assertValueEquality(sortedArr3[1], studentArr[4]); + assertValueEquality(sortedArr3[2], studentArr[0]); + assertValueEquality(sortedArr3[3], studentArr[3]); + assertValueEquality(sortedArr3[4], studentArr[2]); + + assertValueEquality(sortedTup3[0], studentTup[1]); + assertValueEquality(sortedTup3[1], studentTup[4]); + assertValueEquality(sortedTup3[2], studentTup[0]); + assertValueEquality(sortedTup3[3], studentTup[3]); + assertValueEquality(sortedTup3[4], studentTup[2]); Student[] sortedArr4 = studentArr.sort(array:ASCENDING, isolated function(Student s) returns decimal { return s.impact; @@ -1082,42 +1052,27 @@ function testSort1() { return s.impact; }); - assertValueEquality(sortedArr4[0].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedArr4[1].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedArr4[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedArr4[3].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedArr4[4].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); - - assertValueEquality(sortedTup4[0].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedTup4[1].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedTup4[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedTup4[3].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedTup4[4].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedArr4[0], studentArr[0]); + assertValueEquality(sortedArr4[1], studentArr[3]); + assertValueEquality(sortedArr4[2], studentArr[2]); + assertValueEquality(sortedArr4[3], studentArr[4]); + assertValueEquality(sortedArr4[4], studentArr[1]); + + assertValueEquality(sortedTup4[0], studentTup[0]); + assertValueEquality(sortedTup4[1], studentTup[3]); + assertValueEquality(sortedTup4[2], studentTup[2]); + assertValueEquality(sortedTup4[3], studentTup[4]); + assertValueEquality(sortedTup4[4], studentTup[1]); Student[] sortedArr5 = sortedArr4.sort(array:ASCENDING, isolated function(Student s) returns boolean { return s.isUndergrad; }); - assertValueEquality(sortedArr5[0].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedArr5[1].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedArr5[2].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); - assertValueEquality(sortedArr5[3].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedArr5[4].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); + assertValueEquality(sortedArr5[0], studentArr[3]); + assertValueEquality(sortedArr5[1], studentArr[4]); + assertValueEquality(sortedArr5[2], studentArr[1]); + assertValueEquality(sortedArr5[3], studentArr[0]); + assertValueEquality(sortedArr5[4], studentArr[2]); assertFalse(sortedArr4 == sortedArr5); assertValueEquality(getStudentList(), studentArr); // no change to original array @@ -1268,16 +1223,16 @@ function testSort4() { return [val[1], 5.2]; }); - assertValueEquality(sortedArr[0].toString(), "[\"C\",2]"); - assertValueEquality(sortedArr[1].toString(), "[\"A+\",2]"); - assertValueEquality(sortedArr[2].toString(), "[\"A-\",3]"); - assertValueEquality(sortedArr[3].toString(), "[\"B\",3]"); + assertValueEquality(sortedArr[0], grades[3]); + assertValueEquality(sortedArr[1], grades[0]); + assertValueEquality(sortedArr[2], grades[1]); + assertValueEquality(sortedArr[3], grades[2]); assertValueEquality([["A+", 2], ["A-", 3], ["B", 3], ["C", 2]], grades); // no change to original array - assertValueEquality(sortedTup[0].toString(), "[\"C\",2]"); - assertValueEquality(sortedTup[1].toString(), "[\"A+\",2]"); - assertValueEquality(sortedTup[2].toString(), "[\"A-\",3]"); - assertValueEquality(sortedTup[3].toString(), "[\"B\",3]"); + assertValueEquality(sortedTup[0], gradesTup[3]); + assertValueEquality(sortedTup[1], gradesTup[0]); + assertValueEquality(sortedTup[2], gradesTup[1]); + assertValueEquality(sortedTup[3], gradesTup[2]); assertValueEquality([["A+", 2], ["A-", 3], ["B", 3], ["C", 2]], gradesTup); // no change to original array } @@ -1293,28 +1248,18 @@ function testSort5() { return getFullName(s.id, s.fname); }); - assertValueEquality(sortedArr[0].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedArr[1].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedArr[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedArr[3].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedArr[4].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedArr[0], studentArr[4]); + assertValueEquality(sortedArr[1], studentArr[3]); + assertValueEquality(sortedArr[2], studentArr[2]); + assertValueEquality(sortedArr[3], studentArr[0]); + assertValueEquality(sortedArr[4], studentArr[1]); assertValueEquality(getStudentList(), studentArr); // no change to original array - assertValueEquality(sortedTup[0].toString(), - "{\"id\":3,\"fname\":\"Kate\",\"fee\":5000.56,\"impact\":0.4,\"isUndergrad\":false}"); - assertValueEquality(sortedTup[1].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); - assertValueEquality(sortedTup[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedTup[3].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedTup[4].toString(), - "{\"id\":20,\"fname\":null,\"fee\":2000.56,\"impact\":0.45,\"isUndergrad\":false}"); + assertValueEquality(sortedTup[0], studentTup[4]); + assertValueEquality(sortedTup[1], studentTup[3]); + assertValueEquality(sortedTup[2], studentTup[2]); + assertValueEquality(sortedTup[3], studentTup[0]); + assertValueEquality(sortedTup[4], studentTup[1]); assertValueEquality(getStudentListForTuples(), studentTup); // no change to original array } @@ -1360,22 +1305,22 @@ function testSort6() { return (); }); - assertValueEquality(sortedArr.toString(), - "[{\"k\":\"Bar\"},true,1,2.0,3,12.09,32,90,100,\"AA\",[\"BB\",true]]"); + assertValueEquality(sortedArr, + [>{"k": "Bar"},true,1,2.0,3,12.09,32,90,100,"AA",["BB",true]]); assertValueEquality([90, 2.0, 1, true, 32, "AA", 12.09, 100, 3, >{"k": "Bar"}, ["BB", true]], arr); - assertValueEquality(sortedTup.toString(), - "[{\"k\":\"Bar\"},true,1,2.0,3,12.09,32,90,100,\"AA\",[\"BB\",true]]"); + assertValueEquality(sortedTup, + [>{"k": "Bar"},true,1,2.0,3,12.09,32,90,100,"AA",["BB",true]]); assertValueEquality([90, 2.0, 1, true, 32, "AA", 12.09, 100, 3, >{"k": "Bar"}, ["BB", true]], tup); string?[] arr2 = ["Hello", "World!", (), "from", "Ballerina"]; [(string?)...] tup2 = ["Hello", "World!", (), "from", "Ballerina"]; string?[] sortedArr2 = arr2.sort(); - assertValueEquality(sortedArr2.toString(), "[\"Ballerina\",\"Hello\",\"World!\",\"from\",null]"); + assertValueEquality(sortedArr2, ["Ballerina","Hello","World!","from",null]); string?[] sortedTup2 = tup2.sort(); - assertValueEquality(sortedTup2.toString(), "[\"Ballerina\",\"Hello\",\"World!\",\"from\",null]"); + assertValueEquality(sortedTup2, ["Ballerina","Hello","World!","from",null]); Obj obj1 = new Obj(1, 1); Obj obj2 = new Obj(1, 2); @@ -1410,16 +1355,16 @@ function testSort6() { return i; }); - assertValueEquality(sortedArr4.toString(), "[0,1,3,7,9,21]"); - assertValueEquality(sortedTup4.toString(), "[0,1,3,7,9,21]"); + assertValueEquality(sortedArr4, [0,1,3,7,9,21]); + assertValueEquality(sortedTup4, [0,1,3,7,9,21]); int[] arr5 = [2, 0, 12, 1, 23, 3, 100, 55]; [int...] tup5 = [2, 0, 12, 1, 23, 3, 100, 55]; int[] sortedArr5 = arr5.sort(array:DESCENDING); int[] sortedTup5 = tup5.sort(array:DESCENDING); - assertValueEquality(sortedArr5.toString(), "[100,55,23,12,3,2,1,0]"); - assertValueEquality(sortedTup5.toString(), "[100,55,23,12,3,2,1,0]"); + assertValueEquality(sortedArr5, [100,55,23,12,3,2,1,0]); + assertValueEquality(sortedTup5, [100,55,23,12,3,2,1,0]); string?[] sortedArr6 = arr2.sort(array:DESCENDING, isolated function(string? s) returns string?[]? { if (s is string) { @@ -1435,8 +1380,8 @@ function testSort6() { return (); }); - assertValueEquality(sortedArr6.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); - assertValueEquality(sortedTup6.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); + assertValueEquality(sortedArr6, ["from","World!","Hello","Ballerina",null]); + assertValueEquality(sortedTup6, ["from","World!","Hello","Ballerina",null]); string?[] sortedArr7 = arr2.sort(array:ASCENDING, isolated function(string? s) returns string?[] { if (s is string) { @@ -1452,13 +1397,13 @@ function testSort6() { return ["W", "A"]; }); - assertValueEquality(sortedArr7.toString(), "[\"Ballerina\",\"Hello\",null,\"World!\",\"from\"]"); - assertValueEquality(sortedTup7.toString(), "[\"Ballerina\",\"Hello\",null,\"World!\",\"from\"]"); + assertValueEquality(sortedArr7, ["Ballerina","Hello",null,"World!","from"]); + assertValueEquality(sortedTup7, ["Ballerina","Hello",null,"World!","from"]); int[] sortedArr8 = arr5.sort(array:ASCENDING, ()); int[] sortedTup8 = tup5.sort(array:ASCENDING, ()); - assertValueEquality(sortedArr8.toString(), "[0,1,2,3,12,23,55,100]"); - assertValueEquality(sortedTup8.toString(), "[0,1,2,3,12,23,55,100]"); + assertValueEquality(sortedArr8, [0,1,2,3,12,23,55,100]); + assertValueEquality(sortedTup8, [0,1,2,3,12,23,55,100]); Grade[] arr6 = ["A+", "B+", "C", "F", "A-", "C", "A+", "B"]; [Grade...] tup6 = ["A+", "B+", "C", "F", "A-", "C", "A+", "B"]; @@ -1471,9 +1416,9 @@ function testSort6() { return grade; }); - assertValueEquality(sortedArr9.toString(), "[\"F\",\"C\",\"C\",\"B+\",\"B\",\"A-\",\"A+\",\"A+\"]"); + assertValueEquality(sortedArr9, ["F","C","C","B+","B","A-","A+","A+"]); assertValueEquality(["A+", "B+", "C", "F", "A-", "C", "A+", "B"], arr6); // no change to arr6 - assertValueEquality(sortedTup9.toString(), "[\"F\",\"C\",\"C\",\"B+\",\"B\",\"A-\",\"A+\",\"A+\"]"); + assertValueEquality(sortedTup9, ["F","C","C","B+","B","A-","A+","A+"]); assertValueEquality(["A+", "B+", "C", "F", "A-", "C", "A+", "B"], arr6); // no change to tup6 Student s1 = {id: 1, fname: "Amber", fee: 10000.56, impact: 0.127, isUndergrad: true}; @@ -1499,35 +1444,29 @@ function testSort6() { } }); - assertValueEquality(sortedArr10[0].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedArr10[1].toString(), "Anne"); - assertValueEquality(sortedArr10[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedArr10[3].toString(), "Frank"); - assertValueEquality(sortedArr10[4].toString(), "James"); - assertValueEquality(sortedArr10[5].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(sortedArr10[0], s1); + assertValueEquality(sortedArr10[1], "Anne"); + assertValueEquality(sortedArr10[2], s2); + assertValueEquality(sortedArr10[3], "Frank"); + assertValueEquality(sortedArr10[4], "James"); + assertValueEquality(sortedArr10[5], s3); assertValueEquality(["Anne", s3, s1, "James", "Frank", s2], arr7); // no change to arr7 - assertValueEquality(sortedTup10[0].toString(), - "{\"id\":1,\"fname\":\"Amber\",\"fee\":10000.56,\"impact\":0.127,\"isUndergrad\":true}"); - assertValueEquality(sortedTup10[1].toString(), "Anne"); - assertValueEquality(sortedTup10[2].toString(), - "{\"id\":2,\"fname\":\"Dan\",\"fee\":null,\"impact\":0.3,\"isUndergrad\":true}"); - assertValueEquality(sortedTup10[3].toString(), "Frank"); - assertValueEquality(sortedTup10[4].toString(), "James"); - assertValueEquality(sortedTup10[5].toString(), - "{\"id\":10,\"fname\":\"Kate\",\"fee\":NaN,\"impact\":0.146,\"isUndergrad\":false}"); + assertValueEquality(sortedTup10[0], s1); + assertValueEquality(sortedTup10[1], "Anne"); + assertValueEquality(sortedTup10[2], s2); + assertValueEquality(sortedTup10[3], "Frank"); + assertValueEquality(sortedTup10[4], "James"); + assertValueEquality(sortedTup10[5], s3); assertValueEquality(["Anne", s3, s1, "James", "Frank", s2], tup7); // no change to tup7 int[] sortedArr11 = array:sort(arr5); [int...] sortedTup11 = array:sort(tup5); - assertValueEquality(sortedArr11.toString(), "[0,1,2,3,12,23,55,100]"); + assertValueEquality(sortedArr11, [0,1,2,3,12,23,55,100]); assertValueEquality([2, 0, 12, 1, 23, 3, 100, 55], arr5); // no change to arr5 assertValueEquality([0, 1, 2, 3, 12, 23, 55, 100], sortedArr8); // no change to sortedArr8 - assertValueEquality(sortedTup11.toString(), "[0,1,2,3,12,23,55,100]"); + assertValueEquality(sortedTup11, [0,1,2,3,12,23,55,100]); assertValueEquality([2, 0, 12, 1, 23, 3, 100, 55], tup5); // no change to tup5 assertValueEquality([0, 1, 2, 3, 12, 23, 55, 100], sortedTup8); // no change to sortedTup8 @@ -1539,16 +1478,16 @@ function testSort6() { return i; }); - assertValueEquality(sortedArr12.toString(), "[21,9,7,3,1,0]"); + assertValueEquality(sortedArr12, [21,9,7,3,1,0]); assertValueEquality([1, 9, 3, 21, 0, 7], arr4); // no change to arr4 - assertValueEquality(sortedTup12.toString(), "[21,9,7,3,1,0]"); + assertValueEquality(sortedTup12, [21,9,7,3,1,0]); assertValueEquality([1, 9, 3, 21, 0, 7], tup4); // no change to tup4 string?[] sortedArr13 = array:sort(arr2, array:DESCENDING); string?[] sortedTup13 = array:sort(tup2, array:DESCENDING); - assertValueEquality(sortedArr13.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); - assertValueEquality(sortedTup13.toString(), "[\"from\",\"World!\",\"Hello\",\"Ballerina\",null]"); + assertValueEquality(sortedArr13, ["from", "World!", "Hello", "Ballerina", null]); + assertValueEquality(sortedTup13, ["from", "World!", "Hello", "Ballerina", null]); } function testSort7() { @@ -1755,18 +1694,16 @@ function testSort9() { strings:Char[] sortedArr = arr.sort(array:DESCENDING); strings:Char[] sortedTup = tup.sort(array:DESCENDING); - assertValueEquality(sortedArr.toString(), "[\"s\",\"b\",\"a\",\"Z\",\"M\"]"); - assertValueEquality(sortedTup.toString(), "[\"s\",\"b\",\"a\",\"Z\",\"M\"]"); + assertValueEquality(sortedArr, ["s","b","a","Z","M"]); + assertValueEquality(sortedTup, ["s","b","a","Z","M"]); int[] arr2 = [4294967295, 4194967295, 4294967290, 4284967295, 3294967295, 1294967295]; [int...] tup2 = [4294967295, 4194967295, 4294967290, 4284967295, 3294967295, 1294967295]; int[] sortedArr2 = arr2.sort(); int[] sortedTup2 = tup2.sort(); - assertValueEquality(sortedArr2.toString(), - "[1294967295,3294967295,4194967295,4284967295,4294967290,4294967295]"); - assertValueEquality(sortedTup2.toString(), - "[1294967295,3294967295,4194967295,4284967295,4294967290,4294967295]"); + assertValueEquality(sortedArr2, [1294967295,3294967295,4194967295,4284967295,4294967290,4294967295]); + assertValueEquality(sortedTup2, [1294967295,3294967295,4194967295,4284967295,4294967290,4294967295]); ints:Signed32[] arr3 = [2147483647, -2147483648, 2147483637, -1147483648, -2137483648, 1147483647]; [ints:Signed32...] tup3 = [2147483647, -2147483648, 2147483637, -1147483648, -2137483648, 1147483647]; @@ -1859,7 +1796,7 @@ function testSort9() { [ints:Unsigned16...] tup7 = [450, 65335, 0, 12, 65535, 12500, 4]; ints:Unsigned16[] sortedArr7 = arr7.sort(array:DESCENDING); - ints:Unsigned16[] sortedTup7 = arr7.sort(array:DESCENDING); + ints:Unsigned16[] sortedTup7 = tup7.sort(array:DESCENDING); assertValueEquality(sortedArr7[0], 65535); assertValueEquality(sortedArr7[1], 65335); @@ -1907,8 +1844,8 @@ function testSort10() { int[] sortedArr = arr.sort(array:ASCENDING, (i) => i); int[] sortedTup = tup.sort(array:ASCENDING, (i) => i); - assertValueEquality(sortedArr.toString(), "[0,1,2,3,6,10]"); - assertValueEquality(sortedTup.toString(), "[0,1,2,3,6,10]"); + assertValueEquality(sortedArr, [0,1,2,3,6,10]); + assertValueEquality(sortedTup, [0,1,2,3,6,10]); final int methodInt1 = 2; var addFunc1 = isolated function(int funcInt1) returns (int) { @@ -1924,14 +1861,14 @@ function testSort10() { int[] sortedArr2 = arr.sort(array:DESCENDING, addFunc1); int[] sortedTup2 = tup.sort(array:DESCENDING, addFunc1); - assertValueEquality(sortedArr2.toString(), "[10,6,3,2,1,0]"); - assertValueEquality(sortedTup2.toString(), "[10,6,3,2,1,0]"); + assertValueEquality(sortedArr2, [10,6,3,2,1,0]); + assertValueEquality(sortedTup2, [10,6,3,2,1,0]); int[] sortedArr3 = array:sort(arr, array:ASCENDING, isolated function(int x) returns string[] => [x.toString(), "World"]); int[] sortedTup3 = array:sort(tup, array:ASCENDING, isolated function(int x) returns string[] => [x.toString(), "World"]); - assertValueEquality(sortedArr3.toString(), "[0,1,10,2,3,6]"); - assertValueEquality(sortedTup3.toString(), "[0,1,10,2,3,6]"); + assertValueEquality(sortedArr3, [0,1,10,2,3,6]); + assertValueEquality(sortedTup3, [0,1,10,2,3,6]); int[] sortedArr4 = arr.sort(array:DESCENDING, (i) => i.toString()); int[] sortedTup4 = tup.sort(array:DESCENDING, (i) => i.toString()); @@ -1961,6 +1898,35 @@ type Grade2 1|15|"B"; type Grade3 15|17|Grade3[]; type Grade4 (Grade2|int)|Grade3; +function testSort11() { + var keyFunc = isolated function((int|float|string|boolean) x) returns int { + if x is int { + return x; + } else if x is float { + return x; + }else if x is boolean{ + return 0; + }else { + return 100; + } + }; + + [int, float, string] tup1 = [7, 2.4, "Hello"]; + [int|float, float] tup2 = [89, 9.7]; + [boolean, string...] tup3 = [false, "Hello", "World"]; + [Grade2, Grade2, string, int...] tup4 = [1, 15, "Hello", 76, 89]; + + (int|float|string)[] sortedTup1 = tup1.sort("ascending", keyFunc); + (int|float)[] sortedTup2 = tup2.sort("descending", keyFunc); + (boolean|string)[] sortedTup3 = tup3.sort("descending", keyFunc); + (int|string)[] sortedTup4 = tup4.sort("descending", keyFunc); + + assertValueEquality(sortedTup1, [2.4, 7, "Hello"]); + assertValueEquality(sortedTup2, [89, 9.7]); + assertValueEquality(sortedTup3, ["Hello", "World", false]); + assertValueEquality(sortedTup4, ["Hello", 89, 76, 15, 1]); +} + function testSortNegative() { [int, float] tup1 = [5, 7.3]; [int|float, float] tup2 = [5, 7.3]; From d438418aeadc77ac1206e9bfc83daaf5f582a65a Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Fri, 23 Aug 2024 15:26:47 +0530 Subject: [PATCH 09/11] Fix checkstyle issue --- .../java/org/ballerinalang/langlib/array/utils/SortUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java index bbc4d101f09e..1d8afe63f8a3 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java @@ -32,7 +32,7 @@ import java.util.Set; /** - * A utility class containing methods needed for the sort operation on tuples and arrays + * A utility class containing methods needed for the sort operation on tuples and arrays. * * @since 2201.10.0 */ @@ -97,7 +97,7 @@ public static boolean isOrderedType(Type type) { } /** - * Check if the values space of the provided finite type belongs to the value space of the given type + * Check if the values space of the provided finite type belongs to the value space of the given type. * @param finiteType finite type to be checked. * @param type type to be checked against. * @return true if the finite type belongs to the same value space, false otherwise. From 5f118b816390f07e4e19f2f677907234a7348a78 Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Thu, 5 Sep 2024 11:29:35 +0530 Subject: [PATCH 10/11] Add suggestions from code review --- .../org/ballerinalang/langlib/array/Sort.java | 7 ++++--- .../langlib/array/utils/SortUtils.java | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java index 8f6f9864b2b3..2f80505d75f8 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java @@ -70,9 +70,10 @@ public static BArray sort(BArray arr, Object direction, Object func) { } mergesort(sortArr, sortArrClone, 0, sortArr.length - 1, direction.toString()); if (arrType.getTag() == TypeTags.TUPLE_TAG) { - Set typeList = new HashSet<>(((BTupleType) arrType).getTupleTypes()); - if (((BTupleType) arrType).getRestType() != null) { - typeList.add(((BTupleType) arrType).getRestType()); + BTupleType tupleType = (BTupleType) arrType; + Set typeList = new HashSet<>(tupleType.getTupleTypes()); + if (tupleType.getRestType() != null) { + typeList.add(tupleType.getRestType()); } sortedArray = ValueCreator.createArrayValue(TypeCreator.createArrayType( TypeCreator.createUnionType(typeList.stream().toList()))); diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java index 1d8afe63f8a3..ac9b74eadb50 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java @@ -38,6 +38,11 @@ */ public class SortUtils { + /** + * A private constructor to avoid code coverage warnings. + */ + private SortUtils() {}; + /** * Check if the provided type is an Ordered type. * @param type type to be checked. @@ -71,9 +76,10 @@ public static boolean isOrderedType(Type type) { case TypeTags.ARRAY_TAG: return isOrderedType(((BArrayType) type).getElementType()); case TypeTags.TUPLE_TAG: - List tupleTypes = ((BTupleType) type).getTupleTypes(); - if (((BTupleType) type).getRestType() != null) { - tupleTypes.add(((BTupleType) type).getRestType()); + BTupleType tupleType = (BTupleType) type; + List tupleTypes = tupleType.getTupleTypes(); + if (tupleType.getRestType() != null) { + tupleTypes.add(tupleType.getRestType()); } if (!isOrderedType(tupleTypes.get(0))) { return false; @@ -85,9 +91,10 @@ public static boolean isOrderedType(Type type) { } return true; case TypeTags.FINITE_TYPE_TAG: - Set valSpace = ((BFiniteType) type).getValueSpace(); + BFiniteType finiteType = (BFiniteType) type; + Set valSpace = finiteType.getValueSpace(); Type baseExprType = TypeUtils.getType(valSpace.iterator().next()); - if (!checkValueSpaceHasSameType((BFiniteType) type, baseExprType)) { + if (!checkValueSpaceHasSameType(finiteType, baseExprType)) { return false; } return isOrderedType(baseExprType); @@ -97,7 +104,7 @@ public static boolean isOrderedType(Type type) { } /** - * Check if the values space of the provided finite type belongs to the value space of the given type. + * Check if the value space of the provided finite type belongs to the value space of the given type. * @param finiteType finite type to be checked. * @param type type to be checked against. * @return true if the finite type belongs to the same value space, false otherwise. From 47f707437372939e6864383c24e81e2afb5f2500 Mon Sep 17 00:00:00 2001 From: ravinperera00 Date: Thu, 26 Sep 2024 15:35:55 +0530 Subject: [PATCH 11/11] Add suggestions from code review --- .../src/main/java/org/ballerinalang/langlib/array/Sort.java | 2 +- .../java/org/ballerinalang/langlib/array/utils/SortUtils.java | 2 +- .../langlib-test/src/test/resources/test-src/arraylib_test.bal | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java index 2f80505d75f8..f1191a84b226 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Sort.java @@ -54,7 +54,7 @@ public static BArray sort(BArray arr, Object direction, Object func) { // Check if the array type is an Ordered type, otherwise a key function is mandatory if (!isOrderedType(arrType) && function == null) { throw ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB, INVALID_TYPE_TO_SORT), - StringUtils.fromString("Valid key function required")); + StringUtils.fromString("valid key function required")); } Object[][] sortArr = new Object[arr.size()][2]; Object[][] sortArrClone = new Object[arr.size()][2]; diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java index ac9b74eadb50..daf1ec39a765 100644 --- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java +++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/SortUtils.java @@ -34,7 +34,7 @@ /** * A utility class containing methods needed for the sort operation on tuples and arrays. * - * @since 2201.10.0 + * @since 2201.11.0 */ public class SortUtils { 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 e460ef601899..01e0d094abaa 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 @@ -1946,7 +1946,7 @@ function testSortNegative() { assertTrue(res is error); if(res is error) { assertValueEquality("{ballerina/lang.array}SortOperationError", res.message()); - assertValueEquality("Valid key function required", checkpanic res.detail()["message"]); + assertValueEquality("valid key function required", checkpanic res.detail()["message"]); } } }