Skip to content

Commit

Permalink
Merge pull request #42150 from poorna2152/xml_union_indexed_access
Browse files Browse the repository at this point in the history
Fix indexed access on xml union type
  • Loading branch information
KavinduZoysa authored Mar 21, 2024
2 parents 09064f7 + 38c36c4 commit ad6109c
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2808,7 +2808,7 @@ private void generateMappingAccess(BLangIndexBasedAccess astIndexBasedAccessExpr
if (astIndexBasedAccessExpr.getKind() == NodeKind.XML_ATTRIBUTE_ACCESS_EXPR) {
insKind = InstructionKind.XML_ATTRIBUTE_LOAD;
keyRegIndex = getQNameOP(astIndexBasedAccessExpr.indexExpr, keyRegIndex);
} else if (TypeTags.isXMLTypeTag(astAccessExprExprType.tag)) {
} else if (types.isAssignable(astAccessExprExprType, symTable.xmlType)) {
generateXMLAccess((BLangXMLAccessExpr) astIndexBasedAccessExpr, tempVarRef, varRefRegIndex,
keyRegIndex);
this.varAssignment = variableStore;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ private void generateFrameClassFieldLoad(List<BIRVariableDcl> localVars, MethodV
mv.visitFieldInsn(GETFIELD, frameName, localVar.jvmVarName,
GET_BSTRING);
mv.visitVarInsn(ASTORE, index);
} else if (TypeTags.isXMLTypeTag(bType.tag)) {
} else if (types.isAssignable(bType, symbolTable.xmlType)) {
mv.visitFieldInsn(GETFIELD, frameName, localVar.jvmVarName,
GET_XML);
mv.visitVarInsn(ASTORE, index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6433,7 +6433,7 @@ public void visit(BLangIndexBasedAccess indexAccessExpr) {
} else if (types.isSubTypeOfList(varRefType)) {
targetVarRef = new BLangArrayAccessExpr(indexAccessExpr.pos, indexAccessExpr.expr,
indexAccessExpr.indexExpr);
} else if (TypeTags.isXMLTypeTag(varRefType.tag)) {
} else if (types.isAssignable(varRefType, symTable.xmlType)) {
targetVarRef = new BLangXMLAccessExpr(indexAccessExpr.pos, indexAccessExpr.expr,
indexAccessExpr.indexExpr);
} else if (types.isAssignable(varRefType, symTable.stringType)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8703,7 +8703,7 @@ private BType checkIndexAccessExpr(BLangIndexBasedAccess indexBasedAccessExpr, A

indexBasedAccessExpr.originalType = symTable.charStringType;
actualType = symTable.charStringType;
} else if (TypeTags.isXMLTypeTag(varRefType.tag)) {
} else if (types.isAssignable(varRefType, symTable.xmlType)) {
if (indexBasedAccessExpr.isLValue) {
indexExpr.setBType(symTable.semanticError);
dlog.error(indexBasedAccessExpr.pos, DiagnosticErrorCode.CANNOT_UPDATE_XML_SEQUENCE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ public void testLengthOfXMLSequence() {
Assert.assertEquals(returns.get(3), 2L);
}

@Test
public void testInvalidXMLUnionAccessWithNegativeIndex() {
BRunUtil.invoke(result, "testInvalidXMLUnionAccessWithNegativeIndex");
}

@Test
public void testInvalidXMLAccessWithNegativeIndex() {
BRunUtil.invoke(result, "testInvalidXMLAccessWithNegativeIndex");
Expand All @@ -269,6 +274,11 @@ public void testXmlAccessWithLargerIndex() {
BRunUtil.invoke(result, "testXmlAccessWithLargerIndex");
}

@Test
public void testXmlIndexedAccessWithUnionType() {
BRunUtil.invoke(result, "testXmlIndexedAccessWithUnionType");
}

@Test
public void testXMLNavExpressionNegative() {
String methodInvocMessage = "method invocations are not yet supported within XML navigation expressions, " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,150 @@ function testXmlAccessWithLargerIndex() {
assert(xmlValue, xml ``);
}

type XmlType1 xml:Text|xml:Comment;

type XmlType2 xml<xml:Element|xml:ProcessingInstruction>;

type XmlType3 XmlType1|XmlType2;

function testXmlIndexedAccessWithUnionType() {
xml value;
xml:Element|xml:Comment x1 = xml `<a>abc</a>`;
value = x1[0];
assert(value, xml `<a>abc</a>`);
assertTrue(typeof value is typedesc<xml:Element>);
value = x1[1];
assert(value, xml ``);
assertTrue(typeof value is typedesc<xml:Text>);

xml:Element|xml:Text x2 = xml `Hello World`;
value = x2[0];
assert(value, xml `Hello World`);
assertTrue(typeof value is typedesc<xml:Text>);
value = x2[0][1];
assert(value, xml ``);
assertTrue(typeof value is typedesc<xml:Text>);

xml:Element|xml:ProcessingInstruction x3 = xml `<?target data?>`;
value = x3[0];
assert(value, xml `<?target data?>`);
assertTrue(typeof value is typedesc<xml:ProcessingInstruction>);
value = x3[1][100];
assert(value, xml ``);
assertTrue(typeof value is typedesc<xml:Text>);

xml:Element|xml:Comment x4 = xml `<!-- comment node-->`;
value = x4[0];
assert(value, xml `<!-- comment node-->`);
assertTrue(typeof value is typedesc<xml:Comment>);
value = x4[10];
assert(value, xml ``);
assertTrue(typeof value is typedesc<xml:Text>);

xml:Text|xml:Comment x5 = xml `<!-- comment node 2 -->`;
value = x5[0];
assert(value, xml `<!-- comment node 2 -->`);
assertTrue(typeof value is typedesc<xml:Comment>);

xml:ProcessingInstruction|xml:Comment x6 = xml `<?target test?>`;
value = x6[0];
assert(value, xml `<?target test?>`);
assertTrue(typeof value is typedesc<xml:ProcessingInstruction>);

xml:ProcessingInstruction|xml:Text x7 = xml `Test Text`;
value = x7[0];
assert(value, xml `Test Text`);
assertTrue(typeof value is typedesc<xml:Text>);

xml|xml:Comment x8 = xml `<a>abc</a><b>def</b>`;
value = x8[0];
assert(value, xml `<a>abc</a>`);
assertTrue(typeof value is typedesc<xml:Element>);

xml|xml x9 = xml `<c>ghi</c><d>jkl</d>`;
value = x9[0];
assert(value, xml `<c>ghi</c>`);
assertTrue(typeof value is typedesc<xml:Element>);

xml<xml:Text|xml:Comment>|xml<xml:ProcessingInstruction|xml:Element> x10 = xml `<name>Dan Brown</name>`;
value = x10[0];
assert(value, xml `<name>Dan Brown</name>`);
assertTrue(typeof value is typedesc<xml:Element>);
value = x10[1];
assert(value, xml ``);
assertTrue(typeof value is typedesc<xml:Text>);

XmlType1 x11 = xml `Hello!`;
value = x11[0];
assert(value, xml `Hello!`);
assertTrue(typeof value is typedesc<xml:Text>);

XmlType2 x12 = xml `<name>Sherlock Holmes</name><work>Detective</work>`;
value = x12[0];
assert(value, xml `<name>Sherlock Holmes</name>`);
assertTrue(typeof value is typedesc<xml:Element>);
value = x12[1];
assert(value, xml `<work>Detective</work>`);
assertTrue(typeof value is typedesc<xml:Element>);

XmlType3 x13 = xml `<name>Sherlock Holmes</name>`;
value = x13[0];
assert(value, xml `<name>Sherlock Holmes</name>`);
assertTrue(typeof value is typedesc<xml:Element>);
value = x13[50][1];
assert(value, xml ``);
assertTrue(typeof value is typedesc<xml:Text>);
}

function testInvalidXMLUnionAccessWithNegativeIndex() {
int a = -1;
xml:Element|xml:Comment x1 = xml `<a>abc</a>`;
string errorMessage = "xml sequence index out of range. Length: '1' requested: '-1'";

xml|error e = trap x1[-1];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x1[a];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x1[i];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);

xml<xml:Text|xml:Comment>|xml<xml:ProcessingInstruction|xml:Element> x2 = xml `<name>Dan Brown</name>`;
e = trap x2[-1];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x2[a];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x2[i];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);

XmlType1 x3 = xml `Hello!`;
e = trap x3[-1];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x3[a];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x3[i];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);

XmlType3 x4 = xml `<name>Sherlock Holmes</name>`;
e = trap x4[-1];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x4[a];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
e = trap x4[i];
assertTrue(e is error);
assert((<error> e).message(), errorMessage);
}

function assert(anydata actual, anydata expected) {
if (expected != actual) {
typedesc<anydata> expT = typeof expected;
Expand Down

0 comments on commit ad6109c

Please sign in to comment.