KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hammurapi > inspectors > HeterogenousCollection


1 /*
2  * Hammurapi
3  * Automated Java code review system.
4  * Copyright (C) 2005 Johannes Bellert
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * URL: http://www.hammurapi.org
21  * e-Mail: CraftOfObjects@gmail.com
22
23  * FIX 2: Added additional parameter types of add-methods
24  */

25
26 package org.hammurapi.inspectors;
27
28 import java.util.Hashtable JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
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 JavaDoc currentCollectionInstanceVariables = new Hashtable JavaDoc();
54
55     private Hashtable JavaDoc currentCollectionLocalVariables = new Hashtable JavaDoc();
56
57     
58     public void init() {
59         currentCollectionInstanceVariables = new Hashtable JavaDoc();
60         currentCollectionLocalVariables = new Hashtable JavaDoc();
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                 // Collection: Vector implements List
73
// is this a instance or class variable?
74

75                 LanguageElement el = element.getParent();
76                 if (el.getClass().equals(com.pavelvlasov.jsel.impl.ClassImpl.class)) {
77                     // instance variable
78
this.currentCollectionInstanceVariables.put(element.getName(), new ColletionMethodAdd());
79                 } else {
80                     this.currentCollectionLocalVariables.put(element.getName(), new ColletionMethodAdd());
81                 }
82             }
83         } catch (Exception JavaDoc 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 JavaDoc key = fetchProviderVariable(((LanguageElement) methodCall).getAst());
93             determineHetergenousViolationFor(key, methodCall);
94         }
95         return true;
96     }
97
98     private void determineHetergenousViolationFor(String JavaDoc key, MethodCall methodCall) {
99         List JavaDoc parameterList = methodCall.getParameters();
100
101         Iterator JavaDoc pit = parameterList.iterator();
102         while (pit.hasNext()) {
103             Object JavaDoc parameter = pit.next();
104             String JavaDoc typeDef = checkParameterTypeOf(parameter);
105             if ("int".equals(typeDef)) {
106                 // do nothing
107
} else {
108                 checkVariableRegistryFor(this.currentCollectionLocalVariables, key, typeDef, methodCall);
109                 checkVariableRegistryFor(this.currentCollectionInstanceVariables, key, typeDef, methodCall);
110             }
111         }
112     }
113
114     public void checkVariableRegistryFor(Hashtable JavaDoc ht, String JavaDoc key, String JavaDoc 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.reportViolation(srcM);
137
context.getSession().getContext("ER-214").reportViolation(srcM,
138                     typeDef + " is different from " + value.typeDef);
139         } else {
140             // ignore .. probably wrong variable registry
141
}
142     }
143
144     public String JavaDoc fetchProviderVariable(AST myAST) {
145         String JavaDoc errorRet = "<cant-determine-service-providing variable>";
146         if (myAST.getFirstToken() != null && myAST.getFirstToken().getText() != null) {
147             return myAST.getFirstToken().getText();
148         } else {
149             // System.out.println(errorRet);
150
return errorRet;
151         }
152     }
153
154     public String JavaDoc checkParameterTypeOf(Object JavaDoc 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                 /*
182                 Collection exprList = plus.getOperands();
183                 Iterator it = exprList.iterator();
184                 while ( it.hasNext()){
185                     Object obj = (Object)it.next();
186                     System.out.println( "++ " +obj.getClass().toString());
187                 }
188                 */

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 JavaDoc 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 JavaDoc typeDef = "";
209
210         public String JavaDoc 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