Cleaned up abstract metric

This commit is contained in:
oowekyala
2017-06-30 13:32:38 +02:00
parent 40282e77ae
commit 2b56f54824
4 changed files with 40 additions and 119 deletions

View File

@ -9,20 +9,16 @@ import java.util.List;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration.TypeKind;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.AccessNode;
import net.sourceforge.pmd.lang.java.ast.QualifiedName;
import net.sourceforge.pmd.lang.java.oom.api.Metric;
import net.sourceforge.pmd.lang.java.oom.api.MetricVersion;
import net.sourceforge.pmd.lang.java.oom.api.OperationMetricKey;
/**
* Base class for metrics. Metric objects encapsulate the computational logic required to compute a metric from a
* PackageStats and node. They're stateless.
*
* TODO:cf all these methods mimic the behaviour of resultoptions, perhaps not great.
*
* @author Clément Fournier
*/
@ -85,116 +81,4 @@ public abstract class AbstractMetric implements Metric {
return Metrics.getTopLevelPackageStats();
}
/**
* Gets the sum of the value of an operation metric over all operations in this class (excluding nested classes).
* The computation is not forced (memoized results are used if they can be found).
*
* @param node The class node.
* @param key The operation metric to use.
* @param version Version of the metric.
* @param includeNested Adds the operations of nested classes to the sum.
*
* @return Returns the sum of a metric over all operations of a class.
*/
protected static double sumMetricOverOperations(ASTAnyTypeDeclaration node, OperationMetricKey key,
MetricVersion version, boolean includeNested) {
List<ASTMethodOrConstructorDeclaration> operations = findOperations(node, includeNested);
double sum = 0;
for (ASTMethodOrConstructorDeclaration op : operations) {
double val = Metrics.get(key, op, version);
sum += val == Double.NaN ? 0 : val;
}
return sum;
}
/**
* Finds the declaration nodes of all methods or constructors that are declared inside a class.
*
* @param node The class in which to look for.
* @param includeNested Include operations found in nested classes?
*
* @return The list of all operations declared inside the specified class.
*
* TODO:cf this one is computed every time
*
* TODO:cf it might not be at the best place too (used by ClassStats)
*/
public static List<ASTMethodOrConstructorDeclaration> findOperations(ASTAnyTypeDeclaration node,
boolean includeNested) {
if (includeNested) {
return node.findDescendantsOfType(ASTMethodOrConstructorDeclaration.class);
}
List<ASTClassOrInterfaceBodyDeclaration> outerDecls
= node.jjtGetChild(0).findChildrenOfType(ASTClassOrInterfaceBodyDeclaration.class);
List<ASTMethodOrConstructorDeclaration> operations = new ArrayList<>();
for (ASTClassOrInterfaceBodyDeclaration decl : outerDecls) {
if (decl.jjtGetChild(0) instanceof ASTMethodOrConstructorDeclaration) {
operations.add((ASTMethodOrConstructorDeclaration) decl.jjtGetChild(0));
}
}
return operations;
}
/**
* Gets the average of the value of an operation metric over all operations in this class (excluding nested
* classes). The computation is not forced (memoized results are used if they can be found).
*
* @param node The class node
* @param key The operation metric to use
* @param version Version of the metric
* @param includeNested Adds the operations of nested classes to the sum.
*
* @return Returns the average of a metric over all operations of a class.
*/
protected static double averageMetricOverOperations(ASTAnyTypeDeclaration node, OperationMetricKey key,
MetricVersion version, boolean includeNested) {
List<ASTMethodOrConstructorDeclaration> operations = findOperations(node, includeNested);
double total = 0;
for (ASTMethodOrConstructorDeclaration op : operations) {
double val = Metrics.get(key, op, version);
total += val == Double.NaN ? 0 : val;
}
return total / operations.size();
}
/**
* Gets the highest value of an operation metric over all operations in this class (excluding nested classes).
* The computation is not forced (memoized results are used if they can be found).
*
* @param node The class node.
* @param key The operation metric to use.
* @param version Version of the metric.
* @param includeNested Adds the operations of nested classes to the sum.
*
* @return Returns the highest value of a metric over all operations of a class.
*/
protected static double highestMetricOverOperations(ASTAnyTypeDeclaration node, OperationMetricKey key,
MetricVersion version, boolean includeNested) {
List<ASTMethodOrConstructorDeclaration> operations = findOperations(node, includeNested);
double highest = Double.NEGATIVE_INFINITY;
for (ASTMethodOrConstructorDeclaration op : operations) {
double val = Metrics.get(key, op, version);
if (val > highest) {
highest = val;
}
}
return highest;
}
}

