Merge branch 'bug-1494' into pmd/5.4.x
This commit is contained in:
@ -4,16 +4,22 @@
|
||||
package net.sourceforge.pmd.lang.java.rule.design;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTInitializer;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTSynchronizedStatement;
|
||||
@ -42,14 +48,49 @@ public class SingularFieldRule extends AbstractJavaRule {
|
||||
definePropertyDescriptor(CHECK_INNER_CLASSES);
|
||||
definePropertyDescriptor(DISALLOW_NOT_ASSIGNMENT);
|
||||
}
|
||||
|
||||
|
||||
private boolean lombokImported = false;
|
||||
private boolean classHasLombokAnnotation = false;
|
||||
private static final String LOMBOK_PACKAGE = "lombok";
|
||||
private static final Set<String> LOMBOK_ANNOTATIONS = new HashSet<String>();
|
||||
static {
|
||||
LOMBOK_ANNOTATIONS.add("Data");
|
||||
LOMBOK_ANNOTATIONS.add("Getter");
|
||||
LOMBOK_ANNOTATIONS.add("Setter");
|
||||
LOMBOK_ANNOTATIONS.add("Value");
|
||||
LOMBOK_ANNOTATIONS.add("RequiredArgsConstructor");
|
||||
LOMBOK_ANNOTATIONS.add("AllArgsConstructor");
|
||||
LOMBOK_ANNOTATIONS.add("Builder");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTCompilationUnit node, Object data) {
|
||||
lombokImported = false;
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTImportDeclaration node, Object data) {
|
||||
ASTName name = node.getFirstChildOfType(ASTName.class);
|
||||
if (!lombokImported && name != null && name.getImage() != null & name.getImage().startsWith(LOMBOK_PACKAGE)) {
|
||||
lombokImported = true;
|
||||
}
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
|
||||
classHasLombokAnnotation = hasLombokAnnotation(node);
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.CompareObjectsWithEquals")
|
||||
@Override
|
||||
public Object visit(ASTFieldDeclaration node, Object data) {
|
||||
boolean checkInnerClasses = getProperty(CHECK_INNER_CLASSES);
|
||||
boolean disallowNotAssignment = getProperty(DISALLOW_NOT_ASSIGNMENT);
|
||||
|
||||
if (node.isPrivate() && !node.isStatic()) {
|
||||
if (node.isPrivate() && !node.isStatic() && !classHasLombokAnnotation && !hasLombokAnnotation(node)) {
|
||||
for (ASTVariableDeclarator declarator: node.findChildrenOfType(ASTVariableDeclarator.class)) {
|
||||
ASTVariableDeclaratorId declaration = (ASTVariableDeclaratorId) declarator.jjtGetChild(0);
|
||||
List<NameOccurrence> usages = declaration.getUsages();
|
||||
@ -150,4 +191,30 @@ public class SingularFieldRule extends AbstractJavaRule {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasLombokAnnotation(Node node) {
|
||||
boolean result = false;
|
||||
Node parent = node.jjtGetParent();
|
||||
List<ASTAnnotation> annotations = parent.findChildrenOfType(ASTAnnotation.class);
|
||||
for (ASTAnnotation annotation : annotations) {
|
||||
ASTName name = annotation.getFirstDescendantOfType(ASTName.class);
|
||||
if (name != null) {
|
||||
String annotationName = name.getImage();
|
||||
if (lombokImported) {
|
||||
if (LOMBOK_ANNOTATIONS.contains(annotationName)) {
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
if (annotationName.startsWith(LOMBOK_PACKAGE + ".")) {
|
||||
String shortName = annotationName.substring(LOMBOK_PACKAGE.length() + 1);
|
||||
if (LOMBOK_ANNOTATIONS.contains(shortName)) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -530,6 +530,42 @@ public enum Supplier {
|
||||
public static String getSupplierNameIfPresent(String supplier) {
|
||||
return Optional.ofNullable(supplier).map(foo -> valueOf(supplier).supplierName).orElse("");
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1494 [java] SingularField: lombok.Data false positive - part1</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MyClass {
|
||||
|
||||
private String field1;
|
||||
|
||||
public MyClass(String field1) {
|
||||
this.field1 = field1;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1494 [java] SingularField: lombok.Data false positive - part2</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import lombok.Getter;
|
||||
|
||||
public class MyClass {
|
||||
|
||||
@Getter
|
||||
private String field1;
|
||||
|
||||
public MyClass(String field1) {
|
||||
this.field1 = field1;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
Reference in New Issue
Block a user