diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java index 1a8277e94b..31bfd87751 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java @@ -4,11 +4,9 @@ package net.sourceforge.pmd.lang.java.ast; -import net.sourceforge.pmd.lang.ast.Node; - /** * @author Clément Fournier */ -public interface ASTMethodOrConstructorDeclaration extends QualifiableNode, Node, AccessNode { +public interface ASTMethodOrConstructorDeclaration extends QualifiableNode, AccessNode, JavaNode { } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/AbstractMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/AbstractMetric.java index ba74498d54..115e0bbb7d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/AbstractMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/AbstractMetric.java @@ -8,21 +8,19 @@ import java.util.ArrayList; import java.util.List; 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; /** * Base class for metrics. Metric objects encapsulate the computational logic required to compute a metric from a - * PackageStats and node. + * PackageStats and node. They're stateless. * * @author Clément Fournier */ public abstract class AbstractMetric implements Metric { - // TODO:cf useful? - protected boolean isAbstractHandler = false; - /** * Gives access to the toplevel package stats to metrics without having to pass them as a parameter to metrics. * @@ -42,14 +40,15 @@ public abstract class AbstractMetric implements Metric { } /** - * Checks if the metric can be computed on that node. + * Default implementation of the supports method, which filters out abstract nodes. Metrics that support abstract + * nodes should override this method. * - * @param node The node to check for + * @param node The node to check. * - * @return True if the metric can be computed, false otherwise. + * @return True if the metric can be computed on this node. */ - // TODO:cf better wrap that around the metrics implementation - protected boolean isSupported(ASTMethodOrConstructorDeclaration node) { - return isAbstractHandler || !node.isAbstract(); + @Override + public boolean supports(AccessNode node) { + return !node.isAbstract(); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java index 9e111e84fb..ca9553e9c4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java @@ -32,8 +32,7 @@ public final class Metrics { * * @return The top level package stats. */ - /* default */ - static PackageStats getTopLevelPackageStats() { + /* default */ static PackageStats getTopLevelPackageStats() { return TOP_LEVEL_PACKAGE; } @@ -89,6 +88,10 @@ public final class Metrics { */ public static double get(ClassMetricKey key, ASTClassOrInterfaceDeclaration node, MetricVersion version, ResultOption option) { + if (!key.getCalculator().supports(node)) { + return Double.NaN; + } + MetricVersion safeOption = (version == null) ? Version.STANDARD : version; return TOP_LEVEL_PACKAGE.compute(key, node, false, safeOption, option); @@ -117,6 +120,10 @@ public final class Metrics { * @return The value of the metric, or {@code Double.NaN} if the value couln't be computed. */ public static double get(OperationMetricKey key, ASTMethodOrConstructorDeclaration node, MetricVersion version) { + if (!key.getCalculator().supports(node)) { + return Double.NaN; + } + MetricVersion safeOption = (version == null) ? Version.STANDARD : version; return TOP_LEVEL_PACKAGE.compute(key, node, false, safeOption); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/Metric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/Metric.java index 68f5023e63..d85fdd28be 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/Metric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/Metric.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.java.oom.api; +import net.sourceforge.pmd.lang.java.ast.AccessNode; + /** * Umbrella marker interface for metrics. * @@ -11,6 +13,16 @@ package net.sourceforge.pmd.lang.java.oom.api; */ public interface Metric { + + /** + * Checks if the metric can be computed on the node. + * + * @param node The node to check. + * + * @return True if the metric can be computed. + */ + boolean supports(AccessNode node); + /** Default metric version. */ enum Version implements MetricVersion { /** Standard option, used as a default. */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetric.java index 7086eaf334..cb1dca8b06 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetric.java @@ -23,5 +23,4 @@ public interface OperationMetric extends Metric { */ double computeFor(ASTMethodOrConstructorDeclaration node, MetricVersion version); - } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/AtfdMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/AtfdMetric.java index e461526ed2..0b8395c43e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/AtfdMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/AtfdMetric.java @@ -8,6 +8,7 @@ import java.util.List; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; 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.AbstractMetric; import net.sourceforge.pmd.lang.java.oom.api.ClassMetric; @@ -25,11 +26,14 @@ import net.sourceforge.pmd.lang.java.oom.signature.Signature.Visibility; */ public class AtfdMetric extends AbstractMetric implements ClassMetric, OperationMetric { + @Override + public boolean supports(AccessNode node) { + return node instanceof ASTClassOrInterfaceDeclaration + || node instanceof ASTMethodOrConstructorDeclaration && !node.isAbstract(); + } + @Override // TODO:cf public double computeFor(ASTMethodOrConstructorDeclaration node, MetricVersion version) { - if (!isSupported(node)) { - return Double.NaN; - } OperationSigMask targetOps = new OperationSigMask(); targetOps.restrictVisibilitiesTo(Visibility.PUBLIC); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/CycloMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/CycloMetric.java index d37269bcb2..c864163e66 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/CycloMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/CycloMetric.java @@ -63,11 +63,13 @@ public class CycloMetric extends AbstractClassAndOperationMetric { return (double) cyclo.getValue(); } + @Override public OperationMetricKey getOperationMetricKey() { return OperationMetricKey.CYCLO; } + /** Variants of CYCLO. */ public enum Version implements MetricVersion { /** Do not count the paths in boolean expressions as decision points. */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/LocMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/LocMetric.java index c4cb5bff89..53b78525b5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/LocMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/LocMetric.java @@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.java.oom.metrics; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; +import net.sourceforge.pmd.lang.java.ast.AccessNode; import net.sourceforge.pmd.lang.java.oom.api.MetricVersion; import net.sourceforge.pmd.lang.java.oom.api.OperationMetricKey; @@ -20,6 +21,12 @@ import net.sourceforge.pmd.lang.java.oom.api.OperationMetricKey; */ public class LocMetric extends AbstractClassAndOperationMetric { + + @Override + public boolean supports(AccessNode node) { + return true; + } + @Override protected double computeDefaultResultOption(ASTClassOrInterfaceDeclaration node, MetricVersion version) { return node.getEndLine() - node.getBeginLine(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/NcssMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/NcssMetric.java index d188a971ce..f1631c2fae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/NcssMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/metrics/NcssMetric.java @@ -31,6 +31,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTSynchronizedStatement; import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement; import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; +import net.sourceforge.pmd.lang.java.ast.AccessNode; import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; import net.sourceforge.pmd.lang.java.oom.api.MetricVersion; import net.sourceforge.pmd.lang.java.oom.api.OperationMetricKey; @@ -46,6 +47,10 @@ import net.sourceforge.pmd.lang.java.oom.api.OperationMetricKey; */ public class NcssMetric extends AbstractClassAndOperationMetric { + @Override + public boolean supports(AccessNode node) { + return true; + } @Override protected double computeDefaultResultOption(ASTClassOrInterfaceDeclaration node, MetricVersion version) {