From 99ed7a7d2c1861dbf327ea9a421ec56f10c92fc2 Mon Sep 17 00:00:00 2001 From: Oliver Burn Date: Mon, 9 Jun 2003 06:20:19 +0000 Subject: [PATCH] bug-750348: added check for typecast parens. Involved a bit of refactoring. --- docs/checkstyle_checks.xml | 1 + docs/config_whitespace.html | 72 +++++++++++++++ docs/releasenotes.html | 3 + docs/sun_checks.xml | 1 + .../whitespace/AbstractParenPadCheck.java | 91 +++++++++++++++++++ .../checks/whitespace/ParenPadCheck.java | 82 ++++------------- .../whitespace/TypecastParenPadCheck.java | 80 ++++++++++++++++ .../tools/checkstyle/InputWhitespace.java | 2 +- .../puppycrawl/tools/checkstyle/AllTests.java | 2 + .../whitespace/TypecastParenPadCheckTest.java | 37 ++++++++ 10 files changed, 304 insertions(+), 67 deletions(-) create mode 100644 src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/AbstractParenPadCheck.java create mode 100644 src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheck.java create mode 100644 src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheckTest.java diff --git a/docs/checkstyle_checks.xml b/docs/checkstyle_checks.xml index 9c6e1f6d4..f35b2bcee 100644 --- a/docs/checkstyle_checks.xml +++ b/docs/checkstyle_checks.xml @@ -88,6 +88,7 @@ + diff --git a/docs/config_whitespace.html b/docs/config_whitespace.html index ece002e83..3db05acb1 100644 --- a/docs/config_whitespace.html +++ b/docs/config_whitespace.html @@ -37,6 +37,9 @@
  • ParenPad
  • +
  • + TypecastParenPad +
  • TabCharacter
  • @@ -427,6 +430,8 @@

    TreeWalker

    + +

    ParenPad

    Description

    @@ -505,6 +510,73 @@ TreeWalker

    + +

    TypecastParenPad

    + +

    Description

    + +

    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.

    + +

    Properties

    + + + + + + + + + + + + + + + + + + +
    namedescriptiontypedefault value
    optionpolicy on how to pad parenthesespad policynospace
    tokenstokens to checkMust have tokens + TYPECAST, + RPAREN + + TYPECAST, + RPAREN + +
    + +

    Examples

    +

    + To configure the check: +

    +
    +<module name="TypecastParenPad"/>
    +      
    +

    + To configure the check to require spaces: +

    +
    +<module name="TypecastParenPad">
    +    <property name="option" value="space"/>
    +</module>
    +      
    +

    Package

    +

    + com.puppycrawl.tools.checkstyle.checks.whitespace +

    + +

    Parent Module

    +

    + TreeWalker +

    + +

    TabCharacter

    Description

    diff --git a/docs/releasenotes.html b/docs/releasenotes.html index 77cbfa211..6271e0cd6 100644 --- a/docs/releasenotes.html +++ b/docs/releasenotes.html @@ -73,6 +73,9 @@ not exceed a certain length (module AnonInnerLength, request 715709, contributed by Rob Worth). +

  • Added TypecastParenPadCheck to check the padding of + typecasts (bug 750348).
  • +

    diff --git a/docs/sun_checks.xml b/docs/sun_checks.xml index 0e88e37af..3d5104151 100644 --- a/docs/sun_checks.xml +++ b/docs/sun_checks.xml @@ -104,6 +104,7 @@ + diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/AbstractParenPadCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/AbstractParenPadCheck.java new file mode 100644 index 000000000..fba4a5fe7 --- /dev/null +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/AbstractParenPadCheck.java @@ -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; + +/** + *

    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. + *

    + * @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", ")"); + } + } + } +} diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/ParenPadCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/ParenPadCheck.java index 1f1666722..1e7a5abb7 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/ParenPadCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/ParenPadCheck.java @@ -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; /** *

    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; } } diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheck.java new file mode 100644 index 000000000..7be54e52f --- /dev/null +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheck.java @@ -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; + +/** + *

    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. + *

    + *

    + * The policy to verify is specified using the {@link PadOption} class and + * defaults to {@link PadOption#NOSPACE}. + *

    + *

    + * An example of how to configure the check is: + *

    + *
    + * <module name="TypecastParenPad"/>
    + * 
    + *

    + * An example of how to configure the check to require spaces for the + * parentheses of constructor, method, and super constructor invocations is: + *

    + *
    + * <module name="TypecastParenPad">
    + *     <property name="option" value="space"/>
    + * </module>
    + * 
    + * @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); + } + } +} diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/InputWhitespace.java b/src/testinputs/com/puppycrawl/tools/checkstyle/InputWhitespace.java index c86aa1942..f086e3ef6 100644 --- a/src/testinputs/com/puppycrawl/tools/checkstyle/InputWhitespace.java +++ b/src/testinputs/com/puppycrawl/tools/checkstyle/InputWhitespace.java @@ -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 } diff --git a/src/tests/com/puppycrawl/tools/checkstyle/AllTests.java b/src/tests/com/puppycrawl/tools/checkstyle/AllTests.java index e12862149..3d72f7f8e 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/AllTests.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/AllTests.java @@ -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)); diff --git a/src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheckTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheckTest.java new file mode 100644 index 000000000..3b4bd9731 --- /dev/null +++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/TypecastParenPadCheckTest.java @@ -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); + } +}