Source code: com/puppycrawl/tools/checkstyle/checks/whitespace/OperatorWrapCheck.java
1 ////////////////////////////////////////////////////////////////////////////////
2 // checkstyle: Checks Java source code for adherence to a set of rules.
3 // Copyright (C) 2001-2003 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 import com.puppycrawl.tools.checkstyle.api.Utils;
25 import com.puppycrawl.tools.checkstyle.checks.AbstractOption;
26 import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
27
28 /**
29 * <p>
30 * Checks line wrapping for operators.
31 * The policy to verify is specified using the {@link OperatorWrapOption} class
32 * and defaults to {@link OperatorWrapOption#NL}.
33 * </p>
34 * <p> By default the check will check the following operators:
35 * {@link TokenTypes#BAND BAND},
36 * {@link TokenTypes#BOR BOR},
37 * {@link TokenTypes#BSR BSR},
38 * {@link TokenTypes#BXOR BXOR},
39 * {@link TokenTypes#COLON COLON},
40 * {@link TokenTypes#DIV DIV},
41 * {@link TokenTypes#EQUAL EQUAL},
42 * {@link TokenTypes#GE GE},
43 * {@link TokenTypes#GT GT},
44 * {@link TokenTypes#LAND LAND},
45 * {@link TokenTypes#LE LE},
46 * {@link TokenTypes#LITERAL_INSTANCEOF LITERAL_INSTANCEOF},
47 * {@link TokenTypes#LOR LOR},
48 * {@link TokenTypes#LT LT},
49 * {@link TokenTypes#MINUS MINUS},
50 * {@link TokenTypes#MOD MOD},
51 * {@link TokenTypes#NOT_EQUAL NOT_EQUAL},
52 * {@link TokenTypes#PLUS PLUS},
53 * {@link TokenTypes#QUESTION QUESTION},
54 * {@link TokenTypes#SL SL},
55 * {@link TokenTypes#SR SR},
56 * {@link TokenTypes#STAR STAR}.
57 * Other acceptable tokens are
58 * {@link TokenTypes#ASSIGN ASSIGN},
59 * {@link TokenTypes#BAND_ASSIGN BAND_ASSIGN},
60 * {@link TokenTypes#BOR_ASSIGN BOR_ASSIGN},
61 * {@link TokenTypes#BSR_ASSIGN BSR_ASSIGN},
62 * {@link TokenTypes#BXOR_ASSIGN BXOR_ASSIGN},
63 * {@link TokenTypes#DIV_ASSIGN DIV_ASSIGN},
64 * {@link TokenTypes#MINUS_ASSIGN MINUS_ASSIGN},
65 * {@link TokenTypes#MOD_ASSIGN MOD_ASSIGN},
66 * {@link TokenTypes#PLUS_ASSIGN PLUS_ASSIGN},
67 * {@link TokenTypes#SL_ASSIGN SL_ASSIGN},
68 * {@link TokenTypes#SR_ASSIGN SR_ASSIGN},
69 * {@link TokenTypes#STAR_ASSIGN STAR_ASSIGN}.
70 * </p>
71 * <p>
72 * An example of how to configure the check is:
73 * </p>
74 * <pre>
75 * <module name="OperatorWrap"/>
76 * </pre>
77 * <p> An example of how to configure the check for assignment operators at the
78 * end of a line is:
79 * </p>
80 * <pre>
81 * <module name="OperatorWrap">
82 * <property name="tokens"
83 * value="ASSIGN,DIV_ASSIGN,PLUS_ASSIGN,MINUS_ASSIGN,STAR_ASSIGN,MOD_ASSIGN,SR_ASSIGN,BSR_ASSIGN,SL_ASSIGN,BXOR_ASSIGN,BOR_ASSIGN,BAND_ASSIGN"/>
84 * <property name="option" value="eol"/>
85 * </module>
86 * </pre>
87 *
88 * @author Rick Giles
89 * @version 1.0
90 */
91 public class OperatorWrapCheck
92 extends AbstractOptionCheck
93 {
94 /**
95 * Sets the operator wrap option to new line.
96 */
97 public OperatorWrapCheck()
98 {
99 super(OperatorWrapOption.NL);
100 }
101
102 /** @see com.puppycrawl.tools.checkstyle.api.Check */
103 public int[] getDefaultTokens()
104 {
105 return new int[] {
106 TokenTypes.QUESTION, // '?'
107 TokenTypes.COLON, // ':' (not reported for a case)
108 TokenTypes.EQUAL, // "=="
109 TokenTypes.NOT_EQUAL, // "!="
110 TokenTypes.DIV, // '/'
111 TokenTypes.PLUS, //' +' (unary plus is UNARY_PLUS)
112 TokenTypes.MINUS, // '-' (unary minus is UNARY_MINUS)
113 TokenTypes.STAR, // '*'
114 TokenTypes.MOD, // '%'
115 TokenTypes.SR, // ">>"
116 TokenTypes.BSR, // ">>>"
117 TokenTypes.GE, // ">="
118 TokenTypes.GT, // ">"
119 TokenTypes.SL, // "<<"
120 TokenTypes.LE, // "<="
121 TokenTypes.LT, // '<'
122 TokenTypes.BXOR, // '^'
123 TokenTypes.BOR, // '|'
124 TokenTypes.LOR, // "||"
125 TokenTypes.BAND, // '&'
126 TokenTypes.LAND, // "&&"
127 TokenTypes.LITERAL_INSTANCEOF,
128 };
129 }
130
131 /** @see com.puppycrawl.tools.checkstyle.api.Check */
132 public int[] getAcceptableTokens()
133 {
134 return new int[] {
135 TokenTypes.QUESTION, // '?'
136 TokenTypes.COLON, // ':' (not reported for a case)
137 TokenTypes.EQUAL, // "=="
138 TokenTypes.NOT_EQUAL, // "!="
139 TokenTypes.DIV, // '/'
140 TokenTypes.PLUS, //' +' (unary plus is UNARY_PLUS)
141 TokenTypes.MINUS, // '-' (unary minus is UNARY_MINUS)
142 TokenTypes.STAR, // '*'
143 TokenTypes.MOD, // '%'
144 TokenTypes.SR, // ">>"
145 TokenTypes.BSR, // ">>>"
146 TokenTypes.GE, // ">="
147 TokenTypes.GT, // ">"
148 TokenTypes.SL, // "<<"
149 TokenTypes.LE, // "<="
150 TokenTypes.LT, // '<'
151 TokenTypes.BXOR, // '^'
152 TokenTypes.BOR, // '|'
153 TokenTypes.LOR, // "||"
154 TokenTypes.BAND, // '&'
155 TokenTypes.LAND, // "&&"
156 TokenTypes.LITERAL_INSTANCEOF,
157 TokenTypes.ASSIGN, // '='
158 TokenTypes.DIV_ASSIGN, // "/="
159 TokenTypes.PLUS_ASSIGN, // "+="
160 TokenTypes.MINUS_ASSIGN, //"-="
161 TokenTypes.STAR_ASSIGN, // "*="
162 TokenTypes.MOD_ASSIGN, // "%="
163 TokenTypes.SR_ASSIGN, // ">>="
164 TokenTypes.BSR_ASSIGN, // ">>>="
165 TokenTypes.SL_ASSIGN, // "<<="
166 TokenTypes.BXOR_ASSIGN, // "^="
167 TokenTypes.BOR_ASSIGN, // "|="
168 TokenTypes.BAND_ASSIGN, // "&="
169
170 };
171 }
172 /** @see com.puppycrawl.tools.checkstyle.api.Check */
173 public void visitToken(DetailAST aAST)
174 {
175 final AbstractOption wOp = getAbstractOption();
176
177 final String text = aAST.getText();
178 final int colNo = aAST.getColumnNo();
179 final int lineNo = aAST.getLineNo();
180 final String currentLine = getLines()[lineNo - 1];
181 // TODO: Handle comments before and after operator
182 // Check if rest of line is whitespace, and not just the operator
183 // by itself. This last bit is to handle the operator on a line by
184 // itself.
185 if (wOp == OperatorWrapOption.NL
186 && !text.equals(currentLine.trim())
187 && (currentLine.substring(colNo + text.length())
188 .trim().length() == 0))
189 {
190 log(lineNo, colNo, "line.new", text);
191 }
192 else if (wOp == OperatorWrapOption.EOL
193 && Utils.whitespaceBefore(colNo - 1, currentLine))
194 {
195 log(lineNo, colNo, "line.previous", text);
196 }
197 }
198 }