1 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 45 public class FinalLocalVariableCheck extends Check 46 { 47 48 private final Stack mScopeStack = new Stack (); 49 50 53 public int[] getDefaultTokens() 54 { 55 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 69 public int[] getAcceptableTokens() 70 { 71 return new int[] { 72 TokenTypes.VARIABLE_DEF, 73 TokenTypes.PARAMETER_DEF, 74 }; 75 } 76 77 78 public int[] getRequiredTokens() 79 { 80 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 95 public void visitToken(DetailAST aAST) 96 { 97 switch(aAST.getType()) { 98 case TokenTypes.OBJBLOCK: 99 case TokenTypes.SLIST: 100 case TokenTypes.LITERAL_FOR: 101 case TokenTypes.METHOD_DEF: 102 case TokenTypes.CTOR_DEF: 103 case TokenTypes.STATIC_INIT: 104 case TokenTypes.INSTANCE_INIT: 105 mScopeStack.push(new HashMap ()); 106 break; 107 108 case TokenTypes.PARAMETER_DEF: 109 if (ScopeUtils.inInterfaceBlock(aAST) 110 || inAbstractMethod(aAST)) 111 { 112 break; 113 } 114 case TokenTypes.VARIABLE_DEF: 115 if ((aAST.getParent().getType() != TokenTypes.OBJBLOCK) 116 && (aAST.getParent().getType() != TokenTypes.FOR_EACH_CLAUSE)) 117 { 118 insertVariable(aAST); 119 } 120 break; 121 122 case TokenTypes.IDENT: 123 final int parentType = aAST.getParent().getType(); 124 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 if (aAST.getParent().getFirstChild() == aAST) { 144 removeVariable(aAST); 145 } 146 } 147 break; 148 149 default: 150 } 151 } 152 153 158 private boolean inAbstractMethod(DetailAST aAST) 159 { 160 DetailAST parent = aAST.getParent(); 161 while (parent != null) { 162 if (parent.getType() == TokenTypes.METHOD_DEF) { 163 final DetailAST modifiers = 164 parent.findFirstToken(TokenTypes.MODIFIERS); 165 return modifiers.branchContains(TokenTypes.ABSTRACT); 166 } 167 parent = parent.getParent(); 168 } 169 return false; 170 } 171 172 176 private void insertVariable(DetailAST aAST) 177 { 178 if (!aAST.branchContains(TokenTypes.FINAL)) { 179 final HashMap state = (HashMap ) mScopeStack.peek(); 180 final DetailAST ast = aAST.findFirstToken(TokenTypes.IDENT); 181 state.put(ast.getText(), ast); 182 } 183 } 184 185 189 private void removeVariable(DetailAST aAST) 190 { 191 for (int i = mScopeStack.size() - 1; i >= 0; i--) { 192 final HashMap state = (HashMap ) mScopeStack.get(i); 193 final Object obj = state.remove(aAST.getText()); 194 if (obj != null) { 195 break; 196 } 197 } 198 } 199 200 203 public void leaveToken(DetailAST aAST) 204 { 205 super.leaveToken(aAST); 206 207 switch(aAST.getType()) { 208 case TokenTypes.OBJBLOCK: 209 case TokenTypes.SLIST: 210 case TokenTypes.LITERAL_FOR: 211 case TokenTypes.CTOR_DEF: 212 case TokenTypes.STATIC_INIT: 213 case TokenTypes.INSTANCE_INIT: 214 case TokenTypes.METHOD_DEF: 215 final HashMap state = (HashMap ) mScopeStack.pop(); 216 final Iterator finalVars = state.values().iterator(); 217 218 while (finalVars.hasNext()) { 219 final DetailAST var = (DetailAST) finalVars.next(); 220 log(var.getLineNo(), var.getColumnNo(), 221 "final.variable", var.getText()); 222 } 223 break; 224 225 default: 226 } 227 } 228 } 229 | Popular Tags |