Skip to content

Commit

Permalink
Update compiler plugin and compiler plugin tests
Browse files Browse the repository at this point in the history
  • Loading branch information
prakanth97 committed May 3, 2024
1 parent f45dc80 commit 7060664
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
*/
public class CompilerPluginTest {

static final String UNSUPPORTED_UNION_TYPE =
"unsupported union type: union type does not support multiple complex types";
static final String UNSUPPORTED_TYPE = "unsupported type: type is not supported";

@Test
public void testInvalidExpectedUnionType1() {
Expand All @@ -43,7 +42,7 @@ public void testInvalidExpectedUnionType1() {
.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);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
}

@Test
Expand All @@ -54,7 +53,7 @@ public void testInvalidExpectedUnionType2() {
.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);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
}

@Test
Expand All @@ -65,8 +64,8 @@ public void testInvalidRecordFieldType1() {
.filter(r -> r.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR))
.collect(Collectors.toList());
Assert.assertEquals(errorDiagnosticsList.size(), 2);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_UNION_TYPE);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_UNION_TYPE);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
}

@Test
Expand All @@ -77,8 +76,8 @@ public void testInvalidRecordFieldType2() {
.filter(r -> r.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR))
.collect(Collectors.toList());
Assert.assertEquals(errorDiagnosticsList.size(), 2);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_UNION_TYPE);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_UNION_TYPE);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
}

