@Override protected ReferenceType mergeReferenceTypes(ReferenceType aRef, ReferenceType bRef) throws DataflowAnalysisException { byte aType = aRef.getType(); byte bType = bRef.getType(); if (isExtendedStringType(aType) || isExtendedStringType(bType)) { // If both types are the same extended String type, // then the same type is returned. Otherwise, extended // types are downgraded to plain java.lang.String, // and a standard merge is applied. if (aType == bType) { return aRef; } if (isExtendedStringType(aType)) { aRef = Type.STRING; } if (isExtendedStringType(bType)) { bRef = Type.STRING; } } return super.mergeReferenceTypes(aRef, bRef); }
public void getActions(ReferenceType receiverType, String methodName, String signature, boolean isStatic, Collection<ObligationPolicyDatabaseAction> actionList) { if (DEBUG) { System.out.println("Lookup for " + receiverType + "," + methodName + "," + signature + "," + isStatic + ": "); } for (ObligationPolicyDatabaseEntry entry : entryList) { boolean matched = entry.getActions(receiverType, methodName, signature, isStatic, actionList); if (DEBUG) { if (matched) System.out.println(" Entry " + entry + " ==> MATCH"); // else // System.out.println(" ==> no match"); } } if (DEBUG) { System.out.println(" ** Resulting action list: " + actionList); } }
/** * Parse a bytecode signature that has 1 or more (possibly generic) types * and return a list of the Types. * * @param signature * bytecode signature e.g. e.g. * <code>Ljava/util/ArrayList<Ljava/lang/String;>;Ljava/util/ArrayList<TT;>;Ljava/util/ArrayList<*>;</code> */ public static final @CheckForNull List<ReferenceType> getTypeParameters(String signature) { GenericSignatureParser parser = new GenericSignatureParser("(" + signature + ")V"); List<ReferenceType> types = new ArrayList<ReferenceType>(); Iterator<String> iter = parser.parameterSignatureIterator(); while (iter.hasNext()) { String parameterString = iter.next(); ReferenceType t = (ReferenceType) getType(parameterString); if (t == null) return null; types.add(t); } return types; }
/** * Determine if one reference type is a subtype of another. * * @param t * a reference type * @param possibleSupertype * the possible supertype * @return true if t is a subtype of possibleSupertype, false if not */ public static boolean isSubtype(ReferenceType t, ReferenceType possibleSupertype) throws ClassNotFoundException { if (true) { return Global.getAnalysisCache().getDatabase(Subtypes2.class).isSubtype(t, possibleSupertype); } else { Map<ReferenceType, Boolean> subtypes = subtypeCache.get(possibleSupertype); if (subtypes == null) { subtypes = new HashMap<ReferenceType, Boolean>(); subtypeCache.put(possibleSupertype, subtypes); } Boolean result = subtypes.get(t); if (result == null) { result = Boolean.valueOf(t.isAssignmentCompatibleWith(possibleSupertype)); subtypes.put(t, result); } return result; } }
protected void addFindMethod(ParsedMethod m) { GeneratedMethod gm = new GeneratedMethod(m); InstructionList il = gm.start(); writeMethodPreamble(gm, il); il.append(new PUSH(_cp, (ObjectType) gm.getReturnType())); m.getArguments()[0].pushAsObject(il); il.append(_factory.createInvoke(EM_TYPE, "find", Type.OBJECT, new Type[] { Type.CLASS, Type.OBJECT }, Constants.INVOKEINTERFACE)); il.append(_factory.createCheckCast(((ReferenceType) gm.getReturnType()))); il.append(InstructionFactory.createReturn(gm.getReturnType())); gm.done(); }
protected void addPassThruMethod(ParsedMethod m) { GeneratedMethod gm = new GeneratedMethod(m); InstructionList il = gm.start(); Type returnType = gm.getReturnType(); boolean hasArg = m.getArgumentLength() > 0; writeMethodPreamble(gm, il); if (hasArg) il.append(InstructionFactory.createLoad(Type.OBJECT, 1)); il.append(_factory.createInvoke(EM_TYPE, m.getMethod().getName(), returnType == Type.VOID ? Type.VOID : Type.OBJECT, hasArg ? new Type[] { Type.OBJECT } : Type.NO_ARGS, Constants.INVOKEINTERFACE)); if (returnType != Type.VOID) { il.append(_factory.createCheckCast(((ReferenceType) returnType))); } il.append(InstructionFactory.createReturn(returnType)); gm.done(); }
public Type mergeTypes(Type a, Type b) throws DataflowAnalysisException { byte aType = a.getType(), bType = b.getType(); if (aType == T_TOP) // Top is the identity element return b; else if (bType == T_TOP) // Top is the identity element return a; else if (aType == T_BOTTOM || bType == T_BOTTOM) // Bottom meet anything is bottom return BottomType.instance(); else if (isReferenceType(aType) && isReferenceType(bType)) { // Two object types! // Handle the Null type, which serves as a special "top" // value for reference types. if (aType == T_NULL) return b; else if (bType == T_NULL) return a; ReferenceType aRef = (ReferenceType) a; ReferenceType bRef = (ReferenceType) b; return mergeReferenceTypes(aRef, bRef); } else if (isReferenceType(aType) || isReferenceType(bType)) // Object meet non-object is bottom return BottomType.instance(); else if (aType == bType) // Same non-object type? return a; else if (isIntegerType(aType) && isIntegerType(bType)) // Two different integer types - use T_INT return Type.INT; else // Default - types are incompatible return BottomType.instance(); }
/** * Default implementation of merging reference types. * This just returns the first common superclass, which is compliant * with the JVM Spec. Subclasses may override this method * in order to implement extended type rules. * * @param aRef a ReferenceType * @param bRef a ReferenceType * @return the merged Type */ protected Type mergeReferenceTypes(ReferenceType aRef, ReferenceType bRef) throws DataflowAnalysisException { // Two concrete object types. // According to the JVM spec, 2nd edition, 4.9.2, // the result of merging types is the "first common superclass". // Interfaces are NOT considered! // This will use the Repository to look up classes. try { // Special case: ExceptionObjectTypes. // We want to preserve the ExceptionSets associated, // in order to track the exact set of exceptions if (isObjectType(aRef.getType()) && isObjectType(bRef.getType()) && (aRef.getType() == T_EXCEPTION || bRef.getType() == T_EXCEPTION)) { ExceptionSet union = exceptionSetFactory.createExceptionSet(); updateExceptionSet(union, (ObjectType) aRef); updateExceptionSet(union, (ObjectType) bRef); return ExceptionObjectType.fromExceptionSet(union); } return aRef.getFirstCommonSuperclass(bRef); } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); throw new DataflowAnalysisException("Repository lookup failure: " + e.toString(), e); } }
/** * Get the least (lowest in the lattice) common supertype * of the exceptions in the set. Returns the special TOP * type if the set is empty. */ public Type getCommonSupertype() throws ClassNotFoundException { if (commonSupertype != null) return commonSupertype; if (isEmpty()) { // This probably means that we're looking at an // infeasible exception path. return TypeFrame.getTopType(); } // Compute first common superclass ThrownExceptionIterator i = iterator(); ReferenceType result = i.next(); while (i.hasNext()) { result = result.getFirstCommonSuperclass(i.next()); if (result == null) { // This should only happen if the class hierarchy // is incomplete. We'll just be conservative. result = Type.THROWABLE; break; } } // Cache and return the result commonSupertype = result; return result; }
public Method findMethod(InvokeInstruction ins) { String name = ins.getMethodName(cpg); String sig = ins.getSignature(cpg); ReferenceType cls = ins.getReferenceType(cpg); String s = (cls instanceof ObjectType) ? ((ObjectType) cls).getClassName() : "java.lang.Object"; JavaClass cl = lookupClass(s); if (cl == null) { System.out.println("findMethodClass: could not find class " + s); return null; } while (cl != null) { Method[] methods = cl.getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(name) && methods[i].getSignature().equals(sig)) { return methods[i]; } } try { cl = cl.getSuperClass(); } catch (ClassNotFoundException e) { System.out.println("findMethod: could not find class " + cl.getSuperclassName()); return null; } } System.out.println("findMethod: could not find method " + name + sig); return null; }
public JavaClass findMethodClass(InvokeInstruction ins) { String name = ins.getMethodName(cpg); String sig = ins.getSignature(cpg); ReferenceType cls = ins.getReferenceType(cpg); String s = (cls instanceof ObjectType) ? ((ObjectType) cls).getClassName() : "java.lang.Object"; JavaClass cl = lookupClass(s); if (cl == null) { System.out.println("findMethodClass: could not find class " + s); return null; } while (cl != null) { Method[] methods = cl.getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(name) && methods[i].getSignature().equals(sig)) { return cl; } } try { cl = cl.getSuperClass(); } catch (ClassNotFoundException e) { System.out.println("findMethodClass: could not find class " + cl.getSuperclassName()); return null; } } System.out.println("findMethodClass: could not find method " + name + sig); return null; }
private JavaClass findMethodClass(InvokeInstruction ins, ConstantPoolGen cpg) { String name = ins.getMethodName(cpg); String sig = ins.getSignature(cpg); ReferenceType cls = ins.getReferenceType(cpg); String className = (cls instanceof ObjectType) ? ((ObjectType) cls).getClassName() : "java.lang.Object"; JavaClass cl = lookupClass(className); if (cl == null) { return null; } while (cl != null) { Method[] methods = cl.getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(name) && methods[i].getSignature().equals(sig)) { return cl; } } try { cl = cl.getSuperClass(); } catch (ClassNotFoundException e) { System.out.println("findMethodClass: could not find class " + cl.getSuperclassName()); return null; } } return null; }
boolean isNonEscapingConstructor(INVOKESPECIAL invoker) { ReferenceType cls = invoker.getReferenceType(methodGen.getConstantPool()); String className = (cls instanceof ObjectType) ? ((ObjectType) cls).getClassName() : "java.lang.Object"; JavaClass javaClass; try { javaClass = Repository.lookupClass(className); } catch(ClassNotFoundException e) { return false; } return nonEscapingConstructor(javaClass, invoker.getSignature(methodGen.getConstantPool())); }
private int check_reflection(MethodGen mgen, ConstantPoolGen cpgen) { int cnt = 0; InstructionList ilist = mgen.getInstructionList(); if (ilist == null || ilist.size() == 0) return cnt; for (Instruction instr : ilist.getInstructions()) { // go through all instructions and look for invokes if (instr instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) instr; ReferenceType rtype = invoke.getReferenceType(cpgen); if (rtype instanceof ObjectType) { String cname = ((ObjectType) rtype).getClassName(); String mname = invoke.getName(cpgen); // we look for exact match if (cname.equals("java.lang.reflect.Method") && mname.equals("invoke")) { // Util.log(rtype.toString()); cnt++; } } else { // reference type can be ArrayType or UninitializedObjectType } } } return cnt; }
public Stream createStream(Location location, ObjectType type, ConstantPoolGen cpg, RepositoryLookupFailureCallback lookupFailureCallback) { try { Instruction ins = location.getHandle().getInstruction(); // For now, just support instance methods short opcode = ins.getOpcode(); if (!invokeOpcodeSet.get(opcode)) return null; // Is invoked class a subtype of the base class we want // FIXME: should test be different for INVOKESPECIAL and // INVOKESTATIC? InvokeInstruction inv = (InvokeInstruction) ins; ReferenceType classType = inv.getReferenceType(cpg); if (!Hierarchy.isSubtype(classType, baseClassType)) return null; // See if method name and signature match String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); if (!this.methodName.equals(methodName) || !this.methodSig.equals(methodSig)) return null; String streamClass = type.getClassName(); if (streamClass.equals("java.sql.CallableStatement")) streamClass = "java.sql.PreparedStatement"; Stream result = new Stream(location, streamClass, streamClass).setIgnoreImplicitExceptions(true).setIsOpenOnCreation( true); if (!isUninteresting) result.setInteresting(bugType); return result; } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); } return null; }
private void considerMethod(ClassContext classContext, Method method) { if ((method.getReturnType() instanceof ReferenceType) && classContext.getMethodGen(method) != null) { if (VERBOSE_DEBUG) System.out.println("Check " + method); analyzeMethod(classContext, method); } }
private boolean compareTypesOld(Type parmType, Type argType) { // XXX equality not implemented for GenericObjectType // if (parmType.equals(argType)) return true; // Compare type signatures instead if (GenericUtilities.getString(parmType).equals(GenericUtilities.getString(argType))) return true; if (parmType instanceof GenericObjectType) { GenericObjectType o = (GenericObjectType) parmType; if (o.getTypeCategory() == GenericUtilities.TypeCategory.WILDCARD_EXTENDS) { return compareTypesOld(o.getExtension(), argType); } } // ignore type variables for now if (parmType instanceof GenericObjectType && !((GenericObjectType) parmType).hasParameters()) return true; if (argType instanceof GenericObjectType && !((GenericObjectType) argType).hasParameters()) return true; // Case: Both are generic containers if (parmType instanceof GenericObjectType && argType instanceof GenericObjectType) { return true; } else { // Don't consider non reference types (should not be possible) if (!(parmType instanceof ReferenceType && argType instanceof ReferenceType)) return true; // Don't consider non object types (for now) if (!(parmType instanceof ObjectType && argType instanceof ObjectType)) return true; // Otherwise, compare base types ignoring generic information try { return Repository.instanceOf(((ObjectType) argType).getClassName(), ((ObjectType) parmType).getClassName()); } catch (ClassNotFoundException e) { } } return true; }
private void considerMethod(ClassContext classContext, Method method) { boolean hasReferenceParameters = false; for (Type argument : method.getArgumentTypes()) if (argument instanceof ReferenceType) { hasReferenceParameters = true; } if (hasReferenceParameters && classContext.getMethodGen(method) != null) { if (VERBOSE_DEBUG) System.out.println("Check " + method); analyzeMethod(classContext, method); } }
public boolean getActions(ReferenceType receiverType, String methodName, String signature, boolean isStatic, Collection<ObligationPolicyDatabaseAction> actionList) { if (this.methodName.matches(methodName) && this.signature.matches(signature) && this.isStatic == isStatic && this.receiverType.matches(receiverType)) { for (Obligation o : obligations) actionList.add(new ObligationPolicyDatabaseAction(action, o)); return true; } return false; }
/** * Get the least (lowest in the lattice) common supertype of the exceptions * in the set. Returns the special TOP type if the set is empty. */ public Type getCommonSupertype() throws ClassNotFoundException { if (commonSupertype != null) return commonSupertype; if (isEmpty()) { // This probably means that we're looking at an // infeasible exception path. return TypeFrame.getTopType(); } // Compute first common superclass ThrownExceptionIterator i = iterator(); ReferenceType result = i.next(); while (i.hasNext()) { if (Subtypes2.ENABLE_SUBTYPES2_FOR_COMMON_SUPERCLASS_QUERIES) { result = AnalysisContext.currentAnalysisContext().getSubtypes2().getFirstCommonSuperclass(result, i.next()); } else { result = result.getFirstCommonSuperclass(i.next()); } if (result == null) { // This should only happen if the class hierarchy // is incomplete. We'll just be conservative. result = Type.THROWABLE; break; } } // Cache and return the result commonSupertype = result; return result; }
public static ObjectType merge(GenericObjectType t1, ObjectType t2) { if (t2 instanceof GenericObjectType) return t2; List<? extends ReferenceType> parameters = t1.getParameters(); if (parameters == null) return t2; return new GenericObjectType(t2.getClassName(), parameters); }
/** * @param index * should be less than getNumParameters() * @return the type parameter at index */ public ReferenceType getParameterAt(int index) { if (index < getNumParameters()) return parameters.get(index); else throw new IndexOutOfBoundsException("The index " + index + " is too large for " + this); }
public void purgeBoringEntries() { Collection<FieldDescriptor> keys = new ArrayList<FieldDescriptor>(getKeys()); for (FieldDescriptor f : keys) { String s = f.getSignature(); FieldStoreType type = getProperty(f); Type fieldType = Type.getType(f.getSignature()); if (!(fieldType instanceof ReferenceType)) { removeProperty(f); continue; } ReferenceType storeType = type.getLoadType((ReferenceType) fieldType); if (storeType.equals(fieldType)) removeProperty(f); } }
/** * Create a GenericObjectType that represents a Wildcard with extensions * * @param variable * the type variable e.g. <code>T</code> */ GenericObjectType(@Nonnull String wildcard, ReferenceType extension) { super(DescriptorFactory.canonicalizeString(Type.OBJECT.getClassName())); this.variable = DescriptorFactory.canonicalizeString(wildcard); this.extension = extension; parameters = null; }
private void putFirstCommonSuperclassQueryCache(ReferenceType a, ReferenceType b, ReferenceType answer) { if (a.getSignature().compareTo(b.getSignature()) > 0) { ReferenceType tmp = a; a = b; b = tmp; } firstCommonSuperclassQueryCache.put(a, b, answer); }
/** * Constructor. */ public Subtypes2() { this.graph = new InheritanceGraph(); this.classDescriptorToVertexMap = new HashMap<ClassDescriptor, ClassVertex>(); this.supertypeSetMap = new MapCache<ClassDescriptor, SupertypeQueryResults>(500); this.subtypeSetMap = new MapCache<ClassDescriptor, Set<ClassDescriptor>>(500); this.xclassSet = new HashSet<XClass>(); this.SERIALIZABLE = ObjectTypeFactory.getInstance("java.io.Serializable"); this.CLONEABLE = ObjectTypeFactory.getInstance("java.lang.Cloneable"); this.firstCommonSuperclassQueryCache = new DualKeyHashMap<ReferenceType, ReferenceType, ReferenceType>(); }
private ReferenceType checkFirstCommonSuperclassQueryCache(ReferenceType a, ReferenceType b) { if (a.getSignature().compareTo(b.getSignature()) > 0) { ReferenceType tmp = a; a = b; b = tmp; } return firstCommonSuperclassQueryCache.get(a, b); }
/** * Get first common supertype of arrays with the same number of dimensions. * * @param aArrType * an ArrayType * @param bArrType * another ArrayType with the same number of dimensions * @return first common supertype * @throws ClassNotFoundException */ private ReferenceType computeFirstCommonSuperclassOfSameDimensionArrays(ArrayType aArrType, ArrayType bArrType) throws ClassNotFoundException { assert aArrType.getDimensions() == bArrType.getDimensions(); Type aBaseType = aArrType.getBasicType(); Type bBaseType = bArrType.getBasicType(); boolean aBaseIsObjectType = (aBaseType instanceof ObjectType); boolean bBaseIsObjectType = (bBaseType instanceof ObjectType); if (!aBaseIsObjectType || !bBaseIsObjectType) { assert (aBaseType instanceof BasicType) || (bBaseType instanceof BasicType); if (aArrType.getDimensions() > 1) { // E.g.: first common supertype of int[][] and WHATEVER[][] is // Object[] return new ArrayType(Type.OBJECT, aArrType.getDimensions() - 1); } else { assert aArrType.getDimensions() == 1; // E.g.: first common supertype type of int[] and WHATEVER[] is // Object return Type.OBJECT; } } else { assert (aBaseType instanceof ObjectType); assert (bBaseType instanceof ObjectType); // Base types are both ObjectTypes, and number of dimensions is // same. // We just need to find the first common supertype of base types // and return a new ArrayType using that base type. ObjectType firstCommonBaseType = getFirstCommonSuperclass((ObjectType) aBaseType, (ObjectType) bBaseType); return new ArrayType(firstCommonBaseType, aArrType.getDimensions()); } }
/** * Get the first common superclass of arrays with different numbers of * dimensions. * * @param aArrType * an ArrayType * @param bArrType * another ArrayType * @return ReferenceType representing first common superclass */ private ReferenceType computeFirstCommonSuperclassOfDifferentDimensionArrays(ArrayType aArrType, ArrayType bArrType) { assert aArrType.getDimensions() != bArrType.getDimensions(); boolean aBaseTypeIsPrimitive = (aArrType.getBasicType() instanceof BasicType); boolean bBaseTypeIsPrimitive = (bArrType.getBasicType() instanceof BasicType); if (aBaseTypeIsPrimitive || bBaseTypeIsPrimitive) { int minDimensions, maxDimensions; if (aArrType.getDimensions() < bArrType.getDimensions()) { minDimensions = aArrType.getDimensions(); maxDimensions = bArrType.getDimensions(); } else { minDimensions = bArrType.getDimensions(); maxDimensions = aArrType.getDimensions(); } if (minDimensions == 1) { // One of the types was something like int[]. // The only possible common supertype is Object. return Type.OBJECT; } else { // Weird case: e.g., // - first common supertype of int[][] and char[][][] is // Object[] // because f.c.s. of int[] and char[][] is Object // - first common supertype of int[][][] and char[][][][][] is // Object[][] // because f.c.s. of int[] and char[][][] is Object return new ArrayType(Type.OBJECT, maxDimensions - minDimensions); } } else { // Both a and b have base types which are ObjectTypes. // Since the arrays have different numbers of dimensions, the // f.c.s. will have Object as its base type. // E.g., f.c.s. of Cat[] and Dog[][] is Object[] return new ArrayType(Type.OBJECT, Math.min(aArrType.getDimensions(), bArrType.getDimensions())); } }
/** * Resolve possible instance method call targets. * * @param receiverType * type of the receiver object * @param invokeInstruction * the InvokeInstruction * @param cpg * the ConstantPoolGen * @param receiverTypeIsExact * if true, the receiver type is known exactly, which should * allow a precise result * @return Set of methods which might be called * @throws ClassNotFoundException */ public static Set<XMethod> resolveMethodCallTargets(ReferenceType receiverType, InvokeInstruction invokeInstruction, ConstantPoolGen cpg, boolean receiverTypeIsExact) throws ClassNotFoundException { if (invokeInstruction.getOpcode() == Constants.INVOKESTATIC) throw new IllegalArgumentException(); String methodName = invokeInstruction.getName(cpg); String methodSig = invokeInstruction.getSignature(cpg); // Array method calls aren't virtual. // They should just resolve to Object methods. if (receiverType instanceof ArrayType) try { return Util.emptyOrNonnullSingleton(getXClass(objectDescriptor).findMethod(methodName, methodSig, false)); } catch (CheckedAnalysisException e) { return Collections.<XMethod> emptySet(); } if (receiverType instanceof ObjectType) { // Get the receiver class. String receiverClassName = ((ObjectType) receiverType).getClassName(); return resolveVirtualMethodCallTargets(receiverClassName, methodName, methodSig, receiverTypeIsExact, invokeInstruction instanceof INVOKESPECIAL); } assert receiverType instanceof NullType; return Collections.<XMethod> emptySet(); }
public Type mergeTypes(Type a, Type b) throws DataflowAnalysisException { byte aType = a.getType(), bType = b.getType(); if (aType == T_TOP) // Top is the identity element return b; else if (bType == T_TOP) // Top is the identity element return a; else if (aType == T_BOTTOM || bType == T_BOTTOM) // Bottom meet anything // is bottom return BottomType.instance(); else if (isReferenceType(aType) && isReferenceType(bType)) { // Two // object // types! // Handle the Null type, which serves as a special "top" // value for reference types. if (aType == T_NULL) return b; else if (bType == T_NULL) return a; ReferenceType aRef = (ReferenceType) a; ReferenceType bRef = (ReferenceType) b; return mergeReferenceTypes(aRef, bRef); } else if (isReferenceType(aType) || isReferenceType(bType)) // Object // meet // non-object // is // bottom return BottomType.instance(); else if (aType == bType) // Same non-object type? return a; else if (isIntegerType(aType) && isIntegerType(bType)) // Two different // integer types // - use T_INT return Type.INT; else // Default - types are incompatible return BottomType.instance(); }
private boolean isThrowable(ReferenceType ref) /* * throws * ClassNotFoundException */{ try { Subtypes2 subtypes2 = AnalysisContext.currentAnalysisContext().getSubtypes2(); return subtypes2.isSubtype(ref, Type.THROWABLE); } catch (ClassNotFoundException e) { // We'll just assume that it's not an exception type. lookupFailureCallback.reportMissingClass(e); return false; } }
static public @Nonnull IncompatibleTypes getPriorityForAssumingCompatible(GenericObjectType genericType, Type plainType) { IncompatibleTypes result = IncompatibleTypes.getPriorityForAssumingCompatible(genericType.getObjectType(), plainType); List<? extends ReferenceType> parameters = genericType.getParameters(); if (result.getPriority() == Priorities.NORMAL_PRIORITY && parameters != null && parameters.contains(plainType)) { result = UNRELATED_TYPES_BUT_MATCHES_TYPE_PARAMETER; } return result; }
public boolean matches(Type t) { if (!(t instanceof ReferenceType)) { return false; } IAnalysisCache analysisCache = Global.getAnalysisCache(); Subtypes2 subtypes2 = analysisCache.getDatabase(Subtypes2.class); try { return subtypes2.isSubtype((ReferenceType) t, supertype); } catch (ClassNotFoundException e) { analysisCache.getErrorLogger().reportMissingClass(e); return false; } }