diff --git a/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java b/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java index 5511875c6e34..1a2f2f72ce51 100644 --- a/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java +++ b/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java @@ -318,6 +318,7 @@ public enum DiagnosticCode { UNSUPPORTED_METHOD_INVOCATION_XML_NAV("method.invocation.in.xml.navigation.expressions.not.supported"), DEPRECATED_XML_ATTRIBUTE_ACCESS("deprecated.xml.attribute.access.expression"), UNSUPPORTED_INDEX_IN_XML_NAVIGATION("indexing.within.xml.navigation.expression.not.supported"), + DEPRECATED_XML_CHILD_ACCESS("deprecated.xml.child.access"), UNDEFINED_ANNOTATION("undefined.annotation"), ANNOTATION_NOT_ALLOWED("annotation.not.allowed"), 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 32fd2ef27d72..94688a586306 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 @@ -4640,7 +4640,15 @@ private BType checkIndexAccessExpr(BLangIndexBasedAccess indexBasedAccessExpr) { return actualType; } - checkExpr(indexExpr, this.env); + BType indexExprType = checkExpr(indexExpr, this.env); + if (types.isAssignable(indexExprType, symTable.stringType)) { + dlog.warning(indexBasedAccessExpr.pos, DiagnosticCode.DEPRECATED_XML_CHILD_ACCESS); + } else if (!types.isAssignable(indexExprType, symTable.intType)) { + dlog.error( + indexBasedAccessExpr.pos, DiagnosticCode.INCOMPATIBLE_TYPES, symTable.intType, indexExprType); + return symTable.semanticError; + } + actualType = symTable.xmlType; indexBasedAccessExpr.originalType = actualType; } else if (varRefType == symTable.semanticError) { diff --git a/compiler/ballerina-lang/src/main/resources/compiler.properties b/compiler/ballerina-lang/src/main/resources/compiler.properties index 037b877603a2..11c7e5fb6044 100644 --- a/compiler/ballerina-lang/src/main/resources/compiler.properties +++ b/compiler/ballerina-lang/src/main/resources/compiler.properties @@ -1121,6 +1121,10 @@ warning.usage.of.deprecated.construct=\ warning.non.module.qualified.error.reason=\ error reason ''{0}'' is not module qualified +warning.deprecated.xml.child.access=\ + xml child access using member access is deprecated and will be removed in the next minor release. xml \ + step expressions can now be used to access children. + error.redeclared.import.module=\ redeclared import module ''{0}'' diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/xml/XMLAccessTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/xml/XMLAccessTest.java index d3387b317d9e..e760bd1ee216 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/xml/XMLAccessTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/types/xml/XMLAccessTest.java @@ -213,9 +213,18 @@ public void testXMLNavigationExpressionWithQuotedIdentifiers() { @Test public void testInvalidXMLAccessWithIndex() { - BAssertUtil.validateError(negativeResult, 0, "cannot update an xml sequence", 5, 5); + int i = 0; + BAssertUtil.validateError(negativeResult, i++, "cannot update an xml sequence", 5, 5); + BAssertUtil.validateError(negativeResult, i++, "cannot update an xml sequence", 13, 5); + BAssertUtil.validateError(negativeResult, i++, "invalid assignment in variable 'x1/*'", 13, 5); + BAssertUtil.validateWarning(negativeResult, i++, "xml child access using member access is deprecated and " + + "will be removed in the next minor release. xml step expressions can now be used to access children.", + 18, 13); + BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'boolean'", 19, 13); + BAssertUtil.validateError(negativeResult, i++, "incompatible types: expected 'int', found 'float'", 20, 13); - BAssertUtil.validateError(negativeResult, 1, "cannot update an xml sequence", 13, 5); + Assert.assertEquals(negativeResult.getErrorCount(), i - 1); + Assert.assertEquals(negativeResult.getWarnCount(), 1); } @Test diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/types/xml/xml-indexed-access-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/types/xml/xml-indexed-access-negative.bal index 3665aa31d5c2..e23fce8c8cdd 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/types/xml/xml-indexed-access-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/types/xml/xml-indexed-access-negative.bal @@ -12,3 +12,10 @@ function testUpdatingGetAllChildren() { xml x2 = xml `<fruit>apple</fruit>`; x1/* = x2; } + +function testNonStringIndexAccess() { + xml x = xml `<elem></elem>`; + var c = x["child"]; + var k = x[true]; + var b = x[1.2]; +}