Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix compile-time error logging for user defined module prefix for xmldata #22

Merged
merged 5 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,32 @@ public void testCompilerPluginWithAProjectWithSubModule() {
Assert.assertEquals(warningDiagnosticsList.get(0).diagnosticInfo().messageFormat(),
"invalid annotation attachment: child record does not allow name annotation");
}

@Test
public void testComplexUnionTypeCaseWhenUserDefinedModulePrefix() {
DiagnosticResult diagnosticResult =
CompilerPluginTestUtils.loadPackage("sample_package_11").getCompilation().diagnosticResult();
List<Diagnostic> 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(),
"invalid type: expected a record type");
}

@Test
public void testComplexUnionTypeCaseWhenUserDefinedModulePrefix2() {
DiagnosticResult diagnosticResult =
CompilerPluginTestUtils.loadPackage("sample_package_12").getCompilation().diagnosticResult();
List<Diagnostic> 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(),
"invalid type: expected a record type");
Assert.assertEquals(errorDiagnosticsList.get(1).diagnosticInfo().messageFormat(),
"invalid type: expected a record type");
Assert.assertEquals(errorDiagnosticsList.get(2).diagnosticInfo().messageFormat(),
"invalid type: expected a record type");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "xmldata_test"
name = "sample_11"
version = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import ballerina/data.xmldata as xd;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add another file with a different prefix and another file with default. Use file names as m1 -> prefix: xd , m2 -> no prefix, m3-> prefix: xd2

Copy link
Contributor Author

@prakanth97 prakanth97 May 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


type UnionType record {|int a;|}|record {|string b;|};

public function main() returns error? {
string str = string `{"a": 1, "b": "str"}`;
UnionType _ = check xd:parseString(str);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "xmldata_test"
name = "sample_12"
version = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import ballerina/data.xmldata as xd;

public function testFunc() returns error? {
string str = string `{"a": 1, "b": "str"}`;
UnionType _ = check xd:parseString(str);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import ballerina/data.xmldata as xd2;

public function testFunc2() returns error? {
string str = string `{"a": 1, "b": "str"}`;
UnionType _ = check xd2:parseString(str);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import ballerina/data.xmldata;

public function testFunc3() returns error? {
string str = string `{"a": 1, "b": "str"}`;
UnionType _ = check xmldata:parseString(str);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type UnionType record {|int a;|}|record {|string b;|};
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public class Constants {
static final String NAME = "Name";
static final String NAMESPACE = "Namespace";
static final String XMLDATA = "xmldata";
static final String BALLERINA = "ballerina";
static final String DATA_XMLDATA = "data.xmldata";
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package io.ballerina.lib.data.xmldata.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;
Expand All @@ -38,6 +39,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;
Expand Down Expand Up @@ -72,6 +74,7 @@ public class XmldataRecordFieldValidator implements AnalysisTask<SyntaxNodeAnaly

private SemanticModel semanticModel;
private final HashMap<Location, DiagnosticInfo> allDiagnosticInfo = new HashMap<>();
private String modulePrefix = Constants.XMLDATA;

@Override
public void perform(SyntaxNodeAnalysisContext ctx) {
Expand All @@ -80,10 +83,13 @@ public void perform(SyntaxNodeAnalysisContext ctx) {
boolean erroneousCompilation = diagnostics.stream()
.anyMatch(d -> d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR));
if (erroneousCompilation) {
rest();
return;
}

ModulePartNode rootNode = (ModulePartNode) ctx.node();
updateModulePrefix(rootNode);

for (ModuleMemberDeclarationNode member : rootNode.members()) {
switch (member.kind()) {
case FUNCTION_DEFINITION -> processFunctionDefinitionNode((FunctionDefinitionNode) member, ctx);
Expand All @@ -92,6 +98,33 @@ public void perform(SyntaxNodeAnalysisContext ctx) {
case TYPE_DEFINITION -> processTypeDefinitionNode((TypeDefinitionNode) member, ctx);
}
}

rest();
}

private void rest() {
semanticModel = null;
allDiagnosticInfo.clear();
modulePrefix = Constants.XMLDATA;
}

private void updateModulePrefix(ModulePartNode rootNode) {
for (ImportDeclarationNode importDeclarationNode : rootNode.imports()) {
Optional<Symbol> symbol = semanticModel.symbol(importDeclarationNode);
if (symbol.isPresent() && symbol.get().kind() == SymbolKind.MODULE) {
ModuleSymbol moduleSymbol = (ModuleSymbol) symbol.get();
if (isXmldataImport(moduleSymbol)) {
modulePrefix = moduleSymbol.id().modulePrefix();
break;
}
}
}
}

private boolean isXmldataImport(ModuleSymbol moduleSymbol) {
ModuleID moduleId = moduleSymbol.id();
return Constants.BALLERINA.equals(moduleId.orgName())
&& Constants.DATA_XMLDATA.equals(moduleId.moduleName());
}

private void processFunctionDefinitionNode(FunctionDefinitionNode functionDefinitionNode,
Expand Down Expand Up @@ -392,7 +425,7 @@ private boolean isParseFunctionFromXmldata(ExpressionNode expressionNode) {
return false;
}
String prefix = ((QualifiedNameReferenceNode) nameReferenceNode).modulePrefix().text();
if (!prefix.equals(Constants.XMLDATA)) {
if (!prefix.equals(modulePrefix)) {
return false;
}

Expand Down
Loading