@ClassVisitor(order=VisitOrder.BEFORE) public boolean beforeClass(TypeDefinition td) { if(td.isInterface()) return false; implementsCloneable = td.getExplicitInterfaces().stream().map(TypeReference::getInternalName).anyMatch( "java/lang/Cloneable"::equals); isCloneable = implementsCloneable || Types.isInstance(td, "java/lang/Cloneable"); return true; }
@Override public List<TypeReference> visitClassType(final TypeReference t, final Void ignored) { final TypeDefinition r = t.resolve(); if (r == null) { return Collections.emptyList(); } final List<TypeReference> interfaces = r.getExplicitInterfaces(); if (r.isGenericDefinition()) { if (t.isGenericDefinition()) { return interfaces; } if (isRawType(t)) { return eraseRecursive(interfaces); } final List<? extends TypeReference> formal = getTypeArguments(r); final List<? extends TypeReference> actual = getTypeArguments(t); final ArrayList<TypeReference> result = new ArrayList<>(); final Map<TypeReference, TypeReference> mappings = new HashMap<>(); for (int i = 0, n = formal.size(); i < n; i++) { mappings.put(formal.get(i), actual.get(i)); } for (int i = 0, n = interfaces.size(); i < n; i++) { result.add(substituteGenericArguments(interfaces.get(i), mappings)); } return result; } return interfaces; }
@Override public List<TypeReference> visitClassType(final TypeReference t, final Void ignored) { final TypeDefinition r = t.resolve(); if (r == null) { return Collections.emptyList(); } final List<TypeReference> interfaces = r.getExplicitInterfaces(); if (r.isGenericDefinition()) { if (t.isGenericDefinition()) { return interfaces; } if (isRawType(t)) { return eraseRecursive(interfaces); } final List<? extends TypeReference> formal = getTypeArguments(r); final List<? extends TypeReference> actual = getTypeArguments(t); final ArrayList<TypeReference> result = new ArrayList<>(); final Map<TypeReference, TypeReference> mappings = new HashMap<>(); for (int i = 0, n = formal.size(); i < n; i++) { mappings.put(formal.get(i), actual.get(i)); } for (int i = 0, n = interfaces.size(); i < n; i++) { result.add(substituteGenericArguments(interfaces.get(i), mappings)); } return result; } return interfaces; }
@Override protected StringBuilder appendGenericSignature(final StringBuilder sb) { StringBuilder s = super.appendGenericSignature(sb); final TypeReference baseType = getBaseType(); final List<TypeReference> interfaces = getExplicitInterfaces(); if (baseType == null) { if (interfaces.isEmpty()) { s = BuiltinTypes.Object.appendSignature(s); } } else { s = baseType.appendSignature(s); } for (final TypeReference interfaceType : interfaces) { s = interfaceType.appendSignature(s); } return s; }
@Override protected StringBuilder appendGenericSignature(final StringBuilder sb) { StringBuilder s = super.appendGenericSignature(sb); final TypeReference baseType = getBaseType(); final List<TypeReference> interfaces = getExplicitInterfaces(); if (baseType == null) { if (interfaces.isEmpty()) { s = BuiltinTypes.Object.appendSignature(s); } } else { s = baseType.appendSignature(s); } for (final TypeReference interfaceType : interfaces) { s = interfaceType.appendSignature(s); } return s; }
@Override protected StringBuilder appendGenericSignature(final StringBuilder sb) { StringBuilder s = super.appendGenericSignature(sb); final TypeReference baseType = getBaseType(); final List<TypeReference> interfaces = getExplicitInterfaces(); if (baseType == null) { if (interfaces.isEmpty()) { s = BuiltinTypes.Object.appendSignature(s); } } else { s = baseType.appendSignature(s); } for (final TypeReference interfaceType : interfaces) { s = interfaceType.appendSignature(s); } return s; }
public static TypeReference getDeclaredType(final TypeReference type) { if (type == null) { return null; } final TypeDefinition resolvedType = type.resolve(); if (resolvedType == null) { return type; } if (resolvedType.isAnonymous()) { final List<TypeReference> interfaces = resolvedType.getExplicitInterfaces(); final TypeReference baseType = interfaces.isEmpty() ? resolvedType.getBaseType() : interfaces.get(0); if (baseType != null) { final TypeReference asSuperType = asSuper(baseType, type); if (asSuperType != null) { return asSuperType; } return baseType.isGenericType() ? new RawType(baseType) : baseType; } } return type; }
public static TypeReference getDeclaredType(final TypeReference type) { if (type == null) { return null; } final TypeDefinition resolvedType = type.resolve(); if (resolvedType == null) { return type; } if (resolvedType.isAnonymous()) { final List<TypeReference> interfaces = resolvedType.getExplicitInterfaces(); final TypeReference baseType = interfaces.isEmpty() ? resolvedType.getBaseType() : interfaces.get(0); if (baseType != null) { final TypeReference asSuperType = asSuper(baseType, type); if (asSuperType != null) { return asSuperType; } return baseType.isGenericType() ? new RawType(baseType) : baseType; } } return type; }
@Override protected void visitType(TypeDefinition td) { TypeHierarchy th = getOrCreate(td); th.flags = td.getFlags(); link(th, td.getBaseType()); for (TypeReference id : td.getExplicitInterfaces()) link(th, id); }
public static TypeReference getDeclaredType(final TypeReference type) { if (type == null) { return null; } final TypeDefinition resolvedType = type.resolve(); if (resolvedType == null) { return type; } if (resolvedType.isAnonymous()) { final List<TypeReference> interfaces = resolvedType.getExplicitInterfaces(); final TypeReference baseType = interfaces.isEmpty() ? resolvedType.getBaseType() : interfaces.get(0); if (baseType != null) { final TypeReference asSuperType = asSuper(baseType, type); if (asSuperType != null) { return asSuperType; } return baseType.isGenericType() ? new RawType(baseType) : baseType; } } return type; }
public static boolean isInstance(TypeReference type, String wantedType) { if (type == null || type.isPrimitive()) return false; if (wantedType.equals("java/lang/Object")) return true; if (type.getInternalName().equals(wantedType)) return true; if (type.isArray()) { if(!wantedType.startsWith("[")) return false; return isInstance(type.getElementType(), wantedType.substring(1)); } TypeDefinition td = type.resolve(); if (td == null) return false; for (TypeReference iface : td.getExplicitInterfaces()) { if (isInstance(iface, wantedType)) return true; } TypeReference bt = td.getBaseType(); if (bt == null) return false; return isInstance(bt, wantedType); }
private static void collectSuperMethods(TypeDefinition type, MemberInfo mi, Set<MethodDefinition> list) { TypeReference superType = type.getBaseType(); if(superType != null) { TypeDefinition superTd = superType.resolve(); if(superTd != null) { MethodDefinition result = findMethod(superTd, mi); if(result != null) list.add(result); else collectSuperMethods(superTd, mi, list); } } for(TypeReference iface : type.getExplicitInterfaces()) { TypeDefinition ifaceTd = iface.resolve(); if(ifaceTd != null) { MethodDefinition result = findMethod(ifaceTd, mi); if(result != null) list.add(result); else collectSuperMethods(ifaceTd, mi, list); } } }
@ClassVisitor public void visitClass(TypeDefinition td, ClassContext cc) { if (td.isAnonymous() || td.isSynthetic()) return; String name = td.getSimpleName(); if (Character.isLetter(name.charAt(0)) && !Character.isUpperCase(name.charAt(0)) && name.indexOf('_') == -1) { cc.report("BadNameOfClass", td.isPublic() ? 0 : 15); } if (name.endsWith("Exception") && !Types.isInstance(td, "java/lang/Throwable")) { cc.report("BadNameOfClassException", td.isPublic() ? 0 : 15); } TypeReference superClass = td.getBaseType(); if (superClass != null && superClass.getSimpleName().equals(name)) { cc.report("BadNameOfClassSameAsSuperclass", td.isPublic() ? 0 : 15, Roles.SUPERCLASS.create(superClass)); } for (TypeReference iface : td.getExplicitInterfaces()) { if (iface.getSimpleName().equals(name)) { cc.report("BadNameOfClassSameAsInterface", td.isPublic() ? 0 : 15, Roles.INTERFACE.create(iface)); } } }
@ClassVisitor public void visit(TypeDefinition td, ClassContext cc) { TypeDefinition baseType = td.getBaseType().resolve(); if(baseType == null || Types.isObject(baseType)) return; for(TypeReference tr : td.getExplicitInterfaces()) { if(tr.getInternalName().equals("java/io/Serializable")) { continue; } if(Types.isInstance(baseType, tr)) { cc.report("RedundantInterface", td.isPublic() ? 0 : 10, Roles.INTERFACE.create(tr)); } } } }
public static MethodDefinition findSuperMethod(TypeDefinition type, MemberInfo mi) { TypeReference superType = type.getBaseType(); if(superType != null) { TypeDefinition superTd = superType.resolve(); if(superTd != null) { MethodDefinition result = findMethod(superTd, mi); if(result != null) return result; result = findSuperMethod(superTd, mi); if(result != null) return result; } } for(TypeReference iface : type.getExplicitInterfaces()) { TypeDefinition ifaceTd = iface.resolve(); if(ifaceTd != null) { MethodDefinition result = findMethod(ifaceTd, mi); if(result != null) return result; result = findSuperMethod(ifaceTd, mi); if(result != null) return result; } } return null; }
final MethodDefinition getMethod(final TypeDefinition declaringType, final MethodReference reference) { TypeDefinition type = declaringType; MethodDefinition method = getMethod(type.getDeclaredMethods(), reference); if (method != null) { return method; } final TypeReference baseType = declaringType.getBaseType(); if (baseType != null) { type = baseType.resolve(); if (type != null) { method = getMethod(type, reference); if (method != null) { return method; } } } for (final TypeReference interfaceType : declaringType.getExplicitInterfaces()) { type = interfaceType.resolve(); if (type != null) { method = getMethod(type, reference); if (method != null) { return method; } } } return null; }
final MethodDefinition getMethod(final TypeDefinition declaringType, final MethodReference reference) { TypeDefinition type = declaringType; MethodDefinition method = getMethod(type.getDeclaredMethods(), reference); if (method != null) { return method; } final TypeReference baseType = declaringType.getBaseType(); if (baseType != null) { type = baseType.resolve(); if (type != null) { method = getMethod(type, reference); if (method != null) { return method; } } } for (final TypeReference interfaceType : declaringType.getExplicitInterfaces()) { type = interfaceType.resolve(); if (type != null) { method = getMethod(type, reference); if (method != null) { return method; } } } return null; }
final MethodDefinition getMethod(final TypeDefinition declaringType, final MethodReference reference) { TypeDefinition type = declaringType; MethodDefinition method = getMethod(type.getDeclaredMethods(), reference); if (method != null) { return method; } final TypeReference baseType = declaringType.getBaseType(); if (baseType != null) { type = baseType.resolve(); if (type != null) { method = getMethod(type, reference); if (method != null) { return method; } } } for (final TypeReference interfaceType : declaringType.getExplicitInterfaces()) { type = interfaceType.resolve(); if (type != null) { method = getMethod(type, reference); if (method != null) { return method; } } } return null; }
/** * @param type type to check * @return true if all superclasses and superinterfaces could be loaded */ public static boolean hasCompleteHierarchy(TypeDefinition type) { if(type == null) return false; if(type.isArray()) return hasCompleteHierarchy(type.getElementType().resolve()); TypeReference base = type.getBaseType(); if(base != null && !hasCompleteHierarchy(base.resolve())) return false; for(TypeReference tr : type.getExplicitInterfaces()) { if(!hasCompleteHierarchy(tr.resolve())) return false; } return true; }
@Override public TypeReference visitClassType(final TypeReference t, final Void ignored) { final TypeDefinition resolved = t.resolve(); if (resolved == null) { return BuiltinTypes.Object; } TypeReference superType; if (resolved.isInterface()) { superType = resolved.getBaseType(); if (superType == null) { superType = firstOrDefault(resolved.getExplicitInterfaces()); } } else { superType = resolved.getBaseType(); } if (superType == null) { return null; } if (resolved.isGenericDefinition()) { if (!t.isGenericType()) { return eraseRecursive(superType); } if (t.isGenericDefinition()) { return superType; } return substituteGenericArguments(superType, classBound(t)); } return superType; }