Merge branch 'pr-1505'

This commit is contained in:
Andreas Dangel
2018-12-08 10:50:32 +01:00
21 changed files with 218 additions and 93 deletions

View File

@ -4,9 +4,9 @@
package net.sourceforge.pmd.lang.java.rule.bestpractices;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -16,10 +16,14 @@ import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.properties.EnumeratedMultiProperty;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
public class AvoidUsingHardCodedIPRule extends AbstractJavaRule {
// why is everything public?
public static final String IPV4 = "IPv4";
public static final String IPV6 = "IPv6";
public static final String IPV4_MAPPED_IPV6 = "IPv4 mapped IPv6";
@ -35,10 +39,10 @@ public class AvoidUsingHardCodedIPRule extends AbstractJavaRule {
}
public static final EnumeratedMultiProperty<String> CHECK_ADDRESS_TYPES_DESCRIPTOR = new EnumeratedMultiProperty<>(
"checkAddressTypes", "Check for IP address types.", ADDRESSES_TO_CHECK,
Arrays.asList(IPV4, IPV6, IPV4_MAPPED_IPV6),
String.class, 2.0f);
public static final PropertyDescriptor<List<String>> CHECK_ADDRESS_TYPES_DESCRIPTOR =
PropertyFactory.enumListProperty("checkAddressTypes", ADDRESSES_TO_CHECK)
.desc("Check for IP address types.")
.defaultValue(ADDRESSES_TO_CHECK.keySet()).build();
// Provides 4 capture groups that can be used for additional validation
protected static final String IPV4_REGEXP = "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})";

View File

@ -6,8 +6,8 @@ package net.sourceforge.pmd.lang.java.rule.design;
import static net.sourceforge.pmd.properties.constraints.NumericConstraints.positive;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
@ -22,7 +22,6 @@ import net.sourceforge.pmd.lang.java.metrics.impl.CycloMetric.CycloOption;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaMetricsRule;
import net.sourceforge.pmd.lang.metrics.MetricOptions;
import net.sourceforge.pmd.lang.metrics.ResultOption;
import net.sourceforge.pmd.properties.EnumeratedMultiProperty;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
@ -63,13 +62,13 @@ public class CyclomaticComplexityRule extends AbstractJavaMetricsRule {
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
= EnumeratedMultiProperty.<CycloOption>named("cycloOptions").type(CycloOption.class)
.desc("Choose options for the computation of Cyclo")
.mappings(OPTION_MAP)
.defaultValues(Collections.<CycloOption>emptyList())
.uiOrder(3.0f).build();
private static final PropertyDescriptor<List<CycloOption>> CYCLO_OPTIONS_DESCRIPTOR
= PropertyFactory.enumListProperty("cycloOptions", OPTION_MAP)
.desc("Choose options for the computation of Cyclo")
.emptyDefaultValue()
.build();
private int methodReportLevel;
private int classReportLevel;
private MetricOptions cycloOptions;

View File

@ -6,8 +6,8 @@ package net.sourceforge.pmd.lang.java.rule.design;
import static net.sourceforge.pmd.properties.constraints.NumericConstraints.positive;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -22,7 +22,6 @@ import net.sourceforge.pmd.lang.java.metrics.impl.NcssMetric.NcssOption;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaMetricsRule;
import net.sourceforge.pmd.lang.metrics.MetricOptions;
import net.sourceforge.pmd.lang.metrics.ResultOption;
import net.sourceforge.pmd.properties.EnumeratedMultiProperty;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
@ -58,9 +57,11 @@ public final class NcssCountRule extends AbstractJavaMetricsRule {
}
private static final EnumeratedMultiProperty<NcssOption> NCSS_OPTIONS_DESCRIPTOR = new EnumeratedMultiProperty<>(
"ncssOptions", "Choose options for the calculation of Ncss",
OPTION_MAP, Collections.<NcssOption>emptyList(), NcssOption.class, 3.0f);
private static final PropertyDescriptor<List<NcssOption>> NCSS_OPTIONS_DESCRIPTOR =
PropertyFactory.enumListProperty("ncssOptions", OPTION_MAP)
.desc("Choose options for the computation of Cyclo")
.emptyDefaultValue()
.build();
private int methodReportLevel;

View File

@ -23,8 +23,9 @@ import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaAccessNode;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaNode;
import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature;
import net.sourceforge.pmd.properties.EnumeratedProperty;
import net.sourceforge.pmd.properties.EnumeratedProperty.EnumPBuilder;
import net.sourceforge.pmd.properties.PropertyBuilder.GenericPropertyBuilder;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
/**
@ -36,27 +37,25 @@ public class CommentRequiredRule extends AbstractCommentRule {
private static final Map<String, String> DESCRIPTOR_NAME_TO_COMMENT_TYPE = new HashMap<>();
private static final EnumeratedProperty<CommentRequirement> ACCESSOR_CMT_DESCRIPTOR
private static final PropertyDescriptor<CommentRequirement> ACCESSOR_CMT_DESCRIPTOR
= requirementPropertyBuilder("accessorCommentRequirement", "Comments on getters and setters\"")
.defaultValue(CommentRequirement.Ignored).build();
private static final EnumeratedProperty<CommentRequirement> OVERRIDE_CMT_DESCRIPTOR
private static final PropertyDescriptor<CommentRequirement> OVERRIDE_CMT_DESCRIPTOR
= requirementPropertyBuilder("methodWithOverrideCommentRequirement", "Comments on @Override methods")
.defaultValue(CommentRequirement.Ignored).build();
private static final EnumeratedProperty<CommentRequirement> HEADER_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("headerCommentRequirement", "Header comments").uiOrder(1.0f).build();
private static final EnumeratedProperty<CommentRequirement> FIELD_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("fieldCommentRequirement", "Field comments").uiOrder(2.0f).build();
private static final EnumeratedProperty<CommentRequirement> PUB_METHOD_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("publicMethodCommentRequirement", "Public method and constructor comments")
.uiOrder(3.0f).build();
private static final EnumeratedProperty<CommentRequirement> PROT_METHOD_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("protectedMethodCommentRequirement", "Protected method constructor comments")
.uiOrder(4.0f).build();
private static final EnumeratedProperty<CommentRequirement> ENUM_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("enumCommentRequirement", "Enum comments").uiOrder(5.0f).build();
private static final EnumeratedProperty<CommentRequirement> SERIAL_VERSION_UID_CMT_REQUIREMENT_DESCRIPTOR
private static final PropertyDescriptor<CommentRequirement> HEADER_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("headerCommentRequirement", "Header comments").build();
private static final PropertyDescriptor<CommentRequirement> FIELD_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("fieldCommentRequirement", "Field comments").build();
private static final PropertyDescriptor<CommentRequirement> PUB_METHOD_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("publicMethodCommentRequirement", "Public method and constructor comments").build();
private static final PropertyDescriptor<CommentRequirement> PROT_METHOD_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("protectedMethodCommentRequirement", "Protected method constructor comments").build();
private static final PropertyDescriptor<CommentRequirement> ENUM_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("enumCommentRequirement", "Enum comments").build();
private static final PropertyDescriptor<CommentRequirement> SERIAL_VERSION_UID_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("serialVersionUIDCommentRequired", "Serial version UID comments")
.defaultValue(CommentRequirement.Ignored).uiOrder(6.0f).build();
.defaultValue(CommentRequirement.Ignored).build();
public CommentRequiredRule() {
@ -72,7 +71,7 @@ public class CommentRequiredRule extends AbstractCommentRule {
private void checkCommentMeetsRequirement(Object data, AbstractJavaNode node,
EnumeratedProperty<CommentRequirement> descriptor) {
PropertyDescriptor<CommentRequirement> descriptor) {
switch (getProperty(descriptor)) {
case Ignored:
break;
@ -94,7 +93,7 @@ public class CommentRequiredRule extends AbstractCommentRule {
// Adds a violation
private void commentRequiredViolation(Object data, AbstractJavaNode node,
EnumeratedProperty<CommentRequirement> descriptor) {
PropertyDescriptor<CommentRequirement> descriptor) {
addViolationWithMessage(data, node,
@ -242,12 +241,10 @@ public class CommentRequiredRule extends AbstractCommentRule {
// pre-filled builder
private static EnumPBuilder<CommentRequirement> requirementPropertyBuilder(String name, String commentType) {
private static GenericPropertyBuilder<CommentRequirement> requirementPropertyBuilder(String name, String commentType) {
DESCRIPTOR_NAME_TO_COMMENT_TYPE.put(name, commentType);
return EnumeratedProperty.<CommentRequirement>named(name)
return PropertyFactory.enumProperty(name, CommentRequirement.mappings())
.desc(commentType + ". Possible values: " + CommentRequirement.labels())
.mappings(CommentRequirement.mappings())
.defaultValue(CommentRequirement.Required)
.type(CommentRequirement.class);
.defaultValue(CommentRequirement.Required);
}
}

View File

@ -10,6 +10,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTBreakStatement;
import net.sourceforge.pmd.lang.java.ast.ASTContinueStatement;
@ -19,7 +21,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.properties.EnumeratedMultiProperty;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
import net.sourceforge.pmd.properties.PropertySource;
public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRule {
@ -39,15 +42,14 @@ public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRule {
LOOP_TYPES_MAPPINGS = Collections.unmodifiableMap(mappings);
}
public static final EnumeratedMultiProperty<String> CHECK_BREAK_LOOP_TYPES = new EnumeratedMultiProperty<>(
"checkBreakLoopTypes", "Check for break statements in loop types", LOOP_TYPES_MAPPINGS, DEFAULTS,
String.class, 1);
public static final EnumeratedMultiProperty<String> CHECK_CONTINUE_LOOP_TYPES = new EnumeratedMultiProperty<>(
"checkContinueLoopTypes", "Check for continue statements in loop types", LOOP_TYPES_MAPPINGS, DEFAULTS,
String.class, 2);
public static final EnumeratedMultiProperty<String> CHECK_RETURN_LOOP_TYPES = new EnumeratedMultiProperty<>(
"checkReturnLoopTypes", "Check for return statements in loop types", LOOP_TYPES_MAPPINGS, DEFAULTS,
String.class, 3);
// TODO I don't think we need this configurability.
// I think we should tone that down to just be able to ignore some type of statement,
// but I can't see a use case to e.g. report only breaks in 'for' loops but not in 'while'.
public static final PropertyDescriptor<List<String>> CHECK_BREAK_LOOP_TYPES = propertyFor("break");
public static final PropertyDescriptor<List<String>> CHECK_CONTINUE_LOOP_TYPES = propertyFor("continue");
public static final PropertyDescriptor<List<String>> CHECK_RETURN_LOOP_TYPES = propertyFor("return");
public AvoidBranchingStatementAsLastInLoopRule() {
@ -71,7 +73,7 @@ public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRule {
}
protected Object check(EnumeratedMultiProperty<String> property, Node node, Object data) {
protected Object check(PropertyDescriptor<List<String>> property, Node node, Object data) {
Node parent = node.getNthParent(5);
if (parent instanceof ASTForStatement) {
if (hasPropertyValue(property, CHECK_FOR)) {
@ -90,7 +92,7 @@ public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRule {
}
protected boolean hasPropertyValue(EnumeratedMultiProperty<String> property, String value) {
protected boolean hasPropertyValue(PropertyDescriptor<List<String>> property, String value) {
return getProperty(property).contains(value);
}
@ -115,6 +117,12 @@ public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRule {
return checksNothing() ? "All loop types are ignored" : null;
}
private static PropertyDescriptor<List<String>> propertyFor(String stmtName) {
return PropertyFactory.enumListProperty("check" + StringUtils.capitalize(stmtName) + "LoopTypes", LOOP_TYPES_MAPPINGS)
.desc("List of loop types in which " + stmtName + " statements will be checked")
.defaultValue(DEFAULTS)
.build();
}
public boolean checksNothing() {

View File

@ -4,8 +4,8 @@
package net.sourceforge.pmd.lang.java.metrics.impl;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -19,8 +19,6 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaMetricsRule;
import net.sourceforge.pmd.lang.metrics.MetricOption;
import net.sourceforge.pmd.lang.metrics.MetricOptions;
import net.sourceforge.pmd.lang.metrics.ResultOption;
import net.sourceforge.pmd.properties.BooleanProperty;
import net.sourceforge.pmd.properties.EnumeratedMultiProperty;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
@ -33,15 +31,26 @@ import net.sourceforge.pmd.properties.PropertyFactory;
*/
public abstract class AbstractMetricTestRule extends AbstractJavaMetricsRule {
private final EnumeratedMultiProperty<MetricOption> optionsDescriptor = new EnumeratedMultiProperty<>(
"metricOptions", "Choose a variant of the metric or the standard",
optionMappings(), Collections.<MetricOption>emptyList(), MetricOption.class, 3.0f);
private final BooleanProperty reportClassesDescriptor = new BooleanProperty(
"reportClasses", "Add class violations to the report", isReportClasses(), 2.0f);
private final BooleanProperty reportMethodsDescriptor = new BooleanProperty(
"reportMethods", "Add method violations to the report", isReportMethods(), 3.0f);
private final PropertyDescriptor<List<MetricOption>> optionsDescriptor =
PropertyFactory.enumListProperty("metricOptions", optionMappings())
.desc("Choose a variant of the metric or the standard")
.emptyDefaultValue().build();
private final PropertyDescriptor<Boolean> reportClassesDescriptor =
PropertyFactory.booleanProperty("reportClasses")
.desc("Add class violations to the report")
.defaultValue(isReportClasses()).build();
private final PropertyDescriptor<Boolean> reportMethodsDescriptor =
PropertyFactory.booleanProperty("reportMethods")
.desc("Add method violations to the report")
.defaultValue(isReportMethods()).build();
private final PropertyDescriptor<Double> reportLevelDescriptor =
PropertyFactory.doubleProperty("reportLevel").desc("Minimum value required to report").defaultValue(defaultReportLevel()).build();
PropertyFactory.doubleProperty("reportLevel")
.desc("Minimum value required to report")
.defaultValue(defaultReportLevel()).build();
private MetricOptions metricOptions;
private boolean reportClasses;