Added ExecutableStatementCount check from Simon Harris (request 750751).
This commit is contained in:
parent
24c00273b2
commit
b8f9b199ad
|
|
@ -24,6 +24,9 @@
|
|||
<ul>
|
||||
<li>
|
||||
<a href="#CyclomaticComplexity">CyclomaticComplexity</a>
|
||||
<li>
|
||||
<a href="#ExecutableStatementCount">ExecutableStatementCount</a>
|
||||
</li>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
|
@ -96,6 +99,76 @@ considered good, 5-7 ok, 8-10 consider re-factoring, and 11+ re-factor now!
|
|||
</p>
|
||||
|
||||
|
||||
<!-- --><a name="ExecutableStatementCount"></a> <h2>ExecutableStatementCount</h2>
|
||||
<h4>Description</h4>
|
||||
|
||||
<p class="body">
|
||||
Restricts the number of executable statements to a specified limit.
|
||||
</p>
|
||||
|
||||
|
||||
<h4>Properties</h4>
|
||||
<table width="100%" border="1" cellpadding="5" class="body">
|
||||
<tr class="header">
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
<th>type</th>
|
||||
<th>default value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max</td>
|
||||
<td>the maximum threshold allowed</td>
|
||||
<td><a href="property_types.html#integer">integer</a></td>
|
||||
<td><span class="default">30</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>tokens</td>
|
||||
<td>members to check</td>
|
||||
|
||||
<td>subset of tokens <a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#CTOR_DEF">CTOR_DEF</a>,
|
||||
<a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#METHOD_DEF">METHOD_DEF</a>,
|
||||
<a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#INSTANCE_INIT">INSTANCE_INIT</a>,
|
||||
<a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#STATIC_INIT">STATIC_INIT</a>
|
||||
</td>
|
||||
|
||||
<td>all tokens</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<p class="body">
|
||||
To configure the check:
|
||||
</p>
|
||||
<pre class="body">
|
||||
<module name="ExecutableStatementCount"/>
|
||||
</pre>
|
||||
<p class="body">
|
||||
To configure the check with a threshold of 20 for constructor and
|
||||
method definitions:
|
||||
</p>
|
||||
<pre class="body">
|
||||
<module name="ExecutableStatementCount">
|
||||
<property name="max" value="20"/>
|
||||
<property name="tokens" value="CTOR_DEF,METHOD_DEF"/>
|
||||
</module>
|
||||
|
||||
</pre>
|
||||
|
||||
<h4>Package</h4>
|
||||
<p class="body">
|
||||
com.puppycrawl.tools.checkstyle.checks.metrics
|
||||
</p>
|
||||
|
||||
<h4>Parent Module</h4>
|
||||
<p class="body">
|
||||
<a href="config.html#treewalker">TreeWalker</a>
|
||||
</p>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@
|
|||
|
||||
<li class="body">Added ReturnCount check from Simon Harris (request 750745).</li>
|
||||
|
||||
<li class="body">Added CyclomaticComplexity check from Simon Harris (request 750756).</li>
|
||||
|
||||
<li class="body">Added ExecutableStatementCount check from Simon Harris (request 750751).</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p class="body">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,205 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2003 Oliver Burn
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle.checks.metrics;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.Check;
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
|
||||
/**
|
||||
* Restricts the number of executable statements to a specified limit
|
||||
* (default = 30).
|
||||
* @author Simon Harris
|
||||
*/
|
||||
public final class ExecutableStatementCountCheck
|
||||
extends Check
|
||||
{
|
||||
/** default threshold */
|
||||
private static final int DEFAULT_MAX = 30;
|
||||
|
||||
/** threshold to report error for */
|
||||
private int mMax;
|
||||
|
||||
/** Stack of method contexts. */
|
||||
private final Stack mContextStack = new Stack();
|
||||
|
||||
/** Current method context. */
|
||||
private Context mContext;
|
||||
|
||||
/** Constructs a <code>ExecutableStatementCountCheck</code>. */
|
||||
public ExecutableStatementCountCheck()
|
||||
{
|
||||
setMax(DEFAULT_MAX);
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check#getDefaultTokens() */
|
||||
public int[] getDefaultTokens()
|
||||
{
|
||||
return new int[] {
|
||||
TokenTypes.CTOR_DEF,
|
||||
TokenTypes.METHOD_DEF,
|
||||
TokenTypes.INSTANCE_INIT,
|
||||
TokenTypes.STATIC_INIT,
|
||||
TokenTypes.SLIST,
|
||||
};
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check#getRequiredTokens() */
|
||||
public int[] getRequiredTokens()
|
||||
{
|
||||
return new int[] {TokenTypes.SLIST};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum threshold.
|
||||
* @return the maximum threshold.
|
||||
*/
|
||||
public int getMax()
|
||||
{
|
||||
return mMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum threshold.
|
||||
* @param aMax the maximum threshold.
|
||||
*/
|
||||
public void setMax(int aMax)
|
||||
{
|
||||
mMax = aMax;
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public void beginTree(DetailAST aRootAST)
|
||||
{
|
||||
mContext = null;
|
||||
mContextStack.clear();
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public void visitToken(DetailAST aAST)
|
||||
{
|
||||
switch (aAST.getType()) {
|
||||
case TokenTypes.CTOR_DEF:
|
||||
case TokenTypes.METHOD_DEF:
|
||||
case TokenTypes.INSTANCE_INIT:
|
||||
case TokenTypes.STATIC_INIT:
|
||||
visitMethodDef();
|
||||
break;
|
||||
case TokenTypes.SLIST:
|
||||
visitSlist(aAST);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException(aAST.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public void leaveToken(DetailAST aAST)
|
||||
{
|
||||
switch (aAST.getType()) {
|
||||
case TokenTypes.CTOR_DEF:
|
||||
case TokenTypes.METHOD_DEF:
|
||||
case TokenTypes.INSTANCE_INIT:
|
||||
case TokenTypes.STATIC_INIT:
|
||||
leaveMethodDef(aAST);
|
||||
break;
|
||||
case TokenTypes.SLIST:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException(aAST.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/** Process the start of the method definition. */
|
||||
private void visitMethodDef()
|
||||
{
|
||||
mContextStack.push(mContext);
|
||||
mContext = new Context();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the end of a method definition.
|
||||
*
|
||||
* @param aAST the token representing the method definition.
|
||||
*/
|
||||
private void leaveMethodDef(DetailAST aAST)
|
||||
{
|
||||
final int count = mContext.getCount();
|
||||
if (count > getMax()) {
|
||||
log(
|
||||
aAST.getLineNo(),
|
||||
aAST.getColumnNo(),
|
||||
"executableStatementCount",
|
||||
new Integer(count),
|
||||
new Integer(getMax()));
|
||||
}
|
||||
mContext = (Context) mContextStack.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the end of a statement list.
|
||||
*
|
||||
* @param aAST the token representing the statement list.
|
||||
*/
|
||||
private void visitSlist(DetailAST aAST)
|
||||
{
|
||||
if (mContext != null) {
|
||||
mContext.addCount(aAST.getChildCount() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to encapsulate counting information about one member.
|
||||
* @author Simon Harris
|
||||
*/
|
||||
private class Context
|
||||
{
|
||||
/** Counter for context elements. */
|
||||
private int mCount;
|
||||
|
||||
/**
|
||||
* Creates new method context.
|
||||
*/
|
||||
public Context()
|
||||
{
|
||||
mCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase count.
|
||||
* @param aCount the count increment.
|
||||
*/
|
||||
public void addCount(int aCount)
|
||||
{
|
||||
mCount += aCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the count.
|
||||
* @return the count.
|
||||
*/
|
||||
public int getCount()
|
||||
{
|
||||
return mCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -73,6 +73,7 @@ import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheckTest;
|
|||
import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.javadoc.PackageHtmlCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.metrics.CyclomaticComplexityCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.metrics.ExecutableStatementCountCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.naming.AbstractClassNameCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.naming.ConstantNameCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.naming.LocalFinalVariableNameCheckTest;
|
||||
|
|
@ -196,6 +197,7 @@ public class AllTests {
|
|||
suite.addTest(new TestSuite(RightCurlyCheckTest.class));
|
||||
suite.addTest(new TestSuite(SimplifyBooleanExpressionCheckTest.class));
|
||||
suite.addTest(new TestSuite(SimplifyBooleanReturnCheckTest.class));
|
||||
suite.addTest(new TestSuite(ExecutableStatementCountCheckTest.class));
|
||||
suite.addTest(new TestSuite(StaticVariableNameCheckTest.class));
|
||||
suite.addTest(new TestSuite(StringArrayReaderTest.class));
|
||||
suite.addTest(new TestSuite(StringLiteralEqualityCheckTest.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
package com.puppycrawl.tools.checkstyle.checks.metrics;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.BaseCheckTestCase;
|
||||
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
|
||||
|
||||
public class ExecutableStatementCountCheckTest
|
||||
extends BaseCheckTestCase
|
||||
{
|
||||
public void testMaxZero() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(ExecutableStatementCountCheck.class);
|
||||
|
||||
checkConfig.addAttribute("max", "0");
|
||||
|
||||
final String[] expected = {
|
||||
"4:5: Executable statement count is 3 (max allowed is 0).",
|
||||
"7:17: Executable statement count is 1 (max allowed is 0).",
|
||||
"17:5: Executable statement count is 2 (max allowed is 0).",
|
||||
"27:5: Executable statement count is 1 (max allowed is 0).",
|
||||
"34:5: Executable statement count is 3 (max allowed is 0).",
|
||||
"48:5: Executable statement count is 2 (max allowed is 0).",
|
||||
"58:5: Executable statement count is 2 (max allowed is 0).",
|
||||
"67:5: Executable statement count is 2 (max allowed is 0).",
|
||||
};
|
||||
|
||||
verify(checkConfig, getPath("ComplexityCheckTestInput.java"), expected);
|
||||
}
|
||||
|
||||
public void testMethodDef() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(ExecutableStatementCountCheck.class);
|
||||
|
||||
checkConfig.addAttribute("max", "0");
|
||||
checkConfig.addAttribute("tokens", "METHOD_DEF");
|
||||
|
||||
final String[] expected = {
|
||||
"4:5: Executable statement count is 3 (max allowed is 0).",
|
||||
"7:17: Executable statement count is 1 (max allowed is 0).",
|
||||
"17:5: Executable statement count is 2 (max allowed is 0).",
|
||||
"27:5: Executable statement count is 1 (max allowed is 0).",
|
||||
"34:5: Executable statement count is 3 (max allowed is 0).",
|
||||
};
|
||||
|
||||
verify(checkConfig, getPath("ComplexityCheckTestInput.java"), expected);
|
||||
}
|
||||
|
||||
public void testCtorDef() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(ExecutableStatementCountCheck.class);
|
||||
|
||||
checkConfig.addAttribute("max", "0");
|
||||
checkConfig.addAttribute("tokens", "CTOR_DEF");
|
||||
|
||||
final String[] expected = {
|
||||
"48:5: Executable statement count is 2 (max allowed is 0).",
|
||||
};
|
||||
|
||||
verify(checkConfig, getPath("ComplexityCheckTestInput.java"), expected);
|
||||
}
|
||||
|
||||
public void testStaticInit() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(ExecutableStatementCountCheck.class);
|
||||
|
||||
checkConfig.addAttribute("max", "0");
|
||||
checkConfig.addAttribute("tokens", "STATIC_INIT");
|
||||
|
||||
final String[] expected = {
|
||||
"58:5: Executable statement count is 2 (max allowed is 0).",
|
||||
};
|
||||
|
||||
verify(checkConfig, getPath("ComplexityCheckTestInput.java"), expected);
|
||||
}
|
||||
|
||||
public void testInstanceInit() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(ExecutableStatementCountCheck.class);
|
||||
|
||||
checkConfig.addAttribute("max", "0");
|
||||
checkConfig.addAttribute("tokens", "INSTANCE_INIT");
|
||||
|
||||
final String[] expected = {
|
||||
"67:5: Executable statement count is 2 (max allowed is 0).",
|
||||
};
|
||||
|
||||
verify(checkConfig, getPath("ComplexityCheckTestInput.java"), expected);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue