From 9705314a8d814b370929da157385098348bdb854 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Sun, 6 Oct 2024 17:05:23 +0530 Subject: [PATCH 01/10] Add static rule for self comparison operators --- .../io/ballerina/scan/internal/CoreRule.java | 9 +- .../scan/internal/StaticCodeAnalyzer.java | 71 ++++++++++++ .../io/ballerina/scan/utils/Constants.java | 13 +++ .../scan/internal/StaticCodeAnalyzerTest.java | 101 ++++++++++++++++++ .../core-rules/self_comparison_rule.bal | 77 +++++++++++++ 5 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java index 211049e3..d155f032 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java @@ -20,6 +20,7 @@ import io.ballerina.scan.Rule; import io.ballerina.scan.RuleKind; +import io.ballerina.scan.utils.Constants; import java.util.ArrayList; import java.util.List; @@ -30,7 +31,13 @@ * @since 0.1.0 * */ enum CoreRule { - AVOID_CHECKPANIC(RuleFactory.createRule(1, "Avoid checkpanic", RuleKind.CODE_SMELL)); + AVOID_CHECKPANIC(RuleFactory.createRule(1, Constants.RuleDescription.AVOID_CHECKPANIC, RuleKind.CODE_SMELL)), + OPERATION_ALWAYS_EVALUATE_TO_TRUE(RuleFactory.createRule(6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL)), + OPERATION_ALWAYS_EVALUATE_TO_FALSE(RuleFactory.createRule(6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL)), + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE(RuleFactory.createRule(6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL)); private final Rule rule; 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 d7cf2c0e..d4fb9565 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 @@ -18,14 +18,25 @@ package io.ballerina.scan.internal; +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; +import io.ballerina.compiler.syntax.tree.BuiltinSimpleNameReferenceNode; import io.ballerina.compiler.syntax.tree.CheckExpressionNode; +import io.ballerina.compiler.syntax.tree.FieldAccessExpressionNode; import io.ballerina.compiler.syntax.tree.ModulePartNode; +import io.ballerina.compiler.syntax.tree.Node; +import io.ballerina.compiler.syntax.tree.NodeLocation; import io.ballerina.compiler.syntax.tree.NodeVisitor; +import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; +import io.ballerina.compiler.syntax.tree.SimpleNameReferenceNode; import io.ballerina.compiler.syntax.tree.SyntaxKind; import io.ballerina.compiler.syntax.tree.SyntaxTree; +import io.ballerina.compiler.syntax.tree.Token; import io.ballerina.projects.Document; import io.ballerina.scan.ScannerContext; +import java.util.Optional; + /** * {@code StaticCodeAnalyzer} contains the logic to perform core static code analysis on Ballerina documents. * @@ -35,11 +46,13 @@ class StaticCodeAnalyzer extends NodeVisitor { private final Document document; private final SyntaxTree syntaxTree; private final ScannerContext scannerContext; + private final SemanticModel semanticModel; StaticCodeAnalyzer(Document document, ScannerContextImpl scannerContext) { this.document = document; this.syntaxTree = document.syntaxTree(); this.scannerContext = scannerContext; + semanticModel = document.module().getCompilation().getSemanticModel(); } void analyze() { @@ -58,4 +71,62 @@ public void visit(CheckExpressionNode checkExpressionNode) { CoreRule.AVOID_CHECKPANIC.rule()); } } + + @Override + public void visit(ModulePartNode modulePartNode) { + modulePartNode.members().forEach(member -> member.accept(this)); + } + + @Override + public void visit(BinaryExpressionNode binaryExpressionNode) { + isSameOperandRestrictedInOperator(binaryExpressionNode.operator()).ifPresent(rule -> { + checkSameUsageInBinaryOperator(binaryExpressionNode.lhsExpr(), + binaryExpressionNode.rhsExpr(), rule, binaryExpressionNode.location()); + }); + } + + private void checkSameUsageInBinaryOperator(Node lhs, Node rhs, CoreRule rule, NodeLocation location) { + if (isSameSimpleExpression(lhs, rhs)) { + scannerContext.getReporter().reportIssue(document, location, rule.rule()); + } + } + + private boolean isSameSimpleExpression(Node n1, Node n2) { + if (n1 instanceof SimpleNameReferenceNode lhsExp && n2 instanceof SimpleNameReferenceNode rhsExpr) { + return lhsExp.name().text().equals(rhsExpr.name().text()); + } + + if (n1 instanceof QualifiedNameReferenceNode lhsExp && n2 instanceof QualifiedNameReferenceNode rhsExpr) { + return lhsExp.modulePrefix() != null && rhsExpr.modulePrefix() != null + && lhsExp.modulePrefix().text().equals(rhsExpr.modulePrefix().text()) + && lhsExp.identifier().text().equals(rhsExpr.identifier().text()); + } + + if (n1 instanceof FieldAccessExpressionNode lhsExp && n2 instanceof FieldAccessExpressionNode rhsExpr) { + // only the simple field access expressions will be considered. + return isSameSimpleExpression(lhsExp.fieldName(), rhsExpr.fieldName()) + && isSameSimpleExpression(lhsExp.expression(), rhsExpr.expression()); + } + + if (n1 instanceof BuiltinSimpleNameReferenceNode lhsExp + && n2 instanceof BuiltinSimpleNameReferenceNode rhsExpr) { + return lhsExp.name().text().equals(rhsExpr.name().text()); + } + return false; + } + + public Optional isSameOperandRestrictedInOperator(Token operator) { + switch (operator.kind()) { + case GT_EQUAL_TOKEN, LT_EQUAL_TOKEN, DOUBLE_EQUAL_TOKEN, TRIPPLE_EQUAL_TOKEN -> { + return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); + } + case GT_TOKEN, LT_TOKEN, NOT_DOUBLE_EQUAL_TOKEN, NOT_EQUAL_TOKEN -> { + return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); + } + case LOGICAL_OR_TOKEN, LOGICAL_AND_TOKEN, BITWISE_AND_TOKEN, PIPE_TOKEN -> { + return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + } + } + return Optional.empty(); + } } diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java index 372de85d..25924efa 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java @@ -62,6 +62,19 @@ public class Constants { static final String RULE_DESCRIPTION_COLUMN = "Rule Description"; static final String[] RULE_PRIORITY_LIST = {"ballerina", "ballerina/", "ballerinax/", "wso2/"}; + public static class RuleDescription { + public static final String AVOID_CHECKPANIC = "Avoid checkpanic"; + public static final String OPERATION_ALWAYS_EVALUATE_TO_TRUE + = "This operation always evaluate to true"; + public static final String OPERATION_ALWAYS_EVALUATE_TO_FALSE + = "This operation always evaluate to false"; + public static final String OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE + = "This operation always evaluate to false"; + + private RuleDescription() { + } + } + private Constants() { } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java index 242b11e2..3f359125 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java @@ -27,6 +27,7 @@ import io.ballerina.scan.Rule; import io.ballerina.scan.RuleKind; import io.ballerina.scan.Source; +import io.ballerina.scan.utils.Constants; import io.ballerina.tools.text.LineRange; import org.testng.Assert; import org.testng.annotations.Test; @@ -71,4 +72,104 @@ void testCheckpanicAnalyzer() { Assert.assertEquals(rule.description(), "Avoid checkpanic"); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } + + @Test(description = "test ") + void testSelfComparisonAnalyzer() { + String documentName = "self_comparison_rule.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(), + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(), + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + Assert.assertEquals(issues.size(), 34); + + assertIssue(issues.get(0), documentName, 9, 10, 9, 16, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 10, 10, 10, 16, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 11, 10, 11, 16, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 12, 10, 12, 16, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 13, 10, 13, 15, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 14, 10, 14, 15, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 15, 10, 15, 17, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 16, 10, 16, 17, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 17, 10, 17, 15, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 18, 10, 18, 15, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 19, 10, 19, 16, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 20, 10, 20, 16, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 31, 10, 31, 20, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 32, 10, 32, 20, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 33, 10, 33, 20, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 34, 10, 34, 20, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 35, 10, 35, 19, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 36, 10, 36, 19, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 37, 10, 37, 21, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 38, 10, 38, 21, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 39, 10, 39, 19, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(21), documentName, 40, 10, 40, 19, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(22), documentName, 41, 10, 41, 20, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(23), documentName, 42, 10, 42, 20, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(24), documentName, 53, 10, 53, 52, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(25), documentName, 54, 10, 54, 52, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(26), documentName, 55, 10, 55, 52, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(27), documentName, 56, 10, 56, 52, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(28), documentName, 57, 10, 57, 51, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(29), documentName, 58, 10, 58, 51, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(30), documentName, 59, 10, 59, 53, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(31), documentName, 60, 10, 60, 53, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(32), documentName, 61, 10, 61, 51, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(33), documentName, 62, 10, 62, 51, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + + } + + void assertIssue(Issue issue, String documentName, int startLine, int startOffset, int endLine, int endOffset, + String ruleId, int numericId, String description, RuleKind ruleKind) { + Assert.assertEquals(issue.source(), Source.BUILT_IN); + LineRange location = issue.location().lineRange(); + Assert.assertEquals(location.fileName(), documentName); + Assert.assertEquals(location.startLine().line(), startLine); + Assert.assertEquals(location.startLine().offset(), startOffset); + Assert.assertEquals(location.endLine().line(), endLine); + Assert.assertEquals(location.endLine().offset(), endOffset); + Rule rule = issue.rule(); + Assert.assertEquals(rule.id(), ruleId); + Assert.assertEquals(rule.numericId(), numericId); + Assert.assertEquals(rule.description(), description); + Assert.assertEquals(rule.kind(), ruleKind); + } } diff --git a/scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal b/scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal new file mode 100644 index 00000000..bcb12a37 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal @@ -0,0 +1,77 @@ +import ballerina/lang.'int as i; + +function testSimpleVariableReference() { + int a = 1; + int a2 = 1; + boolean b = true; + boolean b2 = true; + string s = "string"; + + test2(a <= a); // warning + test2(a >= a); // warning + test2(a == a); // warning + test2(a != a); // warning + test2(a < a); // warning + test2(a > a); // warning + test2(a === a); // warning + test2(a !== a); // warning + test2(a & a); // warning + test2(a | a); // warning + test2(b && b); // warning + test2(b || b); // warning + + test2(a <= a2); + test2(b2 || b); + test2(s == "string"); +} + +function testFieldAccessVariableReference() { + A a = new; + A b = new; + + test2(a.a <= a.a); // warning + test2(a.a >= a.a); // warning + test2(a.a == a.a); // warning + test2(a.a != a.a); // warning + test2(a.a < a.a); // warning + test2(a.a > a.a); // warning + test2(a.a === a.a); // warning + test2(a.a !== a.a); // warning + test2(a.a & a.a); // warning + test2(a.a | a.a); // warning + test2(a.b && a.b); // warning + test2(a.b || a.b); // warning + + test2(a.a <= b.a); + test2(a.b && b.b); + test2(a.c == "a.c"); +} + +function testQualifiedVariableReference() { + int i = 3; + int SIGNED8_MIN_VALUE = 10; + + test2(i:SIGNED8_MIN_VALUE <= i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE >= i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE == i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE != i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE < i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE > i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE === i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE !== i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE & i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE | i:SIGNED8_MIN_VALUE); // warning + + test2(SIGNED8_MIN_VALUE <= i:SIGNED8_MIN_VALUE); + test2(i <= i:SIGNED8_MIN_VALUE); +} + +class A { + int a = 3; + boolean b = false; + string c = "string"; +} + +function test2(any c) { + _ = c; +} \ No newline at end of file From 34dbcdbd6053fd24d5f4a8517142476fdb4654ad Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Sun, 6 Oct 2024 23:38:01 +0530 Subject: [PATCH 02/10] Add static rule for trivial operations --- .../io/ballerina/scan/internal/CoreRule.java | 4 +- .../scan/internal/StaticCodeAnalyzer.java | 143 +++++++++++++++--- .../io/ballerina/scan/utils/Constants.java | 15 ++ .../scan/utils/ScanCodeAnalyzerUtils.java | 70 +++++++++ .../scan/internal/StaticCodeAnalyzerTest.java | 88 ++++++++--- .../core-rules/trivial_operations.bal | 86 +++++++++++ 6 files changed, 357 insertions(+), 49 deletions(-) create mode 100644 scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java create mode 100644 scan-command/src/test/resources/test-resources/core-rules/trivial_operations.bal diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java index d155f032..c23a4238 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java @@ -34,9 +34,9 @@ enum CoreRule { AVOID_CHECKPANIC(RuleFactory.createRule(1, Constants.RuleDescription.AVOID_CHECKPANIC, RuleKind.CODE_SMELL)), OPERATION_ALWAYS_EVALUATE_TO_TRUE(RuleFactory.createRule(6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATE_TO_FALSE(RuleFactory.createRule(6, + OPERATION_ALWAYS_EVALUATE_TO_FALSE(RuleFactory.createRule(7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE(RuleFactory.createRule(6, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE(RuleFactory.createRule(8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL)); private final Rule rule; 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 d4fb9565..b19a3899 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 @@ -20,23 +20,26 @@ import io.ballerina.compiler.api.SemanticModel; import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; -import io.ballerina.compiler.syntax.tree.BuiltinSimpleNameReferenceNode; import io.ballerina.compiler.syntax.tree.CheckExpressionNode; -import io.ballerina.compiler.syntax.tree.FieldAccessExpressionNode; import io.ballerina.compiler.syntax.tree.ModulePartNode; import io.ballerina.compiler.syntax.tree.Node; import io.ballerina.compiler.syntax.tree.NodeLocation; import io.ballerina.compiler.syntax.tree.NodeVisitor; -import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; -import io.ballerina.compiler.syntax.tree.SimpleNameReferenceNode; import io.ballerina.compiler.syntax.tree.SyntaxKind; import io.ballerina.compiler.syntax.tree.SyntaxTree; import io.ballerina.compiler.syntax.tree.Token; import io.ballerina.projects.Document; import io.ballerina.scan.ScannerContext; +import io.ballerina.scan.utils.Constants; import java.util.Optional; +import static io.ballerina.compiler.syntax.tree.SyntaxKind.CHECKPANIC_KEYWORD; +import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isDefinedQualifiedNameReference; +import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isEqualToProvidedLiteralIdentifier; +import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isSameSimpleExpression; +import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.reportIssue; + /** * {@code StaticCodeAnalyzer} contains the logic to perform core static code analysis on Ballerina documents. * @@ -66,9 +69,8 @@ void analyze() { */ @Override public void visit(CheckExpressionNode checkExpressionNode) { - if (checkExpressionNode.checkKeyword().kind().equals(SyntaxKind.CHECKPANIC_KEYWORD)) { - scannerContext.getReporter().reportIssue(document, checkExpressionNode.location(), - CoreRule.AVOID_CHECKPANIC.rule()); + if (checkExpressionNode.checkKeyword().kind().equals(CHECKPANIC_KEYWORD)) { + reportIssue(scannerContext, document, checkExpressionNode, CoreRule.AVOID_CHECKPANIC.rule()); } } @@ -79,6 +81,7 @@ public void visit(ModulePartNode modulePartNode) { @Override public void visit(BinaryExpressionNode binaryExpressionNode) { + reportIssuesForTrivialOperations(binaryExpressionNode); isSameOperandRestrictedInOperator(binaryExpressionNode.operator()).ifPresent(rule -> { checkSameUsageInBinaryOperator(binaryExpressionNode.lhsExpr(), binaryExpressionNode.rhsExpr(), rule, binaryExpressionNode.location()); @@ -87,35 +90,127 @@ public void visit(BinaryExpressionNode binaryExpressionNode) { private void checkSameUsageInBinaryOperator(Node lhs, Node rhs, CoreRule rule, NodeLocation location) { if (isSameSimpleExpression(lhs, rhs)) { - scannerContext.getReporter().reportIssue(document, location, rule.rule()); + reportIssue(scannerContext, document, location, rule.rule()); } } - private boolean isSameSimpleExpression(Node n1, Node n2) { - if (n1 instanceof SimpleNameReferenceNode lhsExp && n2 instanceof SimpleNameReferenceNode rhsExpr) { - return lhsExp.name().text().equals(rhsExpr.name().text()); + public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressionNode) { + if (binaryExpressionNode.operator().kind() == SyntaxKind.GT_TOKEN) { + if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), + Constants.Token.FLOAT, Constants.Token.INFINITY)) { + // a > Infinity is always false. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + } + + if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), + Constants.Token.INT, Constants.Token.MAX_VALUE)) { + // a > MAX_VALUE is always false. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + } } - if (n1 instanceof QualifiedNameReferenceNode lhsExp && n2 instanceof QualifiedNameReferenceNode rhsExpr) { - return lhsExp.modulePrefix() != null && rhsExpr.modulePrefix() != null - && lhsExp.modulePrefix().text().equals(rhsExpr.modulePrefix().text()) - && lhsExp.identifier().text().equals(rhsExpr.identifier().text()); + if (binaryExpressionNode.operator().kind() == SyntaxKind.LT_EQUAL_TOKEN) { + if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), + Constants.Token.FLOAT, Constants.Token.INFINITY)) { + // a <= Infinity is always true. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + } + + if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), + Constants.Token.INT, Constants.Token.MAX_VALUE)) { + // a <= MAX_VALUE is always true. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + } } - if (n1 instanceof FieldAccessExpressionNode lhsExp && n2 instanceof FieldAccessExpressionNode rhsExpr) { - // only the simple field access expressions will be considered. - return isSameSimpleExpression(lhsExp.fieldName(), rhsExpr.fieldName()) - && isSameSimpleExpression(lhsExp.expression(), rhsExpr.expression()); + if (binaryExpressionNode.operator().kind() == SyntaxKind.LT_TOKEN) { + if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), + Constants.Token.INT, Constants.Token.MIN_VALUE)) { + // a < MIN_VALUE is always false. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + } } - if (n1 instanceof BuiltinSimpleNameReferenceNode lhsExp - && n2 instanceof BuiltinSimpleNameReferenceNode rhsExpr) { - return lhsExp.name().text().equals(rhsExpr.name().text()); + if (binaryExpressionNode.operator().kind() == SyntaxKind.GT_EQUAL_TOKEN) { + if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), + Constants.Token.INT, Constants.Token.MIN_VALUE)) { + // a >= MIN_VALUE is always true. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + } + } + + if (binaryExpressionNode.operator().kind() == SyntaxKind.LOGICAL_AND_TOKEN) { + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.FALSE) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.FALSE)) { + // a && false is always false. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + } + + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.TRUE) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.TRUE)) { + // a && true is always `a`. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + } + } + + if (binaryExpressionNode.operator().kind() == SyntaxKind.LOGICAL_OR_TOKEN) { + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.FALSE) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.FALSE)) { + // a || false is always `a`. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + } + + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.TRUE) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.TRUE)) { + // a || true is always true. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + } + } + + if (binaryExpressionNode.operator().kind() == SyntaxKind.BITWISE_AND_TOKEN) { + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.ZERO) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.ZERO)) { + // a & 0 is always false. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + } + + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.MINUS_ONE) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.MINUS_ONE)) { + // a & -1 is always `a`. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + } + } + + if (binaryExpressionNode.operator().kind() == SyntaxKind.PIPE_TOKEN) { + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.ZERO) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.ZERO)) { + // a | 0 is always `a`. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + } + + if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.MINUS_ONE) + || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.MINUS_ONE)) { + // a | -1 is always true. + reportIssue(scannerContext, document, binaryExpressionNode, + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + } } - return false; } - public Optional isSameOperandRestrictedInOperator(Token operator) { + private Optional isSameOperandRestrictedInOperator(Token operator) { switch (operator.kind()) { case GT_EQUAL_TOKEN, LT_EQUAL_TOKEN, DOUBLE_EQUAL_TOKEN, TRIPPLE_EQUAL_TOKEN -> { return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java index 25924efa..41c973ef 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java @@ -75,6 +75,21 @@ private RuleDescription() { } } + public static class Token { + public static String FLOAT = "float"; + public static String INT = "int"; + public static String INFINITY = "Infinity"; + public static String MAX_VALUE = "MAX_VALUE"; + public static String MIN_VALUE = "MIN_VALUE"; + public static String TRUE = "true"; + public static String FALSE = "false"; + public static String ZERO = "0"; + public static String ONE = "1"; + public static String MINUS_ONE = "-1"; + private Token() { + } + } + private Constants() { } } diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java b/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java new file mode 100644 index 00000000..53e0958c --- /dev/null +++ b/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java @@ -0,0 +1,70 @@ +package io.ballerina.scan.utils; + +import io.ballerina.compiler.syntax.tree.BasicLiteralNode; +import io.ballerina.compiler.syntax.tree.BuiltinSimpleNameReferenceNode; +import io.ballerina.compiler.syntax.tree.FieldAccessExpressionNode; +import io.ballerina.compiler.syntax.tree.Node; +import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; +import io.ballerina.compiler.syntax.tree.SimpleNameReferenceNode; +import io.ballerina.compiler.syntax.tree.SyntaxKind; +import io.ballerina.compiler.syntax.tree.UnaryExpressionNode; +import io.ballerina.projects.Document; +import io.ballerina.scan.Rule; +import io.ballerina.scan.ScannerContext; +import io.ballerina.tools.diagnostics.Location; + +public class ScanCodeAnalyzerUtils { + public static void reportIssue(ScannerContext scannerContext, Document document, Node node, Rule rule) { + scannerContext.getReporter().reportIssue(document, node.location(), rule); + } + + public static void reportIssue(ScannerContext scannerContext, Document document, Location location, Rule rule) { + scannerContext.getReporter().reportIssue(document, location, rule); + } + + public static boolean isSameSimpleExpression(Node n1, Node n2) { + if (n1 instanceof SimpleNameReferenceNode lhsExp && n2 instanceof SimpleNameReferenceNode rhsExpr) { + return lhsExp.name().text().equals(rhsExpr.name().text()); + } + + if (n1 instanceof QualifiedNameReferenceNode lhsExp && n2 instanceof QualifiedNameReferenceNode rhsExpr) { + return lhsExp.modulePrefix() != null && rhsExpr.modulePrefix() != null + && lhsExp.modulePrefix().text().equals(rhsExpr.modulePrefix().text()) + && lhsExp.identifier().text().equals(rhsExpr.identifier().text()); + } + + if (n1 instanceof FieldAccessExpressionNode lhsExp && n2 instanceof FieldAccessExpressionNode rhsExpr) { + // only the simple field access expressions will be considered. + return isSameSimpleExpression(lhsExp.fieldName(), rhsExpr.fieldName()) + && isSameSimpleExpression(lhsExp.expression(), rhsExpr.expression()); + } + + if (n1 instanceof BuiltinSimpleNameReferenceNode lhsExp + && n2 instanceof BuiltinSimpleNameReferenceNode rhsExpr) { + return lhsExp.name().text().equals(rhsExpr.name().text()); + } + return false; + } + + public static boolean isDefinedQualifiedNameReference(Node node, String module, String identifier) { + if (node instanceof QualifiedNameReferenceNode ref) { + return ref.modulePrefix() != null && ref.identifier() != null + && ref.modulePrefix().text().equals(module) && ref.identifier().text().equals(identifier); + } + return false; + } + + public static boolean isEqualToProvidedLiteralIdentifier(Node node, String identifierName) { + if (identifierName.equals(Constants.Token.MINUS_ONE)) { + if (node instanceof UnaryExpressionNode exp) { + return exp.unaryOperator().kind().equals(SyntaxKind.MINUS_TOKEN) + && isEqualToProvidedLiteralIdentifier(exp.expression(), Constants.Token.ONE); + } + return false; + } + if (node instanceof BasicLiteralNode ref) { + return ref.literalToken().text().equals(identifierName); + } + return false; + } +} diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java index 3f359125..66dcca92 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java @@ -73,7 +73,7 @@ void testCheckpanicAnalyzer() { Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } - @Test(description = "test ") + @Test(description = "test self comparisons") void testSelfComparisonAnalyzer() { String documentName = "self_comparison_rule.bal"; Document document = loadDocument(documentName); @@ -92,23 +92,23 @@ void testSelfComparisonAnalyzer() { Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(2), documentName, 11, 10, 11, 16, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 12, 10, 12, 16, "ballerina:6", 6, + assertIssue(issues.get(3), documentName, 12, 10, 12, 16, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 13, 10, 13, 15, "ballerina:6", 6, + assertIssue(issues.get(4), documentName, 13, 10, 13, 15, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 14, 10, 14, 15, "ballerina:6", 6, + assertIssue(issues.get(5), documentName, 14, 10, 14, 15, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(6), documentName, 15, 10, 15, 17, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 16, 10, 16, 17, "ballerina:6", 6, + assertIssue(issues.get(7), documentName, 16, 10, 16, 17, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 17, 10, 17, 15, "ballerina:6", 6, + assertIssue(issues.get(8), documentName, 17, 10, 17, 15, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 18, 10, 18, 15, "ballerina:6", 6, + assertIssue(issues.get(9), documentName, 18, 10, 18, 15, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 19, 10, 19, 16, "ballerina:6", 6, + assertIssue(issues.get(10), documentName, 19, 10, 19, 16, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 20, 10, 20, 16, "ballerina:6", 6, + assertIssue(issues.get(11), documentName, 20, 10, 20, 16, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(12), documentName, 31, 10, 31, 20, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); @@ -116,23 +116,23 @@ void testSelfComparisonAnalyzer() { Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(14), documentName, 33, 10, 33, 20, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(15), documentName, 34, 10, 34, 20, "ballerina:6", 6, + assertIssue(issues.get(15), documentName, 34, 10, 34, 20, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(16), documentName, 35, 10, 35, 19, "ballerina:6", 6, + assertIssue(issues.get(16), documentName, 35, 10, 35, 19, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(17), documentName, 36, 10, 36, 19, "ballerina:6", 6, + assertIssue(issues.get(17), documentName, 36, 10, 36, 19, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(18), documentName, 37, 10, 37, 21, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(19), documentName, 38, 10, 38, 21, "ballerina:6", 6, + assertIssue(issues.get(19), documentName, 38, 10, 38, 21, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(20), documentName, 39, 10, 39, 19, "ballerina:6", 6, + assertIssue(issues.get(20), documentName, 39, 10, 39, 19, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(21), documentName, 40, 10, 40, 19, "ballerina:6", 6, + assertIssue(issues.get(21), documentName, 40, 10, 40, 19, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(22), documentName, 41, 10, 41, 20, "ballerina:6", 6, + assertIssue(issues.get(22), documentName, 41, 10, 41, 20, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(23), documentName, 42, 10, 42, 20, "ballerina:6", 6, + assertIssue(issues.get(23), documentName, 42, 10, 42, 20, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(24), documentName, 53, 10, 53, 52, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); @@ -140,21 +140,63 @@ void testSelfComparisonAnalyzer() { Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(26), documentName, 55, 10, 55, 52, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(27), documentName, 56, 10, 56, 52, "ballerina:6", 6, + assertIssue(issues.get(27), documentName, 56, 10, 56, 52, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(28), documentName, 57, 10, 57, 51, "ballerina:6", 6, + assertIssue(issues.get(28), documentName, 57, 10, 57, 51, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(29), documentName, 58, 10, 58, 51, "ballerina:6", 6, + assertIssue(issues.get(29), documentName, 58, 10, 58, 51, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(30), documentName, 59, 10, 59, 53, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(31), documentName, 60, 10, 60, 53, "ballerina:6", 6, + assertIssue(issues.get(31), documentName, 60, 10, 60, 53, "ballerina:7", 7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(32), documentName, 61, 10, 61, 51, "ballerina:6", 6, + assertIssue(issues.get(32), documentName, 61, 10, 61, 51, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(33), documentName, 62, 10, 62, 51, "ballerina:6", 6, + assertIssue(issues.get(33), documentName, 62, 10, 62, 51, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + } + + @Test(description = "test trivial operations") + void testTrivialOperationsAnalyzer() { + String documentName = "trivial_operations.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(), + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(), + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + Assert.assertEquals(issues.size(), 14); + assertIssue(issues.get(0), documentName, 6, 13, 6, 30, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 7, 13, 7, 31, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 9, 13, 9, 31, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 10, 13, 10, 30, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 12, 13, 12, 32, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 13, 13, 13, 31, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 17, 13, 17, 23, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 18, 13, 18, 22, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 19, 13, 19, 22, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 20, 13, 20, 23, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 23, 18, 23, 23, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 24, 14, 24, 20, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 25, 14, 25, 20, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 26, 14, 26, 19, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); } void assertIssue(Issue issue, String documentName, int startLine, int startOffset, int endLine, int endOffset, diff --git a/scan-command/src/test/resources/test-resources/core-rules/trivial_operations.bal b/scan-command/src/test/resources/test-resources/core-rules/trivial_operations.bal new file mode 100644 index 00000000..954ebf0c --- /dev/null +++ b/scan-command/src/test/resources/test-resources/core-rules/trivial_operations.bal @@ -0,0 +1,86 @@ +function testOperators() { + int x = 1; + float y = 2.3f; + boolean result; + + // Arithmetic operators + result = x < int:MIN_VALUE; // warning + result = x >= int:MIN_VALUE; // warning + + result = x <= int:MAX_VALUE; // warning + result = x > int:MAX_VALUE; // warning + + result = y <= float:Infinity; // warning + result = y > float:Infinity; // warning + + // Logical operators + boolean b = true; + result = b && false; // warning + result = b || true; // warning + result = b && true; // warning + result = b || false; // warning + + // Bitwise operators + int result2 = x | 0;// warning + result2 = x & -1; // warning + result2 = x | -1;// warning + result2 = x & 0; // warning +} + +function testRelationaOperatorsWithoutWarnings() { + string x = "1"; + string y = "2.3f"; + boolean result; + + // Arithmetic operators + result = x < "int:MIN_VALUE"; + result = x >= "int:MIN_VALUE"; + + result = x <= "int:MAX_VALUE"; + result = x > "int:MAX_VALUE"; + + result = y <= "float:Infinity"; + result = y > "float:Infinity"; + + // Logical operators + boolean 'false = false; + boolean 'true = true; + boolean b = true; + + result = b && 'false; + result = b || 'true; + result = b && 'true; + result = b || 'false; + + // Bitwise operators + int '0 = 0; + int \-1 = -1; + int x2 = 1; + + int result2 = x2 | '0; + result2 = x2 & \-1; + result2 = x2 | \-1; + result2 = x2 & '0; + result2 = x2 | 1; + result2 = x2 & 1; +} + +function testRelationaOperatorsWithoutWarnings2() { + int x = 1; + float y = 2.3f; + boolean result; + + // Arithmetic operators + result = x > int:MIN_VALUE; + result = x <= int:MIN_VALUE; + + result = x >= int:MAX_VALUE; + result = x < int:MAX_VALUE; + + result = y >= float:Infinity; + result = y < float:Infinity; + + // Bitwise operators + int result2 = x | 1; + result2 = x & --1; +} From 0f212e1db562c415dbffd947f147da3aacd210af Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Mon, 7 Oct 2024 17:06:20 +0530 Subject: [PATCH 03/10] Add self assignment static analysis rule --- .../io/ballerina/scan/internal/CoreRule.java | 4 +- .../scan/internal/StaticCodeAnalyzer.java | 23 ++++++++ .../io/ballerina/scan/utils/Constants.java | 1 + .../scan/internal/StaticCodeAnalyzerTest.java | 56 ++++++++++++++++++ .../core-rules/self_assignment.bal | 57 +++++++++++++++++++ 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java index c23a4238..d17815b8 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java @@ -37,7 +37,9 @@ enum CoreRule { OPERATION_ALWAYS_EVALUATE_TO_FALSE(RuleFactory.createRule(7, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL)), OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE(RuleFactory.createRule(8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL)); + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL)), + SELF_ASSIGNMENT(RuleFactory.createRule(9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL));; private final Rule rule; 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 b19a3899..c0fcae82 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 @@ -19,8 +19,10 @@ package io.ballerina.scan.internal; import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.compiler.syntax.tree.AssignmentStatementNode; import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; import io.ballerina.compiler.syntax.tree.CheckExpressionNode; +import io.ballerina.compiler.syntax.tree.CompoundAssignmentStatementNode; import io.ballerina.compiler.syntax.tree.ModulePartNode; import io.ballerina.compiler.syntax.tree.Node; import io.ballerina.compiler.syntax.tree.NodeLocation; @@ -88,12 +90,33 @@ public void visit(BinaryExpressionNode binaryExpressionNode) { }); } + @Override + public void visit(AssignmentStatementNode assignmentStatementNode) { + checkSameUsageInAssignment(assignmentStatementNode.varRef(), assignmentStatementNode.expression(), + CoreRule.SELF_ASSIGNMENT, assignmentStatementNode.location()); + this.visitSyntaxNode(assignmentStatementNode); + } + + @Override + public void visit(CompoundAssignmentStatementNode compoundAssignmentStatementNode) { + checkSameUsageInAssignment(compoundAssignmentStatementNode.lhsExpression(), + compoundAssignmentStatementNode.rhsExpression(), CoreRule.SELF_ASSIGNMENT, + compoundAssignmentStatementNode.location()); + this.visitSyntaxNode(compoundAssignmentStatementNode); + } + private void checkSameUsageInBinaryOperator(Node lhs, Node rhs, CoreRule rule, NodeLocation location) { if (isSameSimpleExpression(lhs, rhs)) { reportIssue(scannerContext, document, location, rule.rule()); } } + private void checkSameUsageInAssignment(Node lhs, Node rhs, CoreRule rule, NodeLocation location) { + if (isSameSimpleExpression(lhs, rhs)) { + reportIssue(scannerContext, document, location, rule.rule()); + } + } + public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressionNode) { if (binaryExpressionNode.operator().kind() == SyntaxKind.GT_TOKEN) { if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java index 41c973ef..a4bc24c1 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java @@ -70,6 +70,7 @@ public static class RuleDescription { = "This operation always evaluate to false"; public static final String OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE = "This operation always evaluate to false"; + public static final String SELF_ASSIGNMENT = "Self assignment"; private RuleDescription() { } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java index 66dcca92..a3d0549b 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java @@ -199,6 +199,62 @@ void testTrivialOperationsAnalyzer() { Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); } + @Test(description = "test self assignment") + void testSelfAssignmentAnalyzer() { + String documentName = "self_assignment.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of(CoreRule.SELF_ASSIGNMENT.rule())); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + + Assert.assertEquals(issues.size(), 22); + assertIssue(issues.get(0), documentName, 5, 4, 5, 10, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 6, 4, 6, 11, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 7, 4, 7, 11, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 8, 4, 8, 11, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 9, 4, 9, 11, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 10, 4, 10, 11, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 11, 4, 11, 11, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 12, 4, 12, 11, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 13, 4, 13, 12, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 14, 4, 14, 12, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 15, 4, 15, 13, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 28, 4, 28, 14, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 29, 4, 29, 15, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 30, 4, 30, 15, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 31, 4, 31, 15, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 32, 4, 32, 15, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 33, 4, 33, 15, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 34, 4, 34, 15, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 35, 4, 35, 15, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 36, 4, 36, 16, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 37, 4, 37, 16, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(21), documentName, 38, 4, 38, 17, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + } + void assertIssue(Issue issue, String documentName, int startLine, int startOffset, int endLine, int endOffset, String ruleId, int numericId, String description, RuleKind ruleKind) { Assert.assertEquals(issue.source(), Source.BUILT_IN); diff --git a/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal b/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal new file mode 100644 index 00000000..7e6a3010 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal @@ -0,0 +1,57 @@ +function testSimpleVariableReference() { + int a = 1; + int a2 = 1; + string|int a3 = 1; + + a = a; // warning + a += a; // warning + a -= a; // warning + a *= a; // warning + a /= a; // warning + a &= a; // warning + a |= a; // warning + a ^= a; // warning + a <<= a; // warning + a >>= a; // warning + a >>>= a; // warning + + a = a2; + a3 = "a3"; + + a += a2; + a += 1; +} + +function testFieldAccessVariableReference() { + A a = new; + A b = new; + + a.a = a.a; // warning + a.a += a.a; // warning + a.a -= a.a; // warning + a.a *= a.a; // warning + a.a /= a.a; // warning + a.a &= a.a; // warning + a.a |= a.a; // warning + a.a ^= a.a; // warning + a.a <<= a.a; // warning + a.a >>= a.a; // warning + a.a >>>= a.a; // warning + + a.a = b.a; + a.a3 = "a.a3"; + a.a += 1; + a.a += a.a4; +} + +class A { + int a = 3; + boolean b = false; + string c = "string"; + int|string a3 = 3; + int a4 = 3; +} + +function test2(any c) { + _ = c; +} From f57ab0fbd51d4f97ecb01293d654ed06ef6ad77f Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Mon, 7 Oct 2024 17:46:54 +0530 Subject: [PATCH 04/10] Add tests for indexed expression nodes --- .../scan/utils/ScanCodeAnalyzerUtils.java | 28 ++++++++++ .../scan/internal/StaticCodeAnalyzerTest.java | 52 ++++++++++++++++++- .../core-rules/self_assignment.bal | 22 ++++++++ .../core-rules/self_comparison_rule.bal | 26 ++++++++++ 4 files changed, 126 insertions(+), 2 deletions(-) diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java b/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java index 53e0958c..fe5a8899 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java @@ -2,9 +2,12 @@ import io.ballerina.compiler.syntax.tree.BasicLiteralNode; import io.ballerina.compiler.syntax.tree.BuiltinSimpleNameReferenceNode; +import io.ballerina.compiler.syntax.tree.ExpressionNode; import io.ballerina.compiler.syntax.tree.FieldAccessExpressionNode; +import io.ballerina.compiler.syntax.tree.IndexedExpressionNode; import io.ballerina.compiler.syntax.tree.Node; import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; +import io.ballerina.compiler.syntax.tree.SeparatedNodeList; import io.ballerina.compiler.syntax.tree.SimpleNameReferenceNode; import io.ballerina.compiler.syntax.tree.SyntaxKind; import io.ballerina.compiler.syntax.tree.UnaryExpressionNode; @@ -39,13 +42,38 @@ public static boolean isSameSimpleExpression(Node n1, Node n2) { && isSameSimpleExpression(lhsExp.expression(), rhsExpr.expression()); } + if (n1 instanceof IndexedExpressionNode lhsExp && n2 instanceof IndexedExpressionNode rhsExpr) { + // only the simple field access expressions will be considered. + return isSameSimpleExpression(lhsExp.containerExpression(), rhsExpr.containerExpression()) + && isSameKeyExpression(lhsExp.keyExpression(), rhsExpr.keyExpression()); + } + if (n1 instanceof BuiltinSimpleNameReferenceNode lhsExp && n2 instanceof BuiltinSimpleNameReferenceNode rhsExpr) { return lhsExp.name().text().equals(rhsExpr.name().text()); } + + if (n1 instanceof BasicLiteralNode lhsExp && n2 instanceof BasicLiteralNode rhsExpr) { + return lhsExp.literalToken().text().equals(rhsExpr.literalToken().text()); + } + return false; } + private static boolean isSameKeyExpression(SeparatedNodeList lhsKeyExpNodes, + SeparatedNodeList rhsKeyExpNodes) { + if (lhsKeyExpNodes.size() != rhsKeyExpNodes.size()) { + return false; + } + + for (int i = 0; i < lhsKeyExpNodes.size(); i++) { + if (!isSameSimpleExpression(lhsKeyExpNodes.get(i), rhsKeyExpNodes.get(i))) { + return false; + } + } + return true; + } + public static boolean isDefinedQualifiedNameReference(Node node, String module, String identifier) { if (node instanceof QualifiedNameReferenceNode ref) { return ref.modulePrefix() != null && ref.identifier() != null diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java index a3d0549b..52613f4f 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java @@ -84,7 +84,7 @@ void testSelfComparisonAnalyzer() { StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext); staticCodeAnalyzer.analyze(); List issues = scannerContext.getReporter().getIssues(); - Assert.assertEquals(issues.size(), 34); + Assert.assertEquals(issues.size(), 46); assertIssue(issues.get(0), documentName, 9, 10, 9, 16, "ballerina:6", 6, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); @@ -154,6 +154,30 @@ void testSelfComparisonAnalyzer() { Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(33), documentName, 62, 10, 62, 51, "ballerina:8", 8, Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(34), documentName, 72, 10, 72, 26, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(35), documentName, 73, 10, 73, 26, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(36), documentName, 74, 10, 74, 26, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(37), documentName, 75, 10, 75, 26, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(38), documentName, 76, 10, 76, 25, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(39), documentName, 77, 10, 77, 25, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(40), documentName, 78, 10, 78, 27, "ballerina:6", 6, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(41), documentName, 79, 10, 79, 27, "ballerina:7", 7, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(42), documentName, 80, 10, 80, 25, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(43), documentName, 81, 10, 81, 25, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(44), documentName, 82, 10, 82, 26, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(45), documentName, 83, 10, 83, 26, "ballerina:8", 8, + Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); } @Test(description = "test trivial operations") @@ -208,7 +232,8 @@ void testSelfAssignmentAnalyzer() { staticCodeAnalyzer.analyze(); List issues = scannerContext.getReporter().getIssues(); - Assert.assertEquals(issues.size(), 22); + Assert.assertEquals(issues.size(), 33); + assertIssue(issues.get(0), documentName, 5, 4, 5, 10, "ballerina:9", 9, Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); assertIssue(issues.get(1), documentName, 6, 4, 6, 11, "ballerina:9", 9, @@ -253,6 +278,29 @@ void testSelfAssignmentAnalyzer() { Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); assertIssue(issues.get(21), documentName, 38, 4, 38, 17, "ballerina:9", 9, Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(22), documentName, 62, 4, 62, 20, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(23), documentName, 63, 4, 63, 21, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(24), documentName, 64, 4, 64, 21, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(25), documentName, 65, 4, 65, 21, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(26), documentName, 66, 4, 66, 21, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(27), documentName, 67, 4, 67, 21, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(28), documentName, 68, 4, 68, 21, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(29), documentName, 69, 4, 69, 21, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(30), documentName, 70, 4, 70, 22, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(31), documentName, 71, 4, 71, 22, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(32), documentName, 72, 4, 72, 23, "ballerina:9", 9, + Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + } void assertIssue(Issue issue, String documentName, int startLine, int startOffset, int endLine, int endOffset, diff --git a/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal b/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal index 7e6a3010..e15a65e2 100644 --- a/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal +++ b/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal @@ -55,3 +55,25 @@ class A { function test2(any c) { _ = c; } + +function t() { + map a = {}; + map b = {}; + + a["a"] = a["a"]; // warning + a["a"] += a["a"]; // warning + a["a"] -= a["a"]; // warning + a["a"] *= a["a"]; // warning + a["a"] /= a["a"]; // warning + a["a"] &= a["a"]; // warning + a["a"] |= a["a"]; // warning + a["a"] ^= a["a"]; // warning + a["a"] <<= a["a"]; // warning + a["a"] >>= a["a"]; // warning + a["a"] >>>= a["a"]; // warning + + a["a"] = b["a"]; + a.["a3"] = "a.[\"a3\"]"; + a.["a"] += 1; + a.["a"] += a.["a4"]; +} \ No newline at end of file diff --git a/scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal b/scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal index bcb12a37..db9f54c4 100644 --- a/scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal +++ b/scan-command/src/test/resources/test-resources/core-rules/self_comparison_rule.bal @@ -66,6 +66,32 @@ function testQualifiedVariableReference() { test2(i <= i:SIGNED8_MIN_VALUE); } +function testIndexedExpression() { + map a = {}; + map b = {}; + + test2(a["a"] <= a["a"]); // warning + test2(a["a"] >= a["a"]); // warning + test2(a["a"] == a["a"]); // warning + test2(a["a"] != a["a"]); // warning + test2(a["a"] < a["a"]); // warning + test2(a["a"] > a["a"]); // warning + test2(a["a"] === a["a"]); // warning + test2(a["a"] !== a["a"]); // warning + test2(a["a"] & a["a"]); // warning + test2(a["a"] | a["a"]); // warning + test2(b["a"] && b["a"]); // warning + test2(b["a"] || b["a"]); // warning + + test2(a["a"] <= b["a"]); + test2(a["a"] || b["a"]); + test2(a["a"] == "b[\"a\"]"); + + test2(a["a"] <= a["b"]); + test2(a["a"] || a["b"]); + test2(a["a"] == "a[\"b\"]"); +} + class A { int a = 3; boolean b = false; From b541605cde650fcf4561d537dad3ef28eca6f1c2 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Thu, 20 Feb 2025 18:07:31 +0530 Subject: [PATCH 05/10] Fix tests in self comparison static rule --- .../io/ballerina/scan/internal/CoreRule.java | 9 +- .../scan/internal/StaticCodeAnalyzer.java | 75 ++---- .../io/ballerina/scan/utils/Constants.java | 34 +-- .../ballerina/scan/internal/CoreRuleTest.java | 2 +- .../scan/internal/StaticCodeAnalyzerTest.java | 219 +++++++++--------- .../unix/list-rules-output.txt | 8 +- .../unix/print-rules-to-console.txt | 10 +- .../windows/list-rules-output.txt | 8 +- .../windows/print-rules-to-console.txt | 10 +- ...gnment.bal => rule009_self_assignment.bal} | 0 scan-command/src/test/resources/testng.xml | 1 + 11 files changed, 172 insertions(+), 204 deletions(-) rename scan-command/src/test/resources/test-resources/core-rules/{self_assignment.bal => rule009_self_assignment.bal} (100%) diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java index cb002333..263de0dc 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java @@ -20,7 +20,6 @@ import io.ballerina.scan.Rule; import io.ballerina.scan.RuleKind; -import io.ballerina.scan.utils.Constants; import java.util.ArrayList; import java.util.List; @@ -36,13 +35,13 @@ enum CoreRule { UNUSED_FUNCTION_PARAMETER(RuleFactory.createRule(2, "Unused function parameter", RuleKind.CODE_SMELL)), OPERATION_ALWAYS_EVALUATE_TO_TRUE(RuleFactory.createRule(6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL)), + "This operation always evaluate to true", RuleKind.CODE_SMELL)), OPERATION_ALWAYS_EVALUATE_TO_FALSE(RuleFactory.createRule(7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL)), + "This operation always evaluate to false", RuleKind.CODE_SMELL)), OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE(RuleFactory.createRule(8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL)), + "This operation always evaluate to the same value", RuleKind.CODE_SMELL)), SELF_ASSIGNMENT(RuleFactory.createRule(9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL)); + "Self assignment", RuleKind.CODE_SMELL)); private final Rule rule; 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 fd0cadb9..019fb4fb 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 @@ -19,15 +19,11 @@ package io.ballerina.scan.internal; import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.compiler.api.symbols.Symbol; import io.ballerina.compiler.syntax.tree.AssignmentStatementNode; import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; import io.ballerina.compiler.syntax.tree.CheckExpressionNode; import io.ballerina.compiler.syntax.tree.CompoundAssignmentStatementNode; -import io.ballerina.compiler.syntax.tree.ModulePartNode; -import io.ballerina.compiler.syntax.tree.Node; -import io.ballerina.compiler.syntax.tree.NodeLocation; -import io.ballerina.compiler.api.symbols.Symbol; -import io.ballerina.compiler.syntax.tree.CheckExpressionNode; import io.ballerina.compiler.syntax.tree.ExplicitAnonymousFunctionExpressionNode; import io.ballerina.compiler.syntax.tree.FunctionDefinitionNode; import io.ballerina.compiler.syntax.tree.FunctionSignatureNode; @@ -47,13 +43,9 @@ import java.util.Optional; -import static io.ballerina.compiler.syntax.tree.SyntaxKind.CHECKPANIC_KEYWORD; import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isDefinedQualifiedNameReference; import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isEqualToProvidedLiteralIdentifier; import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isSameSimpleExpression; -import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.reportIssue; - -import java.util.Optional; /** * {@code StaticCodeAnalyzer} contains the logic to perform core static code analysis on Ballerina documents. @@ -70,7 +62,7 @@ class StaticCodeAnalyzer extends NodeVisitor { this.document = document; this.syntaxTree = document.syntaxTree(); this.scannerContext = scannerContext; - semanticModel = document.module().getCompilation().getSemanticModel(); + this.semanticModel = semanticModel; } void analyze() { @@ -89,24 +81,19 @@ public void visit(CheckExpressionNode checkExpressionNode) { } } - @Override - public void visit(ModulePartNode modulePartNode) { - modulePartNode.members().forEach(member -> member.accept(this)); - } - @Override public void visit(BinaryExpressionNode binaryExpressionNode) { reportIssuesForTrivialOperations(binaryExpressionNode); isSameOperandRestrictedInOperator(binaryExpressionNode.operator()).ifPresent(rule -> { checkSameUsageInBinaryOperator(binaryExpressionNode.lhsExpr(), - binaryExpressionNode.rhsExpr(), rule, binaryExpressionNode.location()); + binaryExpressionNode.rhsExpr(), rule, binaryExpressionNode); }); } @Override public void visit(AssignmentStatementNode assignmentStatementNode) { checkSameUsageInAssignment(assignmentStatementNode.varRef(), assignmentStatementNode.expression(), - CoreRule.SELF_ASSIGNMENT, assignmentStatementNode.location()); + CoreRule.SELF_ASSIGNMENT, assignmentStatementNode); this.visitSyntaxNode(assignmentStatementNode); } @@ -114,19 +101,19 @@ public void visit(AssignmentStatementNode assignmentStatementNode) { public void visit(CompoundAssignmentStatementNode compoundAssignmentStatementNode) { checkSameUsageInAssignment(compoundAssignmentStatementNode.lhsExpression(), compoundAssignmentStatementNode.rhsExpression(), CoreRule.SELF_ASSIGNMENT, - compoundAssignmentStatementNode.location()); + compoundAssignmentStatementNode); this.visitSyntaxNode(compoundAssignmentStatementNode); } - private void checkSameUsageInBinaryOperator(Node lhs, Node rhs, CoreRule rule, NodeLocation location) { + private void checkSameUsageInBinaryOperator(Node lhs, Node rhs, CoreRule rule, Node node) { if (isSameSimpleExpression(lhs, rhs)) { - reportIssue(scannerContext, document, location, rule.rule()); + reportIssue(node, rule); } } - private void checkSameUsageInAssignment(Node lhs, Node rhs, CoreRule rule, NodeLocation location) { + private void checkSameUsageInAssignment(Node lhs, Node rhs, CoreRule rule, Node node) { if (isSameSimpleExpression(lhs, rhs)) { - reportIssue(scannerContext, document, location, rule.rule()); + reportIssue(node, rule); } } @@ -135,15 +122,13 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.FLOAT, Constants.Token.INFINITY)) { // a > Infinity is always false. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); } if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MAX_VALUE)) { // a > MAX_VALUE is always false. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); } } @@ -151,15 +136,13 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.FLOAT, Constants.Token.INFINITY)) { // a <= Infinity is always true. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); } if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MAX_VALUE)) { // a <= MAX_VALUE is always true. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); } } @@ -167,8 +150,7 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MIN_VALUE)) { // a < MIN_VALUE is always false. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); } } @@ -176,8 +158,7 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MIN_VALUE)) { // a >= MIN_VALUE is always true. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); } } @@ -185,15 +166,13 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.FALSE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.FALSE)) { // a && false is always false. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.TRUE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.TRUE)) { // a && true is always `a`. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); } } @@ -201,15 +180,13 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.FALSE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.FALSE)) { // a || false is always `a`. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.TRUE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.TRUE)) { // a || true is always true. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); } } @@ -217,15 +194,13 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.ZERO) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.ZERO)) { // a & 0 is always false. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.MINUS_ONE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.MINUS_ONE)) { // a & -1 is always `a`. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); } } @@ -233,15 +208,13 @@ public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressi if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.ZERO) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.ZERO)) { // a | 0 is always `a`. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.MINUS_ONE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.MINUS_ONE)) { // a | -1 is always true. - reportIssue(scannerContext, document, binaryExpressionNode, - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule()); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); } } } @@ -259,6 +232,8 @@ private Optional isSameOperandRestrictedInOperator(Token operator) { } } return Optional.empty(); + } + public void visit(FunctionDefinitionNode functionDefinitionNode) { checkUnusedFunctionParameters(functionDefinitionNode.functionSignature()); this.visitSyntaxNode(functionDefinitionNode); diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java index a4bc24c1..e27ff2fe 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/Constants.java @@ -62,31 +62,17 @@ public class Constants { static final String RULE_DESCRIPTION_COLUMN = "Rule Description"; static final String[] RULE_PRIORITY_LIST = {"ballerina", "ballerina/", "ballerinax/", "wso2/"}; - public static class RuleDescription { - public static final String AVOID_CHECKPANIC = "Avoid checkpanic"; - public static final String OPERATION_ALWAYS_EVALUATE_TO_TRUE - = "This operation always evaluate to true"; - public static final String OPERATION_ALWAYS_EVALUATE_TO_FALSE - = "This operation always evaluate to false"; - public static final String OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE - = "This operation always evaluate to false"; - public static final String SELF_ASSIGNMENT = "Self assignment"; - - private RuleDescription() { - } - } - public static class Token { - public static String FLOAT = "float"; - public static String INT = "int"; - public static String INFINITY = "Infinity"; - public static String MAX_VALUE = "MAX_VALUE"; - public static String MIN_VALUE = "MIN_VALUE"; - public static String TRUE = "true"; - public static String FALSE = "false"; - public static String ZERO = "0"; - public static String ONE = "1"; - public static String MINUS_ONE = "-1"; + public static final String FLOAT = "float"; + public static final String INT = "int"; + public static final String INFINITY = "Infinity"; + public static final String MAX_VALUE = "MAX_VALUE"; + public static final String MIN_VALUE = "MIN_VALUE"; + public static final String TRUE = "true"; + public static final String FALSE = "false"; + public static final String ZERO = "0"; + public static final String ONE = "1"; + public static final String MINUS_ONE = "-1"; private Token() { } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java index 1dd3c15f..243d8412 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java @@ -34,7 +34,7 @@ public class CoreRuleTest { @Test(description = "test all rules") void testAllRules() { - Assert.assertEquals(CoreRule.rules().size(), 2); + Assert.assertEquals(CoreRule.rules().size(), 6); } @Test(description = "test checkpanic rule") diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java index 56d81c5a..8b10bb63 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java @@ -18,6 +18,7 @@ package io.ballerina.scan.internal; +import io.ballerina.compiler.api.SemanticModel; import io.ballerina.projects.Document; import io.ballerina.projects.Module; import io.ballerina.projects.Project; @@ -27,11 +28,12 @@ import io.ballerina.scan.Rule; import io.ballerina.scan.RuleKind; import io.ballerina.scan.Source; -import io.ballerina.scan.utils.Constants; import io.ballerina.tools.text.LineRange; import org.testng.Assert; +import org.testng.annotations.Test; import java.nio.file.Path; +import java.util.List; /** * Static code analyzer test. @@ -47,22 +49,6 @@ Document loadDocument(String documentName) { return defaultModule.document(defaultModule.documentIds().iterator().next()); } - void assertIssue(Issue issue, String documentName, int startLine, int startOffset, int endLine, int endOffset, - String ruleId, int numericId, String description, RuleKind ruleKind) { - Assert.assertEquals(issue.source(), Source.BUILT_IN); - LineRange location = issue.location().lineRange(); - Assert.assertEquals(location.fileName(), documentName); - Assert.assertEquals(location.startLine().line(), startLine); - Assert.assertEquals(location.startLine().offset(), startOffset); - Assert.assertEquals(location.endLine().line(), endLine); - Assert.assertEquals(location.endLine().offset(), endOffset); - Rule rule = issue.rule(); - Assert.assertEquals(rule.id(), ruleId); - Assert.assertEquals(rule.numericId(), numericId); - Assert.assertEquals(rule.description(), description); - Assert.assertEquals(rule.kind(), ruleKind); - } - @Test(description = "test self comparisons") void testSelfComparisonAnalyzer() { String documentName = "self_comparison_rule.bal"; @@ -71,103 +57,105 @@ void testSelfComparisonAnalyzer() { CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(), CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(), CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); - StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext); + + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); staticCodeAnalyzer.analyze(); List issues = scannerContext.getReporter().getIssues(); Assert.assertEquals(issues.size(), 46); assertIssue(issues.get(0), documentName, 9, 10, 9, 16, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(1), documentName, 10, 10, 10, 16, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(2), documentName, 11, 10, 11, 16, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(3), documentName, 12, 10, 12, 16, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(4), documentName, 13, 10, 13, 15, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(5), documentName, 14, 10, 14, 15, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(6), documentName, 15, 10, 15, 17, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(7), documentName, 16, 10, 16, 17, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(8), documentName, 17, 10, 17, 15, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(9), documentName, 18, 10, 18, 15, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(10), documentName, 19, 10, 19, 16, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(11), documentName, 20, 10, 20, 16, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(12), documentName, 31, 10, 31, 20, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(13), documentName, 32, 10, 32, 20, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(14), documentName, 33, 10, 33, 20, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(15), documentName, 34, 10, 34, 20, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(16), documentName, 35, 10, 35, 19, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(17), documentName, 36, 10, 36, 19, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(18), documentName, 37, 10, 37, 21, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(19), documentName, 38, 10, 38, 21, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(20), documentName, 39, 10, 39, 19, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(21), documentName, 40, 10, 40, 19, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(22), documentName, 41, 10, 41, 20, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(23), documentName, 42, 10, 42, 20, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(24), documentName, 53, 10, 53, 52, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(25), documentName, 54, 10, 54, 52, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(26), documentName, 55, 10, 55, 52, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(27), documentName, 56, 10, 56, 52, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(28), documentName, 57, 10, 57, 51, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(29), documentName, 58, 10, 58, 51, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(30), documentName, 59, 10, 59, 53, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(31), documentName, 60, 10, 60, 53, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(32), documentName, 61, 10, 61, 51, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(33), documentName, 62, 10, 62, 51, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(34), documentName, 72, 10, 72, 26, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(35), documentName, 73, 10, 73, 26, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(36), documentName, 74, 10, 74, 26, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(37), documentName, 75, 10, 75, 26, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(38), documentName, 76, 10, 76, 25, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(39), documentName, 77, 10, 77, 25, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(40), documentName, 78, 10, 78, 27, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(41), documentName, 79, 10, 79, 27, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(42), documentName, 80, 10, 80, 25, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(43), documentName, 81, 10, 81, 25, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(44), documentName, 82, 10, 82, 26, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(45), documentName, 83, 10, 83, 26, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); } @Test(description = "test trivial operations") @@ -178,118 +166,121 @@ void testTrivialOperationsAnalyzer() { CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(), CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(), CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); - StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext); + + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); staticCodeAnalyzer.analyze(); List issues = scannerContext.getReporter().getIssues(); Assert.assertEquals(issues.size(), 14); assertIssue(issues.get(0), documentName, 6, 13, 6, 30, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(1), documentName, 7, 13, 7, 31, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(2), documentName, 9, 13, 9, 31, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(3), documentName, 10, 13, 10, 30, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(4), documentName, 12, 13, 12, 32, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(5), documentName, 13, 13, 13, 31, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(6), documentName, 17, 13, 17, 23, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); assertIssue(issues.get(7), documentName, 18, 13, 18, 22, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(8), documentName, 19, 13, 19, 22, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(9), documentName, 20, 13, 20, 23, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(10), documentName, 23, 18, 23, 23, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(11), documentName, 24, 14, 24, 20, "ballerina:8", 8, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + "This operation always evaluate to the same value", RuleKind.CODE_SMELL); assertIssue(issues.get(12), documentName, 25, 14, 25, 20, "ballerina:6", 6, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + "This operation always evaluate to true", RuleKind.CODE_SMELL); assertIssue(issues.get(13), documentName, 26, 14, 26, 19, "ballerina:7", 7, - Constants.RuleDescription.OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + "This operation always evaluate to false", RuleKind.CODE_SMELL); } @Test(description = "test self assignment") void testSelfAssignmentAnalyzer() { - String documentName = "self_assignment.bal"; + String documentName = "rule009_self_assignment.bal"; Document document = loadDocument(documentName); ScannerContextImpl scannerContext = new ScannerContextImpl(List.of(CoreRule.SELF_ASSIGNMENT.rule())); - StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext); + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); staticCodeAnalyzer.analyze(); List issues = scannerContext.getReporter().getIssues(); Assert.assertEquals(issues.size(), 33); assertIssue(issues.get(0), documentName, 5, 4, 5, 10, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(1), documentName, 6, 4, 6, 11, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(2), documentName, 7, 4, 7, 11, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(3), documentName, 8, 4, 8, 11, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(4), documentName, 9, 4, 9, 11, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(5), documentName, 10, 4, 10, 11, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(6), documentName, 11, 4, 11, 11, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(7), documentName, 12, 4, 12, 11, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(8), documentName, 13, 4, 13, 12, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(9), documentName, 14, 4, 14, 12, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(10), documentName, 15, 4, 15, 13, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(11), documentName, 28, 4, 28, 14, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(12), documentName, 29, 4, 29, 15, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(13), documentName, 30, 4, 30, 15, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(14), documentName, 31, 4, 31, 15, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(15), documentName, 32, 4, 32, 15, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(16), documentName, 33, 4, 33, 15, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(17), documentName, 34, 4, 34, 15, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(18), documentName, 35, 4, 35, 15, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(19), documentName, 36, 4, 36, 16, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(20), documentName, 37, 4, 37, 16, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(21), documentName, 38, 4, 38, 17, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(22), documentName, 62, 4, 62, 20, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(23), documentName, 63, 4, 63, 21, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(24), documentName, 64, 4, 64, 21, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(25), documentName, 65, 4, 65, 21, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(26), documentName, 66, 4, 66, 21, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(27), documentName, 67, 4, 67, 21, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(28), documentName, 68, 4, 68, 21, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(29), documentName, 69, 4, 69, 21, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(30), documentName, 70, 4, 70, 22, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(31), documentName, 71, 4, 71, 22, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); assertIssue(issues.get(32), documentName, 72, 4, 72, 23, "ballerina:9", 9, - Constants.RuleDescription.SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + "Self assignment", RuleKind.CODE_SMELL); } diff --git a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt index 5ad2e669..054e2f30 100644 --- a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt @@ -1,8 +1,12 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + -------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:6 | CODE_SMELL | This operation always evaluate to true + ballerina:7 | CODE_SMELL | This operation always evaluate to false + ballerina:8 | CODE_SMELL | This operation always evaluate to the same value + ballerina:9 | CODE_SMELL | Self assignment ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt index 431cad6f..054e2f30 100644 --- a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt @@ -1,8 +1,12 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + -------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:6 | CODE_SMELL | This operation always evaluate to true + ballerina:7 | CODE_SMELL | This operation always evaluate to false + ballerina:8 | CODE_SMELL | This operation always evaluate to the same value + ballerina:9 | CODE_SMELL | Self assignment ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 @@ -11,4 +15,4 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-proj ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 \ No newline at end of file + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt index e384b4ea..b2aa6167 100644 --- a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt @@ -1,8 +1,12 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + -------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:6 | CODE_SMELL | This operation always evaluate to true + ballerina:7 | CODE_SMELL | This operation always evaluate to false + ballerina:8 | CODE_SMELL | This operation always evaluate to the same value + ballerina:9 | CODE_SMELL | Self assignment ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt index cab063a4..4c3091c6 100644 --- a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt @@ -1,8 +1,12 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + -------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:6 | CODE_SMELL | This operation always evaluate to true + ballerina:7 | CODE_SMELL | This operation always evaluate to false + ballerina:8 | CODE_SMELL | This operation always evaluate to the same value + ballerina:9 | CODE_SMELL | Self assignment ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 @@ -11,4 +15,4 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-proj ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 \ No newline at end of file + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal b/scan-command/src/test/resources/test-resources/core-rules/rule009_self_assignment.bal similarity index 100% rename from scan-command/src/test/resources/test-resources/core-rules/self_assignment.bal rename to scan-command/src/test/resources/test-resources/core-rules/rule009_self_assignment.bal diff --git a/scan-command/src/test/resources/testng.xml b/scan-command/src/test/resources/testng.xml index cbdaee06..a28aba05 100644 --- a/scan-command/src/test/resources/testng.xml +++ b/scan-command/src/test/resources/testng.xml @@ -31,6 +31,7 @@ under the License. + From d6bade8f4174987e41f243f6e35e1bf0e81b871b Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Fri, 21 Feb 2025 09:14:22 +0530 Subject: [PATCH 06/10] Update tests for trivial operations related rules --- .../ballerina/scan/internal/CoreRuleTest.java | 41 +++ .../ballerina/scan/internal/Rule006Test.java | 94 +++++++ .../ballerina/scan/internal/Rule007Test.java | 94 +++++++ .../ballerina/scan/internal/Rule008Test.java | 89 +++++++ .../ballerina/scan/internal/Rule009Test.java | 118 +++++++++ .../scan/internal/StaticCodeAnalyzerTest.java | 238 ------------------ .../windows/print-rules-to-console.txt | 2 +- .../core-rules/rule_006_always_true.bal | 128 ++++++++++ .../core-rules/rule_007_always_false.bal | 126 ++++++++++ .../rule_008_evaluates_same_value.bal | 126 ++++++++++ scan-command/src/test/resources/testng.xml | 4 + 11 files changed, 821 insertions(+), 239 deletions(-) create mode 100644 scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java create mode 100644 scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java create mode 100644 scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java create mode 100644 scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java create mode 100644 scan-command/src/test/resources/test-resources/core-rules/rule_006_always_true.bal create mode 100644 scan-command/src/test/resources/test-resources/core-rules/rule_007_always_false.bal create mode 100644 scan-command/src/test/resources/test-resources/core-rules/rule_008_evaluates_same_value.bal diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java index 243d8412..56de0d61 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java @@ -31,6 +31,11 @@ public class CoreRuleTest { public static final String AVOID_CHECKPANIC = "Avoid checkpanic"; public static final String UNUSED_FUNCTION_PARAMETER = "Unused function parameter"; + public static final String OPERATION_ALWAYS_EVALUATE_TO_TRUE = "This operation always evaluate to true"; + public static final String OPERATION_ALWAYS_EVALUATE_TO_FALSE = "This operation always evaluate to false"; + public static final String OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE = + "This operation always evaluate to the same value"; + public static final String SELF_ASSIGNMENT = "Self assignment"; @Test(description = "test all rules") void testAllRules() { @@ -54,4 +59,40 @@ void testUnusedFunctionParameterRule() { Assert.assertEquals(rule.description(), UNUSED_FUNCTION_PARAMETER); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } + + @Test(description = "test always true evaluates") + void testTrueEvaluates() { + Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(); + Assert.assertEquals(rule.id(), "ballerina:6"); + Assert.assertEquals(rule.numericId(), 6); + Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATE_TO_TRUE); + Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); + } + + @Test(description = "test always false evaluates") + void testFalseEvaluates() { + Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(); + Assert.assertEquals(rule.id(), "ballerina:7"); + Assert.assertEquals(rule.numericId(), 7); + Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATE_TO_FALSE); + Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); + } + + @Test(description = "test evaluate to the same value") + void testSelfEvaluates() { + Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule(); + Assert.assertEquals(rule.id(), "ballerina:8"); + Assert.assertEquals(rule.numericId(), 8); + Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); + } + + @Test(description = "test self assignment") + void testSelfAssignmentAnalyzer() { + Rule rule = CoreRule.SELF_ASSIGNMENT.rule(); + Assert.assertEquals(rule.id(), "ballerina:9"); + Assert.assertEquals(rule.numericId(), 9); + Assert.assertEquals(rule.description(), SELF_ASSIGNMENT); + Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); + } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java new file mode 100644 index 00000000..b4f88ea3 --- /dev/null +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.scan.internal; + +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.projects.Document; +import io.ballerina.scan.Issue; +import io.ballerina.scan.RuleKind; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * Always true evaluates tests. + * + * @since 0.1.0 + */ +public class Rule006Test extends StaticCodeAnalyzerTest { + public static final String OPERATION_ALWAYS_EVALUATE_TO_TRUE = "This operation always evaluate to true"; + + @Test(description = "test always true evaluates") + void testTrueEvaluates() { + String documentName = "rule_006_always_true.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule())); + + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + Assert.assertEquals(issues.size(), 21); + + assertIssue(issues.get(0), documentName, 15, 10, 15, 16, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 16, 10, 16, 16, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 17, 10, 17, 16, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 18, 10, 18, 17, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 19, 10, 19, 20, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 20, 10, 20, 20, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 21, 10, 21, 20, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 22, 10, 22, 21, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 23, 10, 23, 52, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 24, 10, 24, 52, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 25, 10, 25, 52, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 26, 10, 26, 53, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 27, 10, 27, 26, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 28, 10, 28, 26, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 29, 10, 29, 26, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 30, 10, 30, 27, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 31, 13, 31, 31, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 32, 13, 32, 31, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 33, 13, 33, 32, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 34, 13, 34, 22, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 35, 14, 35, 20, "ballerina:6", 6, + OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + } +} diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java new file mode 100644 index 00000000..36293f75 --- /dev/null +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.scan.internal; + +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.projects.Document; +import io.ballerina.scan.Issue; +import io.ballerina.scan.RuleKind; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * Always false evaluates tests. + * + * @since 0.1.0 + */ +public class Rule007Test extends StaticCodeAnalyzerTest { + public static final String OPERATION_ALWAYS_EVALUATE_TO_FALSE = "This operation always evaluate to false"; + + @Test(description = "test always false evaluates") + void testFalseEvaluates() { + String documentName = "rule_007_always_false.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule())); + + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + Assert.assertEquals(issues.size(), 21); + + assertIssue(issues.get(0), documentName, 17, 10, 17, 16, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 18, 10, 18, 15, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 19, 10, 19, 15, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 20, 10, 20, 17, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 21, 10, 21, 20, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 22, 10, 22, 19, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 23, 10, 23, 19, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 24, 10, 24, 21, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 25, 10, 25, 52, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 26, 10, 26, 51, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 27, 10, 27, 51, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 28, 10, 28, 53, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 29, 10, 29, 26, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 30, 10, 30, 25, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 31, 10, 31, 25, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 32, 10, 32, 27, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 33, 13, 33, 30, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 34, 13, 34, 30, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 35, 13, 35, 31, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 36, 13, 36, 23, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 37, 14, 37, 19, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + } +} diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java new file mode 100644 index 00000000..c648e48a --- /dev/null +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.scan.internal; + +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.projects.Document; +import io.ballerina.scan.Issue; +import io.ballerina.scan.RuleKind; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * Always self value evaluates tests tests. + * + * @since 0.1.0 + */ +public class Rule008Test extends StaticCodeAnalyzerTest { + public static final String OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE = + "This operation always evaluate to the same value"; + + @Test(description = "test evaluate to the same value") + void testSelfEvaluates() { + String documentName = "rule_008_evaluates_same_value.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( + CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); + + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + Assert.assertEquals(issues.size(), 18); + + assertIssue(issues.get(0), documentName, 16, 10, 16, 15, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 17, 10, 17, 15, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 18, 10, 18, 16, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 19, 10, 19, 16, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 20, 10, 20, 19, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 21, 10, 21, 19, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 22, 10, 22, 20, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 23, 10, 23, 20, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 24, 10, 24, 51, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 25, 10, 25, 51, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 26, 10, 26, 25, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 27, 10, 27, 25, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 28, 10, 28, 26, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 29, 10, 29, 26, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 30, 13, 30, 22, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 31, 13, 31, 23, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 32, 18, 32, 23, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 33, 14, 33, 20, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + } +} diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java new file mode 100644 index 00000000..77655c21 --- /dev/null +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.scan.internal; + +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.projects.Document; +import io.ballerina.scan.Issue; +import io.ballerina.scan.RuleKind; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * Self assignment tests. + * + * @since 0.1.0 + */ +public class Rule009Test extends StaticCodeAnalyzerTest { + public static final String SELF_ASSIGNMENT = "Self assignment"; + + @Test(description = "test self assignment") + void testSelfAssignmentAnalyzer() { + String documentName = "rule009_self_assignment.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of(CoreRule.SELF_ASSIGNMENT.rule())); + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + + Assert.assertEquals(issues.size(), 33); + + assertIssue(issues.get(0), documentName, 5, 4, 5, 10, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 6, 4, 6, 11, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 7, 4, 7, 11, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 8, 4, 8, 11, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 9, 4, 9, 11, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 10, 4, 10, 11, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 11, 4, 11, 11, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 12, 4, 12, 11, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 13, 4, 13, 12, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 14, 4, 14, 12, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 15, 4, 15, 13, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 28, 4, 28, 14, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 29, 4, 29, 15, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 30, 4, 30, 15, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 31, 4, 31, 15, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 32, 4, 32, 15, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 33, 4, 33, 15, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 34, 4, 34, 15, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 35, 4, 35, 15, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 36, 4, 36, 16, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 37, 4, 37, 16, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(21), documentName, 38, 4, 38, 17, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(22), documentName, 62, 4, 62, 20, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(23), documentName, 63, 4, 63, 21, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(24), documentName, 64, 4, 64, 21, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(25), documentName, 65, 4, 65, 21, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(26), documentName, 66, 4, 66, 21, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(27), documentName, 67, 4, 67, 21, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(28), documentName, 68, 4, 68, 21, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(29), documentName, 69, 4, 69, 21, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(30), documentName, 70, 4, 70, 22, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(31), documentName, 71, 4, 71, 22, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(32), documentName, 72, 4, 72, 23, "ballerina:9", 9, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + + } +} diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java index 8b10bb63..32faf327 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/StaticCodeAnalyzerTest.java @@ -18,7 +18,6 @@ package io.ballerina.scan.internal; -import io.ballerina.compiler.api.SemanticModel; import io.ballerina.projects.Document; import io.ballerina.projects.Module; import io.ballerina.projects.Project; @@ -30,10 +29,8 @@ import io.ballerina.scan.Source; import io.ballerina.tools.text.LineRange; import org.testng.Assert; -import org.testng.annotations.Test; import java.nio.file.Path; -import java.util.List; /** * Static code analyzer test. @@ -49,241 +46,6 @@ Document loadDocument(String documentName) { return defaultModule.document(defaultModule.documentIds().iterator().next()); } - @Test(description = "test self comparisons") - void testSelfComparisonAnalyzer() { - String documentName = "self_comparison_rule.bal"; - Document document = loadDocument(documentName); - ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(), - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(), - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); - - SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); - StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); - staticCodeAnalyzer.analyze(); - List issues = scannerContext.getReporter().getIssues(); - Assert.assertEquals(issues.size(), 46); - - assertIssue(issues.get(0), documentName, 9, 10, 9, 16, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 10, 10, 10, 16, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 11, 10, 11, 16, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 12, 10, 12, 16, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 13, 10, 13, 15, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 14, 10, 14, 15, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 15, 10, 15, 17, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 16, 10, 16, 17, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 17, 10, 17, 15, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 18, 10, 18, 15, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 19, 10, 19, 16, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 20, 10, 20, 16, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(12), documentName, 31, 10, 31, 20, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(13), documentName, 32, 10, 32, 20, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(14), documentName, 33, 10, 33, 20, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(15), documentName, 34, 10, 34, 20, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(16), documentName, 35, 10, 35, 19, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(17), documentName, 36, 10, 36, 19, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(18), documentName, 37, 10, 37, 21, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(19), documentName, 38, 10, 38, 21, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(20), documentName, 39, 10, 39, 19, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(21), documentName, 40, 10, 40, 19, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(22), documentName, 41, 10, 41, 20, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(23), documentName, 42, 10, 42, 20, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(24), documentName, 53, 10, 53, 52, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(25), documentName, 54, 10, 54, 52, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(26), documentName, 55, 10, 55, 52, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(27), documentName, 56, 10, 56, 52, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(28), documentName, 57, 10, 57, 51, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(29), documentName, 58, 10, 58, 51, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(30), documentName, 59, 10, 59, 53, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(31), documentName, 60, 10, 60, 53, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(32), documentName, 61, 10, 61, 51, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(33), documentName, 62, 10, 62, 51, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(34), documentName, 72, 10, 72, 26, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(35), documentName, 73, 10, 73, 26, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(36), documentName, 74, 10, 74, 26, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(37), documentName, 75, 10, 75, 26, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(38), documentName, 76, 10, 76, 25, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(39), documentName, 77, 10, 77, 25, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(40), documentName, 78, 10, 78, 27, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(41), documentName, 79, 10, 79, 27, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(42), documentName, 80, 10, 80, 25, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(43), documentName, 81, 10, 81, 25, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(44), documentName, 82, 10, 82, 26, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(45), documentName, 83, 10, 83, 26, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - } - - @Test(description = "test trivial operations") - void testTrivialOperationsAnalyzer() { - String documentName = "trivial_operations.bal"; - Document document = loadDocument(documentName); - ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(), - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(), - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); - - SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); - StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); - staticCodeAnalyzer.analyze(); - List issues = scannerContext.getReporter().getIssues(); - - Assert.assertEquals(issues.size(), 14); - assertIssue(issues.get(0), documentName, 6, 13, 6, 30, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 7, 13, 7, 31, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 9, 13, 9, 31, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 10, 13, 10, 30, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 12, 13, 12, 32, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 13, 13, 13, 31, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 17, 13, 17, 23, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 18, 13, 18, 22, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 19, 13, 19, 22, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 20, 13, 20, 23, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 23, 18, 23, 23, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 24, 14, 24, 20, "ballerina:8", 8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL); - assertIssue(issues.get(12), documentName, 25, 14, 25, 20, "ballerina:6", 6, - "This operation always evaluate to true", RuleKind.CODE_SMELL); - assertIssue(issues.get(13), documentName, 26, 14, 26, 19, "ballerina:7", 7, - "This operation always evaluate to false", RuleKind.CODE_SMELL); - } - - @Test(description = "test self assignment") - void testSelfAssignmentAnalyzer() { - String documentName = "rule009_self_assignment.bal"; - Document document = loadDocument(documentName); - ScannerContextImpl scannerContext = new ScannerContextImpl(List.of(CoreRule.SELF_ASSIGNMENT.rule())); - SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); - StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); - staticCodeAnalyzer.analyze(); - List issues = scannerContext.getReporter().getIssues(); - - Assert.assertEquals(issues.size(), 33); - - assertIssue(issues.get(0), documentName, 5, 4, 5, 10, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 6, 4, 6, 11, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 7, 4, 7, 11, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 8, 4, 8, 11, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 9, 4, 9, 11, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 10, 4, 10, 11, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 11, 4, 11, 11, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 12, 4, 12, 11, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 13, 4, 13, 12, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 14, 4, 14, 12, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 15, 4, 15, 13, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 28, 4, 28, 14, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(12), documentName, 29, 4, 29, 15, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(13), documentName, 30, 4, 30, 15, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(14), documentName, 31, 4, 31, 15, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(15), documentName, 32, 4, 32, 15, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(16), documentName, 33, 4, 33, 15, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(17), documentName, 34, 4, 34, 15, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(18), documentName, 35, 4, 35, 15, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(19), documentName, 36, 4, 36, 16, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(20), documentName, 37, 4, 37, 16, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(21), documentName, 38, 4, 38, 17, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(22), documentName, 62, 4, 62, 20, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(23), documentName, 63, 4, 63, 21, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(24), documentName, 64, 4, 64, 21, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(25), documentName, 65, 4, 65, 21, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(26), documentName, 66, 4, 66, 21, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(27), documentName, 67, 4, 67, 21, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(28), documentName, 68, 4, 68, 21, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(29), documentName, 69, 4, 69, 21, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(30), documentName, 70, 4, 70, 22, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(31), documentName, 71, 4, 71, 22, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - assertIssue(issues.get(32), documentName, 72, 4, 72, 23, "ballerina:9", 9, - "Self assignment", RuleKind.CODE_SMELL); - - } - void assertIssue(Issue issue, String documentName, int startLine, int startOffset, int endLine, int endOffset, String ruleId, int numericId, String description, RuleKind ruleKind) { Assert.assertEquals(issue.source(), Source.BUILT_IN); diff --git a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt index 4c3091c6..b2aa6167 100644 --- a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt @@ -1,5 +1,5 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description + RuleID | Rule Kind | Rule Description -------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter diff --git a/scan-command/src/test/resources/test-resources/core-rules/rule_006_always_true.bal b/scan-command/src/test/resources/test-resources/core-rules/rule_006_always_true.bal new file mode 100644 index 00000000..6e7fcb82 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/core-rules/rule_006_always_true.bal @@ -0,0 +1,128 @@ +import ballerina/lang.'int as i; + +function testSimpleVariableReference() { + int a = 1; + int a2 = 1; + boolean b = true; + boolean b2 = true; + string s = "string"; + A a = new; + A b = new; + int i = 3; + int SIGNED8_MIN_VALUE = 10; + map a = {}; + map b = {}; + + test2(a <= a); // warning + test2(a >= a); // warning + test2(a == a); // warning + test2(a === a); // warning + test2(a.a <= a.a); // warning + test2(a.a >= a.a); // warning + test2(a.a == a.a); // warning + test2(a.a === a.a); // warning + test2(i:SIGNED8_MIN_VALUE <= i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE >= i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE == i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE === i:SIGNED8_MIN_VALUE); // warning + test2(a["a"] <= a["a"]); // warning + test2(a["a"] >= a["a"]); // warning + test2(a["a"] == a["a"]); // warning + test2(a["a"] === a["a"]); // warning + result = x >= int:MIN_VALUE; // warning + result = x <= int:MAX_VALUE; // warning + result = y <= float:Infinity; // warning + result = b || true; // warning + result2 = x | -1;// warning + + test2(a <= a2); + test2(b2 || b); + test2(s == "string"); + test2(a.a <= b.a); + test2(a.b && b.b); + test2(a.c == "a.c"); + + test2(SIGNED8_MIN_VALUE <= i:SIGNED8_MIN_VALUE); + test2(i <= i:SIGNED8_MIN_VALUE); + + test2(a["a"] <= b["a"]); + test2(a["a"] || b["a"]); + test2(a["a"] == "b[\"a\"]"); + + test2(a["a"] <= a["b"]); + test2(a["a"] || a["b"]); + test2(a["a"] == "a[\"b\"]"); +} + +class A { + int a = 3; + boolean b = false; + string c = "string"; +} + +function test2(any c) { + _ = c; +} + +function testOperators() { + int x = 1; + float y = 2.3f; + boolean result; +} + +function testRelationaOperatorsWithoutWarnings() { + string x = "1"; + string y = "2.3f"; + boolean result; + + // Arithmetic operators + result = x < "int:MIN_VALUE"; + result = x >= "int:MIN_VALUE"; + + result = x <= "int:MAX_VALUE"; + result = x > "int:MAX_VALUE"; + + result = y <= "float:Infinity"; + result = y > "float:Infinity"; + + // Logical operators + boolean 'false = false; + boolean 'true = true; + boolean b = true; + + result = b && 'false; + result = b || 'true; + result = b && 'true; + result = b || 'false; + + // Bitwise operators + int '0 = 0; + int \-1 = -1; + int x2 = 1; + + int result2 = x2 | '0; + result2 = x2 & \-1; + result2 = x2 | \-1; + result2 = x2 & '0; + result2 = x2 | 1; + result2 = x2 & 1; + + + int x = 1; + float y = 2.3f; + boolean result; + + // Arithmetic operators + result = x > int:MIN_VALUE; + result = x <= int:MIN_VALUE; + + result = x >= int:MAX_VALUE; + result = x < int:MAX_VALUE; + + result = y >= float:Infinity; + result = y < float:Infinity; + + // Bitwise operators + int result2 = x | 1; + result2 = x & --1; +} diff --git a/scan-command/src/test/resources/test-resources/core-rules/rule_007_always_false.bal b/scan-command/src/test/resources/test-resources/core-rules/rule_007_always_false.bal new file mode 100644 index 00000000..fd2ea5d7 --- /dev/null +++ b/scan-command/src/test/resources/test-resources/core-rules/rule_007_always_false.bal @@ -0,0 +1,126 @@ +import ballerina/lang.'int as i; + +function testSimpleVariableReference() { + int a = 1; + int a2 = 1; + boolean b = true; + boolean b2 = true; + string s = "string"; + A a = new; + A b = new; + int i = 3; + int SIGNED8_MIN_VALUE = 10; + map a = { + "a": 1 + }; + map b = {}; + + test2(a != a); // warning + test2(a < a); // warning + test2(a > a); // warning + test2(a !== a); // warning + test2(a.a != a.a); // warning + test2(a.a < a.a); // warning + test2(a.a > a.a); // warning + test2(a.a !== a.a); // warning + test2(i:SIGNED8_MIN_VALUE != i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE < i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE > i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE !== i:SIGNED8_MIN_VALUE); // warning + test2(a["a"] != a["a"]); // warning + test2(a["a"] < a["a"]); // warning + test2(a["a"] > a["a"]); // warning + test2(a["a"] !== a["a"]); // warning + result = x < int:MIN_VALUE; // warning + result = x > int:MAX_VALUE; // warning + result = y > float:Infinity; // warning + result = b && false; // warning + result2 = x & 0; // warning + + test2(a <= a2); + test2(b2 || b); + test2(s == "string"); + + test2(a.a <= b.a); + test2(a.b && b.b); + test2(a.c == "a.c"); + + test2(SIGNED8_MIN_VALUE <= i:SIGNED8_MIN_VALUE); + test2(i <= i:SIGNED8_MIN_VALUE); + + test2(a["a"] <= b["a"]); + test2(a["a"] || b["a"]); + test2(a["a"] == "b[\"a\"]"); + + test2(a["a"] <= a["b"]); + test2(a["a"] || a["b"]); + test2(a["a"] == "a[\"b\"]"); +} + +class A { + int a = 3; + boolean b = false; + string c = "string"; +} + +function test2(any c) { + _ = c; +} + +function testRelationaOperatorsWithoutWarnings() { + string x = "1"; + string y = "2.3f"; + boolean result; + + // Arithmetic operators + result = x < "int:MIN_VALUE"; + result = x >= "int:MIN_VALUE"; + + result = x <= "int:MAX_VALUE"; + result = x > "int:MAX_VALUE"; + + result = y <= "float:Infinity"; + result = y > "float:Infinity"; + + // Logical operators + boolean 'false = false; + boolean 'true = true; + boolean b = true; + + result = b && 'false; + result = b || 'true; + result = b && 'true; + result = b || 'false; + + // Bitwise operators + int '0 = 0; + int \-1 = -1; + int x2 = 1; + + int result2 = x2 | '0; + result2 = x2 & \-1; + result2 = x2 | \-1; + result2 = x2 & '0; + result2 = x2 | 1; + result2 = x2 & 1; +} + +function testRelationaOperatorsWithoutWarnings2() { + int x = 1; + float y = 2.3f; + boolean result; + + // Arithmetic operators + result = x > int:MIN_VALUE; + result = x <= int:MIN_VALUE; + + result = x >= int:MAX_VALUE; + result = x < int:MAX_VALUE; + + result = y >= float:Infinity; + result = y < float:Infinity; + + // Bitwise operators + int result2 = x | 1; + result2 = x & --1; +} diff --git a/scan-command/src/test/resources/test-resources/core-rules/rule_008_evaluates_same_value.bal b/scan-command/src/test/resources/test-resources/core-rules/rule_008_evaluates_same_value.bal new file mode 100644 index 00000000..7ec1b95c --- /dev/null +++ b/scan-command/src/test/resources/test-resources/core-rules/rule_008_evaluates_same_value.bal @@ -0,0 +1,126 @@ +import ballerina/lang.'int as i; + +function testSimpleVariableReference() { + + int a = 1; + int a2 = 1; + boolean b = true; + boolean b2 = true; + string s = "string"; + A a = new; + A b = new; + int i = 3; + int SIGNED8_MIN_VALUE = 10; + map a = {}; + map b = {}; + + test2(a & a); // warning + test2(a | a); // warning + test2(b && b); // warning + test2(b || b); // warning + test2(a.a & a.a); // warning + test2(a.a | a.a); // warning + test2(a.b && a.b); // warning + test2(a.b || a.b); // warning + test2(i:SIGNED8_MIN_VALUE & i:SIGNED8_MIN_VALUE); // warning + test2(i:SIGNED8_MIN_VALUE | i:SIGNED8_MIN_VALUE); // warning + test2(a["a"] & a["a"]); // warning + test2(a["a"] | a["a"]); // warning + test2(b["a"] && b["a"]); // warning + test2(b["a"] || b["a"]); // warning + result = b && true; // warning + result = b || false; // warning + int result2 = x | 0;// warning + result2 = x & -1; // warning + + test2(a <= a2); + test2(b2 || b); + test2(s == "string"); + test2(a.a <= b.a); + test2(a.b && b.b); + test2(a.c == "a.c"); + + test2(SIGNED8_MIN_VALUE <= i:SIGNED8_MIN_VALUE); + test2(i <= i:SIGNED8_MIN_VALUE); + + test2(a["a"] <= b["a"]); + test2(a["a"] || b["a"]); + test2(a["a"] == "b[\"a\"]"); + + test2(a["a"] <= a["b"]); + test2(a["a"] || a["b"]); + test2(a["a"] == "a[\"b\"]"); +} + +class A { + int a = 3; + boolean b = false; + string c = "string"; +} + +function test2(any c) { + _ = c; +} + +function testOperators() { + int x = 1; + float y = 2.3f; + boolean result; +} + +function testRelationaOperatorsWithoutWarnings() { + string x = "1"; + string y = "2.3f"; + boolean result; + + // Arithmetic operators + result = x < "int:MIN_VALUE"; + result = x >= "int:MIN_VALUE"; + + result = x <= "int:MAX_VALUE"; + result = x > "int:MAX_VALUE"; + + result = y <= "float:Infinity"; + result = y > "float:Infinity"; + + // Logical operators + boolean 'false = false; + boolean 'true = true; + boolean b = true; + + result = b && 'false; + result = b || 'true; + result = b && 'true; + result = b || 'false; + + // Bitwise operators + int '0 = 0; + int \-1 = -1; + int x2 = 1; + + int result2 = x2 | '0; + result2 = x2 & \-1; + result2 = x2 | \-1; + result2 = x2 & '0; + result2 = x2 | 1; + result2 = x2 & 1; + + + int x = 1; + float y = 2.3f; + boolean result; + + // Arithmetic operators + result = x > int:MIN_VALUE; + result = x <= int:MIN_VALUE; + + result = x >= int:MAX_VALUE; + result = x < int:MAX_VALUE; + + result = y >= float:Infinity; + result = y < float:Infinity; + + // Bitwise operators + int result2 = x | 1; + result2 = x & --1; +} diff --git a/scan-command/src/test/resources/testng.xml b/scan-command/src/test/resources/testng.xml index a28aba05..51e3a2a3 100644 --- a/scan-command/src/test/resources/testng.xml +++ b/scan-command/src/test/resources/testng.xml @@ -31,6 +31,10 @@ under the License. + + + + From 0a3fec411699329b563d83b9380e7146f52e6867 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Tue, 25 Feb 2025 13:03:35 +0530 Subject: [PATCH 07/10] Update self assignment rule descriptions --- .../io/ballerina/scan/internal/CoreRule.java | 14 ++-- .../scan/internal/StaticCodeAnalyzer.java | 73 ++++++++++--------- .../scan/utils/ScanCodeAnalyzerUtils.java | 22 ++++++ .../ballerina/scan/internal/CoreRuleTest.java | 22 +++--- .../ballerina/scan/internal/Rule006Test.java | 48 ++++++------ .../ballerina/scan/internal/Rule007Test.java | 48 ++++++------ .../ballerina/scan/internal/Rule008Test.java | 44 +++++------ .../ballerina/scan/internal/Rule009Test.java | 2 +- .../unix/list-rules-output.txt | 12 +-- .../unix/print-rules-to-console.txt | 12 +-- .../windows/list-rules-output.txt | 12 +-- .../windows/print-rules-to-console.txt | 12 +-- 12 files changed, 172 insertions(+), 149 deletions(-) diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java index 263de0dc..a0b778f2 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java @@ -34,14 +34,14 @@ enum CoreRule { AVOID_CHECKPANIC(RuleFactory.createRule(1, "Avoid checkpanic", RuleKind.CODE_SMELL)), UNUSED_FUNCTION_PARAMETER(RuleFactory.createRule(2, "Unused function parameter", RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATE_TO_TRUE(RuleFactory.createRule(6, - "This operation always evaluate to true", RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATE_TO_FALSE(RuleFactory.createRule(7, - "This operation always evaluate to false", RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE(RuleFactory.createRule(8, - "This operation always evaluate to the same value", RuleKind.CODE_SMELL)), + OPERATION_ALWAYS_EVALUATES_TO_TRUE(RuleFactory.createRule(6, + "This operation always evaluates to true", RuleKind.CODE_SMELL)), + OPERATION_ALWAYS_EVALUATES_TO_FALSE(RuleFactory.createRule(7, + "This operation always evaluates to false", RuleKind.CODE_SMELL)), + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE(RuleFactory.createRule(8, + "This operation always evaluates to the same value", RuleKind.CODE_SMELL)), SELF_ASSIGNMENT(RuleFactory.createRule(9, - "Self assignment", RuleKind.CODE_SMELL)); + "This variable is assigned to itself", RuleKind.CODE_SMELL)); private final Rule rule; 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 019fb4fb..9023eee3 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 @@ -83,152 +83,153 @@ public void visit(CheckExpressionNode checkExpressionNode) { @Override public void visit(BinaryExpressionNode binaryExpressionNode) { - reportIssuesForTrivialOperations(binaryExpressionNode); - isSameOperandRestrictedInOperator(binaryExpressionNode.operator()).ifPresent(rule -> { - checkSameUsageInBinaryOperator(binaryExpressionNode.lhsExpr(), + reportIssuesWithTrivialOperations(binaryExpressionNode); + filterSameReferenceIssueBasedOnOperandType(binaryExpressionNode.operator()).ifPresent(rule -> { + checkUsageOfSameOperandInBinaryExpr(binaryExpressionNode.lhsExpr(), binaryExpressionNode.rhsExpr(), rule, binaryExpressionNode); }); } @Override public void visit(AssignmentStatementNode assignmentStatementNode) { - checkSameUsageInAssignment(assignmentStatementNode.varRef(), assignmentStatementNode.expression(), + checkUsageOfAssignment(assignmentStatementNode.varRef(), assignmentStatementNode.expression(), CoreRule.SELF_ASSIGNMENT, assignmentStatementNode); this.visitSyntaxNode(assignmentStatementNode); } @Override public void visit(CompoundAssignmentStatementNode compoundAssignmentStatementNode) { - checkSameUsageInAssignment(compoundAssignmentStatementNode.lhsExpression(), + checkUsageOfAssignment(compoundAssignmentStatementNode.lhsExpression(), compoundAssignmentStatementNode.rhsExpression(), CoreRule.SELF_ASSIGNMENT, compoundAssignmentStatementNode); this.visitSyntaxNode(compoundAssignmentStatementNode); } - private void checkSameUsageInBinaryOperator(Node lhs, Node rhs, CoreRule rule, Node node) { + private void checkUsageOfSameOperandInBinaryExpr(Node lhs, Node rhs, CoreRule rule, Node binaryExprNode) { if (isSameSimpleExpression(lhs, rhs)) { - reportIssue(node, rule); + reportIssue(binaryExprNode, rule); } } - private void checkSameUsageInAssignment(Node lhs, Node rhs, CoreRule rule, Node node) { + private void checkUsageOfAssignment(Node lhs, Node rhs, CoreRule rule, Node assignmentNode) { if (isSameSimpleExpression(lhs, rhs)) { - reportIssue(node, rule); + reportIssue(assignmentNode, rule); } } - public void reportIssuesForTrivialOperations(BinaryExpressionNode binaryExpressionNode) { - if (binaryExpressionNode.operator().kind() == SyntaxKind.GT_TOKEN) { + private void reportIssuesWithTrivialOperations(BinaryExpressionNode binaryExpressionNode) { + SyntaxKind binaryOperatorKind = binaryExpressionNode.operator().kind(); + if (binaryOperatorKind == SyntaxKind.GT_TOKEN) { if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.FLOAT, Constants.Token.INFINITY)) { // a > Infinity is always false. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE); } if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MAX_VALUE)) { // a > MAX_VALUE is always false. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE); } } - if (binaryExpressionNode.operator().kind() == SyntaxKind.LT_EQUAL_TOKEN) { + if (binaryOperatorKind == SyntaxKind.LT_EQUAL_TOKEN) { if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.FLOAT, Constants.Token.INFINITY)) { // a <= Infinity is always true. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE); } if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MAX_VALUE)) { // a <= MAX_VALUE is always true. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE); } } - if (binaryExpressionNode.operator().kind() == SyntaxKind.LT_TOKEN) { + if (binaryOperatorKind == SyntaxKind.LT_TOKEN) { if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MIN_VALUE)) { // a < MIN_VALUE is always false. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE); } } - if (binaryExpressionNode.operator().kind() == SyntaxKind.GT_EQUAL_TOKEN) { + if (binaryOperatorKind == SyntaxKind.GT_EQUAL_TOKEN) { if (isDefinedQualifiedNameReference(binaryExpressionNode.rhsExpr(), Constants.Token.INT, Constants.Token.MIN_VALUE)) { // a >= MIN_VALUE is always true. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE); } } - if (binaryExpressionNode.operator().kind() == SyntaxKind.LOGICAL_AND_TOKEN) { + if (binaryOperatorKind == SyntaxKind.LOGICAL_AND_TOKEN) { if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.FALSE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.FALSE)) { // a && false is always false. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.TRUE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.TRUE)) { // a && true is always `a`. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE); } } - if (binaryExpressionNode.operator().kind() == SyntaxKind.LOGICAL_OR_TOKEN) { + if (binaryOperatorKind == SyntaxKind.LOGICAL_OR_TOKEN) { if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.FALSE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.FALSE)) { // a || false is always `a`. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.TRUE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.TRUE)) { // a || true is always true. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE); } } - if (binaryExpressionNode.operator().kind() == SyntaxKind.BITWISE_AND_TOKEN) { + if (binaryOperatorKind == SyntaxKind.BITWISE_AND_TOKEN) { if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.ZERO) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.ZERO)) { // a & 0 is always false. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.MINUS_ONE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.MINUS_ONE)) { // a & -1 is always `a`. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE); } } - if (binaryExpressionNode.operator().kind() == SyntaxKind.PIPE_TOKEN) { + if (binaryOperatorKind == SyntaxKind.PIPE_TOKEN) { if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.ZERO) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.ZERO)) { // a | 0 is always `a`. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE); } if (isEqualToProvidedLiteralIdentifier(binaryExpressionNode.rhsExpr(), Constants.Token.MINUS_ONE) || isEqualToProvidedLiteralIdentifier(binaryExpressionNode.lhsExpr(), Constants.Token.MINUS_ONE)) { // a | -1 is always true. - reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); + reportIssue(binaryExpressionNode, CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE); } } } - private Optional isSameOperandRestrictedInOperator(Token operator) { + private Optional filterSameReferenceIssueBasedOnOperandType(Token operator) { switch (operator.kind()) { case GT_EQUAL_TOKEN, LT_EQUAL_TOKEN, DOUBLE_EQUAL_TOKEN, TRIPPLE_EQUAL_TOKEN -> { - return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE); + return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE); } case GT_TOKEN, LT_TOKEN, NOT_DOUBLE_EQUAL_TOKEN, NOT_EQUAL_TOKEN -> { - return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE); + return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE); } case LOGICAL_OR_TOKEN, LOGICAL_AND_TOKEN, BITWISE_AND_TOKEN, PIPE_TOKEN -> { - return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + return Optional.of(CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE); } } return Optional.empty(); diff --git a/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java b/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java index fe5a8899..1c52e4c1 100644 --- a/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java +++ b/scan-command/src/main/java/io/ballerina/scan/utils/ScanCodeAnalyzerUtils.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package io.ballerina.scan.utils; import io.ballerina.compiler.syntax.tree.BasicLiteralNode; @@ -16,6 +33,11 @@ import io.ballerina.scan.ScannerContext; import io.ballerina.tools.diagnostics.Location; +/** + * {@code ScanCodeAnalyzerUtils} contains the util functions for the static code analysis. + * + * @since 0.1.0 + * */ public class ScanCodeAnalyzerUtils { public static void reportIssue(ScannerContext scannerContext, Document document, Node node, Rule rule) { scannerContext.getReporter().reportIssue(document, node.location(), rule); diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java index 56de0d61..bc4890e6 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java @@ -31,11 +31,11 @@ public class CoreRuleTest { public static final String AVOID_CHECKPANIC = "Avoid checkpanic"; public static final String UNUSED_FUNCTION_PARAMETER = "Unused function parameter"; - public static final String OPERATION_ALWAYS_EVALUATE_TO_TRUE = "This operation always evaluate to true"; - public static final String OPERATION_ALWAYS_EVALUATE_TO_FALSE = "This operation always evaluate to false"; - public static final String OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE = - "This operation always evaluate to the same value"; - public static final String SELF_ASSIGNMENT = "Self assignment"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_TRUE = "This operation always evaluates to true"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_FALSE = "This operation always evaluates to false"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE = + "This operation always evaluates to the same value"; + public static final String SELF_ASSIGNMENT = "This variable is assigned to itself"; @Test(description = "test all rules") void testAllRules() { @@ -62,28 +62,28 @@ void testUnusedFunctionParameterRule() { @Test(description = "test always true evaluates") void testTrueEvaluates() { - Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule(); + Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE.rule(); Assert.assertEquals(rule.id(), "ballerina:6"); Assert.assertEquals(rule.numericId(), 6); - Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATE_TO_TRUE); + Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATES_TO_TRUE); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } @Test(description = "test always false evaluates") void testFalseEvaluates() { - Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule(); + Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE.rule(); Assert.assertEquals(rule.id(), "ballerina:7"); Assert.assertEquals(rule.numericId(), 7); - Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATE_TO_FALSE); + Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATES_TO_FALSE); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } @Test(description = "test evaluate to the same value") void testSelfEvaluates() { - Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule(); + Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE.rule(); Assert.assertEquals(rule.id(), "ballerina:8"); Assert.assertEquals(rule.numericId(), 8); - Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE); + Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java index b4f88ea3..1b57157f 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java @@ -30,17 +30,17 @@ /** * Always true evaluates tests. * - * @since 0.1.0 + * @since 0.5.0 */ public class Rule006Test extends StaticCodeAnalyzerTest { - public static final String OPERATION_ALWAYS_EVALUATE_TO_TRUE = "This operation always evaluate to true"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_TRUE = "This operation always evaluates to true"; @Test(description = "test always true evaluates") void testTrueEvaluates() { String documentName = "rule_006_always_true.bal"; Document document = loadDocument(documentName); ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_TRUE.rule())); + CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE.rule())); SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); @@ -49,46 +49,46 @@ void testTrueEvaluates() { Assert.assertEquals(issues.size(), 21); assertIssue(issues.get(0), documentName, 15, 10, 15, 16, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(1), documentName, 16, 10, 16, 16, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(2), documentName, 17, 10, 17, 16, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(3), documentName, 18, 10, 18, 17, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(4), documentName, 19, 10, 19, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(5), documentName, 20, 10, 20, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(6), documentName, 21, 10, 21, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(7), documentName, 22, 10, 22, 21, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(8), documentName, 23, 10, 23, 52, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(9), documentName, 24, 10, 24, 52, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(10), documentName, 25, 10, 25, 52, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(11), documentName, 26, 10, 26, 53, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(12), documentName, 27, 10, 27, 26, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(13), documentName, 28, 10, 28, 26, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(14), documentName, 29, 10, 29, 26, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(15), documentName, 30, 10, 30, 27, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(16), documentName, 31, 13, 31, 31, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(17), documentName, 32, 13, 32, 31, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(18), documentName, 33, 13, 33, 32, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(19), documentName, 34, 13, 34, 22, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); assertIssue(issues.get(20), documentName, 35, 14, 35, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATE_TO_TRUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java index 36293f75..4192a974 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java @@ -30,17 +30,17 @@ /** * Always false evaluates tests. * - * @since 0.1.0 + * @since 0.5.0 */ public class Rule007Test extends StaticCodeAnalyzerTest { - public static final String OPERATION_ALWAYS_EVALUATE_TO_FALSE = "This operation always evaluate to false"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_FALSE = "This operation always evaluates to false"; @Test(description = "test always false evaluates") void testFalseEvaluates() { String documentName = "rule_007_always_false.bal"; Document document = loadDocument(documentName); ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_FALSE.rule())); + CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE.rule())); SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); @@ -49,46 +49,46 @@ void testFalseEvaluates() { Assert.assertEquals(issues.size(), 21); assertIssue(issues.get(0), documentName, 17, 10, 17, 16, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(1), documentName, 18, 10, 18, 15, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(2), documentName, 19, 10, 19, 15, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(3), documentName, 20, 10, 20, 17, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(4), documentName, 21, 10, 21, 20, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(5), documentName, 22, 10, 22, 19, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(6), documentName, 23, 10, 23, 19, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(7), documentName, 24, 10, 24, 21, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(8), documentName, 25, 10, 25, 52, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(9), documentName, 26, 10, 26, 51, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(10), documentName, 27, 10, 27, 51, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(11), documentName, 28, 10, 28, 53, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(12), documentName, 29, 10, 29, 26, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(13), documentName, 30, 10, 30, 25, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(14), documentName, 31, 10, 31, 25, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(15), documentName, 32, 10, 32, 27, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(16), documentName, 33, 13, 33, 30, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(17), documentName, 34, 13, 34, 30, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(18), documentName, 35, 13, 35, 31, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(19), documentName, 36, 13, 36, 23, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); assertIssue(issues.get(20), documentName, 37, 14, 37, 19, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATE_TO_FALSE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java index c648e48a..729d11f6 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java @@ -30,18 +30,18 @@ /** * Always self value evaluates tests tests. * - * @since 0.1.0 + * @since 0.5.0 */ public class Rule008Test extends StaticCodeAnalyzerTest { - public static final String OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE = - "This operation always evaluate to the same value"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE = + "This operation always evaluates to the same value"; @Test(description = "test evaluate to the same value") void testSelfEvaluates() { String documentName = "rule_008_evaluates_same_value.bal"; Document document = loadDocument(documentName); ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE.rule())); + CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE.rule())); SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); @@ -50,40 +50,40 @@ void testSelfEvaluates() { Assert.assertEquals(issues.size(), 18); assertIssue(issues.get(0), documentName, 16, 10, 16, 15, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(1), documentName, 17, 10, 17, 15, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(2), documentName, 18, 10, 18, 16, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(3), documentName, 19, 10, 19, 16, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(4), documentName, 20, 10, 20, 19, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(5), documentName, 21, 10, 21, 19, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(6), documentName, 22, 10, 22, 20, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(7), documentName, 23, 10, 23, 20, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(8), documentName, 24, 10, 24, 51, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(9), documentName, 25, 10, 25, 51, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(10), documentName, 26, 10, 26, 25, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(11), documentName, 27, 10, 27, 25, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(12), documentName, 28, 10, 28, 26, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(13), documentName, 29, 10, 29, 26, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(14), documentName, 30, 13, 30, 22, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(15), documentName, 31, 13, 31, 23, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(16), documentName, 32, 18, 32, 23, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); assertIssue(issues.get(17), documentName, 33, 14, 33, 20, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATE_TO_SELF_VALUE, RuleKind.CODE_SMELL); + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java index 77655c21..6cf0cae7 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java @@ -33,7 +33,7 @@ * @since 0.1.0 */ public class Rule009Test extends StaticCodeAnalyzerTest { - public static final String SELF_ASSIGNMENT = "Self assignment"; + public static final String SELF_ASSIGNMENT = "This variable is assigned to itself"; @Test(description = "test self assignment") void testSelfAssignmentAnalyzer() { diff --git a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt index 054e2f30..33e60312 100644 --- a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt @@ -1,12 +1,12 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - -------------------------------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluate to true - ballerina:7 | CODE_SMELL | This operation always evaluate to false - ballerina:8 | CODE_SMELL | This operation always evaluate to the same value - ballerina:9 | CODE_SMELL | Self assignment + ballerina:6 | CODE_SMELL | This operation always evaluates to true + ballerina:7 | CODE_SMELL | This operation always evaluates to false + ballerina:8 | CODE_SMELL | This operation always evaluates to the same value + ballerina:9 | CODE_SMELL | This variable is assigned to itself ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt index 054e2f30..33e60312 100644 --- a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt @@ -1,12 +1,12 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - -------------------------------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluate to true - ballerina:7 | CODE_SMELL | This operation always evaluate to false - ballerina:8 | CODE_SMELL | This operation always evaluate to the same value - ballerina:9 | CODE_SMELL | Self assignment + ballerina:6 | CODE_SMELL | This operation always evaluates to true + ballerina:7 | CODE_SMELL | This operation always evaluates to false + ballerina:8 | CODE_SMELL | This operation always evaluates to the same value + ballerina:9 | CODE_SMELL | This variable is assigned to itself ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt index b2aa6167..8edb059e 100644 --- a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt @@ -1,12 +1,12 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - -------------------------------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluate to true - ballerina:7 | CODE_SMELL | This operation always evaluate to false - ballerina:8 | CODE_SMELL | This operation always evaluate to the same value - ballerina:9 | CODE_SMELL | Self assignment + ballerina:6 | CODE_SMELL | This operation always evaluates to true + ballerina:7 | CODE_SMELL | This operation always evaluates to false + ballerina:8 | CODE_SMELL | This operation always evaluates to the same value + ballerina:9 | CODE_SMELL | This variable is assigned to itself ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt index b2aa6167..8edb059e 100644 --- a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt @@ -1,12 +1,12 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - -------------------------------------------------------------------------------------------------------------------- + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- ballerina:1 | CODE_SMELL | Avoid checkpanic ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluate to true - ballerina:7 | CODE_SMELL | This operation always evaluate to false - ballerina:8 | CODE_SMELL | This operation always evaluate to the same value - ballerina:9 | CODE_SMELL | Self assignment + ballerina:6 | CODE_SMELL | This operation always evaluates to true + ballerina:7 | CODE_SMELL | This operation always evaluates to false + ballerina:8 | CODE_SMELL | This operation always evaluates to the same value + ballerina:9 | CODE_SMELL | This variable is assigned to itself ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 From 1f98e73d6aed24ee0d8331cb5b4f05c3031e392f Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Sat, 15 Mar 2025 22:52:50 +0530 Subject: [PATCH 08/10] Update the rule ids --- .../io/ballerina/scan/internal/CoreRule.java | 8 +- .../ballerina/scan/internal/CoreRuleTest.java | 16 +-- .../ballerina/scan/internal/Rule006Test.java | 94 ------------- .../ballerina/scan/internal/Rule007Test.java | 96 +++++++------- .../ballerina/scan/internal/Rule008Test.java | 93 ++++++------- .../ballerina/scan/internal/Rule009Test.java | 123 +++++++----------- .../ballerina/scan/internal/Rule010Test.java | 118 +++++++++++++++++ .../unix/list-rules-output.txt | 34 ++--- .../unix/print-rules-to-console.txt | 34 ++--- .../windows/list-rules-output.txt | 34 ++--- .../windows/print-rules-to-console.txt | 34 ++--- ...ways_true.bal => rule_007_always_true.bal} | 0 ...ys_false.bal => rule_008_always_false.bal} | 0 ....bal => rule_009_evaluates_same_value.bal} | 0 scan-command/src/test/resources/testng.xml | 2 +- 15 files changed, 343 insertions(+), 343 deletions(-) delete mode 100644 scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java create mode 100644 scan-command/src/test/java/io/ballerina/scan/internal/Rule010Test.java rename scan-command/src/test/resources/test-resources/core-rules/{rule_006_always_true.bal => rule_007_always_true.bal} (100%) rename scan-command/src/test/resources/test-resources/core-rules/{rule_007_always_false.bal => rule_008_always_false.bal} (100%) rename scan-command/src/test/resources/test-resources/core-rules/{rule_008_evaluates_same_value.bal => rule_009_evaluates_same_value.bal} (100%) diff --git a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java index a0b778f2..f5f05b4f 100644 --- a/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java +++ b/scan-command/src/main/java/io/ballerina/scan/internal/CoreRule.java @@ -34,13 +34,13 @@ enum CoreRule { AVOID_CHECKPANIC(RuleFactory.createRule(1, "Avoid checkpanic", RuleKind.CODE_SMELL)), UNUSED_FUNCTION_PARAMETER(RuleFactory.createRule(2, "Unused function parameter", RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATES_TO_TRUE(RuleFactory.createRule(6, + OPERATION_ALWAYS_EVALUATES_TO_TRUE(RuleFactory.createRule(7, "This operation always evaluates to true", RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATES_TO_FALSE(RuleFactory.createRule(7, + OPERATION_ALWAYS_EVALUATES_TO_FALSE(RuleFactory.createRule(8, "This operation always evaluates to false", RuleKind.CODE_SMELL)), - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE(RuleFactory.createRule(8, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE(RuleFactory.createRule(9, "This operation always evaluates to the same value", RuleKind.CODE_SMELL)), - SELF_ASSIGNMENT(RuleFactory.createRule(9, + SELF_ASSIGNMENT(RuleFactory.createRule(10, "This variable is assigned to itself", RuleKind.CODE_SMELL)); private final Rule rule; diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java index bc4890e6..525a9509 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java @@ -63,8 +63,8 @@ void testUnusedFunctionParameterRule() { @Test(description = "test always true evaluates") void testTrueEvaluates() { Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE.rule(); - Assert.assertEquals(rule.id(), "ballerina:6"); - Assert.assertEquals(rule.numericId(), 6); + Assert.assertEquals(rule.id(), "ballerina:7"); + Assert.assertEquals(rule.numericId(), 7); Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATES_TO_TRUE); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } @@ -72,8 +72,8 @@ void testTrueEvaluates() { @Test(description = "test always false evaluates") void testFalseEvaluates() { Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE.rule(); - Assert.assertEquals(rule.id(), "ballerina:7"); - Assert.assertEquals(rule.numericId(), 7); + Assert.assertEquals(rule.id(), "ballerina:8"); + Assert.assertEquals(rule.numericId(), 8); Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATES_TO_FALSE); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } @@ -81,8 +81,8 @@ void testFalseEvaluates() { @Test(description = "test evaluate to the same value") void testSelfEvaluates() { Rule rule = CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE.rule(); - Assert.assertEquals(rule.id(), "ballerina:8"); - Assert.assertEquals(rule.numericId(), 8); + Assert.assertEquals(rule.id(), "ballerina:9"); + Assert.assertEquals(rule.numericId(), 9); Assert.assertEquals(rule.description(), OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } @@ -90,8 +90,8 @@ void testSelfEvaluates() { @Test(description = "test self assignment") void testSelfAssignmentAnalyzer() { Rule rule = CoreRule.SELF_ASSIGNMENT.rule(); - Assert.assertEquals(rule.id(), "ballerina:9"); - Assert.assertEquals(rule.numericId(), 9); + Assert.assertEquals(rule.id(), "ballerina:10"); + Assert.assertEquals(rule.numericId(), 10); Assert.assertEquals(rule.description(), SELF_ASSIGNMENT); Assert.assertEquals(rule.kind(), RuleKind.CODE_SMELL); } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java deleted file mode 100644 index 1b57157f..00000000 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule006Test.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package io.ballerina.scan.internal; - -import io.ballerina.compiler.api.SemanticModel; -import io.ballerina.projects.Document; -import io.ballerina.scan.Issue; -import io.ballerina.scan.RuleKind; -import org.testng.Assert; -import org.testng.annotations.Test; - -import java.util.List; - -/** - * Always true evaluates tests. - * - * @since 0.5.0 - */ -public class Rule006Test extends StaticCodeAnalyzerTest { - public static final String OPERATION_ALWAYS_EVALUATES_TO_TRUE = "This operation always evaluates to true"; - - @Test(description = "test always true evaluates") - void testTrueEvaluates() { - String documentName = "rule_006_always_true.bal"; - Document document = loadDocument(documentName); - ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE.rule())); - - SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); - StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); - staticCodeAnalyzer.analyze(); - List issues = scannerContext.getReporter().getIssues(); - Assert.assertEquals(issues.size(), 21); - - assertIssue(issues.get(0), documentName, 15, 10, 15, 16, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 16, 10, 16, 16, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 17, 10, 17, 16, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 18, 10, 18, 17, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 19, 10, 19, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 20, 10, 20, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 21, 10, 21, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 22, 10, 22, 21, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 23, 10, 23, 52, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 24, 10, 24, 52, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 25, 10, 25, 52, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 26, 10, 26, 53, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(12), documentName, 27, 10, 27, 26, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(13), documentName, 28, 10, 28, 26, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(14), documentName, 29, 10, 29, 26, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(15), documentName, 30, 10, 30, 27, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(16), documentName, 31, 13, 31, 31, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(17), documentName, 32, 13, 32, 31, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(18), documentName, 33, 13, 33, 32, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(19), documentName, 34, 13, 34, 22, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(20), documentName, 35, 14, 35, 20, "ballerina:6", 6, - OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); - } -} diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java index 4192a974..1906dff9 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule007Test.java @@ -28,19 +28,19 @@ import java.util.List; /** - * Always false evaluates tests. + * Always true evaluates tests. * * @since 0.5.0 */ public class Rule007Test extends StaticCodeAnalyzerTest { - public static final String OPERATION_ALWAYS_EVALUATES_TO_FALSE = "This operation always evaluates to false"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_TRUE = "This operation always evaluates to true"; - @Test(description = "test always false evaluates") - void testFalseEvaluates() { - String documentName = "rule_007_always_false.bal"; + @Test(description = "test always true evaluates") + void testTrueEvaluates() { + String documentName = "rule_007_always_true.bal"; Document document = loadDocument(documentName); ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE.rule())); + CoreRule.OPERATION_ALWAYS_EVALUATES_TO_TRUE.rule())); SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); @@ -48,47 +48,47 @@ void testFalseEvaluates() { List issues = scannerContext.getReporter().getIssues(); Assert.assertEquals(issues.size(), 21); - assertIssue(issues.get(0), documentName, 17, 10, 17, 16, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 18, 10, 18, 15, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 19, 10, 19, 15, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 20, 10, 20, 17, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 21, 10, 21, 20, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 22, 10, 22, 19, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 23, 10, 23, 19, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 24, 10, 24, 21, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 25, 10, 25, 52, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 26, 10, 26, 51, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 27, 10, 27, 51, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 28, 10, 28, 53, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(12), documentName, 29, 10, 29, 26, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(13), documentName, 30, 10, 30, 25, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(14), documentName, 31, 10, 31, 25, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(15), documentName, 32, 10, 32, 27, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(16), documentName, 33, 13, 33, 30, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(17), documentName, 34, 13, 34, 30, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(18), documentName, 35, 13, 35, 31, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(19), documentName, 36, 13, 36, 23, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); - assertIssue(issues.get(20), documentName, 37, 14, 37, 19, "ballerina:7", 7, - OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(0), documentName, 15, 10, 15, 16, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 16, 10, 16, 16, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 17, 10, 17, 16, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 18, 10, 18, 17, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 19, 10, 19, 20, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 20, 10, 20, 20, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 21, 10, 21, 20, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 22, 10, 22, 21, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 23, 10, 23, 52, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 24, 10, 24, 52, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 25, 10, 25, 52, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 26, 10, 26, 53, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 27, 10, 27, 26, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 28, 10, 28, 26, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 29, 10, 29, 26, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 30, 10, 30, 27, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 31, 13, 31, 31, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 32, 13, 32, 31, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 33, 13, 33, 32, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 34, 13, 34, 22, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 35, 14, 35, 20, "ballerina:7", 7, + OPERATION_ALWAYS_EVALUATES_TO_TRUE, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java index 729d11f6..bb4c693f 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule008Test.java @@ -28,62 +28,67 @@ import java.util.List; /** - * Always self value evaluates tests tests. + * Always false evaluates tests. * * @since 0.5.0 */ public class Rule008Test extends StaticCodeAnalyzerTest { - public static final String OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE = - "This operation always evaluates to the same value"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_FALSE = "This operation always evaluates to false"; - @Test(description = "test evaluate to the same value") - void testSelfEvaluates() { - String documentName = "rule_008_evaluates_same_value.bal"; + @Test(description = "test always false evaluates") + void testFalseEvaluates() { + String documentName = "rule_008_always_false.bal"; Document document = loadDocument(documentName); ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( - CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE.rule())); + CoreRule.OPERATION_ALWAYS_EVALUATES_TO_FALSE.rule())); SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); staticCodeAnalyzer.analyze(); List issues = scannerContext.getReporter().getIssues(); - Assert.assertEquals(issues.size(), 18); + Assert.assertEquals(issues.size(), 21); - assertIssue(issues.get(0), documentName, 16, 10, 16, 15, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 17, 10, 17, 15, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 18, 10, 18, 16, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 19, 10, 19, 16, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 20, 10, 20, 19, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 21, 10, 21, 19, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 22, 10, 22, 20, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 23, 10, 23, 20, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 24, 10, 24, 51, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 25, 10, 25, 51, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 26, 10, 26, 25, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 27, 10, 27, 25, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(12), documentName, 28, 10, 28, 26, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(13), documentName, 29, 10, 29, 26, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(14), documentName, 30, 13, 30, 22, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(15), documentName, 31, 13, 31, 23, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(16), documentName, 32, 18, 32, 23, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); - assertIssue(issues.get(17), documentName, 33, 14, 33, 20, "ballerina:8", 8, - OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(0), documentName, 17, 10, 17, 16, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 18, 10, 18, 15, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 19, 10, 19, 15, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 20, 10, 20, 17, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 21, 10, 21, 20, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 22, 10, 22, 19, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 23, 10, 23, 19, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 24, 10, 24, 21, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 25, 10, 25, 52, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 26, 10, 26, 51, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 27, 10, 27, 51, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 28, 10, 28, 53, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 29, 10, 29, 26, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 30, 10, 30, 25, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 31, 10, 31, 25, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 32, 10, 32, 27, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 33, 13, 33, 30, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 34, 13, 34, 30, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 35, 13, 35, 31, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 36, 13, 36, 23, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 37, 14, 37, 19, "ballerina:8", 8, + OPERATION_ALWAYS_EVALUATES_TO_FALSE, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java index 6cf0cae7..2f786701 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule009Test.java @@ -28,91 +28,62 @@ import java.util.List; /** - * Self assignment tests. + * Always self value evaluates tests tests. * - * @since 0.1.0 + * @since 0.5.0 */ public class Rule009Test extends StaticCodeAnalyzerTest { - public static final String SELF_ASSIGNMENT = "This variable is assigned to itself"; + public static final String OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE = + "This operation always evaluates to the same value"; - @Test(description = "test self assignment") - void testSelfAssignmentAnalyzer() { - String documentName = "rule009_self_assignment.bal"; + @Test(description = "test evaluate to the same value") + void testSelfEvaluates() { + String documentName = "rule_009_evaluates_same_value.bal"; Document document = loadDocument(documentName); - ScannerContextImpl scannerContext = new ScannerContextImpl(List.of(CoreRule.SELF_ASSIGNMENT.rule())); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of( + CoreRule.OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE.rule())); + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); staticCodeAnalyzer.analyze(); List issues = scannerContext.getReporter().getIssues(); + Assert.assertEquals(issues.size(), 18); - Assert.assertEquals(issues.size(), 33); - - assertIssue(issues.get(0), documentName, 5, 4, 5, 10, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(1), documentName, 6, 4, 6, 11, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(2), documentName, 7, 4, 7, 11, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(3), documentName, 8, 4, 8, 11, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(4), documentName, 9, 4, 9, 11, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(5), documentName, 10, 4, 10, 11, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(6), documentName, 11, 4, 11, 11, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(7), documentName, 12, 4, 12, 11, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(8), documentName, 13, 4, 13, 12, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(9), documentName, 14, 4, 14, 12, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(10), documentName, 15, 4, 15, 13, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(11), documentName, 28, 4, 28, 14, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(12), documentName, 29, 4, 29, 15, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(13), documentName, 30, 4, 30, 15, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(14), documentName, 31, 4, 31, 15, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(15), documentName, 32, 4, 32, 15, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(16), documentName, 33, 4, 33, 15, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(17), documentName, 34, 4, 34, 15, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(18), documentName, 35, 4, 35, 15, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(19), documentName, 36, 4, 36, 16, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(20), documentName, 37, 4, 37, 16, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(21), documentName, 38, 4, 38, 17, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(22), documentName, 62, 4, 62, 20, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(23), documentName, 63, 4, 63, 21, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(24), documentName, 64, 4, 64, 21, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(25), documentName, 65, 4, 65, 21, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(26), documentName, 66, 4, 66, 21, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(27), documentName, 67, 4, 67, 21, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(28), documentName, 68, 4, 68, 21, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(29), documentName, 69, 4, 69, 21, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(30), documentName, 70, 4, 70, 22, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(31), documentName, 71, 4, 71, 22, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - assertIssue(issues.get(32), documentName, 72, 4, 72, 23, "ballerina:9", 9, - SELF_ASSIGNMENT, RuleKind.CODE_SMELL); - + assertIssue(issues.get(0), documentName, 16, 10, 16, 15, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 17, 10, 17, 15, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 18, 10, 18, 16, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 19, 10, 19, 16, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 20, 10, 20, 19, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 21, 10, 21, 19, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 22, 10, 22, 20, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 23, 10, 23, 20, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 24, 10, 24, 51, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 25, 10, 25, 51, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 26, 10, 26, 25, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 27, 10, 27, 25, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 28, 10, 28, 26, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 29, 10, 29, 26, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 30, 13, 30, 22, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 31, 13, 31, 23, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 32, 18, 32, 23, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 33, 14, 33, 20, "ballerina:9", 9, + OPERATION_ALWAYS_EVALUATES_TO_SELF_VALUE, RuleKind.CODE_SMELL); } } diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/Rule010Test.java b/scan-command/src/test/java/io/ballerina/scan/internal/Rule010Test.java new file mode 100644 index 00000000..ab5722b4 --- /dev/null +++ b/scan-command/src/test/java/io/ballerina/scan/internal/Rule010Test.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.scan.internal; + +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.projects.Document; +import io.ballerina.scan.Issue; +import io.ballerina.scan.RuleKind; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * Self assignment tests. + * + * @since 0.1.0 + */ +public class Rule010Test extends StaticCodeAnalyzerTest { + public static final String SELF_ASSIGNMENT = "This variable is assigned to itself"; + + @Test(description = "test self assignment") + void testSelfAssignmentAnalyzer() { + String documentName = "rule009_self_assignment.bal"; + Document document = loadDocument(documentName); + ScannerContextImpl scannerContext = new ScannerContextImpl(List.of(CoreRule.SELF_ASSIGNMENT.rule())); + SemanticModel semanticModel = document.module().getCompilation().getSemanticModel(); + StaticCodeAnalyzer staticCodeAnalyzer = new StaticCodeAnalyzer(document, scannerContext, semanticModel); + staticCodeAnalyzer.analyze(); + List issues = scannerContext.getReporter().getIssues(); + + Assert.assertEquals(issues.size(), 33); + + assertIssue(issues.get(0), documentName, 5, 4, 5, 10, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(1), documentName, 6, 4, 6, 11, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(2), documentName, 7, 4, 7, 11, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(3), documentName, 8, 4, 8, 11, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(4), documentName, 9, 4, 9, 11, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(5), documentName, 10, 4, 10, 11, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(6), documentName, 11, 4, 11, 11, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(7), documentName, 12, 4, 12, 11, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(8), documentName, 13, 4, 13, 12, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(9), documentName, 14, 4, 14, 12, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(10), documentName, 15, 4, 15, 13, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(11), documentName, 28, 4, 28, 14, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(12), documentName, 29, 4, 29, 15, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(13), documentName, 30, 4, 30, 15, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(14), documentName, 31, 4, 31, 15, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(15), documentName, 32, 4, 32, 15, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(16), documentName, 33, 4, 33, 15, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(17), documentName, 34, 4, 34, 15, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(18), documentName, 35, 4, 35, 15, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(19), documentName, 36, 4, 36, 16, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(20), documentName, 37, 4, 37, 16, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(21), documentName, 38, 4, 38, 17, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(22), documentName, 62, 4, 62, 20, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(23), documentName, 63, 4, 63, 21, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(24), documentName, 64, 4, 64, 21, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(25), documentName, 65, 4, 65, 21, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(26), documentName, 66, 4, 66, 21, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(27), documentName, 67, 4, 67, 21, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(28), documentName, 68, 4, 68, 21, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(29), documentName, 69, 4, 69, 21, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(30), documentName, 70, 4, 70, 22, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(31), documentName, 71, 4, 71, 22, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + assertIssue(issues.get(32), documentName, 72, 4, 72, 23, "ballerina:10", 10, + SELF_ASSIGNMENT, RuleKind.CODE_SMELL); + + } +} diff --git a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt index 33e60312..57b26922 100644 --- a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluates to true - ballerina:7 | CODE_SMELL | This operation always evaluates to false - ballerina:8 | CODE_SMELL | This operation always evaluates to the same value - ballerina:9 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + ---------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt index 33e60312..57b26922 100644 --- a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluates to true - ballerina:7 | CODE_SMELL | This operation always evaluates to false - ballerina:8 | CODE_SMELL | This operation always evaluates to the same value - ballerina:9 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + ---------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt index 8edb059e..d5ec48ae 100644 --- a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluates to true - ballerina:7 | CODE_SMELL | This operation always evaluates to false - ballerina:8 | CODE_SMELL | This operation always evaluates to the same value - ballerina:9 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + ---------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt index 8edb059e..d5ec48ae 100644 --- a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - --------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:6 | CODE_SMELL | This operation always evaluates to true - ballerina:7 | CODE_SMELL | This operation always evaluates to false - ballerina:8 | CODE_SMELL | This operation always evaluates to the same value - ballerina:9 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + ---------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/test-resources/core-rules/rule_006_always_true.bal b/scan-command/src/test/resources/test-resources/core-rules/rule_007_always_true.bal similarity index 100% rename from scan-command/src/test/resources/test-resources/core-rules/rule_006_always_true.bal rename to scan-command/src/test/resources/test-resources/core-rules/rule_007_always_true.bal diff --git a/scan-command/src/test/resources/test-resources/core-rules/rule_007_always_false.bal b/scan-command/src/test/resources/test-resources/core-rules/rule_008_always_false.bal similarity index 100% rename from scan-command/src/test/resources/test-resources/core-rules/rule_007_always_false.bal rename to scan-command/src/test/resources/test-resources/core-rules/rule_008_always_false.bal diff --git a/scan-command/src/test/resources/test-resources/core-rules/rule_008_evaluates_same_value.bal b/scan-command/src/test/resources/test-resources/core-rules/rule_009_evaluates_same_value.bal similarity index 100% rename from scan-command/src/test/resources/test-resources/core-rules/rule_008_evaluates_same_value.bal rename to scan-command/src/test/resources/test-resources/core-rules/rule_009_evaluates_same_value.bal diff --git a/scan-command/src/test/resources/testng.xml b/scan-command/src/test/resources/testng.xml index 51e3a2a3..69525f30 100644 --- a/scan-command/src/test/resources/testng.xml +++ b/scan-command/src/test/resources/testng.xml @@ -31,10 +31,10 @@ under the License. - + From ff0badc552fdfe86d8c9caae129de40f47ac846a Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Sat, 15 Mar 2025 23:15:52 +0530 Subject: [PATCH 09/10] Update log rules --- .../unix/list-rules-output.txt | 34 +++++++++---------- .../unix/print-rules-to-console.txt | 34 +++++++++---------- .../windows/list-rules-output.txt | 34 +++++++++---------- .../windows/print-rules-to-console.txt | 34 +++++++++---------- 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt index 57b26922..9291f3e5 100644 --- a/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/unix/list-rules-output.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - ---------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:7 | CODE_SMELL | This operation always evaluates to true - ballerina:8 | CODE_SMELL | This operation always evaluates to false - ballerina:9 | CODE_SMELL | This operation always evaluates to the same value - ballerina:10 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt index 57b26922..9291f3e5 100644 --- a/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/unix/print-rules-to-console.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src/test/resources/test-resources/bal-project-with-config-file/Scan.toml - RuleID | Rule Kind | Rule Description - ---------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:7 | CODE_SMELL | This operation always evaluates to true - ballerina:8 | CODE_SMELL | This operation always evaluates to false - ballerina:9 | CODE_SMELL | This operation always evaluates to the same value - ballerina:10 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt index d5ec48ae..e035ccde 100644 --- a/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt +++ b/scan-command/src/test/resources/command-outputs/windows/list-rules-output.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - ---------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:7 | CODE_SMELL | This operation always evaluates to true - ballerina:8 | CODE_SMELL | This operation always evaluates to false - ballerina:9 | CODE_SMELL | This operation always evaluates to the same value - ballerina:10 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 diff --git a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt index d5ec48ae..e035ccde 100644 --- a/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt +++ b/scan-command/src/test/resources/command-outputs/windows/print-rules-to-console.txt @@ -1,18 +1,18 @@ Loading scan tool configurations from src\test\resources\test-resources\bal-project-with-config-file\Scan.toml - RuleID | Rule Kind | Rule Description - ---------------------------------------------------------------------------------------------------------------------- - ballerina:1 | CODE_SMELL | Avoid checkpanic - ballerina:2 | CODE_SMELL | Unused function parameter - ballerina:7 | CODE_SMELL | This operation always evaluates to true - ballerina:8 | CODE_SMELL | This operation always evaluates to false - ballerina:9 | CODE_SMELL | This operation always evaluates to the same value - ballerina:10 | CODE_SMELL | This variable is assigned to itself - ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 - ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 - exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 - exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 - exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + RuleID | Rule Kind | Rule Description + --------------------------------------------------------------------------------------------------------------------- + ballerina:1 | CODE_SMELL | Avoid checkpanic + ballerina:2 | CODE_SMELL | Unused function parameter + ballerina:7 | CODE_SMELL | This operation always evaluates to true + ballerina:8 | CODE_SMELL | This operation always evaluates to false + ballerina:9 | CODE_SMELL | This operation always evaluates to the same value + ballerina:10 | CODE_SMELL | This variable is assigned to itself + ballerina/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerina/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerina/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + ballerinax/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + ballerinax/example_module_static_code_analyzer:2 | BUG | rule 2 + ballerinax/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 + exampleOrg/example_module_static_code_analyzer:1 | CODE_SMELL | rule 1 + exampleOrg/example_module_static_code_analyzer:2 | BUG | rule 2 + exampleOrg/example_module_static_code_analyzer:3 | VULNERABILITY | rule 3 From e8663fb4295b857aeebb61b94fdc4232076f069a Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Sun, 16 Mar 2025 00:42:59 +0530 Subject: [PATCH 10/10] Fix checkstyle failures --- .../ballerina/scan/internal/StaticCodeAnalyzer.java | 13 ++++++------- .../io/ballerina/scan/internal/CoreRuleTest.java | 4 +++- 2 files changed, 9 insertions(+), 8 deletions(-) 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 a871b3f9..5af096f8 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 @@ -22,15 +22,14 @@ import io.ballerina.compiler.api.symbols.ObjectTypeSymbol; import io.ballerina.compiler.api.symbols.Qualifier; import io.ballerina.compiler.api.symbols.Symbol; -import io.ballerina.compiler.syntax.tree.AssignmentStatementNode; -import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; -import io.ballerina.compiler.syntax.tree.CheckExpressionNode; -import io.ballerina.compiler.syntax.tree.CompoundAssignmentStatementNode; import io.ballerina.compiler.api.symbols.SymbolKind; import io.ballerina.compiler.api.symbols.TypeDefinitionSymbol; import io.ballerina.compiler.api.symbols.TypeSymbol; +import io.ballerina.compiler.syntax.tree.AssignmentStatementNode; +import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; import io.ballerina.compiler.syntax.tree.CheckExpressionNode; import io.ballerina.compiler.syntax.tree.ClassDefinitionNode; +import io.ballerina.compiler.syntax.tree.CompoundAssignmentStatementNode; import io.ballerina.compiler.syntax.tree.ExplicitAnonymousFunctionExpressionNode; import io.ballerina.compiler.syntax.tree.FunctionDefinitionNode; import io.ballerina.compiler.syntax.tree.FunctionSignatureNode; @@ -53,13 +52,13 @@ import java.util.List; import java.util.Optional; -import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isDefinedQualifiedNameReference; -import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isEqualToProvidedLiteralIdentifier; -import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isSameSimpleExpression; import static io.ballerina.compiler.syntax.tree.SyntaxKind.ISOLATED_KEYWORD; import static io.ballerina.compiler.syntax.tree.SyntaxKind.PUBLIC_KEYWORD; import static io.ballerina.scan.utils.Constants.INIT_FUNCTION; import static io.ballerina.scan.utils.Constants.MAIN_FUNCTION; +import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isDefinedQualifiedNameReference; +import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isEqualToProvidedLiteralIdentifier; +import static io.ballerina.scan.utils.ScanCodeAnalyzerUtils.isSameSimpleExpression; /** * {@code StaticCodeAnalyzer} contains the logic to perform core static code analysis on Ballerina documents. diff --git a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java index 54490257..5da964bb 100644 --- a/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java +++ b/scan-command/src/test/java/io/ballerina/scan/internal/CoreRuleTest.java @@ -47,7 +47,7 @@ public class CoreRuleTest { @Test(description = "test all rules") void testAllRules() { - Assert.assertEquals(CoreRule.rules().size(), 6); + Assert.assertEquals(CoreRule.rules().size(), 10); } @Test(description = "test checkpanic rule") @@ -101,6 +101,8 @@ void testSelfAssignmentAnalyzer() { Assert.assertEquals(rule.id(), "ballerina:10"); Assert.assertEquals(rule.numericId(), 10); Assert.assertEquals(rule.description(), SELF_ASSIGNMENT); + } + @Test(description = "test non isolated public functions") void testNonIsolatedPublicFunctionConstructsRule() { Rule rule = CoreRule.PUBLIC_NON_ISOLATED_FUNCTION_CONSTRUCT.rule();