Clover Coverage Report - Checkstyle
Coverage timestamp: Fri May 9 2008 10:48:13 EST
../../../../../../img/srcFileCovDistChart10.png 0% of files have more coverage
59   228   52   7.38
20   151   0.88   8
8     6.5  
1    
 
  FinalLocalVariableCheck       Line # 45 94.3% 0.9425287
52.51 59 52 52 0.88
 
  (2)
 
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    package com.puppycrawl.tools.checkstyle.checks.coding;
20   
21    import java.util.HashMap;
22    import java.util.Iterator;
23    import java.util.Stack;
24   
25    import com.puppycrawl.tools.checkstyle.api.Check;
26    import com.puppycrawl.tools.checkstyle.api.DetailAST;
27    import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
28    import com.puppycrawl.tools.checkstyle.api.TokenTypes;
29   
30    /**
31    * <p>
32    * Ensures that local variables that never get their values changed,
33    * must be declared final.
34    * </p>
35    * <p>
36    * An example of how to configure the check is:
37    * </p>
38    * <pre>
39    * &lt;module name="FinalLocalVariable"&gt;
40    * &lt;property name="token" value="VARIABLE_DEF"/&gt;
41    * &lt;/module&gt;
42    * </pre>
43    * @author k_gibbs, r_auckenthaler
44    */
 
45    public class FinalLocalVariableCheck extends Check
46    {
47    /** Scope Stack */
48    private final Stack mScopeStack = new Stack();
49   
50    /**
51    * {@inheritDoc}
52    */
 
53  1 toggle public int[] getDefaultTokens()
54    {
55  1 return new int[] {
56    TokenTypes.IDENT,
57    TokenTypes.CTOR_DEF,
58    TokenTypes.METHOD_DEF,
59    TokenTypes.VARIABLE_DEF,
60    TokenTypes.INSTANCE_INIT,
61    TokenTypes.STATIC_INIT,
62    TokenTypes.LITERAL_FOR,
63    TokenTypes.SLIST,
64    TokenTypes.OBJBLOCK,
65    };
66    }
67   
68    /** {@inheritDoc} */
 
69  1 toggle public int[] getAcceptableTokens()
70    {
71  1 return new int[] {
72    TokenTypes.VARIABLE_DEF,
73    TokenTypes.PARAMETER_DEF,
74    };
75    }
76   
77    /** {@inheritDoc} */
 
78  1 toggle public int[] getRequiredTokens()
79    {
80  1 return new int[] {
81    TokenTypes.IDENT,
82    TokenTypes.CTOR_DEF,
83    TokenTypes.METHOD_DEF,
84    TokenTypes.INSTANCE_INIT,
85    TokenTypes.STATIC_INIT,
86    TokenTypes.LITERAL_FOR,
87    TokenTypes.SLIST,
88    TokenTypes.OBJBLOCK,
89    };
90    }
91   
92    /**
93    * {@inheritDoc}
94    */
 
95  346 toggle public void visitToken(DetailAST aAST)
96    {
97  346 switch(aAST.getType()) {
98  20 case TokenTypes.OBJBLOCK:
99  34 case TokenTypes.SLIST:
100  4 case TokenTypes.LITERAL_FOR:
101  22 case TokenTypes.METHOD_DEF:
102  4 case TokenTypes.CTOR_DEF:
103  4 case TokenTypes.STATIC_INIT:
104  0 case TokenTypes.INSTANCE_INIT:
105  88 mScopeStack.push(new HashMap());
106  88 break;
107   
108  7 case TokenTypes.PARAMETER_DEF:
109  7 if (ScopeUtils.inInterfaceBlock(aAST)
110    || inAbstractMethod(aAST))
111    {
112  2 break;
113    }
114  35 case TokenTypes.VARIABLE_DEF:
115  40 if ((aAST.getParent().getType() != TokenTypes.OBJBLOCK)
116    && (aAST.getParent().getType() != TokenTypes.FOR_EACH_CLAUSE))
117    {
118  35 insertVariable(aAST);
119    }
120  40 break;
121   
122  216 case TokenTypes.IDENT:
123  216 final int parentType = aAST.getParent().getType();
124  216 if ((TokenTypes.POST_DEC == parentType)
125    || (TokenTypes.DEC == parentType)
126    || (TokenTypes.POST_INC == parentType)
127    || (TokenTypes.INC == parentType)
128    || (TokenTypes.ASSIGN == parentType)
129    || (TokenTypes.PLUS_ASSIGN == parentType)
130    || (TokenTypes.MINUS_ASSIGN == parentType)
131    || (TokenTypes.DIV_ASSIGN == parentType)
132    || (TokenTypes.STAR_ASSIGN == parentType)
133    || (TokenTypes.MOD_ASSIGN == parentType)
134    || (TokenTypes.SR_ASSIGN == parentType)
135    || (TokenTypes.BSR_ASSIGN == parentType)
136    || (TokenTypes.SL_ASSIGN == parentType)
137    || (TokenTypes.BXOR_ASSIGN == parentType)
138    || (TokenTypes.BOR_ASSIGN == parentType)
139    || (TokenTypes.BAND_ASSIGN == parentType))
140    {
141    // TODO: is there better way to check is aAST
142    // in left part of assignment?
143  24 if (aAST.getParent().getFirstChild() == aAST) {
144  22 removeVariable(aAST);
145    }
146    }
147  216 break;
148   
149  0 default:
150    }
151    }
152   
153    /**
154    * Determines whether an AST is a descentant of an abstract method.
155    * @param aAST the AST to check.
156    * @return true if aAST is a descentant of an abstract method.
157    */
 
158  6 toggle private boolean inAbstractMethod(DetailAST aAST)
159    {
160  6 DetailAST parent = aAST.getParent();
161  12 while (parent != null) {
162  12 if (parent.getType() == TokenTypes.METHOD_DEF) {
163  6 final DetailAST modifiers =
164    parent.findFirstToken(TokenTypes.MODIFIERS);
165  6 return modifiers.branchContains(TokenTypes.ABSTRACT);
166    }
167  6 parent = parent.getParent();
168    }
169  0 return false;
170    }
171   
172    /**
173    * Inserts a variable at the topmost scope stack
174    * @param aAST the variable to insert
175    */
 
176  35 toggle private void insertVariable(DetailAST aAST)