diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/StaticCodeAnalyzer.java b/scan-command/src/main/java/io/ballerina/scan/internal/StaticCodeAnalyzer.java index 58a602e1..4a335c07 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/StaticCodeAnalyzer.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/StaticCodeAnalyzer.java @@ -358,10 +358,10 @@ private void checkNonIsolatedConstructsInTypeDefinition(TypeDefinitionNode typeD TypeSymbol typeSymbol = typeDefinitionSymbol.typeDescriptor(); if (typeSymbol instanceof ObjectTypeSymbol objectTypeSymbol) { List qualifiers = objectTypeSymbol.qualifiers(); - List typeDefQualifiers = typeDefinitionSymbol.qualifiers(); - if (hasQualifier(typeDefQualifiers, PUBLIC_KEYWORD) && - !hasQualifier(qualifiers, ISOLATED_KEYWORD)) { - reportIssue(typeDefinitionNode, CoreRule.PUBLIC_NON_ISOLATED_OBJECT_CONSTRUCT); + Optional visibilityQualifier = typeDefinitionNode.visibilityQualifier(); + if (visibilityQualifier.isPresent() && visibilityQualifier.get().kind().equals(PUBLIC_KEYWORD) + && !hasQualifier(qualifiers, ISOLATED_KEYWORD)) { + reportIssue(visibilityQualifier.get(), CoreRule.PUBLIC_NON_ISOLATED_OBJECT_CONSTRUCT); } } } @@ -373,7 +373,9 @@ private void checkNonIsolatedPublicClassDefinition(ClassDefinitionNode classDefi if (symbol instanceof ObjectTypeSymbol objectTypeSymbol) { List qualifiers = objectTypeSymbol.qualifiers(); if (isPublicIsolatedConstruct(qualifiers)) { - reportIssue(classDefinitionNode, CoreRule.PUBLIC_NON_ISOLATED_CLASS_CONSTRUCT); + Token visibilityQualifier = classDefinitionNode.visibilityQualifier().orElseThrow( + () -> new IllegalStateException("Expected visibility qualifier to be present")); + reportIssue(visibilityQualifier, CoreRule.PUBLIC_NON_ISOLATED_CLASS_CONSTRUCT); } } }); @@ -395,8 +397,11 @@ private void checkNonIsolatedPublicClassMethod(ClassDefinitionNode classDefiniti } private void checkNonIsolatedPublicMethod(FunctionDefinitionNode member) { - if (isPublicIsolatedConstruct(member.qualifierList())) { - reportIssue(member, CoreRule.PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT); + NodeList qualifiers = member.qualifierList(); + if (isPublicIsolatedConstruct(qualifiers)) { + Token publicToken = getQualifier(qualifiers, PUBLIC_KEYWORD).orElseThrow( + () -> new IllegalStateException("Expected public token to be present")); + reportIssue(publicToken, CoreRule.PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT); } } @@ -405,12 +410,20 @@ private void checkNonIsolatedPublicFunction(FunctionDefinitionNode functionDefin if (symbol.kind() != SymbolKind.METHOD) { NodeList qualifiers = functionDefinitionNode.qualifierList(); if (isPublicIsolatedConstruct(qualifiers)) { - reportIssue(functionDefinitionNode, CoreRule.PUBLIC_NON_ISOLATED_FUNCTION_CONSTRUCT); + Token publicToken = getQualifier(qualifiers, PUBLIC_KEYWORD).orElseThrow( + () -> new IllegalStateException("Expected public token to be present")); + reportIssue(publicToken, CoreRule.PUBLIC_NON_ISOLATED_FUNCTION_CONSTRUCT); } } }); } + private Optional getQualifier(NodeList qualifierList, SyntaxKind qualifier) { + return qualifierList.stream() + .filter(t -> t.kind() == qualifier) + .findFirst(); + } + private boolean hasQualifier(List qualifierList, SyntaxKind qualifierValue) { String qualifierValueStr = qualifierValue.stringValue(); for (Qualifier qualifier : qualifierList) { diff --git a/scan-command/src/main/resources/report.zip b/scan-command/src/main/resources/report.zip index 966288a6..75be73ae 100644 Binary files a/scan-command/src/main/resources/report.zip and b/scan-command/src/main/resources/report.zip differ diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule003And004Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule003And004Test.java index fd0de087..fa4ecda9 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule003And004Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule003And004Test.java @@ -53,29 +53,29 @@ void testNonIsolatedPublicFunctionOrMethodConstructsUsage() { List issues = scannerContext.getReporter().getIssues(); Assert.assertEquals(issues.size(), 12); - assertIssue(issues.get(0), documentName, 16, 0, 18, 1, "ballerina:3", 3, + assertIssue(issues.get(0), documentName, 16, 0, 16, 6, "ballerina:3", 3, PUBLIC_NON_ISOLATED_FUNCTION_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 63, 4, 65, 5, "ballerina:4", 4, + assertIssue(issues.get(1), documentName, 63, 4, 63, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 67, 4, 69, 5, "ballerina:4", 4, + assertIssue(issues.get(2), documentName, 67, 4, 67, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 75, 4, 77, 5, "ballerina:4", 4, + assertIssue(issues.get(3), documentName, 75, 4, 75, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 89, 4, 91, 5, "ballerina:4", 4, + assertIssue(issues.get(4), documentName, 89, 4, 89, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 97, 4, 99, 5, "ballerina:4", 4, + assertIssue(issues.get(5), documentName, 97, 4, 97, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 102, 0, 122, 1, "ballerina:5", 5, + assertIssue(issues.get(6), documentName, 102, 0, 102, 6, "ballerina:5", 5, PUBLIC_NON_ISOLATED_CLASS_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 111, 4, 113, 5, "ballerina:4", 4, + assertIssue(issues.get(7), documentName, 111, 4, 111, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 133, 4, 135, 5, "ballerina:4", 4, + assertIssue(issues.get(8), documentName, 133, 4, 133, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 146, 0, 166, 1, "ballerina:5", 5, + assertIssue(issues.get(9), documentName, 146, 0, 146, 6, "ballerina:5", 5, PUBLIC_NON_ISOLATED_CLASS_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 155, 4, 157, 5, "ballerina:4", 4, + assertIssue(issues.get(10), documentName, 155, 4, 155, 10, "ballerina:4", 4, PUBLIC_NON_ISOLATED_METHOD_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 180, 0, 184, 1, "ballerina:5", 5, + assertIssue(issues.get(11), documentName, 180, 0, 180, 6, "ballerina:5", 5, PUBLIC_NON_ISOLATED_CLASS_CONSTRUCT, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule005And006Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule005And006Test.java index 545833e0..18572381 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule005And006Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule005And006Test.java @@ -50,13 +50,13 @@ void testNonIsolatedPublicClassOrObjectConstructsUsage() { List issues = scannerContext.getReporter().getIssues(); Assert.assertEquals(issues.size(), 4); - assertIssue(issues.get(0), documentName, 20, 0, 22, 1, "ballerina:5", 5, + assertIssue(issues.get(0), documentName, 20, 0, 20, 6, "ballerina:5", 5, PUBLIC_NON_ISOLATED_CLASS_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 37, 0, 40, 2, "ballerina:6", 6, + assertIssue(issues.get(1), documentName, 37, 0, 37, 6, "ballerina:6", 6, PUBLIC_NON_ISOLATED_OBJECT_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 57, 0, 60, 2, "ballerina:6", 6, + assertIssue(issues.get(2), documentName, 57, 0, 57, 6, "ballerina:6", 6, PUBLIC_NON_ISOLATED_OBJECT_CONSTRUCT, RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 74, 0, 76, 1, "ballerina:5", 5, + assertIssue(issues.get(3), documentName, 74, 0, 74, 6, "ballerina:5", 5, PUBLIC_NON_ISOLATED_CLASS_CONSTRUCT, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/resources/command-outputs/common/empty-issues-html-report.txt b/scan-command/src/test/resources/command-outputs/common/empty-issues-html-report.txt index 14861648..98a861b8 100644 --- a/scan-command/src/test/resources/command-outputs/common/empty-issues-html-report.txt +++ b/scan-command/src/test/resources/command-outputs/common/empty-issues-html-report.txt @@ -1,4 +1,4 @@ -Ballerina Static Code Analysis Report
\ No newline at end of file diff --git a/scan-command/src/test/resources/command-outputs/unix/issues-html-report.txt b/scan-command/src/test/resources/command-outputs/unix/issues-html-report.txt index e7547f14..5cab43ce 100644 --- a/scan-command/src/test/resources/command-outputs/unix/issues-html-report.txt +++ b/scan-command/src/test/resources/command-outputs/unix/issues-html-report.txt @@ -1,4 +1,4 @@ -Ballerina Static Code Analysis Report