bug-750348: added check for typecast parens. Involved
a bit of refactoring.
This commit is contained in:
parent
75a289111e
commit
99ed7a7d2c
|
|
@ -88,6 +88,7 @@
|
|||
</module>
|
||||
<module name="ParameterNumber"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="RedundantImport"/>
|
||||
<module name="RedundantModifier"/>
|
||||
<module name="RightCurly">
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@
|
|||
<li>
|
||||
<a href="#ParenPad">ParenPad</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#TypecastParenPad">TypecastParenPad</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#TabCharacter">TabCharacter</a>
|
||||
</li>
|
||||
|
|
@ -427,6 +430,8 @@
|
|||
<p class="body">
|
||||
<a href="config.html#treewalker">TreeWalker</a>
|
||||
</p>
|
||||
|
||||
|
||||
<a name="ParenPad"></a> <h2>ParenPad</h2> <h4>Description</h4>
|
||||
|
||||
<p class="body">
|
||||
|
|
@ -505,6 +510,73 @@
|
|||
<a href="config.html#treewalker">TreeWalker</a>
|
||||
</p>
|
||||
|
||||
<a name="TypecastParenPad"></a>
|
||||
<h2>TypecastParenPad</h2>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
<p class="body"> Checks the policy on the padding of parentheses for
|
||||
typecasts. That is, whether a space is required after a left parenthesis
|
||||
and before a right parenthesis, or such spaces are forbidden. </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>option</td>
|
||||
<td>policy on how to pad parentheses</td>
|
||||
<td><a href="property_types.html#parenPad">pad policy</a></td>
|
||||
<td><span class="default">nospace</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tokens</td>
|
||||
<td>tokens to check</td>
|
||||
|
||||
<td>Must have tokens
|
||||
<a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#TYPECAST">TYPECAST</a>,
|
||||
<a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#RPAREN">RPAREN</a>
|
||||
|
||||
<td><a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#TYPECAST">TYPECAST</a>,
|
||||
<a
|
||||
href="api/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#RPAREN">RPAREN</a>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<p class="body">
|
||||
To configure the check:
|
||||
</p>
|
||||
<pre class="body">
|
||||
<module name="TypecastParenPad"/>
|
||||
</pre>
|
||||
<p class="body">
|
||||
To configure the check to require spaces:
|
||||
</p>
|
||||
<pre class="body">
|
||||
<module name="TypecastParenPad">
|
||||
<property name="option" value="space"/>
|
||||
</module>
|
||||
</pre>
|
||||
<h4>Package</h4>
|
||||
<p class="body">
|
||||
com.puppycrawl.tools.checkstyle.checks.whitespace
|
||||
</p>
|
||||
|
||||
<h4>Parent Module</h4>
|
||||
<p class="body">
|
||||
<a href="config.html#treewalker">TreeWalker</a>
|
||||
</p>
|
||||
|
||||
|
||||
<a name="TabCharacter"></a> <h2>TabCharacter</h2> <h4>Description</h4>
|
||||
|
||||
<p class="body">
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@
|
|||
not exceed a certain length (module AnonInnerLength,
|
||||
request 715709, contributed by Rob Worth).</li>
|
||||
|
||||
<li class="body">Added TypecastParenPadCheck to check the padding of
|
||||
typecasts (bug 750348).</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p class="body">
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@
|
|||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="TabCharacter"/>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround"/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2002 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.whitespace;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
|
||||
|
||||
/**
|
||||
* <p>Abstract class for checking the padding of parentheses. That is whether a
|
||||
* space is required after a left parenthesis and before a right parenthesis,
|
||||
* or such spaces are forbidden.
|
||||
* </p>
|
||||
* @author Oliver Burn
|
||||
* @version 1.0
|
||||
*/
|
||||
abstract class AbstractParenPadCheck
|
||||
extends AbstractOptionCheck
|
||||
{
|
||||
/**
|
||||
* Sets the paren pad otion to nospace.
|
||||
*/
|
||||
AbstractParenPadCheck()
|
||||
{
|
||||
super(PadOption.NOSPACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a token representing a left parentheses.
|
||||
* @param aAST the token representing a left parentheses
|
||||
*/
|
||||
protected void processLeft(DetailAST aAST)
|
||||
{
|
||||
final String line = getLines()[aAST.getLineNo() - 1];
|
||||
final int after = aAST.getColumnNo() + 1;
|
||||
if (after < line.length()) {
|
||||
if ((PadOption.NOSPACE == getAbstractOption())
|
||||
&& (Character.isWhitespace(line.charAt(after))))
|
||||
{
|
||||
log(aAST.getLineNo(), after, "ws.followed", "(");
|
||||
}
|
||||
else if ((PadOption.SPACE == getAbstractOption())
|
||||
&& !Character.isWhitespace(line.charAt(after))
|
||||
&& (line.charAt(after) != ')'))
|
||||
{
|
||||
log(aAST.getLineNo(), after, "ws.notFollowed", "(");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a token representing a right parentheses.
|
||||
* @param aAST the token representing a right parentheses
|
||||
*/
|
||||
protected void processRight(DetailAST aAST)
|
||||
{
|
||||
final String line = getLines()[aAST.getLineNo() - 1];
|
||||
final int before = aAST.getColumnNo() - 1;
|
||||
if (before >= 0) {
|
||||
if ((PadOption.NOSPACE == getAbstractOption())
|
||||
&& Character.isWhitespace(line.charAt(before))
|
||||
&& !Utils.whitespaceBefore(before, line))
|
||||
{
|
||||
log(aAST.getLineNo(), before, "ws.preceeded", ")");
|
||||
}
|
||||
else if ((PadOption.SPACE == getAbstractOption())
|
||||
&& !Character.isWhitespace(line.charAt(before))
|
||||
&& (line.charAt(before) != '('))
|
||||
{
|
||||
log(aAST.getLineNo(), aAST.getColumnNo(),
|
||||
"ws.notPreceeded", ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,8 +21,6 @@ package com.puppycrawl.tools.checkstyle.checks.whitespace;
|
|||
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
|
||||
|
||||
/**
|
||||
* <p>Checks the padding of parentheses; that is whether a space is required
|
||||
|
|
@ -65,16 +63,8 @@ import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
|
|||
* @version 1.0
|
||||
*/
|
||||
public class ParenPadCheck
|
||||
extends AbstractOptionCheck
|
||||
extends AbstractParenPadCheck
|
||||
{
|
||||
/**
|
||||
* Sets the paren pad otion to nospace.
|
||||
*/
|
||||
public ParenPadCheck()
|
||||
{
|
||||
super(PadOption.NOSPACE);
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public int[] getDefaultTokens()
|
||||
{
|
||||
|
|
@ -97,68 +87,28 @@ public class ParenPadCheck
|
|||
else if ((aAST.getParent() == null)
|
||||
|| (aAST.getParent().getType() != TokenTypes.TYPECAST))
|
||||
{
|
||||
processRight(aAST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a token representing a left parentheses.
|
||||
* @param aAST the token representing a left parentheses
|
||||
*/
|
||||
private void processLeft(DetailAST aAST)
|
||||
{
|
||||
final String line = getLines()[aAST.getLineNo() - 1];
|
||||
final int after = aAST.getColumnNo() + 1;
|
||||
if (after < line.length()) {
|
||||
if ((PadOption.NOSPACE == getAbstractOption())
|
||||
&& (Character.isWhitespace(line.charAt(after))))
|
||||
{
|
||||
log(aAST.getLineNo(), after, "ws.followed", "(");
|
||||
}
|
||||
else if ((PadOption.SPACE == getAbstractOption())
|
||||
&& !Character.isWhitespace(line.charAt(after))
|
||||
&& (line.charAt(after) != ')'))
|
||||
{
|
||||
log(aAST.getLineNo(), after, "ws.notFollowed", "(");
|
||||
if (!isFollowsEmptyForIterator(aAST)) {
|
||||
processRight(aAST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a token representing a right parentheses.
|
||||
* @param aAST the token representing a right parentheses
|
||||
* @param aAST the token to check
|
||||
* @return whether a token follows an empty for iterator
|
||||
*/
|
||||
private void processRight(DetailAST aAST)
|
||||
private boolean isFollowsEmptyForIterator(DetailAST aAST)
|
||||
{
|
||||
final String line = getLines()[aAST.getLineNo() - 1];
|
||||
final int before = aAST.getColumnNo() - 1;
|
||||
if (before >= 0) {
|
||||
boolean followsEmptyForIterator = false;
|
||||
final DetailAST parent = aAST.getParent();
|
||||
if ((parent != null)
|
||||
&& (parent.getType() == TokenTypes.LITERAL_FOR))
|
||||
{
|
||||
final DetailAST forIterator =
|
||||
parent.findFirstToken(TokenTypes.FOR_ITERATOR);
|
||||
followsEmptyForIterator = (forIterator.getChildCount() == 0)
|
||||
&& (aAST == forIterator.getNextSibling());
|
||||
}
|
||||
if (followsEmptyForIterator) {
|
||||
return;
|
||||
}
|
||||
else if ((PadOption.NOSPACE == getAbstractOption())
|
||||
&& Character.isWhitespace(line.charAt(before))
|
||||
&& !Utils.whitespaceBefore(before, line))
|
||||
{
|
||||
log(aAST.getLineNo(), before, "ws.preceeded", ")");
|
||||
}
|
||||
else if ((PadOption.SPACE == getAbstractOption())
|
||||
&& !Character.isWhitespace(line.charAt(before))
|
||||
&& (line.charAt(before) != '('))
|
||||
{
|
||||
log(aAST.getLineNo(), aAST.getColumnNo(),
|
||||
"ws.notPreceeded", ")");
|
||||
}
|
||||
boolean followsEmptyForIterator = false;
|
||||
final DetailAST parent = aAST.getParent();
|
||||
if ((parent != null)
|
||||
&& (parent.getType() == TokenTypes.LITERAL_FOR))
|
||||
{
|
||||
final DetailAST forIterator =
|
||||
parent.findFirstToken(TokenTypes.FOR_ITERATOR);
|
||||
followsEmptyForIterator = (forIterator.getChildCount() == 0)
|
||||
&& (aAST == forIterator.getNextSibling());
|
||||
}
|
||||
return followsEmptyForIterator;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2002 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.whitespace;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
|
||||
/**
|
||||
* <p>Checks the padding of parentheses for typecasts. That is whether a space
|
||||
* is required after a left parenthesis and before a right parenthesis, or such
|
||||
* spaces are forbidden.
|
||||
* <p>
|
||||
* </p>
|
||||
* The policy to verify is specified using the {@link PadOption} class and
|
||||
* defaults to {@link PadOption#NOSPACE}.
|
||||
* </p>
|
||||
* <p>
|
||||
* An example of how to configure the check is:
|
||||
* </p>
|
||||
* <pre>
|
||||
* <module name="TypecastParenPad"/>
|
||||
* </pre>
|
||||
* <p>
|
||||
* An example of how to configure the check to require spaces for the
|
||||
* parentheses of constructor, method, and super constructor invocations is:
|
||||
* </p>
|
||||
* <pre>
|
||||
* <module name="TypecastParenPad">
|
||||
* <property name="option" value="space"/>
|
||||
* </module>
|
||||
* </pre>
|
||||
* @author Oliver Burn
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TypecastParenPadCheck
|
||||
extends AbstractParenPadCheck
|
||||
{
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public int[] getRequiredTokens()
|
||||
{
|
||||
return new int[] {TokenTypes.RPAREN, TokenTypes.TYPECAST};
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public int[] getDefaultTokens()
|
||||
{
|
||||
return getRequiredTokens();
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public void visitToken(DetailAST aAST)
|
||||
{
|
||||
// Strange logic in this method to guard against checking RPAREN tokens
|
||||
// that are not associated with a TYPECAST token.
|
||||
if (aAST.getType() == TokenTypes.TYPECAST) {
|
||||
processLeft(aAST);
|
||||
}
|
||||
else if ((aAST.getParent() != null)
|
||||
&& (aAST.getParent().getType() == TokenTypes.TYPECAST))
|
||||
{
|
||||
processRight(aAST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ class InputWhitespace
|
|||
{
|
||||
Object o = (Object) new Object(); // ok
|
||||
o = (Object)o; // error
|
||||
o = (Object) o; // ok
|
||||
o = ( Object ) o; // ok
|
||||
o = (Object)
|
||||
o; // ok
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import com.puppycrawl.tools.checkstyle.checks.whitespace.NoWhitespaceBeforeCheck
|
|||
import com.puppycrawl.tools.checkstyle.checks.whitespace.OperatorWrapCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.whitespace.ParenPadCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.whitespace.TabCharacterCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.whitespace.TypecastParenPadCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAfterCheckTest;
|
||||
import com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundTest;
|
||||
import junit.framework.Test;
|
||||
|
|
@ -148,6 +149,7 @@ public class AllTests {
|
|||
suite.addTest(new TestSuite(TabCharacterCheckTest.class));
|
||||
suite.addTest(new TestSuite(TodoCommentCheckTest.class));
|
||||
suite.addTest(new TestSuite(TranslationCheckTest.class));
|
||||
suite.addTest(new TestSuite(TypecastParenPadCheckTest.class));
|
||||
suite.addTest(new TestSuite(LeftCurlyCheckTest.class));
|
||||
suite.addTest(new TestSuite(TypeNameCheckTest.class));
|
||||
suite.addTest(new TestSuite(UncommentedMainCheckTest.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package com.puppycrawl.tools.checkstyle.checks.whitespace;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.BaseCheckTestCase;
|
||||
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
|
||||
|
||||
public class TypecastParenPadCheckTest
|
||||
extends BaseCheckTestCase
|
||||
{
|
||||
public void testDefault()
|
||||
throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(TypecastParenPadCheck.class);
|
||||
final String[] expected = {
|
||||
"89:14: '(' is followed by whitespace.",
|
||||
"89:21: ')' is preceeded with whitespace.",
|
||||
};
|
||||
verify(checkConfig, getPath("InputWhitespace.java"), expected);
|
||||
}
|
||||
|
||||
public void testSpace()
|
||||
throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(TypecastParenPadCheck.class);
|
||||
checkConfig.addAttribute("option", PadOption.SPACE.toString());
|
||||
final String[] expected = {
|
||||
"87:21: '(' is not followed by whitespace.",
|
||||
"87:27: ')' is not preceeded with whitespace.",
|
||||
"88:14: '(' is not followed by whitespace.",
|
||||
"88:20: ')' is not preceeded with whitespace.",
|
||||
"90:14: '(' is not followed by whitespace.",
|
||||
"90:20: ')' is not preceeded with whitespace.",
|
||||
};
|
||||
verify(checkConfig, getPath("InputWhitespace.java"), expected);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue