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 Oct 30, 2024
1 parent a830c72 commit 72910cf
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 4 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 @@ -968,6 +968,27 @@ public static String generateStringFromXmlReader(Reader reader) throws IOExcepti
return builder.toString();
}

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;
};
}

public static boolean isContainsUnionType(Type expType) {
if (expType == null) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public enum DiagnosticErrorCode {
CANNOT_CONVERT_SOURCE_INTO_EXP_TYPE("XML_ERROR_0018", "cannot.convert.source.into.expected.type"),
FIELD_CANNOT_CAST_INTO_TYPE("XML_ERROR_0019", "field.cannot.convert.into.type"),
ATTRIBUTE_CANNOT_CONVERT_INTO_ARRAY_TYPE("XML_ERROR_0020","attributes.cannot.convert.to.array.type");
CANNOT_CONVERT_ATTRIBUTE_TO_ARRAY_TYPE("XML_ERROR_0021", "cannot.convert.attributes.to.array.type");

String diagnosticId;
String messageKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -790,14 +790,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
1 change: 1 addition & 0 deletions native/src/main/resources/error.properties
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,5 @@ error.cannot.convert.source.into.expected.type=\
error.field.cannot.convert.into.type=\
field ''{0}'' cannot be converted into the type ''{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 72910cf

Please sign in to comment.