Issue #2451: removed excess hierarchy from CyclomaticComplexityCheck
This commit is contained in:
parent
69ccfd3fa9
commit
ed79281fff
1
pom.xml
1
pom.xml
|
|
@ -1719,6 +1719,7 @@
|
|||
<exclude>com/puppycrawl/tools/checkstyle/checks/coding/AbstractIllegalCheck.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/checks/coding/AbstractIllegalMethodCheck.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/checks/coding/AbstractNestedDepthCheck.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/checks/metrics/AbstractComplexityCheck.class</exclude>
|
||||
<exclude>com/puppycrawl/tools/checkstyle/checks/naming/AbstractTypeParameterNameCheck.class</exclude>
|
||||
</excludes>
|
||||
</instrumentation>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@
|
|||
package com.puppycrawl.tools.checkstyle.checks.metrics;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.Check;
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
|
||||
|
|
@ -43,7 +46,7 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
|||
* @author <a href="mailto:andreyselkin@gmail.com">Andrei Selkin</a>
|
||||
*/
|
||||
public class CyclomaticComplexityCheck
|
||||
extends AbstractComplexityCheck {
|
||||
extends Check {
|
||||
|
||||
/**
|
||||
* A key is pointing to the warning message text in "messages.properties"
|
||||
|
|
@ -51,16 +54,23 @@ public class CyclomaticComplexityCheck
|
|||
*/
|
||||
public static final String MSG_KEY = "cyclomaticComplexity";
|
||||
|
||||
/** The initial current value. */
|
||||
private static final BigInteger INITIAL_VALUE = BigInteger.ONE;
|
||||
|
||||
/** Default allowed complexity. */
|
||||
private static final int DEFAULT_VALUE = 10;
|
||||
private static final int DEFAULT_COMPLEXITY_VALUE = 10;
|
||||
|
||||
/** Whether to treat the whole switch block as a single decision point.*/
|
||||
private boolean switchBlockAsSingleDecisionPoint;
|
||||
|
||||
/** Create an instance. */
|
||||
public CyclomaticComplexityCheck() {
|
||||
super(DEFAULT_VALUE);
|
||||
}
|
||||
/** Stack of values - all but the current value. */
|
||||
private final Deque<BigInteger> valueStack = new ArrayDeque<>();
|
||||
|
||||
/** The current value. */
|
||||
private BigInteger currentValue = INITIAL_VALUE;
|
||||
|
||||
/** Threshold to report error for. */
|
||||
private int max = DEFAULT_COMPLEXITY_VALUE;
|
||||
|
||||
/**
|
||||
* Sets whether to treat the whole switch block as a single decision point.
|
||||
|
|
@ -71,6 +81,15 @@ public class CyclomaticComplexityCheck
|
|||
this.switchBlockAsSingleDecisionPoint = switchBlockAsSingleDecisionPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum threshold allowed.
|
||||
*
|
||||
* @param max the maximum threshold
|
||||
*/
|
||||
public final void setMax(int max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getDefaultTokens() {
|
||||
return new int[] {
|
||||
|
|
@ -112,6 +131,49 @@ public class CyclomaticComplexityCheck
|
|||
}
|
||||
|
||||
@Override
|
||||
public final int[] getRequiredTokens() {
|
||||
return new int[] {
|
||||
TokenTypes.CTOR_DEF,
|
||||
TokenTypes.METHOD_DEF,
|
||||
TokenTypes.INSTANCE_INIT,
|
||||
TokenTypes.STATIC_INIT,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitToken(DetailAST ast) {
|
||||
switch (ast.getType()) {
|
||||
case TokenTypes.CTOR_DEF:
|
||||
case TokenTypes.METHOD_DEF:
|
||||
case TokenTypes.INSTANCE_INIT:
|
||||
case TokenTypes.STATIC_INIT:
|
||||
visitMethodDef();
|
||||
break;
|
||||
default:
|
||||
visitTokenHook(ast);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leaveToken(DetailAST ast) {
|
||||
switch (ast.getType()) {
|
||||
case TokenTypes.CTOR_DEF:
|
||||
case TokenTypes.METHOD_DEF:
|
||||
case TokenTypes.INSTANCE_INIT:
|
||||
case TokenTypes.STATIC_INIT:
|
||||
leaveMethodDef(ast);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called when visiting a token. Will not be called the method
|
||||
* definition tokens.
|
||||
*
|
||||
* @param ast the token being visited
|
||||
*/
|
||||
protected final void visitTokenHook(DetailAST ast) {
|
||||
if (switchBlockAsSingleDecisionPoint) {
|
||||
if (ast.getType() != TokenTypes.LITERAL_CASE) {
|
||||
|
|
@ -123,13 +185,45 @@ public class CyclomaticComplexityCheck
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final String getMessageID() {
|
||||
return MSG_KEY;
|
||||
/**
|
||||
* Process the end of a method definition.
|
||||
*
|
||||
* @param ast the token representing the method definition
|
||||
*/
|
||||
private void leaveMethodDef(DetailAST ast) {
|
||||
final BigInteger bigIntegerMax = BigInteger.valueOf(max);
|
||||
if (currentValue.compareTo(bigIntegerMax) > 0) {
|
||||
log(ast, MSG_KEY, currentValue, bigIntegerMax);
|
||||
}
|
||||
popValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void leaveTokenHook(DetailAST ast) {
|
||||
// no code
|
||||
/**
|
||||
* Increments the current value by a specified amount.
|
||||
*
|
||||
* @param by the amount to increment by
|
||||
*/
|
||||
protected final void incrementCurrentValue(BigInteger by) {
|
||||
currentValue = currentValue.add(by);
|
||||
}
|
||||
|
||||
/** Push the current value on the stack. */
|
||||
protected final void pushValue() {
|
||||
valueStack.push(currentValue);
|
||||
currentValue = INITIAL_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops a value off the stack and makes it the current value.
|
||||
* @return pop a value off the stack and make it the current value
|
||||
*/
|
||||
protected final BigInteger popValue() {
|
||||
currentValue = valueStack.pop();
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
/** Process the start of the method definition. */
|
||||
private void visitMethodDef() {
|
||||
pushValue();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import static com.puppycrawl.tools.checkstyle.checks.metrics.CyclomaticComplexit
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
@ -113,4 +114,14 @@ public class CyclomaticComplexityCheckTest
|
|||
};
|
||||
Assert.assertArrayEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHighMax() throws Exception {
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(CyclomaticComplexityCheck.class);
|
||||
checkConfig.addAttribute("max", "100");
|
||||
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
|
||||
|
||||
verify(checkConfig, getPath("InputComplexitySwitchBlocks.java"), expected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue