Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ruleKey": "S1172",
"hasTruePositives": true,
"falseNegatives": 32,
"falseNegatives": 33,
"falsePositives": 0
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public void nonCompliantAssignments() {
staticValue = value + 1; // Noncompliant {{Make the enclosing method "static" or remove this set.}}
// ^^^^^^^^^^^
staticValue += value; // Noncompliant {{Make the enclosing method "static" or remove this set.}}
staticValue >>= value; // Noncompliant {{Make the enclosing method "static" or remove this set.}}
staticValue++; // Noncompliant {{Make the enclosing method "static" or remove this set.}}
++staticValue; // Noncompliant {{Make the enclosing method "static" or remove this set.}}
StaticFieldUpateCheckSample.staticValue++; // Noncompliant {{Make the enclosing method "static" or remove this set.}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,20 @@ static interface InnerRecord {

}

@NullMarked // Noncompliant {{Remove redundant annotation @NullMarked at class level as inside scope annotation @NullMarked at package level.}}
static @interface Annotation {
}

@NullMarked // Noncompliant {{Remove redundant annotation @NullMarked at class level as inside scope annotation @NullMarked at package level.}}
enum InnerEnum {
A,
B;

public void f(@NonNull String s) { // Noncompliant {{Remove redundant annotation @NonNull as inside scope annotation @NullMarked at class level.}}
// Do something
}
}

}

