1 package com.puppycrawl.tools.checkstyle.checks.coding; 20 21 import java.util.Stack ; 22 23 import com.puppycrawl.tools.checkstyle.api.Check; 24 import com.puppycrawl.tools.checkstyle.api.DetailAST; 25 import com.puppycrawl.tools.checkstyle.api.TokenTypes; 26 32 public final class ModifiedControlVariableCheck extends Check 33 { 34 35 private Stack mCurrentVariables = new Stack (); 36 37 private final Stack mVariableStack = new Stack (); 38 39 40 public int[] getDefaultTokens() 41 { 42 return new int[] { 43 TokenTypes.OBJBLOCK, 44 TokenTypes.LITERAL_FOR, 45 TokenTypes.FOR_ITERATOR, 46 TokenTypes.FOR_EACH_CLAUSE, 47 TokenTypes.ASSIGN, 48 TokenTypes.PLUS_ASSIGN, 49 TokenTypes.MINUS_ASSIGN, 50 TokenTypes.STAR_ASSIGN, 51 TokenTypes.DIV_ASSIGN, 52 TokenTypes.MOD_ASSIGN, 53 TokenTypes.SR_ASSIGN, 54 TokenTypes.BSR_ASSIGN, 55 TokenTypes.SL_ASSIGN, 56 TokenTypes.BAND_ASSIGN, 57 TokenTypes.BXOR_ASSIGN, 58 TokenTypes.BOR_ASSIGN, 59 TokenTypes.INC, 60 TokenTypes.POST_INC, 61 TokenTypes.DEC, 62 TokenTypes.POST_DEC, 63 }; 64 } 65 66 67 public int[] getRequiredTokens() 68 { 69 return getDefaultTokens(); 70 } 71 72 73 public void beginTree(DetailAST aRootAST) 74 { 75 mCurrentVariables.clear(); 77 mVariableStack.clear(); 78 } 79 80 81 public void visitToken(DetailAST aAST) 82 { 83 switch (aAST.getType()) { 84 case TokenTypes.OBJBLOCK: 85 enterBlock(); 86 break; 87 case TokenTypes.LITERAL_FOR: 88 case TokenTypes.FOR_ITERATOR: 89 case TokenTypes.FOR_EACH_CLAUSE: 90 break; 91 case TokenTypes.ASSIGN: 92 case TokenTypes.PLUS_ASSIGN: 93 case TokenTypes.MINUS_ASSIGN: 94 case TokenTypes.STAR_ASSIGN: 95 case TokenTypes.DIV_ASSIGN: 96 case TokenTypes.MOD_ASSIGN: 97 case TokenTypes.SR_ASSIGN: 98 case TokenTypes.BSR_ASSIGN: 99 case TokenTypes.SL_ASSIGN: 100 case TokenTypes.BAND_ASSIGN: 101 case TokenTypes.BXOR_ASSIGN: 102 case TokenTypes.BOR_ASSIGN: 103 case TokenTypes.INC: 104 case TokenTypes.POST_INC: 105 case TokenTypes.DEC: 106 case TokenTypes.POST_DEC: 107 checkIdent(aAST); 108 break; 109 default: 110 throw new IllegalStateException (aAST.toString()); 111 } 112 } 113 114 115 116 public void leaveToken(DetailAST aAST) 117 { 118 switch (aAST.getType()) { 119 case TokenTypes.FOR_ITERATOR: 120 leaveForIter(aAST.getParent()); 121 break; 122 case TokenTypes.FOR_EACH_CLAUSE: 123 leaveForEach(aAST); 124 break; 125 case TokenTypes.LITERAL_FOR: 126 leaveForDef(aAST); 127 break; 128 case TokenTypes.OBJBLOCK: 129 exitBlock(); 130 break; 131 case TokenTypes.ASSIGN: 132 case TokenTypes.PLUS_ASSIGN: 133 case TokenTypes.MINUS_ASSIGN: 134 case TokenTypes.STAR_ASSIGN: 135 case TokenTypes.DIV_ASSIGN: 136 case TokenTypes.MOD_ASSIGN: 137 case TokenTypes.SR_ASSIGN: 138 case TokenTypes.BSR_ASSIGN: 139 case TokenTypes.SL_ASSIGN: 140 case TokenTypes.BAND_ASSIGN: 141 case TokenTypes.BXOR_ASSIGN: 142 case TokenTypes.BOR_ASSIGN: 143 case TokenTypes.INC: 144 case TokenTypes.POST_INC: 145 case TokenTypes.DEC: 146 case TokenTypes.POST_DEC: 147 break; 149 default: 150 throw new IllegalStateException (aAST.toString()); 151 } 152 } 153 154 157 private void enterBlock() 158 { 159 mVariableStack.push(mCurrentVariables); 160 mCurrentVariables = new Stack (); 161 162 } 163 166 private void exitBlock() 167 { 168 mCurrentVariables = (Stack ) mVariableStack.pop(); 169 } 170 171 175 private void checkIdent(DetailAST aAST) 176 { 177 if ((mCurrentVariables != null) && !mCurrentVariables.isEmpty()) { 178 final DetailAST identAST = (DetailAST) aAST.getFirstChild(); 179 180 if ((identAST != null) 181 && (identAST.getType() == TokenTypes.IDENT) 182 && mCurrentVariables.contains(identAST.getText())) 183 { 184 log(aAST.getLineNo(), aAST.getColumnNo(), 185 "modified.control.variable", identAST.getText()); 186 } 187 } 188 } 189 190 194 private void leaveForIter(DetailAST aAST) 195 { 196 final DetailAST forInitAST = aAST.findFirstToken(TokenTypes.FOR_INIT); 197 DetailAST parameterDefAST = 198 forInitAST.findFirstToken(TokenTypes.VARIABLE_DEF); 199 200 for (; parameterDefAST != null; 201 parameterDefAST = (DetailAST) parameterDefAST.getNextSibling()) 202 { 203 if (parameterDefAST.getType() == TokenTypes.VARIABLE_DEF) { 204 final DetailAST param = 205 parameterDefAST.findFirstToken(TokenTypes.IDENT); 206 mCurrentVariables.push(param.getText()); 207 } 208 } 209 } 210 211 215 private void leaveForEach(DetailAST aForEach) 216 { 217 final DetailAST paramDef = 218 aForEach.findFirstToken(TokenTypes.VARIABLE_DEF); 219 final DetailAST paramName = paramDef.findFirstToken(TokenTypes.IDENT); 220 mCurrentVariables.push(paramName.getText()); 221 } 222 223 227 private void leaveForDef(DetailAST aAST) 228 { 229 final DetailAST forInitAST = aAST.findFirstToken(TokenTypes.FOR_INIT); 230 if (forInitAST != null) { 231 DetailAST parameterDefAST = 232 forInitAST.findFirstToken(TokenTypes.VARIABLE_DEF); 233 234 for (; parameterDefAST != null; 235 parameterDefAST = (DetailAST) parameterDefAST.getNextSibling()) 236 { 237 if (parameterDefAST.getType() == TokenTypes.VARIABLE_DEF) { 238 mCurrentVariables.pop(); 239 } 240 } 241 } 242 else { 243 mCurrentVariables.pop(); 245 } 246 } 247 } 248 | Popular Tags |