Use WMC metric in GodClassRule

This commit is contained in:
Clément Fournier
2017-08-20 00:24:56 +02:00
parent 43bbe83e6b
commit a9be7d4f59
2 changed files with 15 additions and 75 deletions

View File

@ -13,13 +13,7 @@ import java.util.Set;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTCatchStatement;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTConditionalAndExpression;
import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
import net.sourceforge.pmd.lang.java.ast.ASTConditionalOrExpression;
import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
@ -27,8 +21,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel;
import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
import net.sourceforge.pmd.lang.java.metrics.JavaMetrics;
import net.sourceforge.pmd.lang.java.metrics.api.JavaClassMetricKey;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.java.rule.JavaRuleViolation;
import net.sourceforge.pmd.lang.java.symboltable.ClassScope;
@ -67,8 +61,6 @@ public class GodClassRule extends AbstractJavaRule {
*/
private static final double ONE_THIRD_THRESHOLD = 1.0 / 3.0;
/** The Weighted Method Count metric. */
private int wmcCounter;
/** The Access To Foreign Data metric. */
private int atfdCounter;
@ -86,8 +78,9 @@ public class GodClassRule extends AbstractJavaRule {
* visited. Afterwards the metrics are evaluated against fixed thresholds.
*/
@Override
public Object visit(ASTCompilationUnit node, Object data) {
wmcCounter = 0;
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
int wmc = (int) JavaMetrics.get(JavaClassMetricKey.WMC, node);
atfdCounter = 0;
methodAttributeAccess = new HashMap<>();
@ -103,14 +96,13 @@ public class GodClassRule extends AbstractJavaRule {
// .append("TCC=").append(tcc);
// System.out.println(debug.toString());
if (wmcCounter >= WMC_VERY_HIGH && atfdCounter > FEW_THRESHOLD && tcc < ONE_THIRD_THRESHOLD) {
if (wmc >= WMC_VERY_HIGH && atfdCounter > FEW_THRESHOLD && tcc < ONE_THIRD_THRESHOLD) {
StringBuilder sb = new StringBuilder();
sb.append(getMessage()).append(" (").append("WMC=").append(wmcCounter).append(", ").append("ATFD=")
.append(atfdCounter).append(", ").append("TCC=").append(tcc).append(')');
String sb = getMessage() + " (" + "WMC=" + wmc + ", " + "ATFD="
+ atfdCounter + ", " + "TCC=" + tcc + ')';
RuleContext ctx = (RuleContext) data;
ctx.getReport().addRuleViolation(new JavaRuleViolation(this, ctx, node, sb.toString()));
ctx.getReport().addRuleViolation(new JavaRuleViolation(this, ctx, node, sb));
}
return result;
}
@ -137,11 +129,10 @@ public class GodClassRule extends AbstractJavaRule {
*
* @return
*/
private double calculateTotalMethodPairs() {
private int calculateTotalMethodPairs() {
int methodCount = methodAttributeAccess.size();
int n = methodCount - 1;
double totalMethodPairs = n * (n + 1) / 2.0;
return totalMethodPairs;
return n * (n + 1) / 2;
}
/**
@ -303,8 +294,6 @@ public class GodClassRule extends AbstractJavaRule {
@Override
public Object visit(ASTMethodDeclaration node, Object data) {
wmcCounter++;
currentMethodName = node.getFirstChildOfType(ASTMethodDeclarator.class).getImage();
methodAttributeAccess.put(currentMethodName, new HashSet<String>());
@ -315,54 +304,4 @@ public class GodClassRule extends AbstractJavaRule {
return result;
}
@Override
public Object visit(ASTConditionalOrExpression node, Object data) {
wmcCounter++;
return super.visit(node, data);
}
@Override
public Object visit(ASTConditionalAndExpression node, Object data) {
wmcCounter++;
return super.visit(node, data);
}
@Override
public Object visit(ASTIfStatement node, Object data) {
wmcCounter++;
return super.visit(node, data);
}
@Override
public Object visit(ASTWhileStatement node, Object data) {
wmcCounter++;
return super.visit(node, data);
}
@Override
public Object visit(ASTForStatement node, Object data) {
wmcCounter++;
return super.visit(node, data);
}
@Override
public Object visit(ASTSwitchLabel node, Object data) {
wmcCounter++;
return super.visit(node, data);
}
@Override
public Object visit(ASTCatchStatement node, Object data) {
wmcCounter++;
return super.visit(node, data);
}
@Override
public Object visit(ASTConditionalExpression node, Object data) {
if (node.isTernary()) {
wmcCounter++;
}
return super.visit(node, data);
}
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0"?>
<ruleset name="Design"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns="http://pmd.sourceforge.net/ruleset/3.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/3.0.0 http://pmd.sourceforge.net/ruleset_3_0_0.xsd">
<description>
The Design ruleset contains rules that flag suboptimal code implementations. Alternate approaches
@ -1857,6 +1857,7 @@ public class HelloWorldBean {
language="java"
since="5.0"
message="Possible God class"
metrics="true"
class="net.sourceforge.pmd.lang.java.rule.design.GodClassRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#godclass">
<description>