KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > IncompatibleTypes


1 /*
2  * FindBugs - Find Bugs in Java programs
3  * Copyright (C) 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.ba;
21
22 import java.util.Set JavaDoc;
23
24 import org.apache.bcel.classfile.JavaClass;
25 import org.apache.bcel.generic.ArrayType;
26 import org.apache.bcel.generic.ObjectType;
27 import org.apache.bcel.generic.ReferenceType;
28 import org.apache.bcel.generic.Type;
29
30 import edu.umd.cs.findbugs.Priorities;
31 import edu.umd.cs.findbugs.annotations.NonNull;
32
33 public class IncompatibleTypes {
34     final int priority;
35
36     final String JavaDoc msg;
37
38     private IncompatibleTypes(String JavaDoc msg, int priority) {
39         this.msg = msg;
40         this.priority = priority;
41     }
42
43     public int getPriority() {
44         return priority;
45     }
46
47     public String JavaDoc getMsg() {
48         return msg;
49     }
50
51     public String JavaDoc toString() {
52         return msg;
53     }
54
55     public static final IncompatibleTypes SEEMS_OK = new IncompatibleTypes(
56             "Seems OK", Priorities.IGNORE_PRIORITY);
57
58     public static final IncompatibleTypes ARRAY_AND_NON_ARRAY = new IncompatibleTypes(
59             "Array and non array", Priorities.HIGH_PRIORITY);
60
61     public static final IncompatibleTypes ARRAY_AND_OBJECT = new IncompatibleTypes(
62             "Array and Object", Priorities.LOW_PRIORITY);
63
64     public static final IncompatibleTypes INCOMPATIBLE_CLASSES = new IncompatibleTypes(
65             "Incompatible classes", Priorities.HIGH_PRIORITY);
66
67     public static final IncompatibleTypes UNRELATED_CLASS_AND_INTERFACE = new IncompatibleTypes(
68             "Unrelated class and interface", Priorities.HIGH_PRIORITY);
69
70     public static final IncompatibleTypes UNRELATED_INTERFACES = new IncompatibleTypes(
71             "Unrelated interfaces", Priorities.NORMAL_PRIORITY);
72
73     static public @NonNull IncompatibleTypes getPriorityForAssumingCompatible(
74             Type lhsType, Type rhsType) {
75         if (!(lhsType instanceof ReferenceType))
76             return SEEMS_OK;
77         if (!(rhsType instanceof ReferenceType))
78             return SEEMS_OK;
79
80     
81         while (lhsType instanceof ArrayType && rhsType instanceof ArrayType) {
82             lhsType = ((ArrayType) lhsType).getElementType();
83             rhsType = ((ArrayType) rhsType).getElementType();
84         }
85
86         if (lhsType instanceof ArrayType) {
87
88             if (rhsType.equals(ObjectType.OBJECT))
89                 return ARRAY_AND_OBJECT;
90             else
91                 return ARRAY_AND_NON_ARRAY;
92         }
93         if (rhsType instanceof ArrayType) {
94             if (lhsType.equals(ObjectType.OBJECT))
95                 return ARRAY_AND_OBJECT;
96             else
97                 return ARRAY_AND_NON_ARRAY;
98         }
99         if (lhsType.equals(rhsType))
100             return SEEMS_OK;
101
102         // For now, ignore the case where either reference is not
103
// of an object type. (It could be either an array or null.)
104
if (!(lhsType instanceof ObjectType)
105                 || !(rhsType instanceof ObjectType))
106             return SEEMS_OK;
107
108         return getPriorityForAssumingCompatible((ObjectType) lhsType,
109                 (ObjectType) rhsType);
110
111     }
112
113     static public @NonNull IncompatibleTypes getPriorityForAssumingCompatible(
114             ObjectType lhsType, ObjectType rhsType) {
115         // See if the types are related by inheritance.
116
try {
117             if (!Hierarchy.isSubtype(lhsType, rhsType)
118                     && !Hierarchy.isSubtype(rhsType, lhsType)) {
119                 AnalysisContext analysisContext = AnalysisContext
120                         .currentAnalysisContext();
121
122                 // Look up the classes
123
JavaClass lhsClass = analysisContext.lookupClass(lhsType
124                         .getClassName());
125                 JavaClass rhsClass = analysisContext.lookupClass(rhsType
126                         .getClassName());
127
128                 if (!lhsClass.isInterface() && !rhsClass.isInterface()) {
129                     // Both are class types, and therefore there is no possible
130
// way
131
// the compared objects can have the same runtime type.
132
return INCOMPATIBLE_CLASSES;
133                 } else {
134
135                     // Look up the common subtypes of the two types. If the
136
// intersection does not contain at least one instantiable
137
// class,
138
// then issue a warning of the appropriate type.
139
Set JavaDoc<JavaClass> commonSubtypes = analysisContext
140                             .getSubtypes().getTransitiveCommonSubtypes(
141                                     lhsClass, rhsClass);
142
143                     if (!containsAtLeastOneInstantiableClass(commonSubtypes)) {
144                         if (lhsClass.isInterface() && rhsClass.isInterface())
145                             return UNRELATED_INTERFACES;
146                         else
147                             return UNRELATED_CLASS_AND_INTERFACE;
148                     }
149
150                 }
151             }
152
153         } catch (ClassNotFoundException JavaDoc e) {
154             AnalysisContext.reportMissingClass(e);
155         }
156         return SEEMS_OK;
157     }
158
159     private static boolean containsAtLeastOneInstantiableClass(
160             Set JavaDoc<JavaClass> commonSubtypes) {
161         for (JavaClass javaClass : commonSubtypes) {
162             if (!javaClass.isInterface() && !javaClass.isAbstract())
163                 return true;
164         }
165         return false;
166     }
167
168 }
169
Popular Tags