1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import java.util.Set ; 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 msg; 37 38 private IncompatibleTypes(String 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 getMsg() { 48 return msg; 49 } 50 51 public String 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 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 try { 117 if (!Hierarchy.isSubtype(lhsType, rhsType) 118 && !Hierarchy.isSubtype(rhsType, lhsType)) { 119 AnalysisContext analysisContext = AnalysisContext 120 .currentAnalysisContext(); 121 122 JavaClass lhsClass = analysisContext.lookupClass(lhsType 124 .getClassName()); 125 JavaClass rhsClass = analysisContext.lookupClass(rhsType 126 .getClassName()); 127 128 if (!lhsClass.isInterface() && !rhsClass.isInterface()) { 129 return INCOMPATIBLE_CLASSES; 133 } else { 134 135 Set <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 e) { 154 AnalysisContext.reportMissingClass(e); 155 } 156 return SEEMS_OK; 157 } 158 159 private static boolean containsAtLeastOneInstantiableClass( 160 Set <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 |