ArrayList<Field> fields = getSortedInstanceFields(getClassDef()); String superclassType = getSuperclass(); if (superclassType != null) { SparseArray<FieldReference> superFields = superclass.getInstanceFields(); FieldReference field = null; int lastOffset = 0;
for (String interfaceType: getClassDef().getInterfaces()) { if (!interfaces.containsKey(interfaceType)) { ClassDef interfaceDef; for (String superInterface: interfaceProto.getInterfaces().keySet()) { if (!interfaces.containsKey(superInterface)) { interfaces.put(superInterface, interfaceProto.getInterfaces().get(superInterface)); unresolvedInterfaces.addAll(interfaceProto.getUnresolvedInterfaces()); interfacesFullyResolved = false; if (isInterface() && !interfaces.containsKey(getType())) { interfaces.put(getType(), null); String superclass = getSuperclass(); try { if (superclass != null) { ClassProto superclassProto = (ClassProto) classPath.getClass(superclass); for (String superclassInterface: superclassProto.getInterfaces().keySet()) { if (!interfaces.containsKey(superclassInterface)) { interfaces.put(superclassInterface, null); unresolvedInterfaces.addAll(superclassProto.getUnresolvedInterfaces()); interfacesFullyResolved = false;
superclassType = getSuperclass(); } catch (UnresolvedClassException ex) { vtable.addAll(((ClassProto)classPath.getClass("Ljava/lang/Object;")).getVtable()); vtableFullyResolved = false; return vtable; vtable.addAll(superclass.getVtable()); if (!isInterface()) { addToVtable(getClassDef().getVirtualMethods(), vtable, true, true); Iterable<ClassDef> interfaces = getDirectInterfaces(); for (ClassDef interfaceDef: interfaces) { List<Method> interfaceMethods = Lists.newArrayList();
public int findMethodIndexInVtable(@Nonnull MethodReference method) { return findMethodIndexInVtable(getVtable(), method); }
boolean isInterface = true; try { isInterface = isInterface(); } catch (UnresolvedClassException ex) { isResolved = false; if (other.implementsInterface(getType())) { return true;
/** * Gets the interfaces directly implemented by this class, or the interfaces they transitively implement. * * This does not include any interfaces that are only implemented by a superclass * * @return An iterables of ClassDefs representing the directly or transitively implemented interfaces * @throws UnresolvedClassException if interfaces could not be fully resolved */ @Nonnull protected Iterable<ClassDef> getDirectInterfaces() { Iterable<ClassDef> directInterfaces = FluentIterable.from(getInterfaces().values()).filter(Predicates.notNull()); if (!interfacesFullyResolved) { throw new UnresolvedClassException("Interfaces for class %s not fully resolved: %s", getType(), Joiner.on(',').join(getUnresolvedInterfaces())); } return directInterfaces; }
superclassType = getSuperclass(); } catch (UnresolvedClassException ex) { vtable.addAll(((ClassProto)classPath.getClass("Ljava/lang/Object;")).getVtable()); vtableFullyResolved = false; return vtable; vtable.addAll(superclass.getVtable()); if (!isInterface()) { addToVtable(getClassDef().getVirtualMethods(), vtable, true, true); List<String> interfaces = Lists.newArrayList(getInterfaces().keySet()); ClassProto existingInterface = (ClassProto)classPath.getClass( defaultMethods.get(defaultMethodIndex).getDefiningClass()); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) { Method removedMethod = defaultMethods.remove(defaultMethodIndex); defaultConflictMethods.add(removedMethod); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) { Method oldMethod = mirandaMethods.remove(mirandaMethodIndex); int methodOrderValue = methodOrder.get(oldMethod);
private void listClassVtable(ClassProto classProto) throws IOException { List<Method> methods = classProto.getVtable(); String className = "Class " + classProto.getType() + " extends " + classProto.getSuperclass() + " : " + methods.size() + " methods\n"; System.out.write(className.getBytes()); for (int i = 0; i < methods.size(); i++) { Method method = methods.get(i); String methodString = i + ":" + method.getDefiningClass() + "->" + method.getName() + "("; for (CharSequence parameter : method.getParameterTypes()) { methodString += parameter; } methodString += ")" + method.getReturnType() + "\n"; System.out.write(methodString.getBytes()); } System.out.write("\n".getBytes()); }
LinkedHashMap<String, ClassDef> interfaces = Maps.newLinkedHashMap(); String superclass = getSuperclass(); if (superclass != null) { ClassProto superclassProto = (ClassProto) classPath.getClass(superclass); for (String superclassInterface: superclassProto.getInterfaces().keySet()) { interfaces.put(superclassInterface, null); unresolvedInterfaces.addAll(superclassProto.getUnresolvedInterfaces()); interfacesFullyResolved = false; for (String interfaceType: getClassDef().getInterfaces()) { if (!interfaces.containsKey(interfaceType)) { ClassProto interfaceProto = (ClassProto)classPath.getClass(interfaceType); try { for (Entry<String, ClassDef> entry: interfaceProto.getInterfaces().entrySet()) { if (!interfaces.containsKey(entry.getKey())) { interfaces.put(entry.getKey(), entry.getValue()); unresolvedInterfaces.addAll(interfaceProto.getUnresolvedInterfaces()); interfacesFullyResolved = false;
/** * Checks if this class implements the given interface. * * If the interfaces of this class cannot be fully resolved then this * method will either return true or throw an UnresolvedClassException * * @param iface The interface to check for * @return true if this class implements the given interface, otherwise false * @throws UnresolvedClassException if the interfaces for this class could not be fully resolved, and the interface * is not one of the interfaces that were successfully resolved */ @Override public boolean implementsInterface(@Nonnull String iface) { if (getInterfaces().containsKey(iface)) { return true; } if (!interfacesFullyResolved) { throw new UnresolvedClassException("Interfaces for class %s not fully resolved", getType()); } return false; }
if (this == other || getType().equals(other.getType())) { return this; if (this.getType().equals("Ljava/lang/Object;")) { return this; if (checkInterface((ClassProto)other)) { return this; if (((ClassProto)other).checkInterface(this)) { return other;
@Override @Nullable public FieldReference getFieldByOffset(int fieldOffset) { if (getInstanceFields().size() == 0) { return null; } return getInstanceFields().get(fieldOffset); }
@Override @Nullable public Method getMethodByVtableIndex(int vtableIndex) { List<Method> vtable = getVtable(); if (vtableIndex < 0 || vtableIndex >= vtable.size()) { return null; } return vtable.get(vtableIndex); }
private int getNextFieldOffset() { SparseArray<FieldReference> instanceFields = getInstanceFields(); if (instanceFields.size() == 0) { return classPath.isArt() ? 0 : 8; } int lastItemIndex = instanceFields.size()-1; int fieldOffset = instanceFields.keyAt(lastItemIndex); FieldReference lastField = instanceFields.valueAt(lastItemIndex); if (classPath.isArt()) { return fieldOffset + getTypeSize(lastField.getType().charAt(0)); } else { switch (lastField.getType().charAt(0)) { case 'J': case 'D': return fieldOffset + 8; default: return fieldOffset + 4; } } }
@Nullable @Override public String getSuperclass() { return getClassDef().getSuperclass(); }
/** * Checks if the interface method overrides the virtual or interface method2 * @param method A Method from an interface * @param method2 A Method from an interface or a class * @return true if the interface method overrides the virtual or interface method2 */ private boolean interfaceMethodOverrides(@Nonnull Method method, @Nonnull Method method2) { ClassProto classProto = (ClassProto)classPath.getClass(method2.getDefiningClass()); if (classProto.isInterface()) { ClassProto targetClassProto = (ClassProto)classPath.getClass(method.getDefiningClass()); return targetClassProto.implementsInterface(method2.getDefiningClass()); } else { return false; } }
@Override public TypeProto load(String type) throws Exception { if (type.charAt(0) == '[') { return new ArrayProto(ClassPath.this, type); } else { return new ClassProto(ClassPath.this, type); } } };
superclassType = getSuperclass(); } catch (UnresolvedClassException ex) { vtable.addAll(((ClassProto)classPath.getClass("Ljava/lang/Object;")).getVtable()); vtableFullyResolved = false; return vtable; vtable.addAll(superclass.getVtable()); if (!isInterface()) { addToVtable(getClassDef().getVirtualMethods(), vtable, true, true); List<String> interfaces = Lists.newArrayList(getInterfaces().keySet()); ClassProto existingInterface = (ClassProto)classPath.getClass( defaultMethods.get(defaultMethodIndex).getDefiningClass()); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) { Method removedMethod = defaultMethods.remove(defaultMethodIndex); defaultConflictMethods.add(removedMethod); if (!existingInterface.implementsInterface(interfaceMethod.getDefiningClass())) { Method oldMethod = mirandaMethods.remove(mirandaMethodIndex); int methodOrderValue = methodOrder.get(oldMethod);
private void listClassVtable(ClassProto classProto) throws IOException { List<Method> methods = classProto.getVtable(); String className = "Class " + classProto.getType() + " extends " + classProto.getSuperclass() + " : " + methods.size() + " methods\n"; System.out.write(className.getBytes()); for (int i = 0; i < methods.size(); i++) { Method method = methods.get(i); String methodString = i + ":" + method.getDefiningClass() + "->" + method.getName() + "("; for (CharSequence parameter : method.getParameterTypes()) { methodString += parameter; } methodString += ")" + method.getReturnType() + "\n"; System.out.write(methodString.getBytes()); } System.out.write("\n".getBytes()); }
boolean isInterface = true; try { isInterface = isInterface(); } catch (UnresolvedClassException ex) { isResolved = false; if (other.implementsInterface(getType())) { return true;