1 20 package com.puppycrawl.tools.checkstyle.checks.coding; 21 22 import java.util.Arrays ; 23 24 import antlr.collections.AST; 25 26 import com.puppycrawl.tools.checkstyle.api.Check; 27 import com.puppycrawl.tools.checkstyle.api.TokenTypes; 28 import com.puppycrawl.tools.checkstyle.api.DetailAST; 29 30 44 public class InnerAssignmentCheck 45 extends Check 46 { 47 51 private static final int[][] ALLOWED_ASSIGMENT_CONTEXT = { 52 {TokenTypes.EXPR, TokenTypes.SLIST}, 53 {TokenTypes.VARIABLE_DEF}, 54 {TokenTypes.EXPR, TokenTypes.ELIST, TokenTypes.FOR_INIT}, 55 {TokenTypes.EXPR, TokenTypes.ELIST, TokenTypes.FOR_ITERATOR}, 56 {TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR}, 57 }; 58 59 63 private static final int[][] CONTROL_CONTEXT = { 64 {TokenTypes.EXPR, TokenTypes.LITERAL_DO}, 65 {TokenTypes.EXPR, TokenTypes.LITERAL_FOR}, 66 {TokenTypes.EXPR, TokenTypes.LITERAL_WHILE}, 67 {TokenTypes.EXPR, TokenTypes.LITERAL_IF}, 68 {TokenTypes.EXPR, TokenTypes.LITERAL_ELSE}, 69 }; 70 71 75 private static final int[][] ALLOWED_ASSIGMENT_IN_COMPARISON_CONTEXT = { 76 {TokenTypes.EXPR, TokenTypes.LITERAL_WHILE, }, 77 }; 78 79 82 private static final int[] COMPARISON_TYPES = { 83 TokenTypes.EQUAL, 84 TokenTypes.GE, 85 TokenTypes.GT, 86 TokenTypes.LE, 87 TokenTypes.LT, 88 TokenTypes.NOT_EQUAL, 89 }; 90 91 static { 92 Arrays.sort(COMPARISON_TYPES); 93 } 94 95 96 public int[] getDefaultTokens() 97 { 98 return new int[] { 99 TokenTypes.ASSIGN, TokenTypes.DIV_ASSIGN, TokenTypes.PLUS_ASSIGN, TokenTypes.MINUS_ASSIGN, TokenTypes.STAR_ASSIGN, TokenTypes.MOD_ASSIGN, TokenTypes.SR_ASSIGN, TokenTypes.BSR_ASSIGN, TokenTypes.SL_ASSIGN, TokenTypes.BXOR_ASSIGN, TokenTypes.BOR_ASSIGN, TokenTypes.BAND_ASSIGN, }; 112 } 113 114 115 public void visitToken(DetailAST aAST) 116 { 117 if (isInContext(aAST, ALLOWED_ASSIGMENT_CONTEXT)) { 118 return; 119 } 120 121 if (isInNoBraceControlStatement(aAST)) { 122 return; 123 } 124 125 if (isInWhileIdiom(aAST)) { 126 return; 127 } 128 129 log(aAST.getLineNo(), aAST.getColumnNo(), "assignment.inner.avoid"); 130 } 131 132 157 private static boolean isInNoBraceControlStatement(DetailAST aAST) 158 { 159 if (!isInContext(aAST, CONTROL_CONTEXT)) { 160 return false; 161 } 162 final DetailAST expr = aAST.getParent(); 163 final AST exprNext = expr.getNextSibling(); 164 return (exprNext != null) && (exprNext.getType() == TokenTypes.SEMI); 165 } 166 167 179 private boolean isInWhileIdiom(DetailAST aAST) 180 { 181 if (!isComparison(aAST.getParent())) { 182 return false; 183 } 184 return isInContext( 185 aAST.getParent(), ALLOWED_ASSIGMENT_IN_COMPARISON_CONTEXT); 186 } 187 188 193 private static boolean isComparison(DetailAST aAST) 194 { 195 final int astType = aAST.getType(); 196 return (Arrays.binarySearch(COMPARISON_TYPES, astType) >= 0); 197 } 198 199 209 private static boolean isInContext(DetailAST aAST, int[][] aContextSet) 210 { 211 for (int i = 0; i < aContextSet.length; i++) { 212 DetailAST current = aAST; 213 final int len = aContextSet[i].length; 214 for (int j = 0; j < len; j++) { 215 current = current.getParent(); 216 final int expectedType = aContextSet[i][j]; 217 if ((current == null) || (current.getType() != expectedType)) { 218 break; 219 } 220 if (j == len - 1) { 221 return true; 222 } 223 } 224 } 225 return false; 226 } 227 } 228 | Popular Tags |