@Test
Expand Down Expand Up @@ -115,10 +114,8 @@ public void testComplexUnionTypeAsExpectedType() {
.filter(r -> r.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR))
.collect(Collectors.toList());
Assert.assertEquals(errorDiagnosticsList.size(), 2);
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(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
Assert.assertEquals(errorDiagnosticsList.get(1).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
}

@Test
Expand All @@ -129,7 +126,6 @@ public void testComplexUnionTypeAsMemberOfIntersection() {
.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");
Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ballerina/data.jsondata;

public function main() returns error? {
int|record {| int a;|}|record {| int b;|} val = check jsondata:parseString("1");
int|table<record {|string a;|}>|record {| int b;|} val = check jsondata:parseString("1");
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ballerina/data.jsondata;

type Union int|record {| int a;|}|record {| int b;|};
type Union int|table<record {|string a;|}>|record {| int b;|};

public function main() returns error? {
Union val = check jsondata:parseString("1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import ballerina/data.jsondata;

type Person record {|
string? name;
record {|string street; string country;|}|map<string> address;
record {|string street; string country;|}|json company;
table<record {| int a;|}>|map<string> address;
xml|json company;
|};


public function main() returns error? {
string str = string `{
"name": "John",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import ballerina/data.jsondata;

type Person record {|
string? name;
record {|string street; string country;|}|map<string> address;
record {|string street; string country;|}|json company;
table<record {| int a;|}>|map<string> address;
xml|json company;
|};

string str = string `{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import ballerina/data.jsondata;

type T1 (map<anydata>|int|boolean)[];
type T1 (map<anydata>|int|xml)[];
type T2 record {|
string p1;
map<anydata>|int p2;
table<record {|string a;|}>|int p2;
|};

public function main() returns error? {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ballerina/data.jsondata;

type UnionType record {|int a;|}|record {|string b;|};
type UnionType table<record {|int a;|}>|record {|string b;|};

type IntersectionType UnionType & readonly;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@
* @since 0.1.0
*/
public enum JsondataDiagnosticCodes {

UNSUPPORTED_UNION_TYPE("JSON_ERROR_201",
"unsupported union type: union type does not support multiple complex types", ERROR),
DUPLICATE_FIELD("JSON_ERROR_202", "invalid field: duplicate field found", ERROR);
DUPLICATE_FIELD("JSON_ERROR_202", "invalid field: duplicate field found", ERROR),
UNSUPPORTED_TYPE("JSON_ERROR_203", "unsupported type: type is not supported", ERROR);

private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,16 @@ public void perform(SyntaxNodeAnalysisContext ctx) {
return;
}

// ModulePartNode rootNode = (ModulePartNode) ctx.node();
// for (ModuleMemberDeclarationNode member : rootNode.members()) {
// switch (member.kind()) {
// case FUNCTION_DEFINITION -> processFunctionDefinitionNode((FunctionDefinitionNode) member, ctx);
// case MODULE_VAR_DECL ->
// processModuleVariableDeclarationNode((ModuleVariableDeclarationNode) member, ctx);
// case TYPE_DEFINITION ->
// processTypeDefinitionNode((TypeDefinitionNode) member, ctx);
// }
// }
ModulePartNode rootNode = (ModulePartNode) ctx.node();
for (ModuleMemberDeclarationNode member : rootNode.members()) {
switch (member.kind()) {
case FUNCTION_DEFINITION -> processFunctionDefinitionNode((FunctionDefinitionNode) member, ctx);
case MODULE_VAR_DECL ->
processModuleVariableDeclarationNode((ModuleVariableDeclarationNode) member, ctx);
case TYPE_DEFINITION ->
processTypeDefinitionNode((TypeDefinitionNode) member, ctx);
}
}
}

private void processFunctionDefinitionNode(FunctionDefinitionNode functionDefinitionNode,
Expand All @@ -117,17 +117,34 @@ private void processFunctionDefinitionNode(FunctionDefinitionNode functionDefini

TypeSymbol typeSymbol = ((VariableSymbol) symbol.get()).typeDescriptor();
if (!isParseFunctionOfStringSource(initializer.get())) {
// TODO: Need to get the referred type symbol and check for the type kind.
if (typeSymbol.typeKind() == TypeDescKind.RECORD) {
detectDuplicateFields((RecordTypeSymbol) typeSymbol, ctx);
}
checkTypeAndDetectDuplicateFields(typeSymbol, ctx);
continue;
}

validateExpectedType(typeSymbol, ctx);
}
}

private void checkTypeAndDetectDuplicateFields(TypeSymbol typeSymbol, SyntaxNodeAnalysisContext ctx) {
switch (typeSymbol.typeKind()) {
case RECORD -> detectDuplicateFields((RecordTypeSymbol) typeSymbol, ctx);
case ARRAY -> checkTypeAndDetectDuplicateFields(((ArrayTypeSymbol) typeSymbol).memberTypeDescriptor(), ctx);
case TUPLE -> {
for (TypeSymbol memberType : ((TupleTypeSymbol) typeSymbol).memberTypeDescriptors()) {
checkTypeAndDetectDuplicateFields(memberType, ctx);
}
}
case UNION -> {
for (TypeSymbol memberType : ((UnionTypeSymbol) typeSymbol).memberTypeDescriptors()) {
checkTypeAndDetectDuplicateFields(memberType, ctx);
}
}
case TYPE_REFERENCE -> checkTypeAndDetectDuplicateFields(
((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor(), ctx);
case INTERSECTION -> checkTypeAndDetectDuplicateFields(getRawType(typeSymbol), ctx);
}
}

private boolean isParseFunctionOfStringSource(ExpressionNode expressionNode) {
if (expressionNode.kind() == SyntaxKind.CHECK_EXPRESSION) {
expressionNode = ((CheckExpressionNode) expressionNode).expression();
Expand Down Expand Up @@ -156,6 +173,8 @@ private void validateExpectedType(TypeSymbol typeSymbol, SyntaxNodeAnalysisConte
case RECORD -> validateRecordType((RecordTypeSymbol) typeSymbol, ctx);
case ARRAY -> validateExpectedType(((ArrayTypeSymbol) typeSymbol).memberTypeDescriptor(), ctx);
case TUPLE -> validateTupleType((TupleTypeSymbol) typeSymbol, ctx);
case TABLE, XML -> reportDiagnosticInfo(ctx, typeSymbol.getLocation(),
JsondataDiagnosticCodes.UNSUPPORTED_TYPE);
case TYPE_REFERENCE -> validateExpectedType(((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor(), ctx);
case INTERSECTION -> validateExpectedType(getRawType(typeSymbol), ctx);
}
Expand All @@ -172,43 +191,24 @@ private void validateRecordType(RecordTypeSymbol recordTypeSymbol, SyntaxNodeAna

for (Map.Entry<String, RecordFieldSymbol> entry : recordTypeSymbol.fieldDescriptors().entrySet()) {
RecordFieldSymbol fieldSymbol = entry.getValue();
validateRecordFieldType(fieldSymbol.typeDescriptor(), fieldSymbol.getLocation(), ctx);
}
}

private void validateRecordFieldType(TypeSymbol typeSymbol, Optional<Location> location,
SyntaxNodeAnalysisContext ctx) {
switch (typeSymbol.typeKind()) {
case UNION -> validateUnionType((UnionTypeSymbol) typeSymbol, location, ctx);
case ARRAY -> validateRecordFieldType(((ArrayTypeSymbol) typeSymbol).memberTypeDescriptor(), location, ctx);
case TYPE_REFERENCE ->
validateRecordFieldType(((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor(), location, ctx);
currentLocation = fieldSymbol.getLocation().orElseGet(() -> currentLocation);
validateExpectedType(fieldSymbol.typeDescriptor(), ctx);
}
}

private void validateUnionType(UnionTypeSymbol unionTypeSymbol, Optional<Location> location,
SyntaxNodeAnalysisContext ctx) {
int nonPrimitiveMemberCount = 0;
boolean isNilOrErrorPresent = false;
boolean isHasUnsupportedType = false;
List<TypeSymbol> memberTypeSymbols = unionTypeSymbol.memberTypeDescriptors();
for (TypeSymbol memberTypeSymbol : memberTypeSymbols) {
TypeSymbol referredSymbol = getRawType(memberTypeSymbol);
if (referredSymbol.typeKind() == TypeDescKind.NIL || referredSymbol.typeKind() == TypeDescKind.ERROR) {
isNilOrErrorPresent = true;
if (isSupportedUnionMemberType(getRawType(memberTypeSymbol))) {
continue;
}
if (isSupportedUnionMemberType(referredSymbol)) {
continue;
}
nonPrimitiveMemberCount++;
}

if (isNilOrErrorPresent && memberTypeSymbols.size() == 2) {
return;
isHasUnsupportedType = true;
}

if (nonPrimitiveMemberCount >= 1) {
reportDiagnosticInfo(ctx, location, JsondataDiagnosticCodes.UNSUPPORTED_UNION_TYPE);
if (isHasUnsupportedType) {
reportDiagnosticInfo(ctx, location, JsondataDiagnosticCodes.UNSUPPORTED_TYPE);
}
}

Expand All @@ -219,11 +219,11 @@ private boolean isSupportedUnionMemberType(TypeSymbol typeSymbol) {
}

switch (kind) {
case INT, FLOAT, DECIMAL, STRING, BOOLEAN, BYTE, NIL, SINGLETON, ERROR -> {
return true;
case TABLE, XML -> {
return false;
}
default -> {
return false;
return true;
}
}
}
Expand Down

0 comments on commit 7060664

Please sign in to comment.