Merge branch 'master' into issue-1325
This commit is contained in:
+14
-9
@@ -16,6 +16,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTResultType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
|
||||
import net.sourceforge.pmd.properties.BooleanProperty;
|
||||
import net.sourceforge.pmd.properties.StringMultiProperty;
|
||||
|
||||
@@ -134,12 +135,16 @@ public class LinguisticNamingRule extends AbstractJavaRule {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBooleanType(ASTType node) {
|
||||
return "boolean".equalsIgnoreCase(node.getTypeImage()) || TypeHelper.isA(node, "java.util.concurrent.atomic.AtomicBoolean");
|
||||
}
|
||||
|
||||
private void checkBooleanMethods(ASTMethodDeclaration node, Object data, String nameOfMethod) {
|
||||
ASTResultType resultType = node.getResultType();
|
||||
ASTType t = node.getResultType().getFirstChildOfType(ASTType.class);
|
||||
if (!resultType.isVoid() && t != null) {
|
||||
for (String prefix : getProperty(BOOLEAN_METHOD_PREFIXES_PROPERTY)) {
|
||||
if (hasPrefix(nameOfMethod, prefix) && !"boolean".equalsIgnoreCase(t.getTypeImage())) {
|
||||
if (hasPrefix(nameOfMethod, prefix) && !isBooleanType(t)) {
|
||||
addViolationWithMessage(data, node, "Linguistics Antipattern - The method ''{0}'' indicates linguistically it returns a boolean, but it returns ''{1}''",
|
||||
new Object[] { nameOfMethod, t.getTypeImage() });
|
||||
}
|
||||
@@ -147,20 +152,20 @@ public class LinguisticNamingRule extends AbstractJavaRule {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkField(String typeImage, ASTVariableDeclarator node, Object data) {
|
||||
private void checkField(ASTType typeNode, ASTVariableDeclarator node, Object data) {
|
||||
for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) {
|
||||
if (hasPrefix(node.getName(), prefix) && !"boolean".equalsIgnoreCase(typeImage)) {
|
||||
if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) {
|
||||
addViolationWithMessage(data, node, "Linguistics Antipattern - The field ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''",
|
||||
new Object[] { node.getName(), typeImage });
|
||||
new Object[] { node.getName(), typeNode.getTypeImage() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkVariable(String typeImage, ASTVariableDeclarator node, Object data) {
|
||||
private void checkVariable(ASTType typeNode, ASTVariableDeclarator node, Object data) {
|
||||
for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) {
|
||||
if (hasPrefix(node.getName(), prefix) && !"boolean".equalsIgnoreCase(typeImage)) {
|
||||
if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) {
|
||||
addViolationWithMessage(data, node, "Linguistics Antipattern - The variable ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''",
|
||||
new Object[] { node.getName(), typeImage });
|
||||
new Object[] { node.getName(), typeNode.getTypeImage() });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,7 +176,7 @@ public class LinguisticNamingRule extends AbstractJavaRule {
|
||||
if (type != null && getProperty(CHECK_FIELDS)) {
|
||||
List<ASTVariableDeclarator> fields = node.findChildrenOfType(ASTVariableDeclarator.class);
|
||||
for (ASTVariableDeclarator field : fields) {
|
||||
checkField(type.getTypeImage(), field, data);
|
||||
checkField(type, field, data);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
@@ -183,7 +188,7 @@ public class LinguisticNamingRule extends AbstractJavaRule {
|
||||
if (type != null && getProperty(CHECK_VARIABLES)) {
|
||||
List<ASTVariableDeclarator> variables = node.findChildrenOfType(ASTVariableDeclarator.class);
|
||||
for (ASTVariableDeclarator variable : variables) {
|
||||
checkVariable(type.getTypeImage(), variable, data);
|
||||
checkVariable(type, variable, data);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
|
||||
@@ -981,7 +981,8 @@ if (foo) { // preferred approach
|
||||
since="6.7.0"
|
||||
message="Linguistics Antipattern - Method name and return type is inconsistent linguistically"
|
||||
class="net.sourceforge.pmd.lang.java.rule.codestyle.LinguisticNamingRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#linguisticnaming">
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#linguisticnaming"
|
||||
typeResolution="true">
|
||||
<description>
|
||||
This rule finds Linguistic Naming Antipatterns. It checks for fields, that are named, as if they should
|
||||
be boolean but have a different type. It also checks for methods, that according to their name, should
|
||||
|
||||
+88
@@ -461,6 +461,94 @@ public class BooleanFieldsMethodFP {
|
||||
public void myMethod() {
|
||||
Boolean hasLegs;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1334 [java] LinguisticNaming should support AtomicBooleans</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class AtomicBooleanFP {
|
||||
private final AtomicBoolean isX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean hasX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean canX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean haveX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean willX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean shouldX = new AtomicBoolean(true);
|
||||
|
||||
public AtomicBoolean isX() {
|
||||
return isX;
|
||||
}
|
||||
public AtomicBoolean hasX() {
|
||||
return hasX;
|
||||
}
|
||||
public AtomicBoolean canX() {
|
||||
return canX;
|
||||
}
|
||||
public AtomicBoolean haveX() {
|
||||
return haveX;
|
||||
}
|
||||
public AtomicBoolean willX() {
|
||||
return willX;
|
||||
}
|
||||
public AtomicBoolean shouldX() {
|
||||
return shouldX;
|
||||
}
|
||||
public void localVariables() {
|
||||
AtomicBoolean isX = new AtomicBoolean(true);
|
||||
AtomicBoolean hasX = new AtomicBoolean(true);
|
||||
AtomicBoolean canX = new AtomicBoolean(true);
|
||||
AtomicBoolean haveX = new AtomicBoolean(true);
|
||||
AtomicBoolean willX = new AtomicBoolean(true);
|
||||
AtomicBoolean shouldX = new AtomicBoolean(true);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1334 [java] LinguisticNaming should support AtomicBooleans false negative</description>
|
||||
<expected-problems>18</expected-problems>
|
||||
<code><![CDATA[
|
||||
import another.pkg.AtomicBoolean;
|
||||
|
||||
public class AtomicBooleanFN {
|
||||
private final AtomicBoolean isX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean hasX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean canX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean haveX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean willX = new AtomicBoolean(true);
|
||||
private final AtomicBoolean shouldX = new AtomicBoolean(true);
|
||||
|
||||
public AtomicBoolean isX() {
|
||||
return isX;
|
||||
}
|
||||
public AtomicBoolean hasX() {
|
||||
return hasX;
|
||||
}
|
||||
public AtomicBoolean canX() {
|
||||
return canX;
|
||||
}
|
||||
public AtomicBoolean haveX() {
|
||||
return haveX;
|
||||
}
|
||||
public AtomicBoolean willX() {
|
||||
return willX;
|
||||
}
|
||||
public AtomicBoolean shouldX() {
|
||||
return shouldX;
|
||||
}
|
||||
public void localVariables() {
|
||||
AtomicBoolean isX = new AtomicBoolean(true);
|
||||
AtomicBoolean hasX = new AtomicBoolean(true);
|
||||
AtomicBoolean canX = new AtomicBoolean(true);
|
||||
AtomicBoolean haveX = new AtomicBoolean(true);
|
||||
AtomicBoolean willX = new AtomicBoolean(true);
|
||||
AtomicBoolean shouldX = new AtomicBoolean(true);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
Reference in New Issue
Block a user