KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > detect > FindBadCast


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2005-2006 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package edu.umd.cs.findbugs.detect;
21
22
23 import edu.umd.cs.findbugs.*;
24 import java.util.*;
25 import org.apache.bcel.Repository;
26 import org.apache.bcel.classfile.*;
27
28 public @java.lang.Deprecated JavaDoc class FindBadCast extends BytecodeScanningDetector implements StatelessDetector {
29
30
31     private HashSet<String JavaDoc> castTo = new HashSet<String JavaDoc>();
32
33     BugReporter bugReporter;
34
35     final static boolean DEBUG = false;
36
37     public FindBadCast(BugReporter bugReporter) {
38         this.bugReporter = bugReporter;
39         abstractCollectionClasses.add("java/util/Collection");
40         abstractCollectionClasses.add("java/util/List");
41         abstractCollectionClasses.add("java/util/Set");
42         abstractCollectionClasses.add("java/util/Map");
43         concreteCollectionClasses.add("java/util/LinkedHashMap");
44         concreteCollectionClasses.add("java/util/LinkedHashSet");
45         concreteCollectionClasses.add("java/util/HashMap");
46         concreteCollectionClasses.add("java/util/HashSet");
47         concreteCollectionClasses.add("java/util/TreeMap");
48         concreteCollectionClasses.add("java/util/TreeSet");
49         concreteCollectionClasses.add("java/util/ArrayList");
50         concreteCollectionClasses.add("java/util/LinkedList");
51         concreteCollectionClasses.add("java/util/Hashtable");
52         concreteCollectionClasses.add("java/util/Vector");
53     }
54
55     private Set<String JavaDoc> concreteCollectionClasses = new HashSet<String JavaDoc>();
56     private Set<String JavaDoc> abstractCollectionClasses = new HashSet<String JavaDoc>();
57
58
59
60     @Override JavaDoc
61          public void visit(JavaClass obj) {
62     }
63
64     @Override JavaDoc
65          public void visit(Method obj) {
66     }
67
68     /*
69         public boolean prescreen(ClassContext classContext, Method method) {
70                 BitSet bytecodeSet = classContext.getBytecodeSet(method);
71                 return bytecodeSet.get(Constants.CHECKCAST) || bytecodeSet.get(Constants.INSTANCEOF);
72         }
73     */

74     private int parameters;
75     OpcodeStack stack = new OpcodeStack();
76     @Override JavaDoc
77          public void visit(Code obj) {
78         if (DEBUG) {
79             System.out.println(getFullyQualifiedMethodName());
80             }
81         parameters = stack.resetForMethodEntry(this);
82         castTo.clear();
83         super.visit(obj);
84     }
85
86
87     @Override JavaDoc
88          public void sawOpcode(int seen) {
89         stack.mergeJumps(this);
90         if (DEBUG) {
91             System.out.println(stack);
92             printOpCode(seen);
93         }
94
95         if (stack.getStackDepth() > 0) {
96             if (seen == CHECKCAST || seen == INSTANCEOF) {
97                 if (DEBUG)
98                     System.out.println(" ... checking ... ");
99                 OpcodeStack.Item it = stack.getStackItem(0);
100                 String JavaDoc signature = it.getSignature();
101                 if (signature.length() > 0 && signature.charAt(0) == 'L')
102                     signature = signature.substring(1, signature.length() - 1);
103                 String JavaDoc signatureDot = signature.replace('/', '.');
104                 String JavaDoc to = getClassConstantOperand();
105                 if (to.length() > 0 && to.charAt(0) == 'L')
106                     to = to.substring(1, to.length() - 1);
107                 String JavaDoc toDot = to.replace('/', '.');
108                 if (signature.length() > 0
109                         && !signature.equals("java/lang/Object")
110                         && !signature.equals(to)) {
111
112                     try {
113                         JavaClass toClass = Repository.lookupClass(toDot);
114                         JavaClass signatureClass = Repository
115                                 .lookupClass(signatureDot);
116                         if (DEBUG)
117                             System.out.println(" ... checking ...... ");
118                         if (!castTo.contains(to)
119                                 && !Repository.instanceOf(signatureClass,
120                                         toClass)) {
121                             if (!Repository.instanceOf(toClass, signatureClass)
122                                     && ((!toClass.isInterface() && !signatureClass
123                                             .isInterface())
124                                             || signatureClass.isFinal() || toClass
125                                             .isFinal()))
126                                 bugReporter
127                                         .reportBug(new BugInstance(
128                                                 this,
129                                                 seen == CHECKCAST ? "BC_IMPOSSIBLE_CAST"
130                                                         : "BC_IMPOSSIBLE_INSTANCEOF",
131                                                 seen == CHECKCAST ? HIGH_PRIORITY
132                                                         : NORMAL_PRIORITY)
133                                                 .addClassAndMethod(this)
134                                                 .addSourceLine(this).addClass(
135                                                         signatureDot).addClass(
136                                                         toDot));
137                             else if (seen == CHECKCAST) {
138                                 int priority = NORMAL_PRIORITY;
139                                 if (DEBUG) {
140                                     System.out.println("Checking BC in "
141                                             + getFullyQualifiedMethodName());
142                                     System.out.println("to class: " + toClass);
143                                     System.out.println("from class: "
144                                             + signatureClass);
145                                     System.out.println("instanceof : "
146                                             + Repository.instanceOf(toClass,
147                                                     signatureClass));
148                                 }
149                                 if (Repository.instanceOf(toClass,
150                                         signatureClass))
151                                     priority += 2;
152                                 if (getThisClass().equals(toClass)
153                                         || getThisClass()
154                                                 .equals(signatureClass))
155                                     priority += 1;
156                                 if (DEBUG)
157                                     System.out
158                                             .println(" priority: " + priority);
159                                 if (toClass.isInterface())
160                                     priority++;
161                                 if (DEBUG)
162                                     System.out
163                                             .println(" priority: " + priority);
164                                 if (priority <= LOW_PRIORITY
165                                         && (signatureClass.isInterface() || signatureClass
166                                                 .isAbstract()))
167                                     priority++;
168                                 if (DEBUG)
169                                     System.out
170                                             .println(" priority: " + priority);
171                                 if (concreteCollectionClasses
172                                         .contains(signature)
173                                         || abstractCollectionClasses
174                                                 .contains(signature))
175                                     priority--;
176                                 if (concreteCollectionClasses.contains(to)
177                                         || abstractCollectionClasses
178                                                 .contains(to))
179                                     priority--;
180                                 if (DEBUG)
181                                     System.out
182                                             .println(" priority: " + priority);
183                                 int reg = it.getRegisterNumber();
184                                 if (reg >= 0 && reg < parameters
185                                         && it.isInitialParameter()
186                                         && getMethod().isPublic()) {
187                                     priority--;
188                                     if (getPC() < 4 && priority > LOW_PRIORITY)
189                                         priority--;
190                                 }
191                                 if (DEBUG)
192                                     System.out
193                                             .println(" priority: " + priority);
194                                 if (getMethodName().equals("compareTo"))
195                                     priority++;
196                                 if (DEBUG)
197                                     System.out
198                                             .println(" priority: " + priority);
199                                 if (priority < HIGH_PRIORITY)
200                                     priority = HIGH_PRIORITY;
201                                 if (priority <= LOW_PRIORITY) {
202                                     String JavaDoc bug = "BC_UNCONFIRMED_CAST";
203                                     if (concreteCollectionClasses.contains(to))
204                                         bug = "BC_BAD_CAST_TO_CONCRETE_COLLECTION";
205                                     else if (abstractCollectionClasses
206                                             .contains(to)
207                                             && (signature
208                                                     .equals("java/util/Collection") || signature
209                                                     .equals("java/lang/Iterable")))
210                                         bug = "BC_BAD_CAST_TO_ABSTRACT_COLLECTION";
211                                     bugReporter.reportBug(new BugInstance(this,
212                                             bug, priority).addClassAndMethod(
213                                             this).addSourceLine(this).addClass(
214                                             signatureDot).addClass(toDot));
215                                 }
216                             }
217
218                         }
219
220                     } catch (RuntimeException JavaDoc e) {
221                         // ignore it
222
} catch (ClassNotFoundException JavaDoc e) {
223                         // ignore it
224
}
225                 }
226             }
227         if (seen == INSTANCEOF) {
228             String JavaDoc to = getClassConstantOperand();
229             castTo.add(to);
230             }
231         }
232         stack.sawOpcode(this,seen);
233
234     }
235
236
237
238
239 }
240
Popular Tags