use of org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference in project android-bundle-support by lizhangqu.
the class DexReferences method gatherBackReferences.
/**
* Goes through all the classes, methods, and fields, and gathers all possible references from
* one type/method/field to another.
*
* @param files dex file
*/
private void gatherBackReferences(@NonNull DexBackedDexFile[] files) {
Map<Reference, ImmutableReference> immutableReferencesBin = new HashMap<>();
for (DexBackedDexFile file : files) {
// build a map from class names (String) to actual TypeReferences,
// as this information is not readily available to query through
// the dexlib2 API.
Map<String, ImmutableTypeReference> typesByName = new HashMap<>();
for (int i = 0, m = file.getTypeCount(); i < m; i++) {
ImmutableTypeReference immutableTypeRef = ImmutableTypeReference.of(new DexBackedTypeReference(file, i));
typesByName.put(immutableTypeRef.getType(), immutableTypeRef);
}
// loop through all methods referenced in the dex file, mapping the following:
for (int i = 0, m = file.getMethodCount(); i < m; i++) {
MethodReference methodReference = new DexBackedMethodReference(file, i);
// - return type => method
ImmutableReference typeRef = typesByName.get(methodReference.getReturnType());
addReference(typeRef, methodReference, immutableReferencesBin);
// - all parameter types => method
for (CharSequence parameterType : methodReference.getParameterTypes()) {
typeRef = typesByName.get(parameterType.toString());
addReference(typeRef, methodReference, immutableReferencesBin);
}
}
// loop through all classes defined in the dex file, mapping the following:
for (DexBackedClassDef classDef : file.getClasses()) {
// - superclass => class
ImmutableReference typeRef = typesByName.get(classDef.getSuperclass());
addReference(typeRef, classDef, immutableReferencesBin);
// - all implemented interfaces => class
for (String iface : classDef.getInterfaces()) {
typeRef = typesByName.get(iface);
addReference(typeRef, classDef, immutableReferencesBin);
}
// map annotations => class
for (Annotation annotation : classDef.getAnnotations()) {
addAnnotation(immutableReferencesBin, typesByName, classDef, annotation);
}
// loop through all the methods defined in this class
for (DexBackedMethod method : classDef.getMethods()) {
// if the method has an implementation, loop through the bytecode
// mapping any references that exist in dex instructions to the method.
// Fortunately, dexlib2 marks every bytecode instruction that accepts
// a reference with one or two interfaces: ReferenceInstruction
// and DualReferenceInstruction.
DexBackedMethodImplementation impl = method.getImplementation();
if (impl != null) {
for (Instruction instruction : impl.getInstructions()) {
if (instruction instanceof ReferenceInstruction) {
Reference reference = ((ReferenceInstruction) instruction).getReference();
addReferenceAndEnclosingClass(immutableReferencesBin, typesByName, method, reference);
}
if (instruction instanceof DualReferenceInstruction) {
Reference reference = ((DualReferenceInstruction) instruction).getReference2();
addReferenceAndEnclosingClass(immutableReferencesBin, typesByName, method, reference);
}
}
}
// map annotations => method
for (Annotation annotation : method.getAnnotations()) {
addAnnotation(immutableReferencesBin, typesByName, method, annotation);
}
}
for (DexBackedField field : classDef.getFields()) {
// map annotations => field
for (Annotation annotation : field.getAnnotations()) {
addAnnotation(immutableReferencesBin, typesByName, field, annotation);
}
}
}
// a mapping from the field type => field
for (int i = 0, m = file.getFieldCount(); i < m; i++) {
FieldReference fieldRef = new DexBackedFieldReference(file, i);
ImmutableReference typeRef = typesByName.get(fieldRef.getType());
addReference(typeRef, fieldRef, immutableReferencesBin);
}
}
}
use of org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference in project android-bundle-support by lizhangqu.
the class PackageTreeCreator method getAllTypeReferencesByClassName.
@NonNull
private static Map<String, TypeReference> getAllTypeReferencesByClassName(@NonNull DexBackedDexFile dexFile) {
HashMap<String, TypeReference> typesByName = new HashMap<>();
for (int i = 0, m = dexFile.getTypeCount(); i < m; i++) {
TypeReference typeRef = new DexBackedTypeReference(dexFile, i);
typesByName.put(typeRef.getType(), typeRef);
}
return typesByName;
}
Aggregations