Source code: com/puppycrawl/tools/checkstyle/checks/indentation/IfHandler.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 package com.puppycrawl.tools.checkstyle.checks.indentation;
20
21 import com.puppycrawl.tools.checkstyle.api.DetailAST;
22 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
23
24 /**
25 * Handler for if statements.
26 *
27 * @author jrichard
28 */
29 public class IfHandler extends BlockParentHandler
30 {
31 /**
32 * Construct an instance of this handler with the given indentation check,
33 * abstract syntax tree, and parent handler.
34 *
35 * @param aIndentCheck the indentation check
36 * @param aAst the abstract syntax tree
37 * @param aParent the parent handler
38 */
39 public IfHandler(IndentationCheck aIndentCheck,
40 DetailAST aAst, ExpressionHandler aParent)
41 {
42 super(aIndentCheck, "if", aAst, aParent);
43 }
44
45 /**
46 * Indentation level suggested for a child element. Children don't have
47 * to respect this, but most do.
48 *
49 * @param aChild child AST (so suggestion level can differ based on child
50 * type)
51 *
52 * @return suggested indentation for child
53 */
54 public IndentLevel suggestedChildLevel(ExpressionHandler aChild)
55 {
56 if (aChild instanceof ElseHandler) {
57 return getLevel();
58 }
59 else {
60 return super.suggestedChildLevel(aChild);
61 }
62 }
63
64 /**
65 * Compute the indentation amount for this handler.
66 *
67 * @return the expected indentation amount
68 */
69 public IndentLevel getLevelImpl()
70 {
71 if (isIfAfterElse()) {
72 return getParent().getLevel();
73 }
74 else {
75 return super.getLevelImpl();
76 }
77 }
78
79 /**
80 * Determines if this 'if' statement is part of an 'else' clause
81 * and on the same line.
82 *
83 * @return true if this 'if' is part of an 'else', false otherwise
84 */
85 private boolean isIfAfterElse()
86 {
87 // check if there is an 'else' and an 'if' on the same line
88 DetailAST parent = getMainAst().getParent();
89 return parent.getType() == TokenTypes.LITERAL_ELSE
90 && parent.getLineNo() == getMainAst().getLineNo();
91 }
92
93 /**
94 * Check the indentation of the top level token.
95 */
96 protected void checkToplevelToken()
97 {
98 if (isIfAfterElse()) {
99 return;
100 }
101
102 super.checkToplevelToken();
103 }
104
105 /**
106 * Check the indentation of the conditional expression.
107 */
108 private void checkCondExpr()
109 {
110 DetailAST condAst = (DetailAST)
111 getMainAst().findFirstToken(TokenTypes.LPAREN).getNextSibling();
112 IndentLevel expected = new IndentLevel(getLevel(), getBasicOffset());
113
114 checkExpressionSubtree(condAst, expected, false, false);
115 }
116
117 /**
118 * Check the indentation of the expression we are handling.
119 */
120 public void checkIndentation()
121 {
122 super.checkIndentation();
123 checkCondExpr();
124 }
125 }