1 23 package org.hammurapi.inspectors; 24 25 import java.io.File ; 26 27 import org.hammurapi.InspectorBase; 28 29 import com.pavelvlasov.config.ConfigurationException; 30 import com.pavelvlasov.config.Parameterizable; 31 import com.pavelvlasov.jsel.Class; 32 import com.pavelvlasov.jsel.CompilationUnit; 33 import com.pavelvlasov.jsel.Interface; 34 import com.pavelvlasov.jsel.LanguageElement; 35 import com.pavelvlasov.jsel.Package; 36 import com.pavelvlasov.jsel.impl.JavaTokenTypes; 37 import com.pavelvlasov.jsel.impl.Token; 38 import com.pavelvlasov.review.SimpleSourceMarker; 39 40 84 public class IndentationRule extends InspectorBase implements Parameterizable { 85 86 89 public static final String PARAMETER_INDENT = "standard-indentation-level"; 90 91 94 public static final String PARAMETER_EXPR_INDENT = "expression-indentation-level"; 95 96 99 private int indentLevel; 100 101 104 private int exprIndentLevel; 105 106 109 private SimpleSourceMarker sourceMarker; 110 111 114 public IndentationRule() { 115 indentLevel = 2; 116 exprIndentLevel = 4; 117 } 118 119 125 public void visit(Class aClass) { 126 initSourceMarker(aClass); 127 check((Token) aClass.getAst().getFirstToken(), getClassLevel(aClass), 128 (Token) aClass.getAst().getLastToken()); 129 } 130 131 137 public void visit(Interface anInterface) { 138 check((Token) anInterface.getAst().getFirstToken(), 139 getClassLevel(anInterface), (Token) anInterface.getAst().getLastToken()); 140 } 141 142 148 protected void initSourceMarker(LanguageElement anElement) { 149 sourceMarker = new SimpleSourceMarker(anElement); 150 CompilationUnit unit = anElement.getCompilationUnit(); 151 Package pack = unit.getPackage(); 152 if (pack.getName().length() == 0) { 153 sourceMarker.setSourceURL(unit.getName()); 154 } else { 155 sourceMarker.setSourceURL(pack.getName().replace('.', File.separatorChar) 156 + File.separator + unit.getName()); 157 } 158 } 159 160 167 protected int getClassLevel(LanguageElement anElement) { 168 int classLevel = 0; 169 LanguageElement parent = anElement.getParent(); 170 while (parent != null && parent instanceof Class ) { 171 classLevel++; 172 parent = parent.getParent(); 173 } 174 return classLevel; 175 } 176 177 188 protected void check(Token firstToken, int classLevel, Token lastToken) { 189 Token current = firstToken; 190 if (current != null) { 191 int line = current.getLine(); 192 int requiredColumn = 1 + (classLevel * indentLevel); 193 int parenthesisLevel = 0; 194 boolean assignment = false; 195 do { 196 if (current.getType() == JavaTokenTypes.RCURLY) { 198 requiredColumn -= indentLevel; 199 } 200 if (current.getType() == JavaTokenTypes.ASSIGN && !assignment) { 202 assignment = true; 203 requiredColumn += exprIndentLevel; 204 } 205 if (current.getType() == JavaTokenTypes.SEMI && assignment) { 207 assignment = false; 208 requiredColumn -= exprIndentLevel; 209 } 210 if (current.getLine() > line) { 212 if (current.getType() != JavaTokenTypes.LITERAL_throws 216 && current.getType() != JavaTokenTypes.DOT) { 217 if (current.getColumn() != requiredColumn) { 218 sourceMarker.setLine(current.getLine()); 219 sourceMarker.setColumn(current.getColumn()); 220 context.reportViolation(sourceMarker); 221 } 222 } else { 223 int specialRequiredColumn = assignment ? requiredColumn 225 : requiredColumn + exprIndentLevel; 226 if (current.getColumn() != specialRequiredColumn) { 227 sourceMarker.setLine(current.getLine()); 228 sourceMarker.setColumn(current.getColumn()); 229 context.reportViolation(sourceMarker); 230 } 231 } 232 line = current.getLine(); 233 } 234 if (current.getType() == JavaTokenTypes.LCURLY) { 236 requiredColumn += indentLevel; 237 } 238 if (current.getType() == JavaTokenTypes.LPAREN 241 && parenthesisLevel++ == 0) { 242 requiredColumn += exprIndentLevel; 243 } 244 if (current.getType() == JavaTokenTypes.RPAREN 245 && --parenthesisLevel == 0) { 246 requiredColumn -= exprIndentLevel; 247 } 248 current = current.getNextNonWhiteSpaceToken(); 249 } while (current != null && current != lastToken); 250 } 251 } 252 253 261 public boolean setParameter(String aName, Object aValue) 262 throws ConfigurationException { 263 boolean parameterSupported = false; 264 if (aName.equals(PARAMETER_INDENT)) { 265 parameterSupported = true; 266 indentLevel = ((Integer ) aValue).intValue(); 267 } 268 if (aName.equals(PARAMETER_EXPR_INDENT)) { 269 parameterSupported = true; 270 exprIndentLevel = ((Integer ) aValue).intValue(); 271 } 272 if (!parameterSupported) { 273 throw new ConfigurationException("Parameter '" + aName 274 + "' is not supported by " + getClass().getName()); 275 } 276 return true; 277 } 278 } | Popular Tags |