View File

@ -12,6 +12,7 @@ import java.util.Map;
import java.util.Set;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.QualifiedName;
import net.sourceforge.pmd.lang.java.oom.api.ClassMetric;
@ -161,7 +162,7 @@ import net.sourceforge.pmd.lang.java.oom.signature.OperationSignature;
/* default */ double computeWithResultOption(OperationMetricKey key, ASTAnyTypeDeclaration node,
boolean force, MetricVersion version, ResultOption option) {
List<ASTMethodOrConstructorDeclaration> ops = AbstractMetric.findOperations(node, false);
List<ASTMethodOrConstructorDeclaration> ops = findOperations(node, false);
List<Double> values = new ArrayList<>();
for (ASTMethodOrConstructorDeclaration op : ops) {
@ -264,4 +265,36 @@ import net.sourceforge.pmd.lang.java.oom.signature.OperationSignature;
return val;
}
/**
* Finds the declaration nodes of all methods or constructors that are declared inside a class.
*
* @param node The class in which to look for.
* @param includeNested Include operations found in nested classes?
*
* @return The list of all operations declared inside the specified class.
*
* TODO:cf this one is computed every time
*/
private static List<ASTMethodOrConstructorDeclaration> findOperations(ASTAnyTypeDeclaration node,
boolean includeNested) {
if (includeNested) {
return node.findDescendantsOfType(ASTMethodOrConstructorDeclaration.class);
}
List<ASTClassOrInterfaceBodyDeclaration> outerDecls
= node.jjtGetChild(0).findChildrenOfType(ASTClassOrInterfaceBodyDeclaration.class);
List<ASTMethodOrConstructorDeclaration> operations = new ArrayList<>();
for (ASTClassOrInterfaceBodyDeclaration decl : outerDecls) {
if (decl.jjtGetChild(0) instanceof ASTMethodOrConstructorDeclaration) {
operations.add((ASTMethodOrConstructorDeclaration) decl.jjtGetChild(0));
}
}
return operations;
}
}

View File

@ -9,10 +9,12 @@ import org.apache.commons.lang3.mutable.MutableInt;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration;
import net.sourceforge.pmd.lang.java.oom.AbstractMetric;
import net.sourceforge.pmd.lang.java.oom.Metrics;
import net.sourceforge.pmd.lang.java.oom.api.ClassMetric;
import net.sourceforge.pmd.lang.java.oom.api.MetricVersion;
import net.sourceforge.pmd.lang.java.oom.api.OperationMetric;
import net.sourceforge.pmd.lang.java.oom.api.OperationMetricKey;
import net.sourceforge.pmd.lang.java.oom.api.ResultOption;
import net.sourceforge.pmd.lang.java.oom.metrics.cyclo.CycloPathUnawareOperationVisitor;
import net.sourceforge.pmd.lang.java.oom.metrics.cyclo.CycloVisitor;
import net.sourceforge.pmd.lang.java.oom.metrics.cyclo.StandardCycloVisitor;
@ -54,7 +56,7 @@ public final class CycloMetric extends AbstractMetric implements ClassMetric, Op
@Override
public double computeFor(ASTAnyTypeDeclaration node, MetricVersion version) {
return 1 + averageMetricOverOperations(node, OperationMetricKey.CYCLO, version, false);
return 1 + Metrics.get(OperationMetricKey.CYCLO, node, ResultOption.AVERAGE);
}

View File

@ -6,9 +6,11 @@ package net.sourceforge.pmd.lang.java.oom.metrics;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.oom.AbstractMetric;
import net.sourceforge.pmd.lang.java.oom.Metrics;
import net.sourceforge.pmd.lang.java.oom.api.ClassMetric;
import net.sourceforge.pmd.lang.java.oom.api.MetricVersion;
import net.sourceforge.pmd.lang.java.oom.api.OperationMetricKey;
import net.sourceforge.pmd.lang.java.oom.api.ResultOption;
/**
* Weighed Method Count. It is the sum of the statical complexity of all operations of a class. We use
@ -23,6 +25,6 @@ public final class WmcMetric extends AbstractMetric implements ClassMetric {
@Override
public double computeFor(ASTAnyTypeDeclaration node, MetricVersion version) {
return sumMetricOverOperations(node, OperationMetricKey.CYCLO, version, false);
return Metrics.get(OperationMetricKey.CYCLO, node, ResultOption.SUM);
}
}