forked from phoedos/pmd
Corrections for PR #567
This commit is contained in:
@ -5,9 +5,7 @@ summary: "PMD was recently enhanced with the ability to compute code metrics on
|
||||
Metrics Framework). This framework provides developers with a straightforward interface to use code metrics in their
|
||||
rules, and to extend the framework with their own custom metrics."
|
||||
last_updated: July 20, 2017
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_devdocs_metrics_howto.html
|
||||
folder: pmd/devdocs
|
||||
---
|
||||
# Using code metrics in custom rules
|
||||
|
||||
@ -79,7 +77,7 @@ public Object visit(ASTMethodDeclaration method, Object data) {
|
||||
|
||||
Some metrics define options that can be used to slightly modify the computation. You'll typically see these options
|
||||
gathered inside an enum in the implementation class of the metric, for example `CycloMetric.CycloOptions`. They're
|
||||
also documented on the [index of metrics](/pmd_java_metrics_index.html).
|
||||
also documented on the [index of metrics](pmd_java_metrics_index.html).
|
||||
|
||||
To use options with a metric, you must first bundle them into a `MetricOptions` object. `MetricOptions` provides the
|
||||
utility method `ofOptions` to get a `MetricOptions` bundle from a collection or with varargs parameters. You can then
|
||||
|
@ -3,9 +3,7 @@ title: Index of code metrics
|
||||
tags: [customizing]
|
||||
summary: "Index of the code metrics available out of the box to Java rule developers."
|
||||
last_updated: July 20, 2017
|
||||
sidebar: pmd_sidebar
|
||||
permalink: pmd_java_metrics_index.html
|
||||
folder: pmd/languages
|
||||
toc:
|
||||
minimumHeaders: 8
|
||||
---
|
||||
|
@ -62,7 +62,7 @@ public final class ApexMetrics {
|
||||
*
|
||||
* @param key The key identifying the metric to be computed
|
||||
* @param node The node on which to compute the metric
|
||||
* @param options The version of the metric
|
||||
* @param options The options of the metric
|
||||
*
|
||||
* @return The value of the metric, or {@code Double.NaN} if the value couldn't be computed
|
||||
*/
|
||||
@ -90,7 +90,7 @@ public final class ApexMetrics {
|
||||
*
|
||||
* @param key The key identifying the metric to be computed
|
||||
* @param node The node on which to compute the metric
|
||||
* @param options The version of the metric
|
||||
* @param options The options of the metric
|
||||
*
|
||||
* @return The value of the metric, or {@code Double.NaN} if the value couldn't be computed
|
||||
*/
|
||||
@ -121,7 +121,7 @@ public final class ApexMetrics {
|
||||
*
|
||||
* @param key The key identifying the metric to be computed
|
||||
* @param node The node on which to compute the metric
|
||||
* @param options The version of the metric
|
||||
* @param options The options of the metric
|
||||
* @param resultOption The result option to use
|
||||
*
|
||||
* @return The value of the metric, or {@code Double.NaN} if the value couldn't be computed or {@code option} is
|
||||
|
@ -97,7 +97,7 @@ public abstract class AbstractApexMetricTestRule extends AbstractApexRule {
|
||||
/**
|
||||
* Mappings of labels to options for use in the options property.
|
||||
*
|
||||
* @return A map of labels to options&
|
||||
* @return A map of labels to options
|
||||
*/
|
||||
protected Map<String, MetricOption> optionMappings() {
|
||||
return new HashMap<>();
|
||||
|
@ -19,6 +19,10 @@ import net.sourceforge.pmd.lang.ast.QualifiableNode;
|
||||
*/
|
||||
public abstract class AbstractMetricsFacade<T extends QualifiableNode, O extends QualifiableNode> {
|
||||
|
||||
private static final String NULL_KEY_MESSAGE = "The metric key must not be null";
|
||||
private static final String NULL_OPTIONS_MESSAGE = "The metric options must not be null";
|
||||
private static final String NULL_NODE_MESSAGE = "The node must not be null";
|
||||
|
||||
|
||||
/**
|
||||
* Gets the language specific metrics computer.
|
||||
@ -48,18 +52,19 @@ public abstract class AbstractMetricsFacade<T extends QualifiableNode, O extends
|
||||
*/
|
||||
public double computeForType(MetricKey<T> key, T node, MetricOptions options) {
|
||||
|
||||
Objects.requireNonNull(key, "The metric key must not be null");
|
||||
Objects.requireNonNull(key, NULL_KEY_MESSAGE);
|
||||
Objects.requireNonNull(options, NULL_OPTIONS_MESSAGE);
|
||||
Objects.requireNonNull(node, NULL_NODE_MESSAGE);
|
||||
|
||||
if (!key.supports(node)) {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
MetricOptions safeOptions = options == null ? MetricOptions.emptyOptions() : options;
|
||||
MetricMemoizer<T> memoizer = getLanguageSpecificProjectMemoizer().getClassMemoizer(node.getQualifiedName());
|
||||
|
||||
return memoizer == null ? Double.NaN
|
||||
: getLanguageSpecificComputer().computeForType(key, node, false,
|
||||
safeOptions, memoizer);
|
||||
options, memoizer);
|
||||
}
|
||||
|
||||
|
||||
@ -74,18 +79,20 @@ public abstract class AbstractMetricsFacade<T extends QualifiableNode, O extends
|
||||
*/
|
||||
public double computeForOperation(MetricKey<O> key, O node, MetricOptions options) {
|
||||
|
||||
Objects.requireNonNull(key, "The metric key must not be null");
|
||||
Objects.requireNonNull(key, NULL_KEY_MESSAGE);
|
||||
Objects.requireNonNull(options, NULL_OPTIONS_MESSAGE);
|
||||
Objects.requireNonNull(node, NULL_NODE_MESSAGE);
|
||||
|
||||
|
||||
if (!key.supports(node)) {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
MetricOptions safeOptions = options == null ? MetricOptions.emptyOptions() : options;
|
||||
MetricMemoizer<O> memoizer = getLanguageSpecificProjectMemoizer().getOperationMemoizer(node.getQualifiedName());
|
||||
|
||||
return memoizer == null ? Double.NaN
|
||||
: getLanguageSpecificComputer().computeForOperation(key, node, false,
|
||||
safeOptions, memoizer);
|
||||
options, memoizer);
|
||||
|
||||
}
|
||||
|
||||
@ -105,12 +112,12 @@ public abstract class AbstractMetricsFacade<T extends QualifiableNode, O extends
|
||||
public double computeWithResultOption(MetricKey<O> key, T node,
|
||||
MetricOptions options, ResultOption resultOption) {
|
||||
|
||||
Objects.requireNonNull(key, "The metric key must not be null");
|
||||
Objects.requireNonNull(key, NULL_KEY_MESSAGE);
|
||||
Objects.requireNonNull(options, NULL_OPTIONS_MESSAGE);
|
||||
Objects.requireNonNull(node, NULL_NODE_MESSAGE);
|
||||
Objects.requireNonNull(resultOption, "The result option must not be null");
|
||||
|
||||
MetricOptions safeOptions = options == null ? MetricOptions.emptyOptions() : options;
|
||||
|
||||
return getLanguageSpecificComputer().computeWithResultOption(key, node, false, safeOptions,
|
||||
return getLanguageSpecificComputer().computeWithResultOption(key, node, false, options,
|
||||
resultOption, getLanguageSpecificProjectMemoizer());
|
||||
}
|
||||
}
|
||||
|
@ -59,9 +59,9 @@ public class MetricOptions {
|
||||
return false;
|
||||
}
|
||||
|
||||
MetricOptions version = (MetricOptions) o;
|
||||
MetricOptions other = (MetricOptions) o;
|
||||
|
||||
return options.equals(version.options);
|
||||
return options.equals(other.options);
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ public final class ParameterizedMetricKey<N extends Node> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParameterizedMetricKey{key=" + key.name() + ", version=" + options + '}';
|
||||
return "ParameterizedMetricKey{key=" + key.name() + ", options=" + options + '}';
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ import net.sourceforge.pmd.lang.metrics.MetricOptions;
|
||||
|
||||
|
||||
/**
|
||||
* Cyclomatic Complexity. See the <a href="https://{pmd.website.baseurl}/pmd_java_metrics_index.html">documentation site</a>.
|
||||
* Cyclomatic Complexity. See the <a href="https://pmd.github.io/latest/pmd_java_metrics_index.html">documentation site</a>.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since June 2017
|
||||
|
@ -35,19 +35,19 @@ public class CyclomaticComplexityRule extends AbstractJavaMetricsRule {
|
||||
private static final IntegerProperty METHOD_LEVEL_DESCRIPTOR = new IntegerProperty(
|
||||
"methodReportLevel", "Cyclomatic complexity reporting threshold", 1, 50, 10, 1.0f);
|
||||
|
||||
private static final Map<String, CycloOption> VERSION_MAP;
|
||||
private static final Map<String, CycloOption> OPTION_MAP;
|
||||
|
||||
|
||||
static {
|
||||
VERSION_MAP = new HashMap<>();
|
||||
VERSION_MAP.put(CycloOption.IGNORE_BOOLEAN_PATHS.valueName(), CycloOption.IGNORE_BOOLEAN_PATHS);
|
||||
VERSION_MAP.put(CycloOption.CONSIDER_ASSERT.valueName(), CycloOption.CONSIDER_ASSERT);
|
||||
OPTION_MAP = new HashMap<>();
|
||||
OPTION_MAP.put(CycloOption.IGNORE_BOOLEAN_PATHS.valueName(), CycloOption.IGNORE_BOOLEAN_PATHS);
|
||||
OPTION_MAP.put(CycloOption.CONSIDER_ASSERT.valueName(), CycloOption.CONSIDER_ASSERT);
|
||||
}
|
||||
|
||||
|
||||
private static final EnumeratedMultiProperty<CycloOption> CYCLO_OPTIONS_DESCRIPTOR = new EnumeratedMultiProperty<>(
|
||||
"cycloOptions", "Choose options for the computation of Cyclo",
|
||||
VERSION_MAP, Collections.<CycloOption>emptyList(), CycloOption.class, 3.0f);
|
||||
OPTION_MAP, Collections.<CycloOption>emptyList(), CycloOption.class, 3.0f);
|
||||
|
||||
private int methodReportLevel;
|
||||
private int classReportLevel;
|
||||
@ -65,9 +65,8 @@ public class CyclomaticComplexityRule extends AbstractJavaMetricsRule {
|
||||
public Object visit(ASTCompilationUnit node, Object data) {
|
||||
methodReportLevel = getProperty(METHOD_LEVEL_DESCRIPTOR);
|
||||
classReportLevel = getProperty(CLASS_LEVEL_DESCRIPTOR);
|
||||
if (cycloOptions == null) {
|
||||
cycloOptions = MetricOptions.ofOptions(getProperty(CYCLO_OPTIONS_DESCRIPTOR));
|
||||
}
|
||||
cycloOptions = MetricOptions.ofOptions(getProperty(CYCLO_OPTIONS_DESCRIPTOR));
|
||||
|
||||
|
||||
super.visit(node, data);
|
||||
return data;
|
||||
|
@ -66,9 +66,7 @@ public final class NcssCountRule extends AbstractJavaMetricsRule {
|
||||
public Object visit(ASTCompilationUnit node, Object data) {
|
||||
methodReportLevel = getProperty(METHOD_REPORT_LEVEL_DESCRIPTOR);
|
||||
classReportLevel = getProperty(CLASS_REPORT_LEVEL_DESCRIPTOR);
|
||||
if (ncssOptions == null) {
|
||||
ncssOptions = MetricOptions.ofOptions(getProperty(NCSS_OPTIONS_DESCRIPTOR));
|
||||
}
|
||||
ncssOptions = MetricOptions.ofOptions(getProperty(NCSS_OPTIONS_DESCRIPTOR));
|
||||
|
||||
super.visit(node, data);
|
||||
return data;
|
||||
|
Reference in New Issue
Block a user