Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ParenPadCheck |
|
| 5.0;5 |
1 | //////////////////////////////////////////////////////////////////////////////// | |
2 | // checkstyle: Checks Java source code for adherence to a set of rules. | |
3 | // Copyright (C) 2001-2014 Oliver Burn | |
4 | // | |
5 | // This library is free software; you can redistribute it and/or | |
6 | // modify it under the terms of the GNU Lesser General Public | |
7 | // License as published by the Free Software Foundation; either | |
8 | // version 2.1 of the License, or (at your option) any later version. | |
9 | // | |
10 | // This library is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | // Lesser General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU Lesser General Public | |
16 | // License along with this library; if not, write to the Free Software | |
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | //////////////////////////////////////////////////////////////////////////////// | |
19 | ||
20 | package com.puppycrawl.tools.checkstyle.checks.whitespace; | |
21 | ||
22 | import com.puppycrawl.tools.checkstyle.api.DetailAST; | |
23 | import com.puppycrawl.tools.checkstyle.api.TokenTypes; | |
24 | ||
25 | /** | |
26 | * <p>Checks the padding of parentheses; that is whether a space is required | |
27 | * after a left parenthesis and before a right parenthesis, or such spaces are | |
28 | * forbidden, with the exception that it does | |
29 | * not check for padding of the right parenthesis at an empty for iterator. | |
30 | * Use Check {@link EmptyForIteratorPadCheck EmptyForIteratorPad} to validate | |
31 | * empty for iterators. | |
32 | * <p> | |
33 | * </p> | |
34 | * The policy to verify is specified using the {@link PadOption} class and | |
35 | * defaults to {@link PadOption#NOSPACE}. | |
36 | * </p> | |
37 | * <p> By default the check will check parentheses that occur with the following | |
38 | * tokens: | |
39 | * {@link TokenTypes#CTOR_CALL CTOR_CALL}, | |
40 | * {@link TokenTypes#LPAREN LPAREN}, | |
41 | * {@link TokenTypes#METHOD_CALL METHOD_CALL}, | |
42 | * {@link TokenTypes#RPAREN RPAREN}, | |
43 | * {@link TokenTypes#SUPER_CTOR_CALL SUPER_CTOR_CALL}, | |
44 | * </p> | |
45 | * <p> | |
46 | * An example of how to configure the check is: | |
47 | * </p> | |
48 | * <pre> | |
49 | * <module name="ParenPad"/> | |
50 | * </pre> | |
51 | * <p> | |
52 | * An example of how to configure the check to require spaces for the | |
53 | * parentheses of constructor, method, and super constructor invocations is: | |
54 | * </p> | |
55 | * <pre> | |
56 | * <module name="ParenPad"> | |
57 | * <property name="tokens" | |
58 | * value="CTOR_CALL, METHOD_CALL, SUPER_CTOR_CALL"/> | |
59 | * <property name="option" value="space"/> | |
60 | * </module> | |
61 | * </pre> | |
62 | * @author Oliver Burn | |
63 | * @version 1.0 | |
64 | */ | |
65 | 5 | public class ParenPadCheck extends AbstractParenPadCheck |
66 | { | |
67 | @Override | |
68 | public int[] getDefaultTokens() | |
69 | { | |
70 | 5 | return new int[] {TokenTypes.RPAREN, |
71 | TokenTypes.LPAREN, | |
72 | TokenTypes.CTOR_CALL, | |
73 | TokenTypes.SUPER_CTOR_CALL, | |
74 | TokenTypes.METHOD_CALL, | |
75 | }; | |
76 | } | |
77 | ||
78 | @Override | |
79 | public void visitToken(DetailAST aAST) | |
80 | { | |
81 | 268 | DetailAST theAst = aAST; |
82 | // Strange logic in this method to guard against checking RPAREN tokens | |
83 | // that are associated with a TYPECAST token. | |
84 | 268 | if (theAst.getType() != TokenTypes.RPAREN) { |
85 | 130 | if ((theAst.getType() == TokenTypes.CTOR_CALL) |
86 | || (theAst.getType() == TokenTypes.SUPER_CTOR_CALL)) | |
87 | { | |
88 | 2 | theAst = theAst.getFirstChild(); |
89 | } | |
90 | 130 | if (!isPreceedsEmptyForInit(theAst)) { |
91 | 124 | processLeft(theAst); |
92 | } | |
93 | } | |
94 | 138 | else if (((theAst.getParent() == null) |
95 | || (theAst.getParent().getType() != TokenTypes.TYPECAST) | |
96 | || (theAst.getParent().findFirstToken(TokenTypes.RPAREN) | |
97 | != theAst)) | |
98 | && !isFollowsEmptyForIterator(theAst)) | |
99 | { | |
100 | 118 | processRight(theAst); |
101 | } | |
102 | 268 | } |
103 | ||
104 | /** | |
105 | * @param aAST the token to check | |
106 | * @return whether a token follows an empty for iterator | |
107 | */ | |
108 | private boolean isFollowsEmptyForIterator(DetailAST aAST) | |
109 | { | |
110 | 128 | boolean followsEmptyForIterator = false; |
111 | 128 | final DetailAST parent = aAST.getParent(); |
112 | //Only traditional for statements are examined, not for-each statements | |
113 | 128 | if ((parent != null) |
114 | && (parent.getType() == TokenTypes.LITERAL_FOR) | |
115 | && (parent.findFirstToken(TokenTypes.FOR_EACH_CLAUSE) == null)) | |
116 | { | |
117 | 28 | final DetailAST forIterator = |
118 | parent.findFirstToken(TokenTypes.FOR_ITERATOR); | |
119 | 28 | followsEmptyForIterator = (forIterator.getChildCount() == 0) |
120 | && (aAST == forIterator.getNextSibling()); | |
121 | } | |
122 | 128 | return followsEmptyForIterator; |
123 | } | |
124 | ||
125 | /** | |
126 | * @param aAST the token to check | |
127 | * @return whether a token preceeds an empty for initializer | |
128 | */ | |
129 | private boolean isPreceedsEmptyForInit(DetailAST aAST) | |
130 | { | |
131 | 130 | boolean preceedsEmptyForInintializer = false; |
132 | 130 | final DetailAST parent = aAST.getParent(); |
133 | //Only traditional for statements are examined, not for-each statements | |
134 | 130 | if ((parent != null) |
135 | && (parent.getType() == TokenTypes.LITERAL_FOR) | |
136 | && (parent.findFirstToken(TokenTypes.FOR_EACH_CLAUSE) == null)) | |
137 | { | |
138 | 28 | final DetailAST forIterator = |
139 | parent.findFirstToken(TokenTypes.FOR_INIT); | |
140 | 28 | preceedsEmptyForInintializer = (forIterator.getChildCount() == 0) |
141 | && (aAST == forIterator.getPreviousSibling()); | |
142 | } | |
143 | 130 | return preceedsEmptyForInintializer; |
144 | } | |
145 | } |