1 package com.puppycrawl.tools.checkstyle.checks.metrics; 20 21 import com.puppycrawl.tools.checkstyle.api.Check; 22 import com.puppycrawl.tools.checkstyle.api.DetailAST; 23 import com.puppycrawl.tools.checkstyle.api.TokenTypes; 24 25 import com.puppycrawl.tools.checkstyle.checks.CheckUtils; 26 27 import java.util.Stack ; 28 29 36 public final class BooleanExpressionComplexityCheck extends Check 37 { 38 39 private static final int DEFAULT_MAX = 3; 40 41 42 private final Stack mContextStack = new Stack (); 43 44 private int mMax; 45 46 private Context mContext; 47 48 49 public BooleanExpressionComplexityCheck() 50 { 51 setMax(DEFAULT_MAX); 52 } 53 54 55 public int[] getDefaultTokens() 56 { 57 return new int[] { 58 TokenTypes.CTOR_DEF, 59 TokenTypes.METHOD_DEF, 60 TokenTypes.EXPR, 61 TokenTypes.LAND, 62 TokenTypes.BAND, 63 TokenTypes.LOR, 64 TokenTypes.BOR, 65 TokenTypes.BXOR, 66 }; 67 } 68 69 70 public int[] getRequiredTokens() 71 { 72 return getDefaultTokens(); 73 } 74 75 79 public int getMax() 80 { 81 return mMax; 82 } 83 84 88 public void setMax(int aMax) 89 { 90 mMax = aMax; 91 } 92 93 94 public void visitToken(DetailAST aAST) 95 { 96 switch (aAST.getType()) { 97 case TokenTypes.CTOR_DEF: 98 case TokenTypes.METHOD_DEF: 99 visitMethodDef(aAST); 100 break; 101 case TokenTypes.EXPR: 102 visitExpr(); 103 break; 104 case TokenTypes.LAND: 105 case TokenTypes.BAND: 106 case TokenTypes.LOR: 107 case TokenTypes.BOR: 108 case TokenTypes.BXOR: 109 mContext.visitBooleanOperator(); 110 break; 111 default: 112 throw new IllegalStateException (aAST.toString()); 113 } 114 } 115 116 117 public void leaveToken(DetailAST aAST) 118 { 119 switch (aAST.getType()) { 120 case TokenTypes.CTOR_DEF: 121 case TokenTypes.METHOD_DEF: 122 leaveMethodDef(); 123 break; 124 case TokenTypes.EXPR: 125 leaveExpr(aAST); 126 break; 127 default: 128 } 130 } 131 132 136 private void visitMethodDef(DetailAST aAST) 137 { 138 mContextStack.push(mContext); 139 mContext = new Context(!CheckUtils.isEqualsMethod(aAST)); 140 } 141 142 143 private void leaveMethodDef() 144 { 145 mContext = (Context) mContextStack.pop(); 146 } 147 148 149 private void visitExpr() 150 { 151 mContextStack.push(mContext); 152 mContext = new Context((mContext == null) || mContext.isChecking()); 153 } 154 155 159 private void leaveExpr(DetailAST aAST) 160 { 161 mContext.checkCount(aAST); 162 mContext = (Context) mContextStack.pop(); 163 } 164 165 171 private class Context 172 { 173 177 private final boolean mChecking; 178 179 private int mCount; 180 181 185 public Context(boolean aChecking) 186 { 187 mChecking = aChecking; 188 mCount = 0; 189 } 190 191 195 public boolean isChecking() 196 { 197 return mChecking; 198 } 199 200 201 public void visitBooleanOperator() 202 { 203 ++mCount; 204 } 205 206 210 public void checkCount(DetailAST aAST) 211 { 212 if (mChecking && (mCount > getMax())) { 213 final DetailAST parentAST = aAST.getParent(); 214 215 log(parentAST.getLineNo(), parentAST.getColumnNo(), 216 "booleanExpressionComplexity", 217 new Integer (mCount), 218 new Integer (getMax())); 219 } 220 } 221 } 222 } 223 | Popular Tags |