Skip to content

Commit

Permalink
Add errors to unsupported attribute types
Browse files Browse the repository at this point in the history
  • Loading branch information
SasinduDilshara committed Sep 6, 2024
1 parent 753e0b1 commit 8e848c4
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 7 deletions.
27 changes: 27 additions & 0 deletions ballerina/tests/fromXml_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -3615,6 +3615,7 @@ isolated function testTypeRefArray() {
function testXmlToRecordWithInvalidExpectedTypeForAttributes() {
xml value = xml `<a id="2">1</a>`;
record {int[] id;}|error rec = parseAsType(value);
test:assertTrue(rec is Error);
test:assertEquals((<error>rec).message(), "attribute 'id' cannot be converted into the array type 'int[]'");

xml value2 = xml `<a id="2">
Expand All @@ -3628,6 +3629,7 @@ function testXmlToRecordWithInvalidExpectedTypeForAttributes() {

xml value3 = xml `<a id="1"><b id="2">3</b></a>`;
record {record{int[] id;} b;}|error rec3 = parseAsType(value3);
test:assertTrue(rec3 is Error);
test:assertEquals((<error>rec3).message(), "attribute 'id' cannot be converted into the array type 'int[]'");

xml value4 = xml `<a id="2">
Expand All @@ -3636,5 +3638,30 @@ function testXmlToRecordWithInvalidExpectedTypeForAttributes() {
<id id="2">3</id>
</a>`;
record {record{int[] id;}[] id;}|error rec4 = parseAsType(value4);
test:assertTrue(rec4 is Error);
test:assertEquals((<error>rec4).message(), "attribute 'id' cannot be converted into the array type 'int[]'");

xml value5 = xml `<a id="2">1</a>`;
record {map<int> id;}|error rec5 = parseAsType(value5);
test:assertTrue(rec5 is Error);
test:assertEquals((<error>rec5).message(), "attribute 'id' cannot be converted into the array type 'map<int>'");

xml value6 = xml `<a id="1"><b id="2">3</b></a>`;
record {record{map<int> id;} b;}|error rec6 = parseAsType(value6);
test:assertTrue(rec6 is Error);
test:assertEquals((<error>rec6).message(), "attribute 'id' cannot be converted into the array type 'map<int>'");

xml value7 = xml `<a id="2">1</a>`;
record {string:RegExp id;}|error rec7 = parseAsType(value7);
test:assertTrue(rec7 is Error);
test:assertEquals((<error>rec7).message(), "unsupported input type");

xml value8 = xml `<a id="2">
<id id="2">1</id>
<id id="2">2</id>
<id id="2">3</id>
</a>`;
record {record{string:RegExp id;}[] id;}|error rec8 = parseAsType(value8);
test:assertTrue(rec8 is Error);
test:assertEquals((<error>rec8).message(), "unsupported input type");
}
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,27 @@ public static boolean isSimpleType(Type type) {
};
}

public static boolean isSupportedTypeForAttributes(Type fieldType) {
if (TypeTags.isIntegerTypeTag(fieldType.getTag())) {
return true;
}

if (TypeTags.isStringTypeTag(fieldType.getTag())) {
return true;
}

if (TypeTags.isXMLTypeTag(fieldType.getTag())) {
return false;
}

return switch (fieldType.getTag()) {
case TypeTags.FLOAT_TAG, TypeTags.BOOLEAN_TAG, TypeTags.NULL_TAG,
TypeTags.DECIMAL_TAG, TypeTags.BYTE_TAG, TypeTags.UNION_TAG, TypeTags.ANYDATA_TAG,
TypeTags.ANY_TAG, TypeTags.JSON_TAG -> true;
default -> false;
};
}

/**
* Holds data required for the traversing.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public enum DiagnosticErrorCode {
STREAM_BROKEN("XML_ERROR_015", "stream.broken"),
XML_PARSE_ERROR("XML_ERROR_016", "xml.parse.error"),
UNDEFINED_FIELD("XML_ERROR_0017", "undefined.field"),
ATTRIBUTE_CANNOT_CONVERT_INTO_ARRAY_TYPE("XML_ERROR_0018",
"attributes.cannot.convert.to.array.type");
CANNOT_CONVERT_ATTRIBUTE_TO_ARRAY_TYPE("XML_ERROR_0018",
"cannot.convert.attributes.to.array.type");

String diagnosticId;
String messageKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,14 +661,20 @@ private void handleAttributes(BXmlItem xmlItem, BMap<BString, Object> currentNod
analyzerData.rootRecord);
}

if (field.getFieldType().getTag() == TypeTags.ARRAY_TAG) {
throw DiagnosticLog.error(DiagnosticErrorCode.ATTRIBUTE_CANNOT_CONVERT_INTO_ARRAY_TYPE,
field.getFieldName(), field.getFieldType());
Type fieldType = field.getFieldType();

if (DataUtils.isRegExpType(fieldType)) {
throw DiagnosticLog.error(DiagnosticErrorCode.UNSUPPORTED_TYPE);
}

if (!DataUtils.isSupportedTypeForAttributes(TypeUtils.getReferredType(fieldType))) {
throw DiagnosticLog.error(DiagnosticErrorCode.CANNOT_CONVERT_ATTRIBUTE_TO_ARRAY_TYPE,
field.getFieldName(), fieldType);
}

try {
currentNode.put(StringUtils.fromString(field.getFieldName()),
DataUtils.convertStringToExpType(attributeMap.get(key), field.getFieldType()));
DataUtils.convertStringToExpType(attributeMap.get(key), fieldType));
} catch (Exception e) {
// Ignore: Expected type will mismatch when element and attribute having same name.
}
Expand Down
2 changes: 1 addition & 1 deletion native/src/main/resources/error.properties
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ error.xml.parse.error=\
error.undefined.field=\
undefined field ''{0}'' in record ''{1}''

error.attributes.cannot.convert.to.array.type=\
error.cannot.convert.attributes.to.array.type=\
attribute ''{0}'' cannot be converted into the array type ''{1}''

0 comments on commit 8e848c4

Please sign in to comment.