Skip to content

Commit

Permalink
SONARJAVA-4933 S1068 add support for lombok class annotations (#4763)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardo-pilastri-sonarsource authored Apr 10, 2024
1 parent 896bda7 commit 5770bbb
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public void javaCheckTestSources() throws Exception {
SoftAssertions softly = new SoftAssertions();
softly.assertThat(newDiffs).containsExactlyInAnyOrderElementsOf(knownDiffs.values());
softly.assertThat(newTotal).isEqualTo(knownTotal);
softly.assertThat(rulesCausingFPs).hasSize(7);
softly.assertThat(rulesCausingFPs).hasSize(8);
softly.assertThat(rulesNotReporting).hasSize(10);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"ruleKey": "S1068",
"hasTruePositives": true,
"falseNegatives": 0,
"falsePositives": 0
"falsePositives": 4
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package checks.unused;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

public class UnusedPrivateFieldLombok {

@Data
class LombokDataClass {
private String data; // Compliant
public class InnerClass {
private String innerData; // Noncompliant
private String usedData; // Compliant
}
void foo(){
var s = new InnerClass().usedData;
}
}

@Getter
class LombokGetterClass{
private String data; // Compliant
}

@Setter
class LombokSetterClass{
private String data; // Compliant
}

@AllArgsConstructor
class AllArgsConstructorClass {
private String data; // Compliant
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ public class UnusedPrivateFieldCheck extends IssuableSubscriptionVisitor {
private static final String DEFAULT_IGNORE_ANNOTATIONS_KEY = "ignoreAnnotations";
private static final String DEFAULT_IGNORE_ANNOTATIONS_DESCRIPTION = "Ignore annotations with next names (fully qualified class names separated with \",\").";

private static final Set<String> OWNER_CLASS_ALLOWED_ANNOTATIONS = Set.of(
"lombok.Data",
"lombok.Getter",
"lombok.Setter",
"lombok.AllArgsConstructor"
);

private static final Tree.Kind[] ASSIGNMENT_KINDS = {
Tree.Kind.ASSIGNMENT,
Tree.Kind.MULTIPLY_ASSIGNMENT,
Expand Down Expand Up @@ -175,7 +182,8 @@ public void checkIfUnused(VariableTree tree) {
if (symbol.isPrivate()
&& onlyUsedInVariableAssignment(symbol)
&& !"serialVersionUID".equals(name)
&& !unknownIdentifiers.contains(name)) {
&& !unknownIdentifiers.contains(name)
&& !hasOwnerClassAllowedAnnotations(tree)) {
QuickFixHelper.newIssue(context)
.forRule(this)
.onTree(tree.simpleName())
Expand All @@ -186,6 +194,13 @@ && onlyUsedInVariableAssignment(symbol)
}
}

private static boolean hasOwnerClassAllowedAnnotations(VariableTree variableTree) {
var ownerClass = (ClassTree) variableTree.parent();
return ownerClass.modifiers().annotations().stream().anyMatch(
annotation -> OWNER_CLASS_ALLOWED_ANNOTATIONS.contains(annotation.annotationType().symbolType().fullyQualifiedName())
);
}

private boolean onlyUsedInVariableAssignment(Symbol symbol) {
return symbol.usages().size() == assignments.getOrDefault(symbol, Collections.emptyList()).size();
}
Expand Down Expand Up @@ -284,7 +299,7 @@ private String computeReplacement(ExpressionTree variable, int index) {
name = identifier.name() + index;
} else {
identifier = ((MemberSelectExpressionTree) variable).identifier();
name = identifier.name() + index;
name = identifier.name() + index;
}
name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
TypeTree typeInDeclaration = ((VariableTree) identifier.symbol().declaration()).type();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ void test_ignored_annotation() {
.withCheck(check)
.verifyIssues();
}

@Test
void test_lombok_annotations() {
InternalCheckVerifier.newInstance()
.onFile(mainCodeSourcesPath("checks/unused/UnusedPrivateFieldLombok.java"))
.withCheck(new UnusedPrivateFieldCheck())
.verifyIssues();
}

}

0 comments on commit 5770bbb

Please sign in to comment.