From 3bde69dfcb23dd381eb25a256cb16aab10a336ee Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Tue, 25 Jun 2019 15:16:52 +0530 Subject: [PATCH 1/5] Fix and enable typecast tests --- .../main/resources/MessagesBundle.properties | 4 +- .../resources/MessagesBundle_en_US.properties | 4 +- .../ballerinalang/jvm/BallerinaErrors.java | 9 +- .../org/ballerinalang/jvm/TypeChecker.java | 74 +++++++- .../org/ballerinalang/jvm/TypeConverter.java | 171 ++++++++++++++---- .../jvm/values/DecimalValue.java | 25 +-- .../compiler_backend_jvm/jvm_cast_gen.bal | 44 ++--- .../compiler_backend_jvm/jvm_type_gen.bal | 4 + .../bir/src/main/ballerina/bir/bir_model.bal | 8 +- .../src/main/ballerina/bir/bir_pkg_parser.bal | 3 +- .../src/main/ballerina/bir/type_parser.bal | 8 +- .../utils/SimpleValueConvert.java | 5 +- .../typecast/NumericConversionTest.java | 8 +- .../typecast/NumericConversionTest.java | 21 +-- .../typecast/TypeCastExprTest.java | 11 +- .../typecast/TypeCastExpressionsTest.java | 2 +- .../typecast/numeric_conversion.bal | 128 ++++++------- .../expressions/typecast/type-casting.bal | 4 +- .../expressions/typecast/type_cast_expr.bal | 28 +-- .../src/test/resources/testng.xml | 1 + 20 files changed, 360 insertions(+), 202 deletions(-) diff --git a/bvm/ballerina-core/src/main/resources/MessagesBundle.properties b/bvm/ballerina-core/src/main/resources/MessagesBundle.properties index 68b934a4fc33..3b5a8987fd1d 100644 --- a/bvm/ballerina-core/src/main/resources/MessagesBundle.properties +++ b/bvm/ballerina-core/src/main/resources/MessagesBundle.properties @@ -152,8 +152,8 @@ illegal.format.conversion = illegal format conversion ''{0}'' incompatible.stamp.operation = incompatible stamp operation: ''{0}'' value cannot be stamped as ''{1}'' cannot.stamp.null = cannot stamp ''null'' value to type ''{0}'' cannot.convert.null = cannot convert ''null'' value to type ''{0}'' -incompatible.convert.operation = incompatible convert operation: ''{0}'' value cannot be converted as ''{1}'' -incompatible.simple.type.convert.operation = incompatible convert operation: ''{0}'' value ''{1}'' cannot be converted as ''{2}'' +incompatible.convert.operation = ''{0}'' value cannot be converted to ''{1}'' +incompatible.simple.type.convert.operation = ''{0}'' value ''{1}'' cannot be converted to ''{2}'' unsupported.clone.operation = ''clone()'' not allowed on ''{0}'' invalid.record.field.access = invalid field access: field ''{0}'' not found in record type ''{1}'' invalid.record.field.addition = invalid value for record field ''{0}'': expected value of type ''{1}'', found ''{2}'' diff --git a/bvm/ballerina-core/src/main/resources/MessagesBundle_en_US.properties b/bvm/ballerina-core/src/main/resources/MessagesBundle_en_US.properties index 3f1a6803c453..dbfec157fcb9 100644 --- a/bvm/ballerina-core/src/main/resources/MessagesBundle_en_US.properties +++ b/bvm/ballerina-core/src/main/resources/MessagesBundle_en_US.properties @@ -149,8 +149,8 @@ illegal.format.conversion = illegal format conversion ''{0}'' incompatible.stamp.operation = incompatible stamp operation: ''{0}'' value cannot be stamped as ''{1}'' cannot.stamp.null = cannot stamp ''null'' value to type ''{0}'' cannot.convert.null = cannot convert ''null'' value to type ''{0}'' -incompatible.convert.operation = incompatible convert operation: ''{0}'' value cannot be converted as ''{1}'' -incompatible.simple.type.convert.operation = incompatible convert operation: ''{0}'' value ''{1}'' cannot be converted as ''{2}'' +incompatible.convert.operation = ''{0}'' value cannot be converted to ''{1}'' +incompatible.simple.type.convert.operation = ''{0}'' value ''{1}'' cannot be converted to ''{2}'' unsupported.clone.operation = ''clone()'' not allowed on ''{0}'' invalid.record.field.access = invalid field access: field ''{0}'' not found in record type ''{1}'' invalid.record.field.addition = invalid value for record field ''{0}'': expected value of type ''{1}'', found ''{2}'' diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaErrors.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaErrors.java index 98da255e49b5..0f2d30c04f4f 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaErrors.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/BallerinaErrors.java @@ -72,20 +72,25 @@ public static ErrorValue createConversionError(Object inputValue, BType targetTy TypeChecker.getType(inputValue), targetType)); } - static ErrorValue createTypeCastError(Object sourceVal, BType targetType) { + public static ErrorValue createTypeCastError(Object sourceVal, BType targetType) { throw createError(BallerinaErrorReasons.TYPE_CAST_ERROR, BLangExceptionHelper.getErrorMessage(RuntimeErrors.TYPE_CAST_ERROR, TypeChecker.getType(sourceVal), targetType)); } - static ErrorValue createNumericConversionError(Object inputValue, BType targetType) { + public static ErrorValue createNumericConversionError(Object inputValue, BType targetType) { throw createError(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, BLangExceptionHelper.getErrorMessage( RuntimeErrors.INCOMPATIBLE_SIMPLE_TYPE_CONVERT_OPERATION, TypeChecker.getType(inputValue), inputValue, targetType)); } + public static ErrorValue createNumericConversionError(Object inputValue, BType inputType, BType targetType) { + throw createError(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, BLangExceptionHelper.getErrorMessage( + RuntimeErrors.INCOMPATIBLE_SIMPLE_TYPE_CONVERT_OPERATION, inputType, inputValue, targetType)); + } + public static ErrorValue createCancelledFutureError() { return createError(BallerinaErrorReasons.FUTURE_CANCELLED); } diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java index 1f5653847a2e..e3fb73e402bd 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java @@ -78,6 +78,23 @@ public static Object checkCast(Object sourceVal, BType targetType) { return sourceVal; } + BType sourceType = getType(sourceVal); + if (sourceType.getTag() <= TypeTags.BOOLEAN_TAG && targetType.getTag() <= TypeTags.BOOLEAN_TAG) { + return TypeConverter.castValues(targetType, sourceVal); + } + + // if the source is a numeric value and the target type is a union, try to find a matching + // member. + if (sourceType.getTag() <= TypeTags.BOOLEAN_TAG && targetType.getTag() == TypeTags.UNION_TAG) { + for(BType memberType : ((BUnionType) targetType).getMemberTypes()) { + try { + return TypeConverter.castValues(memberType, sourceVal); + } catch (Exception e) { + continue; + } + } + } + throw BallerinaErrors.createTypeCastError(sourceVal, targetType); } @@ -1117,25 +1134,66 @@ private static boolean isEqual(Object lhsValue, Object rhsValue, List return false; } + if (lhsValue.equals(rhsValue)) { + return true; + } + int lhsValTypeTag = getType(lhsValue).getTag(); int rhsValTypeTag = getType(rhsValue).getTag(); switch (lhsValTypeTag) { case TypeTags.STRING_TAG: + return lhsValue.equals(rhsValue); case TypeTags.FLOAT_TAG: + if (rhsValTypeTag <= TypeTags.FLOAT_TAG) { + return lhsValue.equals(((Number) rhsValue).doubleValue()); + } + + if (rhsValTypeTag == TypeTags.DECIMAL_TAG) { + return DecimalValue.valueOf((double) lhsValue).equals(rhsValue); + } + + return false; case TypeTags.DECIMAL_TAG: - case TypeTags.BOOLEAN_TAG: - return lhsValue.equals(rhsValue); + if (rhsValTypeTag <= TypeTags.FLOAT_TAG) { + return DecimalValue.valueOf(((Number) rhsValue).doubleValue()).equals(lhsValue); + } + + if (rhsValTypeTag == TypeTags.DECIMAL_TAG) { + return ((DecimalValue) rhsValue).equals(lhsValue); + } + + return false; case TypeTags.INT_TAG: - if (rhsValTypeTag != TypeTags.BYTE_TAG && rhsValTypeTag != TypeTags.INT_TAG) { - return false; + if (rhsValTypeTag <= TypeTags.FLOAT_TAG) { + return lhsValue.equals(((Number) rhsValue).longValue()); + } + + if (rhsValTypeTag == TypeTags.DECIMAL_TAG) { + return DecimalValue.valueOf((long) lhsValue).equals(rhsValue); } - return lhsValue.equals(((Number) rhsValue).longValue()); + + return false; case TypeTags.BYTE_TAG: - if (rhsValTypeTag != TypeTags.BYTE_TAG && rhsValTypeTag != TypeTags.INT_TAG) { - return false; + if (rhsValTypeTag <= TypeTags.FLOAT_TAG) { + return ((Number) lhsValue).byteValue() == ((Number) rhsValue).byteValue(); + } + + if (rhsValTypeTag == TypeTags.DECIMAL_TAG) { + return DecimalValue.valueOf((int) lhsValue).equals(rhsValue); + } + + return false; + case TypeTags.BOOLEAN_TAG: + if (rhsValTypeTag <= TypeTags.FLOAT_TAG) { + return ((boolean) lhsValue) == (((Number) rhsValue).longValue() == 1); } - return ((Number) lhsValue).byteValue() == ((Number) rhsValue).byteValue(); + + if (rhsValTypeTag == TypeTags.DECIMAL_TAG) { + return ((boolean) lhsValue) == ((DecimalValue) rhsValue).booleanValue(); + } + + return false; case TypeTags.XML_TAG: return XMLFactory.isEqual((XMLValue) lhsValue, (XMLValue) rhsValue); case TypeTags.TABLE_TAG: diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java index 2d553fdea844..3334574bb5da 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java @@ -45,6 +45,10 @@ */ public class TypeConverter { + private static final String NaN = "NaN"; + private static final String POSITIVE_INFINITY = "Infinity"; + private static final String NEGATIVE_INFINITY = "-Infinity"; + public static Object convertValues(BType targetType, Object inputValue) { BType inputType = TypeChecker.getType(inputValue); switch (targetType.getTag()) { @@ -73,25 +77,41 @@ public static Object convertValues(BType targetType, Object inputValue) { } } + public static Object castValues(BType targetType, Object inputValue) { + switch (targetType.getTag()) { + case TypeTags.INT_TAG: + return anyToIntCast(inputValue, () -> + BallerinaErrors.createTypeCastError(inputValue, BTypes.typeInt)); + case TypeTags.DECIMAL_TAG: + return anyToDecimal(inputValue, () -> + BallerinaErrors.createTypeCastError(inputValue, BTypes.typeDecimal)); + case TypeTags.FLOAT_TAG: + return anyToFloatCast(inputValue, () -> + BallerinaErrors.createTypeCastError(inputValue, BTypes.typeFloat)); + case TypeTags.STRING_TAG: + return anyToStringCast(inputValue, () -> + BallerinaErrors.createTypeCastError(inputValue, BTypes.typeString)); + case TypeTags.BOOLEAN_TAG: + return anyToBooleanCast(inputValue, () -> + BallerinaErrors.createTypeCastError(inputValue, BTypes.typeBoolean)); + case TypeTags.BYTE_TAG: + return anyToByteCast(inputValue, () -> + BallerinaErrors.createTypeCastError(inputValue, BTypes.typeByte)); + default: + throw BallerinaErrors.createTypeCastError(inputValue, targetType); + } + } + static long anyToInt(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { return (Long) sourceVal; } else if (sourceVal instanceof Double) { - if (Double.isNaN((Double) sourceVal) || Double.isInfinite((Double) sourceVal)) { - throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeInt); - } - if (!isFloatWithinIntRange((Double) sourceVal)) { - throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeInt); - } - return Math.round((Double) sourceVal); + return floatToInt((double) sourceVal); } else if (sourceVal instanceof Integer) { return ((Integer) sourceVal).longValue(); } else if (sourceVal instanceof Boolean) { return (Boolean) sourceVal ? 1 : 0; } else if (sourceVal instanceof DecimalValue) { - if (!isFloatWithinIntRange(((DecimalValue) sourceVal).floatValue())) { - throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeInt); - } return ((DecimalValue) sourceVal).intValue(); } else if (sourceVal instanceof String) { try { @@ -104,6 +124,22 @@ static long anyToInt(Object sourceVal, Supplier errorFunc) { throw errorFunc.get(); } + private static long anyToIntCast(Object sourceVal, Supplier errorFunc) { + if (sourceVal instanceof Long) { + return (Long) sourceVal; + } else if (sourceVal instanceof Double) { + return floatToInt((double) sourceVal); + } else if (sourceVal instanceof Integer) { + return ((Integer) sourceVal).longValue(); + } else if (sourceVal instanceof Boolean) { + return (Boolean) sourceVal ? 1 : 0; + } else if (sourceVal instanceof DecimalValue) { + return ((DecimalValue) sourceVal).intValue(); + } else { + throw errorFunc.get(); + } + } + static double anyToFloat(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { return ((Long) sourceVal).doubleValue(); @@ -114,9 +150,6 @@ static double anyToFloat(Object sourceVal, Supplier errorFunc) { } else if (sourceVal instanceof Boolean) { return (Boolean) sourceVal ? 1.0 : 0.0; } else if (sourceVal instanceof DecimalValue) { - if (!isFloatWithinIntRange(((DecimalValue) sourceVal).floatValue())) { - throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeFloat); - } return ((DecimalValue) sourceVal).floatValue(); } else if (sourceVal instanceof String) { try { @@ -129,25 +162,29 @@ static double anyToFloat(Object sourceVal, Supplier errorFunc) { throw errorFunc.get(); } + private static double anyToFloatCast(Object sourceVal, Supplier errorFunc) { + if (sourceVal instanceof Long) { + return ((Long) sourceVal).doubleValue(); + } else if (sourceVal instanceof Double) { + return (Double) sourceVal; + } else if (sourceVal instanceof Integer) { + return ((Integer) sourceVal).floatValue(); + } else if (sourceVal instanceof Boolean) { + return (Boolean) sourceVal ? 1.0 : 0.0; + } else if (sourceVal instanceof DecimalValue) { + return ((DecimalValue) sourceVal).floatValue(); + } else { + throw errorFunc.get(); + } + } + static boolean anyToBoolean(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { - long val = (Long) sourceVal; - if (val != 1 && val != 0) { - throw errorFunc.get(); - } - return val != 0; + return (long) sourceVal != 0; } else if (sourceVal instanceof Double) { - double val = (Double) sourceVal; - if (val != 1.0 && val != 0.0) { - throw errorFunc.get(); - } return (Double) sourceVal != 0.0; } else if (sourceVal instanceof Integer) { - int val = (int) sourceVal; - if (val != 1 && val != 0) { - throw errorFunc.get(); - } - return val != 0; + return (int) sourceVal != 0; } else if (sourceVal instanceof Boolean) { return (boolean) sourceVal; } else if (sourceVal instanceof DecimalValue) { @@ -163,6 +200,14 @@ static boolean anyToBoolean(Object sourceVal, Supplier errorFunc) { throw errorFunc.get(); } + static boolean anyToBooleanCast(Object sourceVal, Supplier errorFunc) { + if (sourceVal instanceof Boolean) { + return (boolean) sourceVal; + } + + throw errorFunc.get(); + } + public static int intToByte(long sourceVal) { if (!isByteLiteral(sourceVal)) { throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeByte); @@ -170,27 +215,48 @@ public static int intToByte(long sourceVal) { return ((Long) sourceVal).intValue(); } + public static int floatToByte(double sourceVal) { + checkIsValidFloat(sourceVal, BTypes.typeByte); + + long intVal = Math.round(sourceVal); + if (!isByteLiteral(intVal)) { + throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeByte); + } + + return (int) intVal; + } + + public static long floatToInt(double sourceVal) { + checkIsValidFloat(sourceVal, BTypes.typeInt); + + if (!isFloatWithinIntRange(sourceVal)) { + throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeInt); + } + + return Math.round(sourceVal); + } + + private static void checkIsValidFloat(double sourceVal, BType targetType) { + if (Double.isNaN(sourceVal)) { + throw BallerinaErrors.createNumericConversionError(NaN, BTypes.typeFloat, targetType); + } + + if (Double.isInfinite(sourceVal)) { + String value = sourceVal > 0 ? POSITIVE_INFINITY : NEGATIVE_INFINITY; + throw BallerinaErrors.createNumericConversionError(value, BTypes.typeFloat, targetType); + } + } + static int anyToByte(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { return intToByte((Long) sourceVal); } else if (sourceVal instanceof Double) { - Double value = (Double) sourceVal; - if (Double.isNaN(value) || Double.isInfinite(value)) { - throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeByte); - } - long intVal = Math.round(value); - if (!isByteLiteral(intVal)) { - throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeByte); - } - return (int) intVal; + return floatToByte((Double) sourceVal); } else if (sourceVal instanceof Integer) { return (int) sourceVal; } else if (sourceVal instanceof Boolean) { return ((Boolean) sourceVal ? 1 : 0); } else if (sourceVal instanceof DecimalValue) { - if (!isByteLiteral(((DecimalValue) sourceVal).intValue())) { - throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeByte); - } return ((DecimalValue) sourceVal).byteValue(); } else if (sourceVal instanceof String) { try { @@ -203,6 +269,23 @@ static int anyToByte(Object sourceVal, Supplier errorFunc) { throw errorFunc.get(); } + private static int anyToByteCast(Object sourceVal, Supplier errorFunc) { + if (sourceVal instanceof Long) { + return intToByte((Long) sourceVal); + } else if (sourceVal instanceof Double) { + return floatToByte((Double) sourceVal); + } else if (sourceVal instanceof Integer) { + return (int) sourceVal; + } else if (sourceVal instanceof Boolean) { + return ((Boolean) sourceVal ? 1 : 0); + } else if (sourceVal instanceof DecimalValue) { + return ((DecimalValue) sourceVal).byteValue(); + } else { + throw errorFunc.get(); + } + + } + private static String anyToString(Object sourceVal) { if (sourceVal instanceof Long) { return Long.toString((Long) sourceVal); @@ -216,11 +299,21 @@ private static String anyToString(Object sourceVal) { return ((DecimalValue) sourceVal).stringValue(); } else if (sourceVal instanceof String) { return (String) sourceVal; + } else if (sourceVal == null) { + return "()"; } throw BallerinaErrors.createNumericConversionError(sourceVal, BTypes.typeString); } + private static String anyToStringCast(Object sourceVal, Supplier errorFunc) { + if (sourceVal instanceof String) { + return (String) sourceVal; + } + + throw errorFunc.get(); + } + static DecimalValue anyToDecimal(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { return DecimalValue.valueOf((Long) sourceVal); diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java index b8ad7d28b6ff..316971793e61 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java @@ -18,6 +18,7 @@ package org.ballerinalang.jvm.values; +import org.ballerinalang.jvm.BallerinaErrors; import org.ballerinalang.jvm.DecimalValueKind; import org.ballerinalang.jvm.types.BType; import org.ballerinalang.jvm.types.BTypes; @@ -137,19 +138,15 @@ public BigDecimal decimalValue() { public long intValue() { switch (valueKind) { case NOT_A_NUMBER: - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "'decimal' value '" + NaN + "' cannot be converted to 'int'"); + throw BallerinaErrors.createNumericConversionError(NaN, BTypes.typeInt); case NEGATIVE_INFINITY: - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "'decimal' value '" + NEGATIVE_INF + "' cannot be converted to 'int'"); + throw BallerinaErrors.createNumericConversionError(NEGATIVE_INF, BTypes.typeInt); case POSITIVE_INFINITY: - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "'decimal' value '" + POSITIVE_INF + "' cannot be converted to 'int'"); + throw BallerinaErrors.createNumericConversionError(POSITIVE_INF, BTypes.typeInt); } if (!isDecimalWithinIntRange(value)) { - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "out of range 'decimal' value '" + this.stringValue() + "' cannot be converted to 'int'"); + throw BallerinaErrors.createNumericConversionError(this.stringValue(), BTypes.typeDecimal, BTypes.typeInt); } return Math.round(value.doubleValue()); } @@ -162,20 +159,16 @@ private static boolean isDecimalWithinIntRange(BigDecimal decimalValue) { public int byteValue() { switch (valueKind) { case NOT_A_NUMBER: - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "'decimal' value '" + NaN + "' cannot be converted to 'byte'"); + throw BallerinaErrors.createNumericConversionError(NaN, BTypes.typeByte); case NEGATIVE_INFINITY: - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "'decimal' value '" + NEGATIVE_INF + "' cannot be converted to 'byte'"); + throw BallerinaErrors.createNumericConversionError(NEGATIVE_INF, BTypes.typeByte); case POSITIVE_INFINITY: - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "'decimal' value '" + POSITIVE_INF + "' cannot be converted to 'byte'"); + throw BallerinaErrors.createNumericConversionError(POSITIVE_INF, BTypes.typeByte); } long intVal = Math.round(this.value.doubleValue()); if (!isByteLiteral(intVal)) { - throw new BallerinaException(BallerinaErrorReasons.NUMBER_CONVERSION_ERROR, - "'decimal' value '" + value + "' cannot be converted to 'byte'"); + throw BallerinaErrors.createNumericConversionError(value, BTypes.typeDecimal, BTypes.typeByte); } return (int) intVal; } diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal index db374e8dc39d..e2d51668947d 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal @@ -78,7 +78,7 @@ function generateCheckCastToInt(jvm:MethodVisitor mv, bir:BType sourceType) { } else if (sourceType is bir:BTypeByte) { mv.visitInsn(I2L); } else if (sourceType is bir:BTypeFloat) { - mv.visitInsn(D2L); + mv.visitMethodInsn(INVOKESTATIC, TYPE_CONVERTER, "floatToInt", "(D)J", false); } else if (sourceType is bir:BTypeAny || sourceType is bir:BTypeAnyData || sourceType is bir:BUnionType || @@ -97,6 +97,8 @@ function generateCheckCastToFloat(jvm:MethodVisitor mv, bir:BType sourceType) { // do nothing } else if (sourceType is bir:BTypeInt) { mv.visitInsn(L2D); + } else if (sourceType is bir:BTypeByte) { + mv.visitInsn(I2D); } else if (sourceType is bir:BTypeAny || sourceType is bir:BTypeAnyData || sourceType is bir:BUnionType || @@ -124,6 +126,8 @@ function generateCheckCastToDecimal(jvm:MethodVisitor mv, bir:BType sourceType) mv.visitMethodInsn(INVOKESTATIC, DECIMAL_VALUE, "valueOf", io:sprintf("(J)L%s;", DECIMAL_VALUE), false); } else if (sourceType is bir:BTypeFloat) { mv.visitMethodInsn(INVOKESTATIC, DECIMAL_VALUE, "valueOf", io:sprintf("(D)L%s;", DECIMAL_VALUE), false); + } else if (sourceType is bir:BTypeByte) { + mv.visitMethodInsn(INVOKESTATIC, DECIMAL_VALUE, "valueOf", io:sprintf("(I)L%s;", DECIMAL_VALUE), false); } else { error err = error(io:sprintf("Casting is not supported from '%s' to 'decimal'", sourceType)); panic err; @@ -173,12 +177,17 @@ function generateCheckCastToBoolean(jvm:MethodVisitor mv, bir:BType sourceType) function generateCheckCastToByte(jvm:MethodVisitor mv, bir:BType sourceType) { if (sourceType is bir:BTypeInt) { mv.visitMethodInsn(INVOKESTATIC, TYPE_CONVERTER, "intToByte", "(J)I", false); + } else if (sourceType is bir:BTypeFloat) { + mv.visitMethodInsn(INVOKESTATIC, TYPE_CONVERTER, "floatToByte", "(D)I", false); + } else if (sourceType is bir:BTypeDecimal) { + mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToByte", io:sprintf("(L%s;)I", OBJECT), false); } else if (sourceType is bir:BTypeByte) { // do nothing } else if (sourceType is bir:BTypeAny || - sourceType is bir:BTypeAnyData || - sourceType is bir:BUnionType || - sourceType is bir:BFiniteType) { + sourceType is bir:BTypeAnyData || + sourceType is bir:BUnionType || + sourceType is bir:BFiniteType || + sourceType is bir:BJSONType) { mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToByte", io:sprintf("(L%s;)I", OBJECT), false); } else { error err = error(io:sprintf("Casting is not supported from '%s' to 'byte'", sourceType)); @@ -207,15 +216,8 @@ function generateCheckCastToJSON(jvm:MethodVisitor mv, bir:BType sourceType) { } function generateCheckCastToUnionType(jvm:MethodVisitor mv, bir:BType sourceType, bir:BUnionType targetType) { - if (sourceType is bir:BTypeAny || - sourceType is bir:BTypeAnyData || - sourceType is bir:BUnionType|| - sourceType is bir:BJSONType) { - checkCast(mv, targetType); - } else { - // if value types, then ad box instruction - generateCastToAny(mv, sourceType); - } + generateCastToAny(mv, sourceType); + checkCast(mv, targetType); } function checkCast(jvm:MethodVisitor mv, bir:BType targetType) { @@ -256,15 +258,8 @@ function getTargetClass(bir:BType sourceType, bir:BType targetType) returns stri } function generateCheckCastToFiniteType(jvm:MethodVisitor mv, bir:BType sourceType, bir:BFiniteType targetType) { - if (sourceType is bir:BTypeAny || - sourceType is bir:BTypeAnyData || - sourceType is bir:BUnionType|| - sourceType is bir:BJSONType) { - checkCast(mv, targetType); - } else { - // if value types, then add box instruction - generateCastToAny(mv, sourceType); - } + generateCastToAny(mv, sourceType); + checkCast(mv, targetType); } @@ -403,8 +398,9 @@ function generateCastToByte(jvm:MethodVisitor mv, bir:BType sourceType) { } else if (sourceType is bir:BTypeByte) { // do nothing } else if (sourceType is bir:BTypeAny || - sourceType is bir:BTypeAnyData || - sourceType is bir:BUnionType) { + sourceType is bir:BTypeAnyData || + sourceType is bir:BUnionType || + sourceType is bir:BJSONType) { mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToByte", io:sprintf("(L%s;)I", OBJECT), false); } else { error err = error(io:sprintf("Casting is not supported from '%s' to 'byte'", sourceType)); diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal index db00bb6e8b21..737eaeb6464c 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal @@ -963,6 +963,10 @@ function loadFiniteType(jvm:MethodVisitor mv, bir:BFiniteType finiteType) { mv.visitMethodInsn(INVOKESTATIC, DOUBLE_VALUE, "valueOf", io:sprintf("(D)L%s;", DOUBLE_VALUE), false); } else if (value is byte) { mv.visitMethodInsn(INVOKESTATIC, BYTE_VALUE, "valueOf", io:sprintf("(B)L%s;", BYTE_VALUE), false); + } else if (value is bir:Decimal) { + mv.visitTypeInsn(NEW, DECIMAL_VALUE); + mv.visitInsn(DUP); + mv.visitMethodInsn(INVOKESPECIAL, DECIMAL_VALUE, "", io:sprintf("(L%s;)V", STRING_VALUE), false); } else { // if value is string or (), then do nothing } diff --git a/stdlib/bir/src/main/ballerina/bir/bir_model.bal b/stdlib/bir/src/main/ballerina/bir/bir_model.bal index 902faf077a3c..5842118a1ac7 100644 --- a/stdlib/bir/src/main/ballerina/bir/bir_model.bal +++ b/stdlib/bir/src/main/ballerina/bir/bir_model.bal @@ -392,7 +392,7 @@ public type BFutureType record {| public type BFiniteType record {| Name name = {}; int flags; - (int | string | boolean | float | byte| ()) [] values; + (int | string | boolean | float | byte| () | Decimal) [] values; |}; public type BType BTypeInt | BTypeBoolean | BTypeAny | BTypeNil | BTypeByte | BTypeFloat | BTypeString | BUnionType | @@ -438,7 +438,7 @@ public type ConstantLoad record {| InstructionKind kind; VarRef lhsOp; BType typeValue; - int | string | boolean | float | byte | () value; + int | string | boolean | float | byte | () | Decimal value; |}; public type NewMap record {| @@ -737,3 +737,7 @@ public type WaitAll record {| string[] keys; BasicBlock thenBB; |}; + +public type Decimal record {| + string value; +|}; diff --git a/stdlib/bir/src/main/ballerina/bir/bir_pkg_parser.bal b/stdlib/bir/src/main/ballerina/bir/bir_pkg_parser.bal index 2bb95a73b42c..42b5bebcb4e8 100644 --- a/stdlib/bir/src/main/ballerina/bir/bir_pkg_parser.bal +++ b/stdlib/bir/src/main/ballerina/bir/bir_pkg_parser.bal @@ -416,7 +416,8 @@ function parseLiteralValue(BirChannelReader reader, BType bType) returns anydata } else if (bType is BTypeString) { value = reader.readStringCpRef(); } else if (bType is BTypeDecimal) { - value = reader.readStringCpRef(); + Decimal d = {value : reader.readStringCpRef()}; + value = d; } else if (bType is BTypeBoolean) { value = reader.readBoolean(); } else if (bType is BTypeFloat) { diff --git a/stdlib/bir/src/main/ballerina/bir/type_parser.bal b/stdlib/bir/src/main/ballerina/bir/type_parser.bal index a491298aeec1..7f057b48a1b6 100644 --- a/stdlib/bir/src/main/ballerina/bir/type_parser.bal +++ b/stdlib/bir/src/main/ballerina/bir/type_parser.bal @@ -365,13 +365,17 @@ public type TypeParser object { return finiteType; } - private function getValue(BType valueType) returns (int | string | boolean | float | byte| ()) { + private function getValue(BType valueType) returns (int | string | boolean | float | byte| () | Decimal) { if (valueType is BTypeInt) { return self.readIntCpRef(); } else if (valueType is BTypeByte) { return self.readByteCpRef(); - } else if (valueType is BTypeString || valueType is BTypeDecimal) { + } else if (valueType is BTypeString) { return self.readStringCpRef(); + } else if (valueType is BTypeDecimal) { + + io:println("************"); + return {value: self.readStringCpRef()}; } else if (valueType is BTypeBoolean) { return self.readInt8() == 1; } else if (valueType is BTypeFloat) { diff --git a/stdlib/utils/src/main/java/org/ballerinalang/utils/SimpleValueConvert.java b/stdlib/utils/src/main/java/org/ballerinalang/utils/SimpleValueConvert.java index fd7c2c48440d..b11ae68cac81 100644 --- a/stdlib/utils/src/main/java/org/ballerinalang/utils/SimpleValueConvert.java +++ b/stdlib/utils/src/main/java/org/ballerinalang/utils/SimpleValueConvert.java @@ -110,7 +110,7 @@ public void execute(Context ctx) { public static Object simpleValueConvert(Strand strand, TypedescValue typedescValue, Object inputValue) { org.ballerinalang.jvm.types.BType targetType = typedescValue.getDescribingType(); - if (inputValue == null) { + if (inputValue == null && targetType.getTag() != TypeTags.STRING_TAG) { return BallerinaErrors .createError(org.ballerinalang.jvm.util.exceptions.BallerinaErrorReasons.CONVERSION_ERROR, org.ballerinalang.jvm.util.exceptions.BLangExceptionHelper @@ -128,6 +128,9 @@ public static Object simpleValueConvert(Strand strand, TypedescValue typedescVal // function. try { if (targetType.getTag() == org.ballerinalang.jvm.types.TypeTags.STRING_TAG) { + if (inputValue == null) { + return "()"; + } return ((RefValue) inputValue).stringValue(); } return BallerinaErrors.createConversionError(inputValue, targetType); diff --git a/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java b/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java index c6cf86a85e29..9fc0ddc1ab0b 100644 --- a/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java +++ b/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java @@ -16,6 +16,7 @@ */ package org.ballerinalang.test.expressions.typecast; +import org.ballerinalang.model.types.ValueType; import org.ballerinalang.model.values.BBoolean; import org.ballerinalang.model.values.BByte; import org.ballerinalang.model.values.BDecimal; @@ -23,6 +24,7 @@ import org.ballerinalang.model.values.BFloat; import org.ballerinalang.model.values.BInteger; import org.ballerinalang.model.values.BValue; +import org.ballerinalang.model.values.BValueType; import org.ballerinalang.test.util.BCompileUtil; import org.ballerinalang.test.util.BRunUtil; import org.ballerinalang.test.util.CompileResult; @@ -186,8 +188,7 @@ public void testIntAsByte(String functionName, int i) { Assert.assertEquals(returns.length, 2); Assert.assertSame(returns[0].getClass(), BBoolean.class); Assert.assertTrue(((BBoolean) returns[0]).booleanValue(), "expected bytes to be the same"); - Assert.assertSame(returns[1].getClass(), BByte.class); - Assert.assertEquals(((BByte) returns[1]).byteValue(), (new BInteger(i)).byteValue(), "incorrect int " + + Assert.assertEquals(((ValueType) returns[1]).byteValue(), (new BInteger(i)).byteValue(), "incorrect int " + "representation as byte"); } @@ -219,8 +220,7 @@ public void testByteAsInt(String functionName, long i) { Assert.assertEquals(returns.length, 2); Assert.assertSame(returns[0].getClass(), BBoolean.class); Assert.assertTrue(((BBoolean) returns[0]).booleanValue(), "expected ints to be the same"); - Assert.assertSame(returns[1].getClass(), BInteger.class); - Assert.assertEquals(((BInteger) returns[1]).intValue(), (new BByte(i)).intValue(), "incorrect byte " + + Assert.assertEquals(((BValueType) returns[1]).intValue(), (new BByte(i)).intValue(), "incorrect byte " + "representation as int"); } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java index c6cf86a85e29..5208854faae7 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java @@ -23,6 +23,7 @@ import org.ballerinalang.model.values.BFloat; import org.ballerinalang.model.values.BInteger; import org.ballerinalang.model.values.BValue; +import org.ballerinalang.model.values.BValueType; import org.ballerinalang.test.util.BCompileUtil; import org.ballerinalang.test.util.BRunUtil; import org.ballerinalang.test.util.CompileResult; @@ -186,8 +187,7 @@ public void testIntAsByte(String functionName, int i) { Assert.assertEquals(returns.length, 2); Assert.assertSame(returns[0].getClass(), BBoolean.class); Assert.assertTrue(((BBoolean) returns[0]).booleanValue(), "expected bytes to be the same"); - Assert.assertSame(returns[1].getClass(), BByte.class); - Assert.assertEquals(((BByte) returns[1]).byteValue(), (new BInteger(i)).byteValue(), "incorrect int " + + Assert.assertEquals(((BValueType) returns[1]).byteValue(), (new BInteger(i)).byteValue(), "incorrect int " + "representation as byte"); } @@ -219,8 +219,7 @@ public void testByteAsInt(String functionName, long i) { Assert.assertEquals(returns.length, 2); Assert.assertSame(returns[0].getClass(), BBoolean.class); Assert.assertTrue(((BBoolean) returns[0]).booleanValue(), "expected ints to be the same"); - Assert.assertSame(returns[1].getClass(), BInteger.class); - Assert.assertEquals(((BInteger) returns[1]).intValue(), (new BByte(i)).intValue(), "incorrect byte " + + Assert.assertEquals(((BValueType) returns[1]).intValue(), (new BByte(i)).intValue(), "incorrect byte " + "representation as int"); } @@ -271,10 +270,10 @@ public void testInvalidDecimalAsByte(int i) { } @Test(dataProvider = "invalidByteValues", expectedExceptions = BLangRuntimeException.class, - expectedExceptionsMessageRegExp = "error: \\{ballerina\\}NumberConversionError \\{\"message\":\"'decimal'" + - " value '.*' cannot be converted to 'byte'\"\\}.*") + expectedExceptionsMessageRegExp = "error: \\{ballerina\\}TypeCastError \\{\"message\":\"incompatible " + + "types: 'decimal' cannot be cast to 'byte\\|Employee'\"}.*") public void testInvalidDecimalAsByteInUnions(int i) { - BRunUtil.invoke(result, "testDecimalAsByteInUnions", new BValue[]{new BDecimal(new BigDecimal(i))}); + BRunUtil.invoke(result, "testDecimalAsByteInUnions", new BValue[] { new BDecimal(new BigDecimal(i)) }); } @Test(dataProvider = "naNFloatAsByteTests", expectedExceptions = BLangRuntimeException.class, @@ -306,15 +305,15 @@ public void testInfiniteFloatAsInt(String functionName) { } @Test(dataProvider = "outOfRangeFloatAsIntTests", expectedExceptions = BLangRuntimeException.class, - expectedExceptionsMessageRegExp = "error: \\{ballerina\\}NumberConversionError \\{\"message\":\"out of " + - "range 'float' value '.*' cannot be converted to 'int'\"\\}.*") + expectedExceptionsMessageRegExp = "error: \\{ballerina\\}NumberConversionError \\{\"message\":\"" + + "'float' value '.*' cannot be converted to 'int'\"\\}.*") public void testOutOfRangeFloatAsInt(String functionName) { BRunUtil.invoke(result, functionName, new BValue[0]); } @Test(dataProvider = "outOfRangeDecimalAsIntTests", expectedExceptions = BLangRuntimeException.class, - expectedExceptionsMessageRegExp = "error: \\{ballerina\\}NumberConversionError \\{\"message\":\"out of " + - "range 'decimal' value '.*' cannot be converted to 'int'\"}.*") + expectedExceptionsMessageRegExp = "error: \\{ballerina\\}NumberConversionError \\{\"message\":\"" + + "'decimal' value '.*' cannot be converted to 'int'\"}.*") public void testOutOfRangeDecimalAsInt(String functionName) { BRunUtil.invoke(result, functionName, new BValue[0]); } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java index 1f01cee822d4..a1a2089fd30e 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java @@ -320,8 +320,7 @@ public void testIncompatibleJsonToInt() { Assert.assertTrue(returns[0] instanceof BError); BError error = (BError) returns[0]; String errorMsg = ((BMap) error.getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'string' value 'hello' cannot be converted as " - + "'int'"); + Assert.assertEquals(errorMsg, "'string' value 'hello' cannot be converted to 'int'"); } @Test @@ -330,8 +329,7 @@ public void testIncompatibleJsonToFloat() { Assert.assertTrue(returns[0] instanceof BError); BError error = (BError) returns[0]; String errorMsg = ((BMap) error.getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'string' value 'hello' cannot be converted as " - + "'float'"); + Assert.assertEquals(errorMsg, "'string' value 'hello' cannot be converted to 'float'"); } @Test @@ -562,7 +560,7 @@ public void testInCompatibleStructForceCasting() { Assert.assertTrue(returns[0] instanceof BError); BError error = (BError) returns[0]; String errorMsg = ((BMap) error.getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'B' value cannot be converted as 'A'"); + Assert.assertEquals(errorMsg, "'B' value cannot be converted to 'A'"); } @Test (description = "Test any to int casting happens without errors, error struct should be null") @@ -597,8 +595,7 @@ public void testAnyNullToString() { BValue[] returns = BRunUtil.invoke(result, "testAnyNullToString"); // null to string should return string null - Assert.assertEquals(returns[0].stringValue(), "{ballerina}ConversionError {\"message\":\"cannot convert " - + "'null' value to type 'string'\"}"); + Assert.assertEquals(returns[0].stringValue(), "()"); } @Test diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExpressionsTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExpressionsTest.java index b4cf906e6bfc..a4335a3a08b6 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExpressionsTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExpressionsTest.java @@ -81,7 +81,7 @@ public void testNilValueCastAsStructuredTypeNegative() { @Test(expectedExceptions = BLangRuntimeException.class, expectedExceptionsMessageRegExp = "error: \\{ballerina\\}TypeCastError \\{\"message\":\"incompatible " + - "types: 'string\\|int\\|null\\[2\\]' cannot be cast to 'string\\[2\\]'\"\\}.*") + "types: 'string\\|int\\|\\(\\)\\[2\\]' cannot be cast to 'string\\[2\\]'\"\\}.*") public void testArrayCastNegative() { BRunUtil.invoke(result, "testArrayCastNegative"); } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/numeric_conversion.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/numeric_conversion.bal index 3b601ee88d21..87dbd3ac67c2 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/numeric_conversion.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/numeric_conversion.bal @@ -15,14 +15,14 @@ // under the License. //////////////////////// from float //////////////////////// -function testFloatAsFloat(float f1) returns (boolean, float) { +function testFloatAsFloat(float f1) returns [boolean, float] { float s3 = f1; anydata s4 = getFloat(f1); - return (s3 == s4 && s4 is float, s3); + return [s3 == s4 && s4 is float, s3]; } -function testFloatAsFloatInUnions(float f1) returns (boolean, float) { +function testFloatAsFloatInUnions(float f1) returns [boolean, float] { Employee|string|float f2 = f1; json f3 = f1; anydata f4 = f1; @@ -33,17 +33,17 @@ function testFloatAsFloatInUnions(float f1) returns (boolean, float) { float s8 = f4; float s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testFloatAsDecimal(float f1) returns (boolean, decimal) { +function testFloatAsDecimal(float f1) returns [boolean, decimal] { decimal s3 = f1; anydata s4 = getFloat(f1); - return (s3 == s4 && s4 is decimal, s3); + return [s3 == s4 && s4 is decimal, s3]; } -function testFloatAsDecimalInUnions(float f1) returns (boolean, decimal) { +function testFloatAsDecimalInUnions(float f1) returns [boolean, decimal] { Employee|string|float f2 = f1; json f3 = f1; anydata f4 = getFloat(f1); @@ -54,17 +54,17 @@ function testFloatAsDecimalInUnions(float f1) returns (boolean, decimal) { decimal s8 = f4; decimal s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testFloatAsInt(float f1) returns (boolean, int) { +function testFloatAsInt(float f1) returns [boolean, int] { int s3 = f1; anydata s4 = getFloat(f1); - return (s3 == s4 && s4 is int, s3); + return [s3 == s4 && s4 is int, s3]; } -function testFloatAsIntInUnions(float f1) returns (boolean, int) { +function testFloatAsIntInUnions(float f1) returns [boolean, int] { Employee|string|float f2 = f1; json f3 = f1; anydata f4 = getFloat(f1); @@ -75,17 +75,17 @@ function testFloatAsIntInUnions(float f1) returns (boolean, int) { int s8 = f4; int|string s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testFloatAsByte(float f1) returns (boolean, byte) { +function testFloatAsByte(float f1) returns [boolean, byte] { byte s3 = f1; anydata s4 = getFloat(f1); - return (s3 == s4 && s4 is byte, s3); + return [s3 == s4 && s4 is byte, s3]; } -function testFloatAsByteInUnions(float f1) returns (boolean, byte) { +function testFloatAsByteInUnions(float f1) returns [boolean, byte] { Employee|string|float f2 = f1; json f3 = f1; anydata f4 = getFloat(f1); @@ -96,18 +96,18 @@ function testFloatAsByteInUnions(float f1) returns (boolean, byte) { byte s8 = f4; byte|string s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } //////////////////////// from decimal //////////////////////// -function testDecimalAsFloat(decimal f1) returns (boolean, float) { +function testDecimalAsFloat(decimal f1) returns [boolean, float] { float s3 = f1; anydata s4 = getDecimal(f1); - return (s3 == s4 && s4 is float, s3); + return [s3 == s4 && s4 is float, s3]; } -function testDecimalAsFloatInUnions(decimal f1) returns (boolean, float|Employee|boolean|string) { +function testDecimalAsFloatInUnions(decimal f1) returns [boolean, float|Employee|boolean|string] { Employee|string|decimal f2 = f1; json f3 = f1; anydata f4 = f1; @@ -118,17 +118,17 @@ function testDecimalAsFloatInUnions(decimal f1) returns (boolean, float|Employee float s8 = f4; float s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testDecimalAsDecimal(decimal f1) returns (boolean, decimal) { +function testDecimalAsDecimal(decimal f1) returns [boolean, decimal] { decimal s3 = f1; anydata s4 = getDecimal(f1); - return (s3 == s4 && s4 is decimal, s3); + return [s3 == s4 && s4 is decimal, s3]; } -function testDecimalAsDecimalInUnions(decimal f1) returns (boolean, decimal|string) { +function testDecimalAsDecimalInUnions(decimal f1) returns [boolean, decimal|string] { Employee|string|decimal f2 = f1; json f3 = f1; anydata f4 = f1; @@ -139,16 +139,16 @@ function testDecimalAsDecimalInUnions(decimal f1) returns (boolean, decimal|stri decimal s8 = f4; decimal s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testDecimalAsInt(decimal f1) returns (boolean, int) { +function testDecimalAsInt(decimal f1) returns [boolean, int] { int s3 = f1; anydata s4 = getDecimal(f1); - return (s3 == s4 && s4 is int, s3); + return [s3 == s4 && s4 is int, s3]; } -function testDecimalAsIntInUnions(decimal f1) returns (boolean, int) { +function testDecimalAsIntInUnions(decimal f1) returns [boolean, int] { Employee|string|decimal f2 = f1; json f3 = f1; anydata f4 = f1; @@ -159,16 +159,16 @@ function testDecimalAsIntInUnions(decimal f1) returns (boolean, int) { int s8 = f4; int s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testDecimalAsByte(decimal f1) returns (boolean, byte) { +function testDecimalAsByte(decimal f1) returns [boolean, byte] { byte s3 = f1; anydata s4 = getDecimal(f1); - return (s3 == s4 && s4 is byte, s3); + return [s3 == s4 && s4 is byte, s3]; } -function testDecimalAsByteInUnions(decimal f1) returns (boolean, byte) { +function testDecimalAsByteInUnions(decimal f1) returns [boolean, byte] { Employee|string|decimal f2 = f1; json f3 = f1; anydata f4 = f1; @@ -179,18 +179,18 @@ function testDecimalAsByteInUnions(decimal f1) returns (boolean, byte) { byte s8 = f4; byte s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s9); + return [s7 == s6 && s7 == s8 && s9 == s8, s9]; } //////////////////////// from int //////////////////////// -function testIntAsFloat(int f1) returns (boolean, float) { +function testIntAsFloat(int f1) returns [boolean, float] { float s3 = f1; anydata s4 = getInt(f1); - return (s3 == s4 && s4 is float, s3); + return [s3 == s4 && s4 is float, s3]; } -function testIntAsFloatInUnions(int f1) returns (boolean, float) { +function testIntAsFloatInUnions(int f1) returns [boolean, float] { string|int|boolean f2 = f1; json f3 = f1; anydata f4 = f1; @@ -201,17 +201,17 @@ function testIntAsFloatInUnions(int f1) returns (boolean, float) { float|Employee|map s8 = > f4; float s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testIntAsDecimal(int f1) returns (boolean, decimal) { +function testIntAsDecimal(int f1) returns [boolean, decimal] { decimal s3 = f1; anydata s4 = getInt(f1); - return (s3 == s4 && s4 is decimal, s3); + return [s3 == s4 && s4 is decimal, s3]; } -function testIntAsDecimalInUnions(int f1) returns (boolean, decimal) { +function testIntAsDecimalInUnions(int f1) returns [boolean, decimal] { string|int|boolean f2 = f1; json f3 = f1; anydata f4 = f1; @@ -222,16 +222,16 @@ function testIntAsDecimalInUnions(int f1) returns (boolean, decimal) { decimal|Employee|map s8 = > f4; decimal s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testIntAsInt(int f1) returns (boolean, int) { +function testIntAsInt(int f1) returns [boolean, int] { int s3 = f1; anydata s4 = getInt(f1); - return (s3 == s4 && s4 is int, s3); + return [s3 == s4 && s4 is int, s3]; } -function testIntAsIntInUnions(int f1) returns (boolean, int|boolean) { +function testIntAsIntInUnions(int f1) returns [boolean, int|boolean] { Employee|string|int f2 = f1; json f3 = f1; anydata f4 = f1; @@ -242,16 +242,16 @@ function testIntAsIntInUnions(int f1) returns (boolean, int|boolean) { int s8 = f4; int s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } -function testIntAsByte(int f1) returns (boolean, byte) { +function testIntAsByte(int f1) returns [boolean, byte] { byte s3 = f1; anydata s4 = getInt(f1); - return (s3 == s4 && s4 is byte, s3); + return [s3 == s4 && s4 is byte, s3]; } -function testIntAsByteInUnions(int f1) returns (boolean, byte|boolean) { +function testIntAsByteInUnions(int f1) returns [boolean, byte|boolean] { Employee|string|int f2 = f1; json f3 = f1; anydata f4 = f1; @@ -262,18 +262,18 @@ function testIntAsByteInUnions(int f1) returns (boolean, byte|boolean) { byte s8 = f4; byte s9 = f5; - return (s7 == s6 && s7 == s8 && s9 == s8, s6); + return [s7 == s6 && s7 == s8 && s9 == s8, s6]; } //////////////////////// from byte //////////////////////// -function testByteAsFloat(byte f1) returns (boolean, float) { +function testByteAsFloat(byte f1) returns [boolean, float] { float s3 = f1; anydata s4 = getByte(f1); - return (s3 == s4 && s4 is float, s3); + return [s3 == s4 && s4 is float, s3]; } -function testByteAsFloatInUnions(byte f1) returns (boolean, float) { +function testByteAsFloatInUnions(byte f1) returns [boolean, float] { string|byte|boolean f2 = f1; anydata f3 = f1; any f4 = f1; @@ -282,17 +282,17 @@ function testByteAsFloatInUnions(byte f1) returns (boolean, float) { float|string s7 = f3; float|Employee|map s8 = > f4; - return (s7 == s6 && s7 == s8, s6); + return [s7 == s6 && s7 == s8, s6]; } -function testByteAsDecimal(byte f1) returns (boolean, decimal) { +function testByteAsDecimal(byte f1) returns [boolean, decimal] { decimal s3 = f1; anydata s4 = getByte(f1); - return (s3 == s4 && s4 is decimal, s3); + return [s3 == s4 && s4 is decimal, s3]; } -function testByteAsDecimalInUnions(byte f1) returns (boolean, decimal) { +function testByteAsDecimalInUnions(byte f1) returns [boolean, decimal] { string|byte f2 = f1; anydata f3 = f1; any f4 = f1; @@ -301,16 +301,16 @@ function testByteAsDecimalInUnions(byte f1) returns (boolean, decimal) { decimal|string s7 = f3; decimal|Employee|map s8 = > f4; - return (s7 == s6 && s7 == s8, s6); + return [s7 == s6 && s7 == s8, s6]; } -function testByteAsInt(byte f1) returns (boolean, int) { +function testByteAsInt(byte f1) returns [boolean, int] { int s3 = f1; anydata s4 = getByte(f1); - return (s3 == s4 && s4 is int, s3); + return [s3 == s4 && s4 is int, s3]; } -function testByteAsIntInUnions(byte f1) returns (boolean, int|boolean) { +function testByteAsIntInUnions(byte f1) returns [boolean, int|boolean] { Employee|byte f2 = f1; anydata f3 = f1; any f4 = f1; @@ -319,16 +319,16 @@ function testByteAsIntInUnions(byte f1) returns (boolean, int|boolean) { int s7 = f3; int s8 = f4; - return (s7 == s6 && s7 == s8, s6); + return [s7 == s6 && s7 == s8, s6]; } -function testByteAsByte(byte f1) returns (boolean, byte) { +function testByteAsByte(byte f1) returns [boolean, byte] { byte s3 = f1; anydata s4 = getByte(f1); - return (s3 == s4 && s4 is byte, s3); + return [s3 == s4 && s4 is byte, s3]; } -function testByteAsByteInUnions(byte f1) returns (boolean, byte|boolean) { +function testByteAsByteInUnions(byte f1) returns [boolean, byte|boolean] { Employee|string|byte f2 = f1; anydata f3 = f1; any f4 = f1; @@ -337,7 +337,7 @@ function testByteAsByteInUnions(byte f1) returns (boolean, byte|boolean) { byte s7 = f3; byte s8 = f4; - return (s7 == s6 && s7 == s8, s6); + return [s7 == s6 && s7 == s8, s6]; } function testNaNFloatAsByte() { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal index 04d9f88b8ab4..9d59292b10a8 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal @@ -482,7 +482,7 @@ function testSameTypeCast() returns int { return b; } -function testJSONValueCasting() returns (string|error, int|error, float|error, boolean|error) { +function testJSONValueCasting() returns [string|error, int|error, float|error, boolean|error] { // json to string json j1 = "hello"; @@ -500,7 +500,7 @@ function testJSONValueCasting() returns (string|error, int|error, float|error, b json j4 = true; var b = j4; - return (s, i, f, b); + return [s, i, f, b]; } function testAnyToTable() returns table|error { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type_cast_expr.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type_cast_expr.bal index cfb337eeec02..2a8ab54080b2 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type_cast_expr.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type_cast_expr.bal @@ -227,21 +227,21 @@ function testArrayCastNegative() { } function testTupleCastPositive() returns boolean { - (string, int, float) s = ("this is an array", 1, 3.0); + [string, int, float] s = ["this is an array", 1, 3.0]; any a = s; - (string, int, float) s2 = <(string, int, float)> a; + [string, int, float] s2 = <[string, int, float]> a; - (string, int|string, float) s3 = ("this is an array", 1, 3.0); + [string, int|string, float] s3 = ["this is an array", 1, 3.0]; anydata a2 = s3; - (string, int|string, float) s4 = <(string, int|string, float)> a2; + [string, int|string, float] s4 = <[string, int|string, float]> a2; return s === s2 && s3 === s4; } function testTupleCastNegative() { - (string, int|string, float) s = ("this is an array", 1, 3.0); + [string, int|string, float] s = ["this is an array", 1, 3.0]; any a = s; - (string, int|string, float) s2 = <(string, int, float)> a; + [string, int|string, float] s2 = <[string, int, float]> a; } function testJsonCastPositive() returns boolean { @@ -477,7 +477,7 @@ function testListElementCastPositive() returns boolean { string sVal = "Hello from Ballerina"; any[] anyArr = [iValTwo, sVal, bVal]; - (Employee, int, any[]) t1 = (e1, iVal, anyArr); + [Employee, int, any[]] t1 = [e1, iVal, anyArr]; any a = t1[2]; any[] anyArrTwo = a; @@ -493,7 +493,7 @@ function testListElementCastNegative() { string sVal = "Hello from Ballerina"; any[] anyArr = [sVal, bVal]; - (Employee, int, any[]) t1 = (e1, iVal, anyArr); + [Employee, int, any[]] t1 = [e1, iVal, anyArr]; any a = t1[2]; any[] anyArrTwo = a; @@ -584,7 +584,7 @@ function testStringInUnionAsString(string s1) returns boolean { //////////////////////// from boolean //////////////////////// -function testBooleanAsBoolean() returns (boolean, boolean, boolean, boolean) { +function testBooleanAsBoolean() returns [boolean, boolean, boolean, boolean] { boolean b1 = true; boolean s1 = b1; anydata a = getBoolean(b1); @@ -597,10 +597,10 @@ function testBooleanAsBoolean() returns (boolean, boolean, boolean, boolean) { boolean s3 = b1; boolean s4 = getBoolean(b1); - return (s1, s2, s3, s4); + return [s1, s2, s3, s4]; } -function testBooleanInUnionAsBoolean() returns (boolean, boolean) { +function testBooleanInUnionAsBoolean() returns [boolean, boolean] { boolean f1 = true; Employee|string|int|boolean f2 = f1; json f3 = true; @@ -627,7 +627,7 @@ function testBooleanInUnionAsBoolean() returns (boolean, boolean) { boolean ft2 = (s7 == s6 && s7 == s8 && s9 == s8) ? s6 : true; - return(ft1, ft2); + return [ft1, ft2]; } function testSimpleTypeToUnionCastPositive() returns boolean { @@ -666,11 +666,11 @@ function testDirectlyUnmatchedUnionToUnionCastNegative_2() { Lead|int v4 = v3; } -function testTypeCastOnRecordLiterals() returns (string, string, string) { +function testTypeCastOnRecordLiterals() returns [string, string, string] { string s1 = init({}); string s2 = init({}); string s3 = init({}); - return (s1, s2, s3); + return [s1, s2, s3]; } function init(InMemoryModeConfig|ServerModeConfig|EmbeddedModeConfig rec) returns string { diff --git a/tests/jballerina-unit-test/src/test/resources/testng.xml b/tests/jballerina-unit-test/src/test/resources/testng.xml index 2858c4ea8371..4069abf601cb 100644 --- a/tests/jballerina-unit-test/src/test/resources/testng.xml +++ b/tests/jballerina-unit-test/src/test/resources/testng.xml @@ -100,6 +100,7 @@ + From 1a0547ac92d05e44b865ea89df721157ea01a6a6 Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Tue, 25 Jun 2019 17:05:21 +0530 Subject: [PATCH 2/5] Fix XML attribute acceess --- .../main/ballerina/compiler_backend_jvm/jvm_constants.bal | 1 - .../main/ballerina/compiler_backend_jvm/jvm_type_gen.bal | 5 ++++- .../compiler/semantics/analyzer/TypeChecker.java | 6 +++++- stdlib/bir/src/main/ballerina/bir/type_parser.bal | 2 -- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal index 81309c6c5ef5..913396c3d90b 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_constants.bal @@ -219,7 +219,6 @@ const string LONG_VALUE = "java/lang/Long"; const string BOOLEAN_VALUE = "java/lang/Boolean"; const string DOUBLE_VALUE = "java/lang/Double"; const string DECIMAL_VALUE = "org/ballerinalang/jvm/values/DecimalValue"; -const string BYTE_VALUE = "java/lang/Byte"; const string INT_VALUE = "java/lang/Integer"; const string XML_VALUE = "org/ballerinalang/jvm/values/XMLValue"; const string XML_QNAME = "org/ballerinalang/jvm/values/XMLQName"; diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal index 737eaeb6464c..387b752bef0c 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_type_gen.bal @@ -951,6 +951,8 @@ function loadFiniteType(jvm:MethodVisitor mv, bir:BFiniteType finiteType) { if (value is ()) { mv.visitInsn(ACONST_NULL); + } else if (value is bir:Decimal) { + // do nothing } else { mv.visitLdcInsn(value); } @@ -962,10 +964,11 @@ function loadFiniteType(jvm:MethodVisitor mv, bir:BFiniteType finiteType) { } else if (value is float) { mv.visitMethodInsn(INVOKESTATIC, DOUBLE_VALUE, "valueOf", io:sprintf("(D)L%s;", DOUBLE_VALUE), false); } else if (value is byte) { - mv.visitMethodInsn(INVOKESTATIC, BYTE_VALUE, "valueOf", io:sprintf("(B)L%s;", BYTE_VALUE), false); + mv.visitMethodInsn(INVOKESTATIC, INT_VALUE, "valueOf", io:sprintf("(I)L%s;", INT_VALUE), false); } else if (value is bir:Decimal) { mv.visitTypeInsn(NEW, DECIMAL_VALUE); mv.visitInsn(DUP); + mv.visitLdcInsn(value.value); mv.visitMethodInsn(INVOKESPECIAL, DECIMAL_VALUE, "", io:sprintf("(L%s;)V", STRING_VALUE), false); } else { // if value is string or (), then do nothing diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java index 63ca40047155..4baa0c52aeed 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/TypeChecker.java @@ -2186,7 +2186,11 @@ public void visit(BLangXMLAttributeAccess xmlAttributeAccessExpr) { checkExpr(indexExpr, env, symTable.stringType); if (indexExpr.type.tag == TypeTags.STRING) { - actualType = BUnionType.create(null, symTable.stringType, symTable.nilType); + if (xmlAttributeAccessExpr.lhsVar) { + actualType = symTable.stringType; + } else { + actualType = BUnionType.create(null, symTable.stringType, symTable.nilType); + } } xmlAttributeAccessExpr.namespaces.putAll(symResolver.resolveAllNamespaces(env)); diff --git a/stdlib/bir/src/main/ballerina/bir/type_parser.bal b/stdlib/bir/src/main/ballerina/bir/type_parser.bal index 7f057b48a1b6..84a85e0ac85d 100644 --- a/stdlib/bir/src/main/ballerina/bir/type_parser.bal +++ b/stdlib/bir/src/main/ballerina/bir/type_parser.bal @@ -373,8 +373,6 @@ public type TypeParser object { } else if (valueType is BTypeString) { return self.readStringCpRef(); } else if (valueType is BTypeDecimal) { - - io:println("************"); return {value: self.readStringCpRef()}; } else if (valueType is BTypeBoolean) { return self.readInt8() == 1; From 530069688ce18fa02ef32355cf1b263a403b1144 Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Tue, 25 Jun 2019 22:28:36 +0530 Subject: [PATCH 3/5] Fix tests --- .../org/ballerinalang/jvm/TypeChecker.java | 15 +++---- .../org/ballerinalang/jvm/TypeConverter.java | 6 +-- .../jvm/values/DecimalValue.java | 2 - .../compiler_backend_jvm/jvm_cast_gen.bal | 1 + .../compiler/desugar/Desugar.java | 4 +- .../stdlib/config/EnvVarConfigTest.java | 6 +-- .../typecast/NumericConversionTest.java | 3 +- .../BinaryExprEvalPrecedenceTest.java | 19 ++++---- .../NativeConversionNegativeTest.java | 14 +++--- .../conversion/NativeConversionTest.java | 43 ++++++++----------- .../fieldaccess/SafeNavigationTest.java | 6 +-- .../statements/foreach/ForeachJSONTests.java | 12 +++--- .../bytetype/BByteValueNegativeTest.java | 6 +-- .../test/types/map/ConstrainedMapTest.java | 3 +- .../var/VarDeclaredAssignmentStmtTest.java | 4 +- 15 files changed, 63 insertions(+), 81 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java index e3fb73e402bd..5a4b1be11880 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeChecker.java @@ -86,7 +86,7 @@ public static Object checkCast(Object sourceVal, BType targetType) { // if the source is a numeric value and the target type is a union, try to find a matching // member. if (sourceType.getTag() <= TypeTags.BOOLEAN_TAG && targetType.getTag() == TypeTags.UNION_TAG) { - for(BType memberType : ((BUnionType) targetType).getMemberTypes()) { + for (BType memberType : ((BUnionType) targetType).getMemberTypes()) { try { return TypeConverter.castValues(memberType, sourceVal); } catch (Exception e) { @@ -99,21 +99,22 @@ public static Object checkCast(Object sourceVal, BType targetType) { } public static long anyToInt(Object sourceVal) { - return TypeConverter.anyToInt(sourceVal, () -> BallerinaErrors.createTypeCastError(sourceVal, BTypes.typeInt)); + return TypeConverter.anyToIntCast(sourceVal, + () -> BallerinaErrors.createTypeCastError(sourceVal, BTypes.typeInt)); } public static double anyToFloat(Object sourceVal) { - return TypeConverter.anyToFloat(sourceVal, () -> BallerinaErrors.createTypeCastError(sourceVal, + return TypeConverter.anyToFloatCast(sourceVal, () -> BallerinaErrors.createTypeCastError(sourceVal, BTypes.typeFloat)); } public static boolean anyToBoolean(Object sourceVal) { - return TypeConverter.anyToBoolean(sourceVal, () -> BallerinaErrors.createTypeCastError(sourceVal, + return TypeConverter.anyToBooleanCast(sourceVal, () -> BallerinaErrors.createTypeCastError(sourceVal, BTypes.typeBoolean)); } public static int anyToByte(Object sourceVal) { - return TypeConverter.anyToByte(sourceVal, () -> BallerinaErrors.createTypeCastError(sourceVal, + return TypeConverter.anyToByteCast(sourceVal, () -> BallerinaErrors.createTypeCastError(sourceVal, BTypes.typeByte)); } @@ -1134,10 +1135,6 @@ private static boolean isEqual(Object lhsValue, Object rhsValue, List return false; } - if (lhsValue.equals(rhsValue)) { - return true; - } - int lhsValTypeTag = getType(lhsValue).getTag(); int rhsValTypeTag = getType(rhsValue).getTag(); diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java index 3334574bb5da..a33683ded68f 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/TypeConverter.java @@ -124,7 +124,7 @@ static long anyToInt(Object sourceVal, Supplier errorFunc) { throw errorFunc.get(); } - private static long anyToIntCast(Object sourceVal, Supplier errorFunc) { + static long anyToIntCast(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { return (Long) sourceVal; } else if (sourceVal instanceof Double) { @@ -162,7 +162,7 @@ static double anyToFloat(Object sourceVal, Supplier errorFunc) { throw errorFunc.get(); } - private static double anyToFloatCast(Object sourceVal, Supplier errorFunc) { + static double anyToFloatCast(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { return ((Long) sourceVal).doubleValue(); } else if (sourceVal instanceof Double) { @@ -269,7 +269,7 @@ static int anyToByte(Object sourceVal, Supplier errorFunc) { throw errorFunc.get(); } - private static int anyToByteCast(Object sourceVal, Supplier errorFunc) { + static int anyToByteCast(Object sourceVal, Supplier errorFunc) { if (sourceVal instanceof Long) { return intToByte((Long) sourceVal); } else if (sourceVal instanceof Double) { diff --git a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java index 316971793e61..4014cb2ef36b 100644 --- a/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java +++ b/bvm/ballerina-runtime/src/main/java/org/ballerinalang/jvm/values/DecimalValue.java @@ -23,8 +23,6 @@ import org.ballerinalang.jvm.types.BType; import org.ballerinalang.jvm.types.BTypes; import org.ballerinalang.jvm.util.BLangConstants; -import org.ballerinalang.jvm.util.exceptions.BallerinaErrorReasons; -import org.ballerinalang.jvm.util.exceptions.BallerinaException; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal index e2d51668947d..9abce5f81564 100644 --- a/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal +++ b/compiler/ballerina-backend-jvm/src/main/ballerina/compiler_backend_jvm/jvm_cast_gen.bal @@ -266,6 +266,7 @@ function generateCheckCastToFiniteType(jvm:MethodVisitor mv, bir:BType sourceTyp // ------------------------------------------------------------------ // Generate Cast Methods - Performs cast without type checking // ------------------------------------------------------------------ + function generateCast(jvm:MethodVisitor mv, bir:BType sourceType, bir:BType targetType) { if (targetType is bir:BTypeInt) { generateCastToInt(mv, sourceType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java index 342f7cd6b056..63f9aabb964c 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java @@ -2941,9 +2941,7 @@ public void visit(BLangFunctionVarRef functionVarRef) { @Override public void visit(BLangStructFieldAccessExpr fieldAccessExpr) { - BType expType = fieldAccessExpr.type; - fieldAccessExpr.type = symTable.anyType; - result = addConversionExprIfRequired(fieldAccessExpr, expType); + result = fieldAccessExpr; } @Override diff --git a/stdlib/config-api/src/test/java/org/ballerinalang/stdlib/config/EnvVarConfigTest.java b/stdlib/config-api/src/test/java/org/ballerinalang/stdlib/config/EnvVarConfigTest.java index 76b9cf3e2dc6..f2b19bb8ffc8 100644 --- a/stdlib/config-api/src/test/java/org/ballerinalang/stdlib/config/EnvVarConfigTest.java +++ b/stdlib/config-api/src/test/java/org/ballerinalang/stdlib/config/EnvVarConfigTest.java @@ -171,16 +171,14 @@ public void testNonExistentEnvVarLookupForBoolean() { } @Test(expectedExceptions = BLangRuntimeException.class, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'string' value 'b7auser' cannot be " - + "converted as 'int'.*") + expectedExceptionsMessageRegExp = ".*'string' value 'b7auser' cannot be converted to 'int'.*") public void testInvalidIntEnvVarLookup() { BString key = new BString("user.name"); BRunUtil.invoke(compileResult, "testGetAsInt", new BValue[]{key}); } @Test(expectedExceptions = BLangRuntimeException.class, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'string' value 'b7auser' cannot be " - + "converted as 'float'.*") + expectedExceptionsMessageRegExp = ".*'string' value 'b7auser' cannot be converted to 'float'.*") public void testInvalidFloatEnvVarLookup() { BString key = new BString("user.name"); BRunUtil.invoke(compileResult, "testGetAsFloat", new BValue[]{key}); diff --git a/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java b/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java index 9fc0ddc1ab0b..48c3e517b13e 100644 --- a/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java +++ b/tests/ballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/NumericConversionTest.java @@ -16,7 +16,6 @@ */ package org.ballerinalang.test.expressions.typecast; -import org.ballerinalang.model.types.ValueType; import org.ballerinalang.model.values.BBoolean; import org.ballerinalang.model.values.BByte; import org.ballerinalang.model.values.BDecimal; @@ -188,7 +187,7 @@ public void testIntAsByte(String functionName, int i) { Assert.assertEquals(returns.length, 2); Assert.assertSame(returns[0].getClass(), BBoolean.class); Assert.assertTrue(((BBoolean) returns[0]).booleanValue(), "expected bytes to be the same"); - Assert.assertEquals(((ValueType) returns[1]).byteValue(), (new BInteger(i)).byteValue(), "incorrect int " + + Assert.assertEquals(((BValueType) returns[1]).byteValue(), (new BInteger(i)).byteValue(), "incorrect int " + "representation as byte"); } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/binaryoperations/BinaryExprEvalPrecedenceTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/binaryoperations/BinaryExprEvalPrecedenceTest.java index acd7359aeeba..f40820dc2fb6 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/binaryoperations/BinaryExprEvalPrecedenceTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/binaryoperations/BinaryExprEvalPrecedenceTest.java @@ -22,7 +22,6 @@ import org.ballerinalang.test.util.BCompileUtil; import org.ballerinalang.test.util.BRunUtil; import org.ballerinalang.test.util.CompileResult; -import org.ballerinalang.util.exceptions.BLangRuntimeException; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -56,16 +55,15 @@ public void testBinaryOrExprWithLeftMostExprTrue() { Assert.assertEquals(actualResult, expectedResult); } - //TODO this expected NullPointerException should be properly handled at ballerina layer when - //TODO accessing non existing JSON elements. - @Test(description = "Test binary OR expression with " + - "left most expr evaluated to false expression.", expectedExceptions = {BLangRuntimeException.class}) + @Test(description = "Test binary OR expression with left most expr evaluated to false expression.") public void testBinaryOrExprWithLeftMostExprFalseNegativeCase() { boolean one = false; boolean two = false; boolean three = false; BValue[] args = {new BBoolean(one), new BBoolean(two), new BBoolean(three)}; - BRunUtil.invoke(result, "binaryOrExprWithLeftMostSubExprTrue", args); + BValue[] returns = BRunUtil.invoke(result, "binaryOrExprWithLeftMostSubExprTrue", args); + boolean actualResult = ((BBoolean) returns[0]).booleanValue(); + Assert.assertEquals(actualResult, one); } @Test(description = "Test binary AND expression with left most expr evaluated to false expression.") @@ -85,16 +83,15 @@ public void testBinaryAndExprWithLeftMostExprTrue() { Assert.assertEquals(actualResult, expectedResult); } - //TODO this expected NullPointerException should be properly handled at ballerina layer when - //TODO accessing non existing JSON elements. - @Test(description = "Test binary AND expression with " + - "left most expr evaluated to true expression.", expectedExceptions = {BLangRuntimeException.class}) + @Test(description = "Test binary AND expression with left most expr evaluated to true expression.") public void testBinaryAndExprWithLeftMostExprFalseNegativeCase() { boolean one = true; boolean two = false; boolean three = false; BValue[] args = {new BBoolean(one), new BBoolean(two), new BBoolean(three)}; - BRunUtil.invoke(result, "binaryANDExprWithLeftMostSubExprFalse", args); + BValue[] returns = BRunUtil.invoke(result, "binaryANDExprWithLeftMostSubExprFalse", args); + boolean actualResult = ((BBoolean) returns[0]).booleanValue(); + Assert.assertEquals(actualResult, false); } @Test(description = "Test multi binary expression with OR sub expressions inside If condition.") diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionNegativeTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionNegativeTest.java index 93057cdf6bd9..6967de957182 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionNegativeTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionNegativeTest.java @@ -60,7 +60,7 @@ public void testIncompatibleJsonToStructWithErrors() { // check the error Assert.assertTrue(returns[0] instanceof BError); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'json' value cannot be converted as 'Person'"); + Assert.assertEquals(errorMsg, "'json' value cannot be converted to 'Person'"); } @Test @@ -68,7 +68,7 @@ public void testEmptyJSONtoStructWithoutDefaults() { BValue[] returns = BRunUtil.invoke(negativeResult, "testEmptyJSONtoStructWithoutDefaults"); Assert.assertTrue(returns[0] instanceof BError); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'json' value cannot be converted as " + Assert.assertEquals(errorMsg, "'json' value cannot be converted to " + "'StructWithoutDefaults'"); } @@ -77,7 +77,7 @@ public void testEmptyMaptoStructWithDefaults() { BValue[] returns = BRunUtil.invoke(negativeResult, "testEmptyMaptoStructWithDefaults"); Assert.assertTrue(returns[0] instanceof BError); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'map' value cannot be converted as " + Assert.assertEquals(errorMsg, "'map' value cannot be converted to " + "'StructWithDefaults'"); } @@ -86,7 +86,7 @@ public void testEmptyMaptoStructWithoutDefaults() { BValue[] returns = BRunUtil.invoke(negativeResult, "testEmptyMaptoStructWithoutDefaults"); Assert.assertTrue(returns[0] instanceof BError); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'map' value cannot be converted as " + Assert.assertEquals(errorMsg, "'map' value cannot be converted to " + "'StructWithoutDefaults'"); } @@ -94,7 +94,7 @@ public void testEmptyMaptoStructWithoutDefaults() { public void testTupleConversionFail() { BValue[] returns = BRunUtil.invoke(negativeResult, "testTupleConversionFail"); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: '(T1,T1)' value cannot be converted as '(T1," + Assert.assertEquals(errorMsg, "'(T1,T1)' value cannot be converted to '(T1," + "T2)'"); } @@ -103,7 +103,7 @@ public void testArrayToJsonFail() { BValue[] returns = BRunUtil.invoke(negativeResult, "testArrayToJsonFail"); Assert.assertTrue(returns[0] instanceof BError); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'TX[]' value cannot be converted as 'json'"); + Assert.assertEquals(errorMsg, "'TX[]' value cannot be converted to 'json'"); } @Test(description = "Test passing tainted value with convert") @@ -140,7 +140,7 @@ public void testIncompatibleImplicitConversion() { BValue[] returns = BRunUtil.invoke(negativeResult, "testIncompatibleImplicitConversion"); Assert.assertTrue(returns[0] instanceof BError); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, "incompatible convert operation: 'string' value 'abjd' cannot be converted as " + Assert.assertEquals(errorMsg, "'string' value 'abjd' cannot be converted to " + "'int'"); } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionTest.java index 0ee3f112b227..bc688762ed9f 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/conversion/NativeConversionTest.java @@ -232,8 +232,7 @@ public void testMapToJsonConversion() { @Test(description = "Test converting a struct with map of blob to a JSON", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'Info2' value cannot be converted as" - + " 'json'.*") + expectedExceptionsMessageRegExp = ".*'Info2' value cannot be converted to 'json'.*") public void testStructWithIncompatibleTypeToJson() { BRunUtil.invoke(compileResult, "testStructWithIncompatibleTypeToJson"); } @@ -263,22 +262,21 @@ public void testMapWithMissingOptionalFieldsToStruct() { @Test(description = "Test converting a map with incompatible inner array to a struct", expectedExceptions = { BLangRuntimeException.class }, expectedExceptionsMessageRegExp = - ".*incompatible convert operation: 'map' value cannot be converted as 'Person'.*") + ".*'map' value cannot be converted to 'Person'.*") public void testMapWithIncompatibleArrayToStruct() { BRunUtil.invoke(compileResult, "testMapWithIncompatibleArrayToStruct"); } @Test(description = "Test converting a map with incompatible inner struct to a struct", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'map' value cannot be converted " - + "as 'Employee'.*") + expectedExceptionsMessageRegExp = ".*'map' value cannot be converted to 'Employee'.*") public void testMapWithIncompatibleStructToStruct() { BRunUtil.invoke(compileResult, "testMapWithIncompatibleStructToStruct"); } @Test(description = "Test converting a incompatible JSON to a struct", expectedExceptions = {BLangRuntimeException.class}, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'json' value cannot be converted as " + expectedExceptionsMessageRegExp = ".*'json' value cannot be converted to " + "'Person'.*") public void testIncompatibleJsonToStruct() { BRunUtil.invoke(compileResult, "testIncompatibleJsonToStruct"); @@ -295,48 +293,45 @@ public void testJsonToStructWithMissingOptionalFields() { @Test(description = "Test converting a incompatible JSON to a struct", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"incompatible " - + "convert operation: 'json' value cannot be converted as 'Person'\"\\}.*") + expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"'json' value " + + "cannot be converted to 'Person'\"\\}.*") public void testJsonToStructWithMissingRequiredFields() { BRunUtil.invoke(compileResult, "testJsonToStructWithMissingRequiredFields"); } @Test(description = "Test converting a JSON with incompatible inner map to a struct", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"incompatible " - + "convert operation: 'json' value cannot be converted as 'Person'\"\\}.*") + expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"'json' value " + + "cannot be converted to 'Person'\"\\}.*") public void testJsonWithIncompatibleMapToStruct() { BRunUtil.invoke(compileResult, "testJsonWithIncompatibleMapToStruct"); } @Test(description = "Test converting a JSON with incompatible inner struct to a struct", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"incompatible " - + "convert operation: 'json' value cannot be converted as 'Person'\"\\}.*") + expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"'json' value " + + "cannot be converted to 'Person'\"\\}.*") public void testJsonWithIncompatibleStructToStruct() { BRunUtil.invoke(compileResult, "testJsonWithIncompatibleStructToStruct"); } @Test(description = "Test converting a JSON array to a struct", expectedExceptions = {BLangRuntimeException.class}, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'json\\[\\]' value cannot be converted" - + " as 'Person'.*") + expectedExceptionsMessageRegExp = ".*'json\\[\\]' value cannot be converted to 'Person'.*") public void testJsonArrayToStruct() { BRunUtil.invoke(compileResult, "testJsonArrayToStruct"); } @Test(description = "Test converting a JSON with incompatible inner type to a struct", expectedExceptions = {BLangRuntimeException.class}, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'json' value cannot be converted as " - + "'Person'.*") + expectedExceptionsMessageRegExp = ".*'json' value cannot be converted to 'Person'.*") public void testJsonWithIncompatibleTypeToStruct() { BRunUtil.invoke(compileResult, "testJsonWithIncompatibleTypeToStruct"); } @Test(description = "Test converting a struct with map of blob to a JSON", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'Info' value cannot be converted as " - + "'json'.*") + expectedExceptionsMessageRegExp = ".*'Info' value cannot be converted to 'json'.*") public void testStructWithIncompatibleTypeMapToJson() { BRunUtil.invoke(compileResult, "testStructWithIncompatibleTypeMapToJson"); } @@ -399,7 +394,7 @@ public void testJsonIntArrayToStringArray() { @Test(description = "Test converting a JSON array to xml array", expectedExceptions = {BLangRuntimeException.class}, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'json' value cannot be converted as " + expectedExceptionsMessageRegExp = ".*'json' value cannot be converted to " + "'XmlArray.*") public void testJsonToXmlArray() { BRunUtil.invoke(compileResult, "testJsonToXmlArray"); @@ -416,15 +411,15 @@ public void testNullJsonToArray() { @Test(description = "Test converting a JSON null to string array", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"incompatible " - + "convert operation: 'json' value cannot be converted as 'StringArray'\"\\}.*") + expectedExceptionsMessageRegExp = "error: \\{ballerina\\}ConversionError \\{\"message\":\"'json' value " + + "cannot be converted to 'StringArray'\"\\}.*") public void testNullJsonArrayToArray() { BRunUtil.invoke(compileResult, "testNullJsonArrayToArray"); } @Test(description = "Test converting a JSON string to string array", expectedExceptions = {BLangRuntimeException.class}, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'json' value cannot be converted as " + expectedExceptionsMessageRegExp = ".*'json' value cannot be converted to " + "'StringArray.*") public void testNonArrayJsonToArray() { BRunUtil.invoke(compileResult, "testNonArrayJsonToArray"); @@ -583,7 +578,7 @@ public void testJsonToMapConstrained2() { @Test(description = "Test converting json to constrained map", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'json' value cannot be converted as " + expectedExceptionsMessageRegExp = ".*'json' value cannot be converted to " + "'map'.*") public void testJsonToMapConstrainedFail() { BRunUtil.invoke(compileResult, "testJsonToMapConstrainedFail"); @@ -655,7 +650,7 @@ public void testJsonToArray2() { @Test(description = "Test an invalid json to array conversion", expectedExceptions = { BLangRuntimeException.class }, - expectedExceptionsMessageRegExp = ".*incompatible convert operation: 'json' value cannot be converted as " + expectedExceptionsMessageRegExp = ".*'json' value cannot be converted to " + "'int\\[\\]'.*") public void testJsonToArrayFail() { BRunUtil.invoke(compileResult, "testJsonToArrayFail"); diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/fieldaccess/SafeNavigationTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/fieldaccess/SafeNavigationTest.java index b4babb59ffe8..4283ce16dda1 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/fieldaccess/SafeNavigationTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/fieldaccess/SafeNavigationTest.java @@ -231,9 +231,9 @@ public void testJSONNilLiftingOnLHS_1() { Assert.assertEquals(returns[3].stringValue(), "{\"info\":{\"address4\":{\"city\":\"Jaffna\"}}}"); } - @Test(expectedExceptions = {BLangRuntimeException.class}, - expectedExceptionsMessageRegExp = "error: failed to get element from json: " + - "\\{\"message\":\"array index out of range: index: 2, size: 0\"\\}.*") + @Test(expectedExceptions = { BLangRuntimeException.class }, + expectedExceptionsMessageRegExp = "error: failed to get element from json: array index out of range:" + + " index: 2, size: 0.*") public void testJSONNilLiftingOnLHS_2() { BRunUtil.invoke(result, "testJSONNilLiftingOnLHS_2"); } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/foreach/ForeachJSONTests.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/foreach/ForeachJSONTests.java index f3a499069549..8e7c3ba1b03d 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/foreach/ForeachJSONTests.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/foreach/ForeachJSONTests.java @@ -65,8 +65,8 @@ public void testArrayOfJSON() { @Test public void testJSONString() { - String result = "{ballerina}ConversionError {\"message\":\"incompatible convert operation: 'string' value " - + "cannot be converted as 'map'\"}"; + String result = "{ballerina}ConversionError {\"message\":\"'string' value " + + "cannot be converted to 'map'\"}"; BValue[] returns = BRunUtil.invoke(program, "testJSONString"); Assert.assertEquals(returns.length, 1); Assert.assertEquals(returns[0].stringValue(), result); @@ -74,8 +74,8 @@ public void testJSONString() { @Test public void testJSONNumber() { - String result = "{ballerina}ConversionError {\"message\":\"incompatible convert operation: 'int' value cannot" - + " be converted as 'map'\"}"; + String result = "{ballerina}ConversionError {\"message\":\"'int' value cannot" + + " be converted to 'map'\"}"; BValue[] returns = BRunUtil.invoke(program, "testJSONNumber"); Assert.assertEquals(returns.length, 1); Assert.assertEquals(returns[0].stringValue(), result); @@ -83,8 +83,8 @@ public void testJSONNumber() { @Test public void testJSONBoolean() { - String result = "{ballerina}ConversionError {\"message\":\"incompatible convert operation: 'boolean' value " - + "cannot be converted as 'map'\"}"; + String result = "{ballerina}ConversionError {\"message\":\"'boolean' value " + + "cannot be converted to 'map'\"}"; BValue[] returns = BRunUtil.invoke(program, "testJSONBoolean"); Assert.assertEquals(returns.length, 1); Assert.assertEquals(returns[0].stringValue(), result); diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/bytetype/BByteValueNegativeTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/bytetype/BByteValueNegativeTest.java index 9991459e3e80..baf1cb328259 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/bytetype/BByteValueNegativeTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/bytetype/BByteValueNegativeTest.java @@ -95,7 +95,7 @@ public void byteValueRuntimeNegative1() { Assert.assertEquals(returnValue.length, 1); Assert.assertTrue(returnValue[0] instanceof BError); Assert.assertEquals(returnValue[0].stringValue(), "{ballerina}NumberConversionError {\"message\":" + - "\"incompatible convert operation: 'int' value '-12' cannot be converted as 'byte'\"}"); + "\"'int' value '-12' cannot be converted to 'byte'\"}"); } @Test(description = "Test int to byte conversion negative") @@ -104,7 +104,7 @@ public void byteValueRuntimeNegative2() { Assert.assertEquals(returnValue.length, 1); Assert.assertTrue(returnValue[0] instanceof BError); Assert.assertEquals(returnValue[0].stringValue(), "{ballerina}NumberConversionError {\"message\":" + - "\"incompatible convert operation: 'int' value '-257' cannot be converted as 'byte'\"}"); + "\"'int' value '-257' cannot be converted to 'byte'\"}"); } @Test(description = "Test int to byte conversion negative") @@ -113,6 +113,6 @@ public void byteValueRuntimeNegative3() { Assert.assertEquals(returnValue.length, 1); Assert.assertTrue(returnValue[0] instanceof BError); Assert.assertEquals(returnValue[0].stringValue(), "{ballerina}NumberConversionError {\"message\":" + - "\"incompatible convert operation: 'int' value '12,345' cannot be converted as 'byte'\"}"); + "\"'int' value '12,345' cannot be converted to 'byte'\"}"); } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/map/ConstrainedMapTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/map/ConstrainedMapTest.java index 59f7dd0c09b2..d04acb724f6a 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/map/ConstrainedMapTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/map/ConstrainedMapTest.java @@ -431,8 +431,7 @@ public void testJsonToStructConversionStructWithConstrainedMapNegative() { "testJsonToStructConversionStructWithConstrainedMapNegative"); Assert.assertTrue(returns[0] instanceof BError); String errorMsg = ((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(); - Assert.assertEquals(errorMsg, - "incompatible convert operation: 'json' value cannot be converted as 'PersonComplexTwo'"); + Assert.assertEquals(errorMsg, "'json' value cannot be converted to 'PersonComplexTwo'"); } @Test(description = "Test constrained map with union retrieving string value.") diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/var/VarDeclaredAssignmentStmtTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/var/VarDeclaredAssignmentStmtTest.java index 6690ea74e438..b0d2b5e3dd85 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/var/VarDeclaredAssignmentStmtTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/var/VarDeclaredAssignmentStmtTest.java @@ -207,7 +207,7 @@ public void testIncompatibleJsonToStructWithErrors() { Assert.assertSame(returns[0].getClass(), BError.class); Assert.assertEquals(((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(), - "incompatible convert operation: 'json' value cannot be converted as 'Person'"); + "'json' value cannot be converted to 'Person'"); } @Test(description = "Test incompatible json to struct with errors.") @@ -219,7 +219,7 @@ public void testJsonToStructWithErrors() { Assert.assertSame(returns[0].getClass(), BError.class); Assert.assertEquals(((BMap) ((BError) returns[0]).getDetails()).get("message").stringValue(), - "incompatible convert operation: 'json' value cannot be converted as 'PersonA'"); + "'json' value cannot be converted to 'PersonA'"); } @Test(description = "Test compatible struct with force casting.") From 5e3c59a80482828798c1c245aa16d446c3ef995a Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Thu, 27 Jun 2019 10:48:58 +0530 Subject: [PATCH 4/5] Fixing tests --- .../foreach-arrays-typed-binding-patterns.bal | 74 ++++++++----------- .../src/test/resources/testng.xml | 2 +- 2 files changed, 31 insertions(+), 45 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/statements/foreach/foreach-arrays-typed-binding-patterns.bal b/tests/jballerina-unit-test/src/test/resources/test-src/statements/foreach/foreach-arrays-typed-binding-patterns.bal index 36e6e47232ed..ae526ba8a60f 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/statements/foreach/foreach-arrays-typed-binding-patterns.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/statements/foreach/foreach-arrays-typed-binding-patterns.bal @@ -1,5 +1,3 @@ -string output = ""; - type Data record { int i; string v; @@ -15,92 +13,80 @@ type Data3 record { [int, string] v; }; -function concatIntString(int i, string s) { - output = output + i + ":" + s + " "; -} - -function concatIntStringFloat(int i, string s, float f) { - output = output + i + ":" + s + ":" + f + " "; -} - -function concatIntIntString(int i1, int i2, string s) { - output = output + i1 + ":" + i2 + ":" + s + " "; -} - // --------------------------------------------------------------------------------------------------------------------- function testArrayWithSimpleVariableWithoutType() returns string { - output = ""; + string output = ""; string[] arr = ["A", "B", "C"]; int i = 0; foreach var v in arr { - concatIntString(i, v); + output = output + i + ":" + v + " "; i += 1; } return output; } function testArrayWithSimpleVariableWithType() returns string { - output = ""; + string output = ""; string[] arr = ["A", "B", "C"]; int i = 0; foreach string v in arr { - concatIntString(i, v); + output = output + i + ":" + v + " "; i += 1; } return output; } function testArrayWithTupleWithoutType() returns string { - output = ""; + string output = ""; [int, string][] arr = [[1, "A"], [2, "B"], [3, "C"]]; foreach var [i, v] in arr { - concatIntString(i, v); + output = output + i + ":" + v + " "; } return output; } function testArrayWithTupleWithType() returns string { - output = ""; + string output = ""; [int, string][] arr = [[1, "A"], [2, "B"], [3, "C"]]; foreach [int, string] [i, v] in arr { - concatIntString(i, v); + output = output + i + ":" + v + " "; } return output; } function testArrayWithTupleInTupleWithoutType() returns string { - output = ""; + string output = ""; [int, [string, float]][] arr = [[1, ["A", 2.0]], [2, ["B", 3.0]], [3, ["C", 4.0]]]; foreach var [i, [s, f]] in arr { - concatIntStringFloat(i, s, f); + output = output + i + ":" + s + ":" + f + " "; } return output; } function testArrayWithTupleInTupleWithType() returns string { - output = ""; + string output = ""; [int, [string, float]][] arr = [[1, ["A", 2.0]], [2, ["B", 3.0]], [3, ["C", 4.0]]]; foreach [int, [string, float]] [i, [s, f]] in arr { - concatIntStringFloat(i, s, f); + output = output + i + ":" + s + ":" + f + " "; } return output; } function testArrayWithRecordInTupleWithoutType() returns string { - output = ""; + string output = ""; Data d1 = { i: 1, v: "A" }; Data d2 = { i: 2, v: "B" }; @@ -109,13 +95,13 @@ function testArrayWithRecordInTupleWithoutType() returns string { [int, Data][] arr = [[1, d1], [2, d2], [3, d3]]; foreach var [i, {i: j, v: k}] in arr { - concatIntIntString(i, j, k); + output = output + i + ":" + i + ":" + k + " "; } return output; } function testArrayWithRecordInTupleWithType() returns string { - output = ""; + string output = ""; Data d1 = { i: 1, v: "A" }; Data d2 = { i: 2, v: "B" }; @@ -124,13 +110,13 @@ function testArrayWithRecordInTupleWithType() returns string { [int, Data][] arr = [[1, d1], [2, d2], [3, d3]]; foreach [int, Data] [i, {i: j, v: k}] in arr { - concatIntIntString(i, j, k); + output = output + i + ":" + i + ":" + k + " "; } return output; } function testArrayWithRecordWithoutType() returns string { - output = ""; + string output = ""; Data d1 = { i: 1, v: "A" }; Data d2 = { i: 2, v: "B" }; @@ -139,13 +125,13 @@ function testArrayWithRecordWithoutType() returns string { Data[] arr = [d1, d2, d3]; foreach var {i, v} in arr { - concatIntString(i, v); + output = output + i + ":" + v + " "; } return output; } function testArrayWithRecordWithType() returns string { - output = ""; + string output = ""; Data d1 = { i: 1, v: "A" }; Data d2 = { i: 2, v: "B" }; @@ -154,13 +140,13 @@ function testArrayWithRecordWithType() returns string { Data[] arr = [d1, d2, d3]; foreach Data {i, v} in arr { - concatIntString(i, v); + output = output + i + ":" + v + " "; } return output; } function testArrayWithRecordInRecordWithoutType() returns string { - output = ""; + string output = ""; Data d11 = { i: 1, v: "A" }; Data d12 = { i: 2, v: "B" }; @@ -173,13 +159,13 @@ function testArrayWithRecordInRecordWithoutType() returns string { Data2[] arr = [d21, d22, d23]; foreach var {i, v: {i: j, v: k}} in arr { - concatIntIntString(i, j, k); + output = output + i + ":" + i + ":" + k + " "; } return output; } function testArrayWithRecordInRecordWithType() returns string { - output = ""; + string output = ""; Data d11 = { i: 1, v: "A" }; Data d12 = { i: 2, v: "B" }; @@ -192,13 +178,13 @@ function testArrayWithRecordInRecordWithType() returns string { Data2[] arr = [d21, d22, d23]; foreach Data2 {i, v: {i: j, v: k}} in arr { - concatIntIntString(i, j, k); + output = output + i + ":" + i + ":" + k + " "; } return output; } function testArrayWithTupleInRecordWithoutType() returns string { - output = ""; + string output = ""; Data3 d1 = { i: 1, v: [1, "A"] }; Data3 d2 = { i: 2, v: [2, "B"] }; @@ -207,13 +193,13 @@ function testArrayWithTupleInRecordWithoutType() returns string { Data3[] arr = [d1, d2, d3]; foreach var {i, v: [j, k]} in arr { - concatIntIntString(i, j, k); + output = output + i + ":" + i + ":" + k + " "; } return output; } function testArrayWithTupleInRecordWithType() returns string { - output = ""; + string output = ""; Data3 d1 = { i: 1, v: [1, "A"] }; Data3 d2 = { i: 2, v: [2, "B"] }; @@ -222,7 +208,7 @@ function testArrayWithTupleInRecordWithType() returns string { Data3[] arr = [d1, d2, d3]; foreach Data3 {i, v: [j, k]} in arr { - concatIntIntString(i, j, k); + output = output + i + ":" + i + ":" + k + " "; } return output; } @@ -230,13 +216,13 @@ function testArrayWithTupleInRecordWithType() returns string { // --------------------------------------------------------------------------------------------------------------------- function testEmptyArrayIteration() returns string { - output = ""; + string output = ""; string[] arr = []; int i = 0; foreach var v in arr { - concatIntString(i, v); + output = output + i + ":" + v + " "; i += 1; } return output; diff --git a/tests/jballerina-unit-test/src/test/resources/testng.xml b/tests/jballerina-unit-test/src/test/resources/testng.xml index 5bb7759b8037..43cd7ddd3344 100644 --- a/tests/jballerina-unit-test/src/test/resources/testng.xml +++ b/tests/jballerina-unit-test/src/test/resources/testng.xml @@ -27,7 +27,7 @@ - + From fc0b4b21e5b475862f57db21a49fa582ec82b719 Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Thu, 27 Jun 2019 11:08:38 +0530 Subject: [PATCH 5/5] Disable lang-server completion tests --- .../modules/langserver-core/src/test/resources/testng.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language-server/modules/langserver-core/src/test/resources/testng.xml b/language-server/modules/langserver-core/src/test/resources/testng.xml index 59c60dfbb665..52c2db5c406a 100644 --- a/language-server/modules/langserver-core/src/test/resources/testng.xml +++ b/language-server/modules/langserver-core/src/test/resources/testng.xml @@ -27,7 +27,7 @@ under the License. - +