enum TEST_COVERAGE {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.sonar.java.checks;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand All @@ -29,6 +28,7 @@
import org.sonar.plugins.java.api.tree.MethodTree;
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.VariableTree;
import org.sonarsource.analyzer.commons.collections.ListUtils;

public abstract class AbstractCallToDeprecatedCodeChecker extends IssuableSubscriptionVisitor {

Expand All @@ -41,7 +41,7 @@ public final void leaveFile(JavaFileScannerContext context) {

@Override
public final List<Tree.Kind> nodesToVisit() {
return Arrays.asList(Tree.Kind.IDENTIFIER, Tree.Kind.CLASS, Tree.Kind.ENUM, Tree.Kind.INTERFACE, Tree.Kind.ANNOTATION_TYPE, Tree.Kind.METHOD, Tree.Kind.CONSTRUCTOR);
return ListUtils.concat(Tree.Kind.CLASS_KINDS, List.of(Tree.Kind.IDENTIFIER, Tree.Kind.METHOD, Tree.Kind.CONSTRUCTOR));
}

@Override
Expand Down Expand Up @@ -120,7 +120,7 @@ private static boolean isDeprecatedMethod(Tree tree) {
}

private static boolean isDeprecatedClassTree(Tree tree) {
return tree.is(Tree.Kind.CLASS, Tree.Kind.ENUM, Tree.Kind.INTERFACE, Tree.Kind.ANNOTATION_TYPE) && ((ClassTree) tree).symbol().isDeprecated();
return Tree.Kind.CLASS_KINDS.contains(tree.kind()) && ((ClassTree) tree).symbol().isDeprecated();
}

boolean isFlaggedForRemoval(Symbol deprecatedSymbol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,6 @@
@Rule(key = "S1121")
public class AssignmentInSubExpressionCheck extends BaseTreeVisitor implements JavaFileScanner {

private static final Kind[] ASSIGNMENT_EXPRESSIONS = new Kind[]{
Kind.AND_ASSIGNMENT,
Kind.ASSIGNMENT,
Kind.DIVIDE_ASSIGNMENT,
Kind.LEFT_SHIFT_ASSIGNMENT,
Kind.RIGHT_SHIFT_ASSIGNMENT,
Kind.MINUS_ASSIGNMENT,
Kind.MULTIPLY_ASSIGNMENT,
Kind.OR_ASSIGNMENT,
Kind.PLUS_ASSIGNMENT,
Kind.REMAINDER_ASSIGNMENT,
Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT,
Kind.XOR_ASSIGNMENT};

private JavaFileScannerContext context;

@Override
Expand All @@ -71,7 +57,7 @@ public void visitAnnotation(AnnotationTree annotationTree) {
@Override
public void visitLambdaExpression(LambdaExpressionTree lambdaExpressionTree) {
//skip lambda if body is an assignment
if(!lambdaExpressionTree.body().is(ASSIGNMENT_EXPRESSIONS)) {
if(!(lambdaExpressionTree.body() instanceof AssignmentExpressionTree)) {
super.visitLambdaExpression(lambdaExpressionTree);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.sonar.java.checks;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -44,7 +43,7 @@ public class CallOuterPrivateMethodCheck extends IssuableSubscriptionVisitor {

@Override
public List<Tree.Kind> nodesToVisit() {
return Arrays.asList(Tree.Kind.CLASS, Tree.Kind.INTERFACE);
return Tree.Kind.CLASS_KINDS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.sonar.java.checks;

import java.util.Arrays;
import java.util.List;
import org.sonar.check.Rule;
import org.sonar.java.model.ExpressionUtils;
Expand All @@ -34,7 +33,7 @@ public class CallSuperMethodFromInnerClassCheck extends IssuableSubscriptionVisi

@Override
public List<Tree.Kind> nodesToVisit() {
return Arrays.asList(Tree.Kind.CLASS, Tree.Kind.INTERFACE);
return Tree.Kind.CLASS_KINDS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.sonar.java.checks;

import java.util.List;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
Expand All @@ -24,9 +25,6 @@
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.VariableTree;

import java.util.Arrays;
import java.util.List;

import static org.sonar.java.checks.helpers.ExpressionsHelper.reportOnClassTree;

@Rule(key = "S1820")
Expand All @@ -43,7 +41,7 @@ public class ClassFieldCountCheck extends IssuableSubscriptionVisitor {

@Override
public List<Tree.Kind> nodesToVisit() {
return Arrays.asList(Tree.Kind.CLASS, Tree.Kind.INTERFACE, Tree.Kind.ENUM);
return Tree.Kind.CLASS_KINDS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,7 @@ private enum EmptyComparisonType {
Tree.Kind.GREATER_THAN,
Tree.Kind.GREATER_THAN_OR_EQUAL_TO
};
private static final Tree.Kind[] CLASS_TREES = {
Tree.Kind.CLASS,
Tree.Kind.ENUM,
Tree.Kind.INTERFACE,
Tree.Kind.RECORD,
Tree.Kind.ANNOTATION_TYPE
};
private static final Tree.Kind[] CLASS_TREES = Tree.Kind.CLASS_KINDS.toArray(new Tree.Kind[0]);
private static final Deque<Boolean> IS_COLLECTION_ENCLOSING_TYPES_STACK = new LinkedList<>();

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
*/
package org.sonar.java.checks;

import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.java.checks.helpers.MethodTreeUtils;
Expand All @@ -24,12 +28,7 @@
import org.sonar.plugins.java.api.tree.LambdaExpressionTree;
import org.sonar.plugins.java.api.tree.MethodTree;
import org.sonar.plugins.java.api.tree.Tree;

import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import org.sonarsource.analyzer.commons.collections.ListUtils;

@Rule(key = "S1067")
public class ExpressionComplexityCheck extends IssuableSubscriptionVisitor {
Expand All @@ -56,9 +55,7 @@ public void setContext(JavaFileScannerContext context) {

@Override
public List<Tree.Kind> nodesToVisit() {
return Arrays.asList(
Tree.Kind.CLASS,
Tree.Kind.RECORD,
return ListUtils.concat(Tree.Kind.CLASS_KINDS, Tree.Kind.ASSIGNMENT_KINDS, List.of(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Bug: ExpressionComplexityCheck now scopes enum/interface bodies

Previously nodesToVisit() and the visitNode/leaveNode/isInsideEquals branches only treated CLASS and RECORD as complexity-reset boundaries; switching to Tree.Kind.CLASS_KINDS additionally treats ENUM, INTERFACE, ANNOTATION_TYPE and IMPLICIT_CLASS as boundaries that push/pop a fresh count/level scope. This changes how S1067 counts operators for expressions inside enum/interface/annotation bodies, so reported issues may differ, yet no test accompanies this behavior change (unlike RedundantNullabilityAnnotationsCheck). Confirm the new scoping is intended and add a test covering an expression inside an enum/interface, or restrict this check to the previous CLASS/RECORD set if the broadening is unintended.

Was this helpful? React with 👍 / 👎

Tree.Kind.POSTFIX_INCREMENT,
Tree.Kind.POSTFIX_DECREMENT,
Tree.Kind.PREFIX_INCREMENT,
Expand Down Expand Up @@ -95,18 +92,6 @@ public List<Tree.Kind> nodesToVisit() {
Tree.Kind.TYPE_CAST,
Tree.Kind.INSTANCE_OF,
Tree.Kind.PARENTHESIZED_EXPRESSION,
Tree.Kind.ASSIGNMENT,
Tree.Kind.MULTIPLY_ASSIGNMENT,
Tree.Kind.DIVIDE_ASSIGNMENT,
Tree.Kind.REMAINDER_ASSIGNMENT,
Tree.Kind.PLUS_ASSIGNMENT,
Tree.Kind.MINUS_ASSIGNMENT,
Tree.Kind.LEFT_SHIFT_ASSIGNMENT,
Tree.Kind.RIGHT_SHIFT_ASSIGNMENT,
Tree.Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT,
Tree.Kind.AND_ASSIGNMENT,
Tree.Kind.XOR_ASSIGNMENT,
Tree.Kind.OR_ASSIGNMENT,
Tree.Kind.INT_LITERAL,
Tree.Kind.LONG_LITERAL,
Tree.Kind.FLOAT_LITERAL,
Expand All @@ -118,12 +103,12 @@ public List<Tree.Kind> nodesToVisit() {
Tree.Kind.IDENTIFIER,
Tree.Kind.ARRAY_TYPE,
Tree.Kind.LAMBDA_EXPRESSION,
Tree.Kind.PRIMITIVE_TYPE);
Tree.Kind.PRIMITIVE_TYPE));
}

@Override
public void visitNode(Tree tree) {
if (tree.is(Tree.Kind.CLASS, Tree.Kind.RECORD, Tree.Kind.NEW_ARRAY) || isLambdaWithBlock(tree)) {
if (Tree.Kind.CLASS_KINDS.contains(tree.kind()) || tree.is(Tree.Kind.NEW_ARRAY) || isLambdaWithBlock(tree)) {
count.push(0);
level.push(0);
} else {
Expand All @@ -136,7 +121,7 @@ public void visitNode(Tree tree) {

@Override
public void leaveNode(Tree tree) {
if (tree.is(Tree.Kind.CLASS, Tree.Kind.RECORD, Tree.Kind.NEW_ARRAY) || isLambdaWithBlock(tree)) {
if (Tree.Kind.CLASS_KINDS.contains(tree.kind()) || tree.is(Tree.Kind.NEW_ARRAY) || isLambdaWithBlock(tree)) {
count.pop();
level.pop();
} else {
Expand All @@ -155,7 +140,7 @@ public void leaveNode(Tree tree) {

private static boolean isInsideEquals(Tree tree) {
Tree parent = tree.parent();
while (parent != null && !parent.is(Tree.Kind.CLASS, Tree.Kind.RECORD)) {
while (parent != null && !Tree.Kind.CLASS_KINDS.contains(parent.kind())) {
if (parent.is(Tree.Kind.METHOD) && MethodTreeUtils.isEqualsMethod((MethodTree) parent)) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.sonar.java.checks;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
Expand All @@ -27,8 +26,6 @@
import java.util.Set;
import javax.annotation.Nullable;
import org.sonar.check.Rule;
import org.sonarsource.analyzer.commons.collections.MapBuilder;
import org.sonarsource.analyzer.commons.collections.SetUtils;
import org.sonar.java.model.JavaTree;
import org.sonar.java.model.LineUtils;
import org.sonar.java.model.ModifiersUtils;
Expand All @@ -42,6 +39,9 @@
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.VariableTree;
import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey;
import org.sonarsource.analyzer.commons.collections.ListUtils;
import org.sonarsource.analyzer.commons.collections.MapBuilder;
import org.sonarsource.analyzer.commons.collections.SetUtils;

@DeprecatedRuleKey(ruleKey = "HiddenFieldCheck", repositoryKey = "squid")
@Rule(key = "S1117")
Expand All @@ -53,18 +53,12 @@ public class HiddenFieldCheck extends IssuableSubscriptionVisitor {

@Override
public List<Tree.Kind> nodesToVisit() {
return Arrays.asList(
Tree.Kind.CLASS,
Tree.Kind.ENUM,
Tree.Kind.INTERFACE,
Tree.Kind.ANNOTATION_TYPE,
Tree.Kind.RECORD,
Tree.Kind.IMPLICIT_CLASS,
Tree.Kind.VARIABLE,
Tree.Kind.METHOD,
Tree.Kind.CONSTRUCTOR,
Tree.Kind.STATIC_INITIALIZER
);
return ListUtils.concat(Tree.Kind.CLASS_KINDS, List.of(
Tree.Kind.VARIABLE,
Tree.Kind.METHOD,
Tree.Kind.CONSTRUCTOR,
Tree.Kind.STATIC_INITIALIZER
));
}

@Override
Expand Down Expand Up @@ -131,14 +125,7 @@ private static boolean isInStaticInnerClass(VariableTree hiddenVariable, Variabl
}

private static boolean isClassTree(Tree tree) {
return tree.is(
Tree.Kind.CLASS,
Tree.Kind.ENUM,
Tree.Kind.INTERFACE,
Tree.Kind.ANNOTATION_TYPE,
Tree.Kind.RECORD,
Tree.Kind.IMPLICIT_CLASS
);
return Tree.Kind.CLASS_KINDS.contains(tree.kind());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.sonar.java.checks;

import java.util.List;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.java.checks.helpers.ExpressionsHelper;
Expand All @@ -27,9 +28,6 @@
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.Tree.Kind;

import java.util.Arrays;
import java.util.List;

@Rule(key = "S2972")
public class InnerClassTooManyLinesCheck extends IssuableSubscriptionVisitor {

Expand All @@ -42,7 +40,7 @@ public class InnerClassTooManyLinesCheck extends IssuableSubscriptionVisitor {

@Override
public List<Kind> nodesToVisit() {
return Arrays.asList(Kind.CLASS, Kind.ENUM, Kind.INTERFACE, Kind.ANNOTATION_TYPE);
return Kind.CLASS_KINDS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,22 @@
*/
package org.sonar.java.checks;

import java.util.List;
import java.util.Locale;
import javax.annotation.Nullable;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.tree.ClassTree;
import org.sonar.plugins.java.api.tree.Tree;
import javax.annotation.Nullable;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

@Rule(key = "S2176")
public class InterfaceOrSuperclassShadowingCheck extends IssuableSubscriptionVisitor {

@Override
public List<Tree.Kind> nodesToVisit() {
return Arrays.asList(Tree.Kind.CLASS, Tree.Kind.INTERFACE, Tree.Kind.RECORD);
return Tree.Kind.CLASS_KINDS;
}

@Override
Expand Down
Loading
Loading