1 | /////////////////////////////////////////////////////////////////////////////////////////////// | |
2 | // checkstyle: Checks Java source code and other text files for adherence to a set of rules. | |
3 | // Copyright (C) 2001-2022 the original author or authors. | |
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.blocks; | |
21 | ||
22 | import java.util.Locale; | |
23 | ||
24 | import com.puppycrawl.tools.checkstyle.StatelessCheck; | |
25 | import com.puppycrawl.tools.checkstyle.api.AbstractCheck; | |
26 | import com.puppycrawl.tools.checkstyle.api.DetailAST; | |
27 | import com.puppycrawl.tools.checkstyle.api.TokenTypes; | |
28 | import com.puppycrawl.tools.checkstyle.utils.CommonUtil; | |
29 | import com.puppycrawl.tools.checkstyle.utils.TokenUtil; | |
30 | ||
31 | /** | |
32 | * <p> | |
33 | * Checks for the placement of left curly braces (<code>'{'</code>) for code blocks. | |
34 | * </p> | |
35 | * <ul> | |
36 | * <li> | |
37 | * Property {@code option} - Specify the policy on placement of a left curly brace | |
38 | * (<code>'{'</code>). | |
39 | * Type is {@code com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyOption}. | |
40 | * Default value is {@code eol}. | |
41 | * </li> | |
42 | * <li> | |
43 | * Property {@code ignoreEnums} - Allow to ignore enums when left curly brace policy is EOL. | |
44 | * Type is {@code boolean}. | |
45 | * Default value is {@code true}. | |
46 | * </li> | |
47 | * <li> | |
48 | * Property {@code tokens} - tokens to check | |
49 | * Type is {@code java.lang.String[]}. | |
50 | * Validation type is {@code tokenSet}. | |
51 | * Default value is: | |
52 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#ANNOTATION_DEF"> | |
53 | * ANNOTATION_DEF</a>, | |
54 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#CLASS_DEF"> | |
55 | * CLASS_DEF</a>, | |
56 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#CTOR_DEF"> | |
57 | * CTOR_DEF</a>, | |
58 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#ENUM_CONSTANT_DEF"> | |
59 | * ENUM_CONSTANT_DEF</a>, | |
60 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#ENUM_DEF"> | |
61 | * ENUM_DEF</a>, | |
62 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#INTERFACE_DEF"> | |
63 | * INTERFACE_DEF</a>, | |
64 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LAMBDA"> | |
65 | * LAMBDA</a>, | |
66 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_CASE"> | |
67 | * LITERAL_CASE</a>, | |
68 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_CATCH"> | |
69 | * LITERAL_CATCH</a>, | |
70 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_DEFAULT"> | |
71 | * LITERAL_DEFAULT</a>, | |
72 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_DO"> | |
73 | * LITERAL_DO</a>, | |
74 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_ELSE"> | |
75 | * LITERAL_ELSE</a>, | |
76 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_FINALLY"> | |
77 | * LITERAL_FINALLY</a>, | |
78 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_FOR"> | |
79 | * LITERAL_FOR</a>, | |
80 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_IF"> | |
81 | * LITERAL_IF</a>, | |
82 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_SWITCH"> | |
83 | * LITERAL_SWITCH</a>, | |
84 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_SYNCHRONIZED"> | |
85 | * LITERAL_SYNCHRONIZED</a>, | |
86 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_TRY"> | |
87 | * LITERAL_TRY</a>, | |
88 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_WHILE"> | |
89 | * LITERAL_WHILE</a>, | |
90 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#METHOD_DEF"> | |
91 | * METHOD_DEF</a>, | |
92 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#OBJBLOCK"> | |
93 | * OBJBLOCK</a>, | |
94 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#STATIC_INIT"> | |
95 | * STATIC_INIT</a>, | |
96 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#RECORD_DEF"> | |
97 | * RECORD_DEF</a>, | |
98 | * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#COMPACT_CTOR_DEF"> | |
99 | * COMPACT_CTOR_DEF</a>. | |
100 | * </li> | |
101 | * </ul> | |
102 | * <p> | |
103 | * To configure the check: | |
104 | * </p> | |
105 | * <pre> | |
106 | * <module name="LeftCurly"/> | |
107 | * </pre> | |
108 | * <pre> | |
109 | * class Test | |
110 | * { // Violation - '{' should be on the previous line | |
111 | * private interface TestInterface | |
112 | * { // Violation - '{' should be on the previous line | |
113 | * } | |
114 | * | |
115 | * private | |
116 | * class | |
117 | * MyClass { // OK | |
118 | * } | |
119 | * | |
120 | * enum Colors {RED, // OK | |
121 | * BLUE, | |
122 | * GREEN; | |
123 | * } | |
124 | * } | |
125 | * </pre> | |
126 | * <p> | |
127 | * To configure the check to apply the {@code nl} policy to type blocks: | |
128 | * </p> | |
129 | * <pre> | |
130 | * <module name="LeftCurly"> | |
131 | * <property name="option" value="nl"/> | |
132 | * <property name="tokens" value="CLASS_DEF,INTERFACE_DEF"/> | |
133 | * </module> | |
134 | * </pre> | |
135 | * <pre> | |
136 | * class Test | |
137 | * { // OK | |
138 | * private interface TestInterface | |
139 | * { // OK | |
140 | * } | |
141 | * | |
142 | * private | |
143 | * class | |
144 | * MyClass { // Violation - '{' should be on a new line | |
145 | * } | |
146 | * | |
147 | * enum Colors {RED, // OK | |
148 | * BLUE, | |
149 | * GREEN; | |
150 | * } | |
151 | * } | |
152 | * </pre> | |
153 | * <p> | |
154 | * An example of how to configure the check to validate enum definitions: | |
155 | * </p> | |
156 | * <pre> | |
157 | * <module name="LeftCurly"> | |
158 | * <property name="ignoreEnums" value="false"/> | |
159 | * </module> | |
160 | * </pre> | |
161 | * <pre> | |
162 | * class Test | |
163 | * { // Violation - '{' should be on the previous line | |
164 | * private interface TestInterface | |
165 | * { // Violation - '{' should be on the previous line | |
166 | * } | |
167 | * | |
168 | * private | |
169 | * class | |
170 | * MyClass { // OK | |
171 | * } | |
172 | * | |
173 | * enum Colors {RED, // Violation - '{' should have line break after | |
174 | * BLUE, | |
175 | * GREEN; | |
176 | * } | |
177 | * } | |
178 | * </pre> | |
179 | * <p> | |
180 | * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker} | |
181 | * </p> | |
182 | * <p> | |
183 | * Violation Message Keys: | |
184 | * </p> | |
185 | * <ul> | |
186 | * <li> | |
187 | * {@code line.break.after} | |
188 | * </li> | |
189 | * <li> | |
190 | * {@code line.new} | |
191 | * </li> | |
192 | * <li> | |
193 | * {@code line.previous} | |
194 | * </li> | |
195 | * </ul> | |
196 | * | |
197 | * @since 3.0 | |
198 | */ | |
199 | @StatelessCheck | |
200 | public class LeftCurlyCheck | |
201 | extends AbstractCheck { | |
202 | ||
203 | /** | |
204 | * A key is pointing to the warning message text in "messages.properties" | |
205 | * file. | |
206 | */ | |
207 | public static final String MSG_KEY_LINE_NEW = "line.new"; | |
208 | ||
209 | /** | |
210 | * A key is pointing to the warning message text in "messages.properties" | |
211 | * file. | |
212 | */ | |
213 | public static final String MSG_KEY_LINE_PREVIOUS = "line.previous"; | |
214 | ||
215 | /** | |
216 | * A key is pointing to the warning message text in "messages.properties" | |
217 | * file. | |
218 | */ | |
219 | public static final String MSG_KEY_LINE_BREAK_AFTER = "line.break.after"; | |
220 | ||
221 | /** Open curly brace literal. */ | |
222 | private static final String OPEN_CURLY_BRACE = "{"; | |
223 | ||
224 | /** Allow to ignore enums when left curly brace policy is EOL. */ | |
225 | private boolean ignoreEnums = true; | |
226 | ||
227 | /** | |
228 | * Specify the policy on placement of a left curly brace (<code>'{'</code>). | |
229 | * */ | |
230 | private LeftCurlyOption option = LeftCurlyOption.EOL; | |
231 | ||
232 | /** | |
233 | * Setter to specify the policy on placement of a left curly brace (<code>'{'</code>). | |
234 | * | |
235 | * @param optionStr string to decode option from | |
236 | * @throws IllegalArgumentException if unable to decode | |
237 | */ | |
238 | public void setOption(String optionStr) { | |
239 | option = LeftCurlyOption.valueOf(optionStr.trim().toUpperCase(Locale.ENGLISH)); | |
240 | } | |
241 | ||
242 | /** | |
243 | * Setter to allow to ignore enums when left curly brace policy is EOL. | |
244 | * | |
245 | * @param ignoreEnums check's option for ignoring enums. | |
246 | */ | |
247 | public void setIgnoreEnums(boolean ignoreEnums) { | |
248 | this.ignoreEnums = ignoreEnums; | |
249 | } | |
250 | ||
251 | @Override | |
252 | public int[] getDefaultTokens() { | |
253 | return getAcceptableTokens(); | |
254 | } | |
255 | ||
256 | @Override | |
257 | public int[] getAcceptableTokens() { | |
258 | return new int[] { | |
259 | TokenTypes.ANNOTATION_DEF, | |
260 | TokenTypes.CLASS_DEF, | |
261 | TokenTypes.CTOR_DEF, | |
262 | TokenTypes.ENUM_CONSTANT_DEF, | |
263 | TokenTypes.ENUM_DEF, | |
264 | TokenTypes.INTERFACE_DEF, | |
265 | TokenTypes.LAMBDA, | |
266 | TokenTypes.LITERAL_CASE, | |
267 | TokenTypes.LITERAL_CATCH, | |
268 | TokenTypes.LITERAL_DEFAULT, | |
269 | TokenTypes.LITERAL_DO, | |
270 | TokenTypes.LITERAL_ELSE, | |
271 | TokenTypes.LITERAL_FINALLY, | |
272 | TokenTypes.LITERAL_FOR, | |
273 | TokenTypes.LITERAL_IF, | |
274 | TokenTypes.LITERAL_SWITCH, | |
275 | TokenTypes.LITERAL_SYNCHRONIZED, | |
276 | TokenTypes.LITERAL_TRY, | |
277 | TokenTypes.LITERAL_WHILE, | |
278 | TokenTypes.METHOD_DEF, | |
279 | TokenTypes.OBJBLOCK, | |
280 | TokenTypes.STATIC_INIT, | |
281 | TokenTypes.RECORD_DEF, | |
282 | TokenTypes.COMPACT_CTOR_DEF, | |
283 | }; | |
284 | } | |
285 | ||
286 | @Override | |
287 | public int[] getRequiredTokens() { | |
288 | return CommonUtil.EMPTY_INT_ARRAY; | |
289 | } | |
290 | ||
291 | /** | |
292 | * We cannot reduce the number of branches in this switch statement, | |
293 | * since many tokens require specific methods to find the first left | |
294 | * curly. | |
295 | * | |
296 | * @param ast the token to process | |
297 | * @noinspection SwitchStatementWithTooManyBranches | |
298 | */ | |
299 | @Override | |
300 | public void visitToken(DetailAST ast) { | |
301 | final DetailAST startToken; | |
302 | final DetailAST brace; | |
303 | ||
304 | switch (ast.getType()) { | |
305 | case TokenTypes.CTOR_DEF: | |
306 | case TokenTypes.METHOD_DEF: | |
307 | case TokenTypes.COMPACT_CTOR_DEF: | |
308 | startToken = skipModifierAnnotations(ast); | |
309 | brace = ast.findFirstToken(TokenTypes.SLIST); | |
310 | break; | |
311 | case TokenTypes.INTERFACE_DEF: | |
312 | case TokenTypes.CLASS_DEF: | |
313 | case TokenTypes.ANNOTATION_DEF: | |
314 | case TokenTypes.ENUM_DEF: | |
315 | case TokenTypes.ENUM_CONSTANT_DEF: | |
316 | case TokenTypes.RECORD_DEF: | |
317 | startToken = skipModifierAnnotations(ast); | |
318 | brace = ast.findFirstToken(TokenTypes.OBJBLOCK); | |
319 | break; | |
320 | case TokenTypes.LITERAL_WHILE: | |
321 | case TokenTypes.LITERAL_CATCH: | |
322 | case TokenTypes.LITERAL_SYNCHRONIZED: | |
323 | case TokenTypes.LITERAL_FOR: | |
324 | case TokenTypes.LITERAL_TRY: | |
325 | case TokenTypes.LITERAL_FINALLY: | |
326 | case TokenTypes.LITERAL_DO: | |
327 | case TokenTypes.LITERAL_IF: | |
328 | case TokenTypes.STATIC_INIT: | |
329 | case TokenTypes.LAMBDA: | |
330 | startToken = ast; | |
331 | brace = ast.findFirstToken(TokenTypes.SLIST); | |
332 | break; | |
333 | case TokenTypes.LITERAL_ELSE: | |
334 | startToken = ast; | |
335 | brace = getBraceAsFirstChild(ast); | |
336 | break; | |
337 | case TokenTypes.LITERAL_CASE: | |
338 | case TokenTypes.LITERAL_DEFAULT: | |
339 | startToken = ast; | |
340 | brace = getBraceFromSwitchMember(ast); | |
341 | break; | |
342 | default: | |
343 | // ATTENTION! We have default here, but we expect case TokenTypes.METHOD_DEF, | |
344 | // TokenTypes.LITERAL_FOR, TokenTypes.LITERAL_WHILE, TokenTypes.LITERAL_DO only. | |
345 | // It has been done to improve coverage to 100%. I couldn't replace it with | |
346 | // if-else-if block because code was ugly and didn't pass pmd check. | |
347 | ||
348 | startToken = ast; | |
349 | brace = ast.findFirstToken(TokenTypes.LCURLY); | |
350 | break; | |
351 | } | |
352 | ||
353 | if (brace != null) { | |
354 | verifyBrace(brace, startToken); | |
355 | } | |
356 | } | |
357 | ||
358 | /** | |
359 | * Gets the brace of a switch statement/ expression member. | |
360 | * | |
361 | * @param ast {@code DetailAST}. | |
362 | * @return {@code DetailAST} if the first child is {@code TokenTypes.SLIST}, | |
363 | * {@code null} otherwise. | |
364 | */ | |
365 | private static DetailAST getBraceFromSwitchMember(DetailAST ast) { | |
366 | final DetailAST brace; | |
367 | final DetailAST parent = ast.getParent(); | |
368 | if (parent.getType() == TokenTypes.SWITCH_RULE) { | |
369 | brace = parent.findFirstToken(TokenTypes.SLIST); | |
370 | } | |
371 | else { | |
372 | brace = getBraceAsFirstChild(ast.getNextSibling()); | |
373 | } | |
374 | return brace; | |
375 | } | |
376 | ||
377 | /** | |
378 | * Gets a SLIST if it is the first child of the AST. | |
379 | * | |
380 | * @param ast {@code DetailAST}. | |
381 | * @return {@code DetailAST} if the first child is {@code TokenTypes.SLIST}, | |
382 | * {@code null} otherwise. | |
383 | */ | |
384 | private static DetailAST getBraceAsFirstChild(DetailAST ast) { | |
385 | DetailAST brace = null; | |
386 | if (ast != null) { | |
387 | final DetailAST candidate = ast.getFirstChild(); | |
388 | if (candidate != null && candidate.getType() == TokenTypes.SLIST) { | |
389 | brace = candidate; | |
390 | } | |
391 | } | |
392 | return brace; | |
393 | } | |
394 | ||
395 | /** | |
396 | * Skip all {@code TokenTypes.ANNOTATION}s to the first non-annotation. | |
397 | * | |
398 | * @param ast {@code DetailAST}. | |
399 | * @return {@code DetailAST}. | |
400 | */ | |
401 | private static DetailAST skipModifierAnnotations(DetailAST ast) { | |
402 | DetailAST resultNode = ast; | |
403 | final DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS); | |
404 | ||
405 | if (modifiers != null) { | |
406 | final DetailAST lastAnnotation = findLastAnnotation(modifiers); | |
407 | ||
408 | if (lastAnnotation != null) { | |
409 | if (lastAnnotation.getNextSibling() == null) { | |
410 | resultNode = modifiers.getNextSibling(); | |
411 | } | |
412 | else { | |
413 | resultNode = lastAnnotation.getNextSibling(); | |
414 | } | |
415 | } | |
416 | } | |
417 | return resultNode; | |
418 | } | |
419 | ||
420 | /** | |
421 | * Find the last token of type {@code TokenTypes.ANNOTATION} | |
422 | * under the given set of modifiers. | |
423 | * | |
424 | * @param modifiers {@code DetailAST}. | |
425 | * @return {@code DetailAST} or null if there are no annotations. | |
426 | */ | |
427 | private static DetailAST findLastAnnotation(DetailAST modifiers) { | |
428 | DetailAST annotation = modifiers.findFirstToken(TokenTypes.ANNOTATION); | |
429 | while (annotation != null && annotation.getNextSibling() != null | |
430 | && annotation.getNextSibling().getType() == TokenTypes.ANNOTATION) { | |
431 | annotation = annotation.getNextSibling(); | |
432 | } | |
433 | return annotation; | |
434 | } | |
435 | ||
436 | /** | |
437 | * Verifies that a specified left curly brace is placed correctly | |
438 | * according to policy. | |
439 | * | |
440 | * @param brace token for left curly brace | |
441 | * @param startToken token for start of expression | |
442 | */ | |
443 | private void verifyBrace(final DetailAST brace, | |
444 | final DetailAST startToken) { | |
445 |
1
1. verifyBrace : Replaced integer subtraction with addition → KILLED |
final String braceLine = getLine(brace.getLineNo() - 1); |
446 | ||
447 | // Check for being told to ignore, or have '{}' which is a special case | |
448 |
1
1. verifyBrace : Replaced integer addition with subtraction → KILLED |
if (braceLine.length() <= brace.getColumnNo() + 1 |
449 |
1
1. verifyBrace : Replaced integer addition with subtraction → KILLED |
|| braceLine.charAt(brace.getColumnNo() + 1) != '}') { |
450 | if (option == LeftCurlyOption.NL) { | |
451 | if (!CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) { | |
452 |
1
1. verifyBrace : Replaced integer addition with subtraction → KILLED |
log(brace, MSG_KEY_LINE_NEW, OPEN_CURLY_BRACE, brace.getColumnNo() + 1); |
453 | } | |
454 | } | |
455 | else if (option == LeftCurlyOption.EOL) { | |
456 | validateEol(brace, braceLine); | |
457 | } | |
458 | else if (!TokenUtil.areOnSameLine(startToken, brace)) { | |
459 | validateNewLinePosition(brace, startToken, braceLine); | |
460 | } | |
461 | } | |
462 | } | |
463 | ||
464 | /** | |
465 | * Validate EOL case. | |
466 | * | |
467 | * @param brace brace AST | |
468 | * @param braceLine line content | |
469 | */ | |
470 | private void validateEol(DetailAST brace, String braceLine) { | |
471 | if (CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) { | |
472 |
1
1. validateEol : Replaced integer addition with subtraction → KILLED |
log(brace, MSG_KEY_LINE_PREVIOUS, OPEN_CURLY_BRACE, brace.getColumnNo() + 1); |
473 | } | |
474 | if (!hasLineBreakAfter(brace)) { | |
475 |
1
1. validateEol : Replaced integer addition with subtraction → KILLED |
log(brace, MSG_KEY_LINE_BREAK_AFTER, OPEN_CURLY_BRACE, brace.getColumnNo() + 1); |
476 | } | |
477 | } | |
478 | ||
479 | /** | |
480 | * Validate token on new Line position. | |
481 | * | |
482 | * @param brace brace AST | |
483 | * @param startToken start Token | |
484 | * @param braceLine content of line with Brace | |
485 | */ | |
486 | private void validateNewLinePosition(DetailAST brace, DetailAST startToken, String braceLine) { | |
487 | // not on the same line | |
488 |
1
1. validateNewLinePosition : Replaced integer addition with subtraction → KILLED |
if (startToken.getLineNo() + 1 == brace.getLineNo()) { |
489 | if (CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) { | |
490 |
1
1. validateNewLinePosition : Replaced integer addition with subtraction → KILLED |
log(brace, MSG_KEY_LINE_PREVIOUS, OPEN_CURLY_BRACE, brace.getColumnNo() + 1); |
491 | } | |
492 | else { | |
493 |
1
1. validateNewLinePosition : Replaced integer addition with subtraction → KILLED |
log(brace, MSG_KEY_LINE_NEW, OPEN_CURLY_BRACE, brace.getColumnNo() + 1); |
494 | } | |
495 | } | |
496 | else if (!CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) { | |
497 |
1
1. validateNewLinePosition : Replaced integer addition with subtraction → KILLED |
log(brace, MSG_KEY_LINE_NEW, OPEN_CURLY_BRACE, brace.getColumnNo() + 1); |
498 | } | |
499 | } | |
500 | ||
501 | /** | |
502 | * Checks if left curly has line break after. | |
503 | * | |
504 | * @param leftCurly | |
505 | * Left curly token. | |
506 | * @return | |
507 | * True, left curly has line break after. | |
508 | */ | |
509 | private boolean hasLineBreakAfter(DetailAST leftCurly) { | |
510 | DetailAST nextToken = null; | |
511 | if (leftCurly.getType() == TokenTypes.SLIST) { | |
512 | nextToken = leftCurly.getFirstChild(); | |
513 | } | |
514 | else { | |
515 | if (!ignoreEnums | |
516 | && leftCurly.getParent().getParent().getType() == TokenTypes.ENUM_DEF) { | |
517 | nextToken = leftCurly.getNextSibling(); | |
518 | } | |
519 | } | |
520 | return nextToken == null | |
521 | || nextToken.getType() == TokenTypes.RCURLY | |
522 | || !TokenUtil.areOnSameLine(leftCurly, nextToken); | |
523 | } | |
524 | ||
525 | } | |
Mutations | ||
445 |
1.1 |
|
448 |
1.1 |
|
449 |
1.1 |
|
452 |
1.1 |
|
472 |
1.1 |
|
475 |
1.1 |
|
488 |
1.1 |
|
490 |
1.1 |
|
493 |
1.1 |
|
497 |
1.1 |