private boolean isGenericCollection(ClassDescriptor operandClass) { String dottedClassName = operandClass.getDottedClassName(); if (baseGenericTypes.contains(dottedClassName)) return true; String found = null; for (String c : baseGenericTypes) { if (Subtypes2.instanceOf(operandClass, c)) { found = c; break; } } if (found == null) return false; if (dottedClassName.startsWith("java.util.") || dottedClassName.startsWith("com.google.common.collect.")) return true; try { XClass xclass = Global.getAnalysisCache().getClassAnalysis(XClass.class, operandClass); String sig = xclass.getSourceSignature(); if (sig == null) return false; String typeParameter = null; List<String> split = GenericUtilities.split(sig, true); if (sig.charAt(0) == '<') { int end = sig.indexOf(':'); if (end > 0) typeParameter = sig.substring(1, end); } if (DEBUG) System.out.println(dottedClassName + " " + typeParameter + " " + split); for (String s : split) { int i = s.indexOf('<'); if (i < 0) continue; if (s.charAt(0) != 'L') throw new IllegalStateException("unexpected non signature: " + s); ClassDescriptor c = DescriptorFactory.createClassDescriptor(s.substring(1, i)); String superTypeParameter = s.substring(i + 1); if (isGenericCollection(c) && (typeParameter == null || superTypeParameter.startsWith("T" + typeParameter))) { if (DEBUG) System.out.println(operandClass + " is a subtype of " + s); return true; } } if (DEBUG) System.out.println("Not a subtype"); } catch (CheckedAnalysisException e1) { AnalysisContext.logError( "Error checking for weird generic parameterization of " + operandClass, e1); } return false; }