Skip to content

Commit

Permalink
Merge pull request #22 from prakanth97/issue_6540
Browse files Browse the repository at this point in the history
Fix compile-time error logging for user defined module prefix for xmldata
  • Loading branch information
hasithaa committed Jun 6, 2024
2 parents 810132d + 79dd70a commit b9bb649
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 1 deletion.
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;

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

0 comments on commit b9bb649

Please sign in to comment.