1 25 26 package org.hammurapi.inspectors; 27 28 import java.util.Hashtable ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 32 import org.hammurapi.InspectorBase; 33 34 import com.pavelvlasov.jsel.JselException; 35 import com.pavelvlasov.jsel.LanguageElement; 36 import com.pavelvlasov.jsel.OperationInfo; 37 import com.pavelvlasov.jsel.TypeSpecification; 38 import com.pavelvlasov.jsel.VariableDefinition; 39 import com.pavelvlasov.jsel.expressions.Dot; 40 import com.pavelvlasov.jsel.expressions.Ident; 41 import com.pavelvlasov.jsel.expressions.IndexOperation; 42 import com.pavelvlasov.jsel.expressions.IntegerConstant; 43 import com.pavelvlasov.jsel.expressions.MethodCall; 44 import com.pavelvlasov.jsel.expressions.NewObject; 45 import com.pavelvlasov.jsel.expressions.Plus; 46 import com.pavelvlasov.jsel.expressions.StringConstant; 47 import com.pavelvlasov.jsel.expressions.TypeCast; 48 import com.pavelvlasov.jsel.impl.AST; 49 import com.pavelvlasov.review.SourceMarker; 50 51 public class HeterogenousCollection extends InspectorBase { 52 53 private Hashtable currentCollectionInstanceVariables = new Hashtable (); 54 55 private Hashtable currentCollectionLocalVariables = new Hashtable (); 56 57 58 public void init() { 59 currentCollectionInstanceVariables = new Hashtable (); 60 currentCollectionLocalVariables = new Hashtable (); 61 } 62 63 public void visit(com.pavelvlasov.jsel.Class type) { 64 init(); 65 } 66 67 public void visit(VariableDefinition element) { 68 69 try { 70 TypeSpecification ts = element.getTypeSpecification(); 71 if (element.getTypeSpecification().isKindOf("java.util.Collection")) { 72 75 LanguageElement el = element.getParent(); 76 if (el.getClass().equals(com.pavelvlasov.jsel.impl.ClassImpl.class)) { 77 this.currentCollectionInstanceVariables.put(element.getName(), new ColletionMethodAdd()); 79 } else { 80 this.currentCollectionLocalVariables.put(element.getName(), new ColletionMethodAdd()); 81 } 82 } 83 } catch (Exception e) { 84 context.warn(element, e); 85 } 86 87 } 88 89 public boolean visit(MethodCall methodCall) throws JselException { 90 91 if ("add".equals(methodCall.getMethodName()) || "addAll".equals(methodCall.getMethodName())) { 92 String key = fetchProviderVariable(((LanguageElement) methodCall).getAst()); 93 determineHetergenousViolationFor(key, methodCall); 94 } 95 return true; 96 } 97 98 private void determineHetergenousViolationFor(String key, MethodCall methodCall) { 99 List parameterList = methodCall.getParameters(); 100 101 Iterator pit = parameterList.iterator(); 102 while (pit.hasNext()) { 103 Object parameter = pit.next(); 104 String typeDef = checkParameterTypeOf(parameter); 105 if ("int".equals(typeDef)) { 106 } else { 108 checkVariableRegistryFor(this.currentCollectionLocalVariables, key, typeDef, methodCall); 109 checkVariableRegistryFor(this.currentCollectionInstanceVariables, key, typeDef, methodCall); 110 } 111 } 112 } 113 114 public void checkVariableRegistryFor(Hashtable ht, String key, String typeDef, MethodCall methodCall) { 115 116 SourceMarker srcM = (SourceMarker) methodCall; 117 LanguageElement parent = ((LanguageElement) methodCall).getParent(); 118 ColletionMethodAdd value = (ColletionMethodAdd) ht.get(key); 119 if (value != null && value.isInitialize()) { 120 value.typeDef = typeDef; 121 value.callerMethodName = parent.getSignature(); 122 value.lineNumber = srcM.getLine(); 123 value.occurance++; 124 125 ht.put(key, value); 126 } else if (value != null && value.occurance > 0) { 127 value.occurance++; 128 context.debug(srcM, parent.getSignature() + " >> " + value.callerMethodName); 129 if ((3 > (srcM.getLine() - value.lineNumber))) { 130 context.getSession().getContext("ER-215").reportViolation(srcM, 131 "Collection " + key + " got " + value.occurance + " add-messages with parameter type " + value.typeDef ); 132 133 } 134 } 135 if (value != null && !value.isInitialize() && !typeDef.equals(value.typeDef)) { 136 context.getSession().getContext("ER-214").reportViolation(srcM, 138 typeDef + " is different from " + value.typeDef); 139 } else { 140 } 142 } 143 144 public String fetchProviderVariable(AST myAST) { 145 String errorRet = "<cant-determine-service-providing variable>"; 146 if (myAST.getFirstToken() != null && myAST.getFirstToken().getText() != null) { 147 return myAST.getFirstToken().getText(); 148 } else { 149 return errorRet; 151 } 152 } 153 154 public String checkParameterTypeOf(Object parameter) { 155 156 try { 157 if (parameter != null && parameter instanceof Ident) { 158 Ident p = (Ident) parameter; 159 return p.getTypeSpecification().getName(); 160 } else if (parameter != null && parameter instanceof StringConstant) { 161 return "java.lang.String"; 162 } else if (parameter != null && parameter instanceof MethodCall) { 163 MethodCall p = (MethodCall) parameter; 164 OperationInfo opi = p.getProvider(); 165 return opi.getReturnType().getName(); 166 } else if (parameter != null && parameter instanceof Dot) { 167 Dot p = (Dot) parameter; 168 return p.getTypeSpecification().getName(); 169 170 } else if (parameter != null && parameter instanceof IndexOperation) { 171 IndexOperation p = (IndexOperation) parameter; 172 return p.getTypeSpecification().getName(); 173 174 } else if (parameter != null && parameter instanceof TypeCast) { 175 TypeCast p = (TypeCast) parameter; 176 return p.getTypeSpecification().getName(); 177 178 179 } else if (parameter != null && parameter instanceof Plus) { 180 Plus plus = (Plus)parameter; 181 189 return "java.lang.String"; 190 191 192 } else if (parameter != null && parameter instanceof NewObject) { 193 NewObject p = (NewObject) parameter; 194 return p.getTypeSpecification().getName(); 195 } else if (parameter != null && parameter instanceof IntegerConstant) { 196 return "int"; 197 } 198 } catch (Exception e) { 199 context.warn((SourceMarker) parameter, e); 200 } 201 context.warn((SourceMarker) parameter, "Problem to determine parameters type " + parameter.toString()); 202 return "<parameter-type-not-determined>"; 203 } 204 205 class ColletionMethodAdd { 206 public int occurance = 0; 207 208 public String typeDef = ""; 209 210 public String callerMethodName = ""; 211 212 public int lineNumber = 0; 213 214 public boolean isInitialize() { 215 return (occurance == 0) && "".equals(callerMethodName) && (lineNumber == 0); 216 } 217 218 } 219 220 } 221 | Popular Tags |