diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index 58e33d7..6a35cb0 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -1,7 +1,7 @@ [package] org = "ballerina" name = "data.jsondata" -version = "0.1.0" +version = "0.1.1" authors = ["Ballerina"] keywords = ["json", "json path", "json-transform", "json transform", "json to json", "json-convert", "json convert"] repository = "https://github.com/ballerina-platform/module-ballerina-data.jsondata" @@ -15,8 +15,8 @@ graalvmCompatible = true [[platform.java17.dependency]] groupId = "io.ballerina.lib" artifactId = "jsondata-native" -version = "0.1.0" -path = "../native/build/libs/data.jsondata-native-0.1.0.jar" +version = "0.1.1" +path = "../native/build/libs/data.jsondata-native-0.1.1-SNAPSHOT.jar" [[platform.java17.dependency]] path = "./lib/json-path-2.9.0.jar" diff --git a/ballerina/CompilerPlugin.toml b/ballerina/CompilerPlugin.toml index a3b6b88..b9500f5 100644 --- a/ballerina/CompilerPlugin.toml +++ b/ballerina/CompilerPlugin.toml @@ -3,4 +3,4 @@ id = "constraint-compiler-plugin" class = "io.ballerina.lib.data.jsondata.compiler.JsondataCompilerPlugin" [[dependency]] -path = "../compiler-plugin/build/libs/data.jsondata-compiler-plugin-0.1.0.jar" +path = "../compiler-plugin/build/libs/data.jsondata-compiler-plugin-0.1.1-SNAPSHOT.jar" diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index e9640c9..ad7123d 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -10,7 +10,7 @@ distribution-version = "2201.9.0" [[package]] org = "ballerina" name = "data.jsondata" -version = "0.1.0" +version = "0.1.1" dependencies = [ {org = "ballerina", name = "file"}, {org = "ballerina", name = "io"}, 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 bc4c0e0..a70fab9 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 @@ -132,4 +132,32 @@ public void testComplexUnionTypeAsMemberOfIntersection() { Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), "unsupported union type: union type does not support multiple complex types"); } + + @Test + public void testComplexUnionTypeCaseWhenUserDefinedModulePrefix1() { + DiagnosticResult diagnosticResult = + CompilerPluginTestUtils.loadPackage("sample_package_9").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"); + } + + @Test + public void testComplexUnionTypeCaseWhenUserDefinedModulePrefix2() { + DiagnosticResult diagnosticResult = + CompilerPluginTestUtils.loadPackage("sample_package_10").getCompilation().diagnosticResult(); + List errorDiagnosticsList = diagnosticResult.diagnostics().stream() + .filter(r -> r.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) + .collect(Collectors.toList()); + Assert.assertEquals(errorDiagnosticsList.size(), 3); + Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), + "unsupported union type: union type does not support multiple complex types"); + Assert.assertEquals(errorDiagnosticsList.get(1).diagnosticInfo().messageFormat(), + "unsupported union type: union type does not support multiple complex types"); + Assert.assertEquals(errorDiagnosticsList.get(2).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_10/Ballerina.toml b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/Ballerina.toml new file mode 100644 index 0000000..5669682 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "jsondata_test" +name = "sample_10" +version = "0.1.0" diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_1.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_1.bal new file mode 100644 index 0000000..de39f10 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_1.bal @@ -0,0 +1,6 @@ +import ballerina/data.jsondata as jd; + +public function testFunc1() returns error? { + string str = string `{"a": 1, "b": "str"}`; + UnionType _ = check jd:parseString(str); +} diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_2.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_2.bal new file mode 100644 index 0000000..93c0972 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_2.bal @@ -0,0 +1,6 @@ +import ballerina/data.jsondata as jd2; + +public function testFunc2() returns error? { + string str = string `{"a": 1, "b": "str"}`; + UnionType _ = check jd2:parseString(str); +} diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_3.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_3.bal new file mode 100644 index 0000000..22204ce --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/file_3.bal @@ -0,0 +1,6 @@ +import ballerina/data.jsondata; + +public function testFunc3() returns error? { + string str = string `{"a": 1, "b": "str"}`; + UnionType _ = check jsondata:parseString(str); +} diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/types.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/types.bal new file mode 100644 index 0000000..4383f4d --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_10/types.bal @@ -0,0 +1 @@ +type UnionType record {|int a;|}|record {|string b;|}; diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_9/Ballerina.toml b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_9/Ballerina.toml new file mode 100644 index 0000000..abbb0c9 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_9/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "jsondata_test" +name = "sample_9" +version = "0.1.0" diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_9/sample.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_9/sample.bal new file mode 100644 index 0000000..054187e --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_9/sample.bal @@ -0,0 +1,8 @@ +import ballerina/data.jsondata as jd; + +type UnionType record {|int a;|}|record {|string b;|}; + +public function main() returns error? { + string str = string `{"a": 1, "b": "str"}`; + UnionType _ = check jd:parseString(str); +} diff --git a/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/Constants.java b/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/Constants.java index 9478613..38d78dd 100644 --- a/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/Constants.java +++ b/compiler-plugin/src/main/java/io/ballerina/lib/data/jsondata/compiler/Constants.java @@ -29,4 +29,6 @@ public class Constants { static final String PARSE_STREAM = "parseStream"; static final String NAME = "Name"; static final String JSONDATA = "jsondata"; + static final String BALLERINA = "ballerina"; + static final String DATA_JSONDATA = "data.jsondata"; } 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 412e100..59d39e3 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 @@ -18,6 +18,7 @@ package io.ballerina.lib.data.jsondata.compiler; +import io.ballerina.compiler.api.ModuleID; import io.ballerina.compiler.api.SemanticModel; import io.ballerina.compiler.api.symbols.AnnotationAttachmentSymbol; import io.ballerina.compiler.api.symbols.AnnotationSymbol; @@ -27,6 +28,7 @@ import io.ballerina.compiler.api.symbols.RecordFieldSymbol; import io.ballerina.compiler.api.symbols.RecordTypeSymbol; import io.ballerina.compiler.api.symbols.Symbol; +import io.ballerina.compiler.api.symbols.SymbolKind; import io.ballerina.compiler.api.symbols.TupleTypeSymbol; import io.ballerina.compiler.api.symbols.TypeDefinitionSymbol; import io.ballerina.compiler.api.symbols.TypeDescKind; @@ -39,6 +41,7 @@ import io.ballerina.compiler.syntax.tree.ExpressionNode; import io.ballerina.compiler.syntax.tree.FunctionCallExpressionNode; import io.ballerina.compiler.syntax.tree.FunctionDefinitionNode; +import io.ballerina.compiler.syntax.tree.ImportDeclarationNode; import io.ballerina.compiler.syntax.tree.ModuleMemberDeclarationNode; import io.ballerina.compiler.syntax.tree.ModulePartNode; import io.ballerina.compiler.syntax.tree.ModuleVariableDeclarationNode; @@ -73,6 +76,7 @@ public class JsondataTypeValidator implements AnalysisTask allDiagnosticInfo = new HashMap<>(); Location currentLocation; + private String modulePrefix = Constants.JSONDATA; @Override public void perform(SyntaxNodeAnalysisContext ctx) { @@ -81,10 +85,13 @@ public void perform(SyntaxNodeAnalysisContext ctx) { boolean erroneousCompilation = diagnostics.stream() .anyMatch(d -> d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)); if (erroneousCompilation) { + reset(); return; } ModulePartNode rootNode = (ModulePartNode) ctx.node(); + updateModulePrefix(rootNode); + for (ModuleMemberDeclarationNode member : rootNode.members()) { switch (member.kind()) { case FUNCTION_DEFINITION -> processFunctionDefinitionNode((FunctionDefinitionNode) member, ctx); @@ -94,6 +101,28 @@ public void perform(SyntaxNodeAnalysisContext ctx) { processTypeDefinitionNode((TypeDefinitionNode) member, ctx); } } + + reset(); + } + + private void reset() { + semanticModel = null; + allDiagnosticInfo.clear(); + currentLocation = null; + modulePrefix = Constants.JSONDATA; + } + + private void updateModulePrefix(ModulePartNode rootNode) { + for (ImportDeclarationNode importDeclarationNode : rootNode.imports()) { + Optional symbol = semanticModel.symbol(importDeclarationNode); + if (symbol.isPresent() && symbol.get().kind() == SymbolKind.MODULE) { + ModuleSymbol moduleSymbol = (ModuleSymbol) symbol.get(); + if (isJsondataImport(moduleSymbol)) { + modulePrefix = moduleSymbol.id().modulePrefix(); + break; + } + } + } } private void processFunctionDefinitionNode(FunctionDefinitionNode functionDefinitionNode, @@ -140,7 +169,7 @@ private boolean isParseFunctionOfStringSource(ExpressionNode expressionNode) { return false; } String prefix = ((QualifiedNameReferenceNode) nameReferenceNode).modulePrefix().text(); - if (!prefix.equals(Constants.JSONDATA)) { + if (!prefix.equals(modulePrefix)) { return false; } String functionName = ((FunctionCallExpressionNode) expressionNode).functionName().toString().trim(); @@ -329,4 +358,10 @@ private String getAnnotModuleName(AnnotationSymbol annotation) { Optional moduleName = moduleSymbol.get().getName(); return moduleName.orElse(""); } + + private boolean isJsondataImport(ModuleSymbol moduleSymbol) { + ModuleID moduleId = moduleSymbol.id(); + return Constants.BALLERINA.equals(moduleId.orgName()) + && Constants.DATA_JSONDATA.equals(moduleId.moduleName()); + } }