diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index ef2b4f3..3604b13 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.8.6" +distribution-version = "2201.9.0-20240326-110600-aca0cc0c" [[package]] org = "ballerina" @@ -42,6 +42,26 @@ modules = [ {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} ] +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + [[package]] org = "ballerina" name = "lang.error" @@ -51,6 +71,12 @@ dependencies = [ {org = "ballerina", name = "jballerina.java"} ] +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + [[package]] org = "ballerina" name = "lang.value" @@ -70,6 +96,7 @@ version = "0.0.0" scope = "testOnly" dependencies = [ {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, {org = "ballerina", name = "lang.error"} ] modules = [ diff --git a/compiler-plugin-test/src/test/java/io/ballerina/lib/data/jsondata/compiler/CompilerPluginTest.java b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/jsondata/compiler/CompilerPluginTest.java index bf49165..bc4c0e0 100644 --- a/compiler-plugin-test/src/test/java/io/ballerina/lib/data/jsondata/compiler/CompilerPluginTest.java +++ b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/jsondata/compiler/CompilerPluginTest.java @@ -120,4 +120,16 @@ public void testComplexUnionTypeAsExpectedType() { Assert.assertEquals(errorDiagnosticsList.get(1).diagnosticInfo().messageFormat(), "unsupported union type: union type does not support multiple complex types"); } + + @Test + public void testComplexUnionTypeAsMemberOfIntersection() { + DiagnosticResult diagnosticResult = + CompilerPluginTestUtils.loadPackage("sample_package_8").getCompilation().diagnosticResult(); + List errorDiagnosticsList = diagnosticResult.diagnostics().stream() + .filter(r -> r.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) + .collect(Collectors.toList()); + Assert.assertEquals(errorDiagnosticsList.size(), 1); + Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), + "unsupported union type: union type does not support multiple complex types"); + } } diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_8/Ballerina.toml b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_8/Ballerina.toml new file mode 100644 index 0000000..ea08ff8 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_8/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "jsondata_test" +name = "sample_8" +version = "0.1.0" diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_8/sample.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_8/sample.bal new file mode 100644 index 0000000..5736be5 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_8/sample.bal @@ -0,0 +1,10 @@ +import ballerina/data.jsondata; + +type UnionType record {|int a;|}|record {|string b;|}; + +type IntersectionType UnionType & readonly; + +public function main() returns error? { + string str = string `{"a": 1, "b": "str"}`; + IntersectionType _ = check jsondata:parseString(str); +} diff --git a/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/JsondataTypeValidator.java b/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/JsondataTypeValidator.java index 89bf584..3ecb913 100644 --- a/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/JsondataTypeValidator.java +++ b/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/JsondataTypeValidator.java @@ -22,6 +22,7 @@ import io.ballerina.compiler.api.symbols.AnnotationAttachmentSymbol; import io.ballerina.compiler.api.symbols.AnnotationSymbol; import io.ballerina.compiler.api.symbols.ArrayTypeSymbol; +import io.ballerina.compiler.api.symbols.IntersectionTypeSymbol; import io.ballerina.compiler.api.symbols.ModuleSymbol; import io.ballerina.compiler.api.symbols.RecordFieldSymbol; import io.ballerina.compiler.api.symbols.RecordTypeSymbol; @@ -145,6 +146,7 @@ private void validateExpectedType(TypeSymbol typeSymbol, SyntaxNodeAnalysisConte case ARRAY -> validateExpectedType(((ArrayTypeSymbol) typeSymbol).memberTypeDescriptor(), ctx); case TUPLE -> validateTupleType((TupleTypeSymbol) typeSymbol, ctx); case TYPE_REFERENCE -> validateExpectedType(((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor(), ctx); + case INTERSECTION -> validateExpectedType(getRawType(typeSymbol), ctx); } } @@ -179,7 +181,7 @@ private void validateUnionType(UnionTypeSymbol unionTypeSymbol, Optional memberTypeSymbols = unionTypeSymbol.memberTypeDescriptors(); for (TypeSymbol memberTypeSymbol : memberTypeSymbols) { - TypeSymbol referredSymbol = getReferredSymbol(memberTypeSymbol); + TypeSymbol referredSymbol = getRawType(memberTypeSymbol); if (referredSymbol.typeKind() == TypeDescKind.NIL || referredSymbol.typeKind() == TypeDescKind.ERROR) { isNilOrErrorPresent = true; continue; @@ -215,9 +217,22 @@ private boolean isSupportedUnionMemberType(TypeSymbol typeSymbol) { } } - private TypeSymbol getReferredSymbol(TypeSymbol typeSymbol) { - return typeSymbol.typeKind() == TypeDescKind.TYPE_REFERENCE ? - ((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor() : typeSymbol; + public static TypeSymbol getRawType(TypeSymbol typeDescriptor) { + if (typeDescriptor.typeKind() == TypeDescKind.INTERSECTION) { + return getRawType(((IntersectionTypeSymbol) typeDescriptor).effectiveTypeDescriptor()); + } + if (typeDescriptor.typeKind() == TypeDescKind.TYPE_REFERENCE) { + TypeReferenceTypeSymbol typeRef = (TypeReferenceTypeSymbol) typeDescriptor; + if (typeRef.typeDescriptor().typeKind() == TypeDescKind.INTERSECTION) { + return getRawType(((IntersectionTypeSymbol) typeRef.typeDescriptor()).effectiveTypeDescriptor()); + } + TypeSymbol rawType = typeRef.typeDescriptor(); + if (rawType.typeKind() == TypeDescKind.TYPE_REFERENCE) { + return getRawType(rawType); + } + return rawType; + } + return typeDescriptor; } private void reportDiagnosticInfo(SyntaxNodeAnalysisContext ctx, Optional location,