Clover Coverage Report - Checkstyle
Coverage timestamp: Fri May 9 2008 10:48:13 EST
../../../../../../img/srcFileCovDistChart10.png 0% of files have more coverage
23   149   13   4.6
10   55   0.57   5
5     2.6  
1    
 
  SimplifyBooleanReturnCheck       Line # 41 100% 1.0
13 23 13 13 0.57
 
  (1)
 
1    ////////////////////////////////////////////////////////////////////////////////
2    // checkstyle: Checks Java source code for adherence to a set of rules.
3    // Copyright (C) 2001-2005 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.coding;
21   
22    import antlr.collections.AST;
23    import com.puppycrawl.tools.checkstyle.api.Check;
24    import com.puppycrawl.tools.checkstyle.api.TokenTypes;
25    import com.puppycrawl.tools.checkstyle.api.DetailAST;
26   
27   
28    /**
29    * <p>
30    * Checks for overly complicated boolean return statements.
31    * Idea shamelessly stolen from the equivalent PMD rule (pmd.sourceforge.net).
32    * </p>
33    * <p>
34    * An example of how to configure the check is:
35    * </p>
36    * <pre>
37    * &lt;module name="SimplifyBooleanReturn"/&gt;
38    * </pre>
39    * @author Lars Kühne
40    */
 
41    public class SimplifyBooleanReturnCheck
42    extends Check
43    {
44    /** {@inheritDoc} */
 
45  1 toggle public int[] getDefaultTokens()
46    {
47  1 return new int[] {TokenTypes.LITERAL_IF};
48    }
49   
50    /** {@inheritDoc} */
 
51  5 toggle public void visitToken(DetailAST aAST)
52    {
53    // LITERAL_IF has the following four or five children:
54    // '('
55    // condition
56    // ')'
57    // thenStatement
58    // [ LITERAL_ELSE (with the elseStatement as a child) ]
59   
60    // don't bother if this is not if then else
61  5 final AST elseLiteral =
62    aAST.findFirstToken(TokenTypes.LITERAL_ELSE);
63  5 if (elseLiteral == null) {
64  1 return;
65    }
66  4 final AST elseStatement = elseLiteral.getFirstChild();
67   
68    // skip '(' and ')'
69    // TODO: Introduce helpers in DetailAST
70  4 final AST condition = aAST.getFirstChild().getNextSibling();
71  4 final AST thenStatement = condition.getNextSibling().getNextSibling();
72   
73  4 if (returnsOnlyBooleanLiteral(thenStatement)
74    && returnsOnlyBooleanLiteral(elseStatement))
75    {
76  2 log(aAST.getLineNo(), aAST.getColumnNo(), "simplify.boolreturn");
77    }
78    }
79   
80    /**
81    * Returns if an AST is a return statment with a boolean literal
82    * or a compound statement that contains only such a return statement.
83    *
84    * Returns <code>true</code> iff aAST represents
85    * <br>
86    * <pre>
87    * return true/false;
88    * <pre>
89    * or
90    * <br>
91    * <pre>
92    * {
93    * return true/false;
94    * }
95    * <pre>
96    *
97    * @param aAST the sytax tree to check
98    * @return if aAST is a return statment with a boolean literal.
99    */
 
100  6 toggle private static boolean returnsOnlyBooleanLiteral(AST aAST)
101    {
102  6 if (isBooleanLiteralReturnStatement(aAST)) {
103  2 return true;
104    }
105   
106  4 final AST firstStmnt = aAST.getFirstChild();
107  4 return isBooleanLiteralReturnStatement(firstStmnt);
108    }
109   
110    /**
111    * Returns if an AST is a return statment with a boolean literal.
112    *
113    * Returns <code>true</code> iff aAST represents
114    * <br>
115    * <pre>
116    * return true/false;
117    * <pre>
118    *
119    * @param aAST the sytax tree to check
120    * @return if aAST is a return statment with a boolean literal.
121    */
 
122  10 toggle private static boolean isBooleanLiteralReturnStatement(AST aAST)
123    {
124  10 if ((aAST == null) || (aAST.getType() != TokenTypes.LITERAL_RETURN)) {
125  5 return false;
126    }
127   
128  5 final AST expr = aAST.getFirstChild();
129   
130  5 if ((expr == null) || (expr.getType() == TokenTypes.SEMI)) {
131  1 return false;
132    }
133   
134  4 final AST value = expr.getFirstChild();
135  4 return isBooleanLiteralType(value.getType());
136    }
137   
138    /**
139    * Checks if a token type is a literal true or false.
140    * @param aTokenType the TokenType
141    * @return true iff aTokenType is LITERAL_TRUE or LITERAL_FALSE
142    */
 
143  4 toggle private static boolean isBooleanLiteralType(final int aTokenType)
144    {
145  4 final boolean isTrue = (aTokenType == TokenTypes.LITERAL_TRUE);
146  4 final boolean isFalse = (aTokenType == TokenTypes.LITERAL_FALSE);
147  4 return isTrue || isFalse;
148    }
149    }