Added IllegalAbstractClassName check (request 750749).
This commit is contained in:
parent
5245c14883
commit
f06e7b12c3
|
|
@ -31,6 +31,9 @@
|
|||
<li>
|
||||
<a href="#HideUtilityClassConstructor">HideUtilityClassConstructor</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#IllegalAbstractClassName">IllegalAbstractClassName</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#InterfaceIsType">InterfaceIsType</a>
|
||||
</li>
|
||||
|
|
@ -346,6 +349,52 @@ public class StringUtils // not final to allow subclassing
|
|||
<a href="config.html#treewalker">TreeWalker</a>
|
||||
</p>
|
||||
|
||||
<!-- --> <a name="IllegalAbstractClassName"></a> <h2>IllegalAbstractClassName</h2>
|
||||
<h4>Description</h4>
|
||||
<p class="body">
|
||||
Ensures that the names of abstract classes conforming to some
|
||||
regular expression.
|
||||
</p>
|
||||
|
||||
<p class="body">
|
||||
Rationale:
|
||||
Abtsract classes are conevnience base class
|
||||
implementations of interfaces not types as such. As
|
||||
such they should be named to indicate this.
|
||||
</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>format</td>
|
||||
<td>pattern for abstract class name.</td>
|
||||
<td><a href="property_types.html#regexp">regular expression</a></td>
|
||||
<td><span class="default">^Abstract.*$|^.*Factory$</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<p class="body">
|
||||
To configure the check:
|
||||
</p>
|
||||
<pre class="body">
|
||||
<module name="IllegalAbstractClassName"/>
|
||||
</pre>
|
||||
<h4>Package</h4>
|
||||
<p class="body">
|
||||
com.puppycrawl.tools.checkstyle.checks.design
|
||||
</p>
|
||||
<h4>Parent Module</h4>
|
||||
<p class="body">
|
||||
<a href="config.html#treewalker">TreeWalker</a>
|
||||
</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@
|
|||
|
||||
<li class="body">Added MutableException check (request 750750).</li>
|
||||
|
||||
<li class="body">Added IllegalAbstractClassName check (request 750749).</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p class="body">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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.design;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
import com.puppycrawl.tools.checkstyle.checks.AbstractFormatCheck;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Ensures that the names of abstract classes conforming to some
|
||||
* regular expression.
|
||||
* </p>
|
||||
* <p>
|
||||
* Rationale: Abtsract classes are conevnience base class
|
||||
* implementations of interfaces not types as such. As such
|
||||
* they should be named to indicate this.
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
|
||||
*/
|
||||
public final class IllegalAbstractClassNameCheck extends AbstractFormatCheck
|
||||
{
|
||||
/** Defualt format for abstract class names */
|
||||
private static final String DEFAULT_FORMAT = "^Abstract.*$|^.*Factory$";
|
||||
|
||||
/** Creates new instance of the check. */
|
||||
public IllegalAbstractClassNameCheck()
|
||||
{
|
||||
super(DEFAULT_FORMAT);
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public int[] getDefaultTokens()
|
||||
{
|
||||
return new int[]{TokenTypes.CLASS_DEF};
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public int[] getRequiredTokens()
|
||||
{
|
||||
return getDefaultTokens();
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public void visitToken(DetailAST aAST)
|
||||
{
|
||||
switch (aAST.getType()) {
|
||||
case TokenTypes.CLASS_DEF:
|
||||
visitClassDef(aAST);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException(aAST.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks class definition.
|
||||
* @param aAST class definition for check.
|
||||
*/
|
||||
private void visitClassDef(DetailAST aAST)
|
||||
{
|
||||
if (isAbstract(aAST)) {
|
||||
String className = aAST.findFirstToken(TokenTypes.IDENT).getText();
|
||||
|
||||
if (!isMatchingClassName(className)) {
|
||||
log(aAST.getLineNo(), aAST.getColumnNo(),
|
||||
"illegal.abstract.class.name", className, getFormat());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aAST class definition for check.
|
||||
* @return true if a given class declared as abstract.
|
||||
*/
|
||||
private boolean isAbstract(DetailAST aAST)
|
||||
{
|
||||
final DetailAST abstractAST = aAST.findFirstToken(TokenTypes.MODIFIERS)
|
||||
.findFirstToken(TokenTypes.ABSTRACT);
|
||||
|
||||
return abstractAST != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aClassName class name for check.
|
||||
* @return true if class name matches format of abstract class names.
|
||||
*/
|
||||
private boolean isMatchingClassName(String aClassName)
|
||||
{
|
||||
return getRegexp().match(aClassName);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,3 +3,4 @@ final.class=Class {0} should be declared as final.
|
|||
interface.type=interfaces should describe a type and hence have methods.
|
||||
variable.notPrivate=Variable ''{0}'' must be private and have accessor methods.
|
||||
mutable.exception=The field ''{0}'' must be declared final.
|
||||
illegal.abstract.class.name=Name ''{0}'' must match pattern ''{1}''.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.puppycrawl.tools.checkstyle.checks.design;
|
||||
|
||||
abstract public class InputAbstractClassName {
|
||||
}
|
||||
|
||||
abstract class NonAbstractClassName {
|
||||
}
|
||||
|
||||
abstract class FactoryWithBadName {
|
||||
}
|
||||
|
||||
abstract class AbstractClassName {
|
||||
abstract class NonAbstractInnerClass {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ClassFactory {
|
||||
abstract class WellNamedFactory {
|
||||
}
|
||||
}
|
||||
|
||||
class NonAbstractClass {
|
||||
}
|
||||
|
|
@ -47,6 +47,7 @@ import com.puppycrawl.tools.checkstyle.checks.coding.SuperFinalizeCheckTest;
|
|||
import com.puppycrawl.tools.checkstyle.checks.design.DesignForExtensionCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.design.FinalClassCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.design.IllegalAbstractClassNameCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.design.InterfaceIsTypeCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.design.MutableExceptionCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.design.VisibilityModifierCheckTest;
|
||||
|
|
@ -144,6 +145,7 @@ public class AllTests {
|
|||
suite.addTest(new TestSuite(HeaderCheckTest.class));
|
||||
suite.addTest(new TestSuite(HiddenFieldCheckTest.class));
|
||||
suite.addTest(new TestSuite(HideUtilityClassConstructorCheckTest.class));
|
||||
suite.addTest(new TestSuite(IllegalAbstractClassNameCheckTest.class));
|
||||
suite.addTest(new TestSuite(IllegalCatchCheckTest.class));
|
||||
suite.addTest(new TestSuite(IllegalImportCheckTest.class));
|
||||
suite.addTest(new TestSuite(IllegalInstantiationCheckTest.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.puppycrawl.tools.checkstyle.checks.design;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.BaseCheckTestCase;
|
||||
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class IllegalAbstractClassNameCheckTest
|
||||
extends BaseCheckTestCase
|
||||
{
|
||||
public void testIllegalAbstractClassName() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(IllegalAbstractClassNameCheck.class);
|
||||
final String[] expected = {
|
||||
"3:1: Name 'InputAbstractClassName' must match pattern '^Abstract.*$|^.*Factory$'.",
|
||||
"6:1: Name 'NonAbstractClassName' must match pattern '^Abstract.*$|^.*Factory$'.",
|
||||
"9:1: Name 'FactoryWithBadName' must match pattern '^Abstract.*$|^.*Factory$'.",
|
||||
"13:5: Name 'NonAbstractInnerClass' must match pattern '^Abstract.*$|^.*Factory$'.",
|
||||
};
|
||||
verify(checkConfig, getPath("design" + File.separator + "InputAbstractClassName.java"), expected);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue