Skip to content

Commit

Permalink
Merge pull request #39913 from Nadeeshan96/stage4.1-typref-iss-39907
Browse files Browse the repository at this point in the history
[2201.4.1-stage] Fix converting reference type values to `json`
  • Loading branch information
warunalakshitha authored Mar 19, 2023
2 parents e03ba9e + d73f0ab commit b34f6a6
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2635,52 +2635,55 @@ private static boolean checkIsLikeStreamType(Object sourceValue, BStreamType tar

private static boolean checkIsLikeJSONType(Object sourceValue, Type sourceType, BJsonType targetType,
List<TypeValuePair> unresolvedValues, boolean allowNumericConversion) {
if (sourceType.getTag() == TypeTags.ARRAY_TAG) {
ArrayValue source = (ArrayValue) sourceValue;
Type elementType = ((BArrayType) source.getType()).getElementType();
if (isValueType(elementType)) {
return checkIsType(elementType, targetType, new ArrayList<>());
}
Type referredSourceType = TypeUtils.getReferredType(sourceType);
switch (referredSourceType.getTag()) {
case TypeTags.ARRAY_TAG:
ArrayValue source = (ArrayValue) sourceValue;
Type elementType = ((BArrayType) referredSourceType).getElementType();
if (isValueType(elementType)) {
return checkIsType(elementType, targetType, new ArrayList<>());
}

Object[] arrayValues = source.getValues();
for (int i = 0; i < ((ArrayValue) sourceValue).size(); i++) {
if (!checkIsLikeType(null, arrayValues[i], targetType, unresolvedValues,
allowNumericConversion, null)) {
return false;
Object[] arrayValues = source.getValues();
for (int i = 0; i < source.size(); i++) {
if (!checkIsLikeType(null, arrayValues[i], targetType, unresolvedValues,
allowNumericConversion, null)) {
return false;
}
}
}
return true;
} else if (sourceType.getTag() == TypeTags.MAP_TAG) {
for (Object value : ((MapValueImpl) sourceValue).values()) {
if (!checkIsLikeType(null, value, targetType, unresolvedValues, allowNumericConversion,
null)) {
return false;
return true;
case TypeTags.TUPLE_TAG:
for (Object obj : ((TupleValueImpl) sourceValue).getValues()) {
if (!checkIsLikeType(null, obj, targetType, unresolvedValues, allowNumericConversion,
null)) {
return false;
}
}
}
return true;
} else if (sourceType.getTag() == TypeTags.RECORD_TYPE_TAG) {
TypeValuePair typeValuePair = new TypeValuePair(sourceValue, targetType);
if (unresolvedValues.contains(typeValuePair)) {
return true;
}
unresolvedValues.add(typeValuePair);
for (Object object : ((MapValueImpl) sourceValue).values()) {
if (!checkIsLikeType(null, object, targetType, unresolvedValues, allowNumericConversion,
null)) {
return false;
case TypeTags.MAP_TAG:
for (Object value : ((MapValueImpl) sourceValue).values()) {
if (!checkIsLikeType(null, value, targetType, unresolvedValues, allowNumericConversion,
null)) {
return false;
}
}
}
return true;
} else if (sourceType.getTag() == TypeTags.TUPLE_TAG) {
for (Object obj : ((TupleValueImpl) sourceValue).getValues()) {
if (!checkIsLikeType(null, obj, targetType, unresolvedValues, allowNumericConversion,
null)) {
return false;
return true;
case TypeTags.RECORD_TYPE_TAG:
TypeValuePair typeValuePair = new TypeValuePair(sourceValue, targetType);
if (unresolvedValues.contains(typeValuePair)) {
return true;
}
}
return true;
unresolvedValues.add(typeValuePair);
for (Object object : ((MapValueImpl) sourceValue).values()) {
if (!checkIsLikeType(null, object, targetType, unresolvedValues, allowNumericConversion,
null)) {
return false;
}
}
return true;
default:
return false;
}
return false;
}

private static boolean checkIsLikeRecordType(Object sourceValue, BRecordType targetType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ public Object[] cloneWithTypeFunctions() {
"testCloneWithTypeWithFiniteTypeArrayFromIntArrayNegative", "testConvertJsonToNestedRecordsWithErrors",
"testCloneWithTypeNestedStructuredTypesNegative", "testCloneWithTypeJsonToRecordRestField",
"testCloneWithTypeWithAmbiguousUnion",
"testCloneWithTypeWithTuples",
"testCloneWithTypeWithTuples", "testCloneWithTypeToJson",
"testCloneWithTypeToUnion", "testCloneWithTypeToUnionOfTypeReference"
};
}
Expand Down
55 changes: 55 additions & 0 deletions langlib/langlib-test/src/test/resources/test-src/valuelib_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -2346,6 +2346,61 @@ function testCloneWithTypeToUnionOfTypeReference() {
assertEquality(t5, <Table2> table [{a: "a", b: "b"}]);
}

type GraphQLQuery record {|
string operationName?;
string query?;
record {} variables?;
|};

type GraphQLQueries1 GraphQLQuery[];

type GraphQLQueries2 [int, GraphQLQuery...];

type GraphQLQueries3 map<GraphQLQuery>;

type GraphQLQueries4 record {|
GraphQLQuery a;
|};

function testCloneWithTypeToJson() {
GraphQLQueries1 payload1 = [{query: "abc"}, {query: "xyz"}];
GraphQLQueries2 payload2 = [1, {query: "abc"}, {query: "xyz"}];
GraphQLQueries3 payload3 = {"a": {query: "abc"}, "b": {query: "xyz"}};
GraphQLQueries4 payload4 = {a: {query: "abc"}};
json stdJson1 = checkpanic payload1.cloneWithType();
json stdJson2 = checkpanic payload2.cloneWithType();
json stdJson3 = checkpanic payload3.cloneWithType();
json stdJson4 = checkpanic payload4.cloneWithType();

assertEquality(stdJson1, <json>[{query: "abc"}, {query: "xyz"}]);
assertEquality(stdJson2, <json>[1, {query: "abc"}, {query: "xyz"}]);
assertEquality(stdJson3, <json>{"a": {query: "abc"}, "b": {query: "xyz"}});
assertEquality(stdJson4, <json>{a: {query: "abc"}});

GraphQLQueries1 payload5 = [{query: "abc"}, {query: "xyz", variables: {"nonJson": xml `<a>abc</a>`}}];
GraphQLQueries2 payload6 = [1, {query: "abc"}, {query: "xyz", variables: {"nonJson": xml `<a>abc</a>`}}];
GraphQLQueries3 payload7 = {"a": {query: "abc"}, "b": {query: "xyz", variables: {"nonJson": xml `<a>abc</a>`}}};

json|error stdJson5 = payload5.cloneWithType();
assertEquality(stdJson5 is error, true);
if (stdJson5 is error) {
assertEquality("'GraphQLQueries1' value cannot be converted to 'json'",
<string>checkpanic stdJson5.detail()["message"]);
}
json|error stdJson6 = payload6.cloneWithType();
assertEquality(stdJson6 is error, true);
if (stdJson6 is error) {
assertEquality("'GraphQLQuery' value cannot be converted to 'json'",
<string>checkpanic stdJson6.detail()["message"]);
}
json|error stdJson7 = payload7.cloneWithType();
assertEquality(stdJson7 is error, true);
if (stdJson7 is error) {
assertEquality("'GraphQLQueries3' value cannot be converted to 'json'",
<string>checkpanic stdJson7.detail()["message"]);
}
}

/////////////////////////// Tests for `toJson()` ///////////////////////////

type Student2 record {
Expand Down

0 comments on commit b34f6a6

Please sign in to comment.