diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassStats.java index 11e87b8d0d..d1f2d5c7ae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassStats.java @@ -9,7 +9,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.QualifiedName; import net.sourceforge.pmd.lang.java.metrics.signature.FieldSigMask; import net.sourceforge.pmd.lang.java.metrics.signature.FieldSignature; @@ -77,14 +76,14 @@ import net.sourceforge.pmd.lang.java.metrics.signature.OperationSignature; } - OperationStats getOperationStats(String operationName, ASTMethodOrConstructorDeclaration node) { - Map sigMap = operations.get(OperationSignature.buildFor(node)); - - if (sigMap == null) { - return null; + OperationStats getOperationStats(String operationName, OperationSignature sig) { + if (sig == null) { + return getOperationStats(operationName); } - return sigMap.get(operationName); + Map sigMap = operations.get(sig); + + return sigMap == null ? null : sigMap.get(operationName); } @@ -93,12 +92,16 @@ import net.sourceforge.pmd.lang.java.metrics.signature.OperationSignature; * * @param name The name of the operation * @param sig The signature of the operation + * + * @return The newly created operation stats */ - /* default */ void addOperation(String name, OperationSignature sig) { + /* default */ OperationStats addOperation(String name, OperationSignature sig) { if (!operations.containsKey(sig)) { operations.put(sig, new HashMap()); } - operations.get(sig).put(name, new OperationStats(name)); + OperationStats newOp = new OperationStats(name); + operations.get(sig).put(name, newOp); + return newOp; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MetricsComputer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MetricsComputer.java index cd736c131f..7ff8e4a26f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MetricsComputer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MetricsComputer.java @@ -10,6 +10,7 @@ import java.util.List; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeBodyDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; +import net.sourceforge.pmd.lang.java.metrics.signature.OperationSignature; import net.sourceforge.pmd.lang.metrics.ParameterizedMetricKey; import net.sourceforge.pmd.lang.metrics.api.MetricKey; import net.sourceforge.pmd.lang.metrics.api.MetricVersion; @@ -99,7 +100,8 @@ public class MetricsComputer { List values = new ArrayList<>(); for (ASTMethodOrConstructorDeclaration op : ops) { if (key.supports(op)) { - OperationStats opStats = stats.getOperationStats(op.getQualifiedName().getOperation(), op); + OperationStats opStats = stats.getOperationStats(op.getQualifiedName().getOperation(), + OperationSignature.buildFor(op)); double val = this.compute(key, op, force, version, opStats); if (val != Double.NaN) { values.add(val); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java index bbfa5907b4..4ba79f7aa9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.QualifiedName; import net.sourceforge.pmd.lang.java.metrics.signature.FieldSigMask; import net.sourceforge.pmd.lang.java.metrics.signature.OperationSigMask; +import net.sourceforge.pmd.lang.java.metrics.signature.OperationSignature; import net.sourceforge.pmd.lang.metrics.api.MetricKey; import net.sourceforge.pmd.lang.metrics.api.MetricVersion; import net.sourceforge.pmd.lang.metrics.api.ResultOption; @@ -62,6 +63,35 @@ public final class PackageStats { } + /** + * Gets the OperationStats corresponding to the qualified name. + * + * @param qname The qualified name of the operation to fetch + * @param sig The signature of the operation, which must be non-null if createIfNotFound is set + * @param createIfNotFound Create an OperationStats if missing + * + * @return The new OperationStat, or the one that was found. Can return null only if createIfNotFound is unset + */ + OperationStats getOperationStats(QualifiedName qname, OperationSignature sig, boolean createIfNotFound) { + ClassStats container = getClassStats(qname, createIfNotFound); + + if (container == null || !qname.isOperation()) { + return null; + } + + OperationStats target = container.getOperationStats(qname.getOperation(), sig); + + if (target == null && createIfNotFound) { + if (sig == null) { + throw new IllegalArgumentException("Cannot add an operation with a null signature"); + } + target = container.addOperation(qname.getOperation(), sig); + } + + return target; + } + + /** * Gets the ClassStats corresponding to the named resource. The class can be nested. If the createIfNotFound * parameter is set, the method also creates the hierarchy if it doesn't exist. @@ -105,7 +135,7 @@ public final class PackageStats { * missing PackageStats along the way. * * @param qname The qualified name of the resource - * @param createIfNotFound If set to true, the hierarch is created if non existent + * @param createIfNotFound If set to true, the hierarch is created if missing * * @return The deepest package that contains this resource. Can only return null if createIfNotFound is unset */ @@ -179,7 +209,8 @@ public final class PackageStats { boolean force, MetricVersion version) { QualifiedName qname = node.getQualifiedName(); ClassStats container = getClassStats(qname, false); - OperationStats memoizer = container == null ? null : container.getOperationStats(qname.getOperation(), node); + OperationStats memoizer = container == null ? null : container.getOperationStats(qname.getOperation(), + OperationSignature.buildFor(node)); return memoizer == null ? Double.NaN : MetricsComputer.INSTANCE.compute(key, node, force, version, memoizer);