1418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file 2418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// for details. All rights reserved. Use of this source code is governed by a 3418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// BSD-style license that can be found in the LICENSE file. 4418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerpackage com.android.tools.r8.optimize; 5418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 62da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhutimport com.android.tools.r8.errors.Unreachable; 7418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexClass; 8418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexEncodedField; 9418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexEncodedMethod; 10418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexField; 11418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexMethod; 122da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhutimport com.android.tools.r8.graph.DexProgramClass; 13418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexType; 14418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.GraphLense; 15418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness; 16418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.google.common.collect.Sets; 17418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.Set; 182da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhutimport java.util.function.BiConsumer; 19418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.function.BiFunction; 20418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.function.Function; 21418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 22418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerpublic class MemberRebindingAnalysis { 232da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut 24418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private final AppInfoWithLiveness appInfo; 25418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private final GraphLense lense; 26d5aa09296ee17dd3ef20fc07eed18a9708331e5bStephan Herhut private final GraphLense.Builder builder = GraphLense.builder(); 27418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 28418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public MemberRebindingAnalysis(AppInfoWithLiveness appInfo, GraphLense lense) { 29418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assert lense.isContextFree(); 30418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager this.appInfo = appInfo; 31418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager this.lense = lense; 32418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 33418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 34418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private DexMethod validTargetFor(DexMethod target, DexMethod original, 35418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager BiFunction<DexClass, DexMethod, DexEncodedMethod> lookup) { 36418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexClass clazz = appInfo.definitionFor(target.getHolder()); 37418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assert clazz != null; 38418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (!clazz.isLibraryClass()) { 39418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return target; 40418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 41418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexType newHolder; 42418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (clazz.isInterface()) { 43418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager newHolder = firstLibraryClassForInterfaceTarget(target, original.getHolder(), lookup); 44418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } else { 45418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager newHolder = firstLibraryClass(target.getHolder(), original.getHolder()); 46418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 47418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return appInfo.dexItemFactory.createMethod(newHolder, original.proto, original.name); 48418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 49418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 50418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private DexField validTargetFor(DexField target, DexField original, 51418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager BiFunction<DexClass, DexField, DexEncodedField> lookup) { 52418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexClass clazz = appInfo.definitionFor(target.getHolder()); 53418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assert clazz != null; 54418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (!clazz.isLibraryClass()) { 55418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return target; 56418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 57418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexType newHolder; 58418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (clazz.isInterface()) { 59418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager newHolder = firstLibraryClassForInterfaceTarget(target, original.getHolder(), lookup); 60418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } else { 61418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager newHolder = firstLibraryClass(target.getHolder(), original.getHolder()); 62418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 63418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return appInfo.dexItemFactory.createField(newHolder, original.type, original.name); 64418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 65418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 66418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private <T> DexType firstLibraryClassForInterfaceTarget(T target, DexType current, 67418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager BiFunction<DexClass, T, ?> lookup) { 68418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexClass clazz = appInfo.definitionFor(current); 69418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Object potential = lookup.apply(clazz, target); 70418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (potential != null) { 71418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager // Found, return type. 72418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return current; 73418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 74418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (clazz.superType != null) { 75418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexType matchingSuper = firstLibraryClassForInterfaceTarget(target, clazz.superType, lookup); 76418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (matchingSuper != null) { 77418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager // Found in supertype, return first libray class. 78418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return clazz.isLibraryClass() ? current : matchingSuper; 79418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 80418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 81418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager for (DexType iface : clazz.interfaces.values) { 82418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexType matchingIface = firstLibraryClassForInterfaceTarget(target, iface, lookup); 83418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (matchingIface != null) { 84418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager // Found in interface, return first library class. 85418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return clazz.isLibraryClass() ? current : matchingIface; 86418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 87418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 88418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return null; 89418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 90418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 91418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private DexType firstLibraryClass(DexType top, DexType bottom) { 92418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assert appInfo.definitionFor(top).isLibraryClass(); 93418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexClass searchClass = appInfo.definitionFor(bottom); 94418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager while (!searchClass.isLibraryClass()) { 95418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager searchClass = appInfo.definitionFor(searchClass.superType); 96418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 97418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return searchClass.type; 98418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 99418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 100418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private DexEncodedMethod virtualLookup(DexMethod method) { 101418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return appInfo.lookupVirtualDefinition(method.getHolder(), method); 102418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 103418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 104418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private DexEncodedMethod superLookup(DexMethod method) { 105418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return appInfo.lookupVirtualTarget(method.getHolder(), method); 106418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 107418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 108418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private void computeMethodRebinding(Set<DexMethod> methods, 109418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Function<DexMethod, DexEncodedMethod> lookupTarget, 1102da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut BiFunction<DexClass, DexMethod, DexEncodedMethod> lookupTargetOnClass, 1112da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut BiConsumer<DexProgramClass, DexEncodedMethod> addMethod) { 112418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager for (DexMethod method : methods) { 113418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager method = lense.lookupMethod(method, null); 114418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager // We can safely ignore array types, as the corresponding methods are defined in a library. 115418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (!method.getHolder().isClassType()) { 116418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager continue; 117418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 1182da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexClass originalClass = appInfo.definitionFor(method.holder); 1192da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // We can safely ignore calls to library classes, as those cannot be rebound. 1202da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut if (originalClass == null || originalClass.isLibraryClass()) { 1212da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut continue; 1222da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 123418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexEncodedMethod target = lookupTarget.apply(method); 124418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager // Rebind to the lowest library class or program class. 125418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (target != null && target.method != method) { 1262da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexClass targetClass = appInfo.definitionFor(target.method.holder); 1272da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // If the targetclass is not public but the targeted method is, we might run into 1282da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // visibility problems when rebinding. 1292da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut if (!targetClass.accessFlags.isPublic() && target.accessFlags.isPublic()) { 1302da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // If the original class is public and this method is public, it might have been called 1312da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // from anywhere, so we need a bridge. Likewise, if the original is in a different 1322da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // package, we might need a bridge, too. 1332da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut String packageDescriptor = 1342da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut originalClass.accessFlags.isPublic() ? null : method.holder.getPackageDescriptor(); 1352da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut if (packageDescriptor == null 1362da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut || !packageDescriptor.equals(targetClass.type.getPackageDescriptor())) { 1372da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexProgramClass bridgeHolder = findBridgeMethodHolder(originalClass, targetClass, 1382da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut packageDescriptor); 1392da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut assert bridgeHolder != null; 1402da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexEncodedMethod bridgeMethod = target 1412da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut .toForwardingMethod(bridgeHolder, appInfo.dexItemFactory); 1422da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut addMethod.accept(bridgeHolder, bridgeMethod); 1432da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut assert lookupTarget.apply(method) == bridgeMethod; 1442da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut target = bridgeMethod; 1452da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 1462da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 14774f1c6f2254f82fcec7612df782d125e621049b9Stephan Herhut builder.map(method, validTargetFor(target.method, method, lookupTargetOnClass)); 148418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 149418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 150418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 151418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 1522da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut private DexProgramClass findBridgeMethodHolder(DexClass originalClass, DexClass targetClass, 1532da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut String packageDescriptor) { 1542da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut if (originalClass == targetClass || originalClass.isLibraryClass()) { 1552da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut return null; 1562da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 1572da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexProgramClass newHolder = null; 1582da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // Recurse through supertype chain. 15952c0414fff5db9769a60a3e2880acd8781a88ab1Denis Vnukov if (originalClass.superType.isSubtypeOf(targetClass.type, appInfo)) { 1602da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexClass superClass = appInfo.definitionFor(originalClass.superType); 1612da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut newHolder = findBridgeMethodHolder(superClass, targetClass, packageDescriptor); 1622da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } else { 1632da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut for (DexType iface : originalClass.interfaces.values) { 16452c0414fff5db9769a60a3e2880acd8781a88ab1Denis Vnukov if (iface.isSubtypeOf(targetClass.type, appInfo)) { 1652da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexClass interfaceClass = appInfo.definitionFor(iface); 1662da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut newHolder = findBridgeMethodHolder(interfaceClass, targetClass, packageDescriptor); 1672da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 1682da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 1692da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 1702da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut if (newHolder != null) { 1712da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // A supertype fulfills the visibility requirements. 1722da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut return newHolder; 1732da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } else if (originalClass.accessFlags.isPublic() 1742da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut || originalClass.type.getPackageDescriptor().equals(packageDescriptor)) { 1752da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut // This class is visible. Return it if it is a program class, otherwise null. 1762da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut return originalClass.asProgramClass(); 1772da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 1782da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut return null; 1792da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 1802da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut 181418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private void computeFieldRebinding(Set<DexField> fields, 182418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager BiFunction<DexType, DexField, DexEncodedField> lookup, 183418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager BiFunction<DexClass, DexField, DexEncodedField> lookupTargetOnClass) { 184418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager for (DexField field : fields) { 185418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager field = lense.lookupField(field, null); 186418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager DexEncodedField target = lookup.apply(field.getHolder(), field); 187fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut // Rebind to the lowest library class or program class. Do not rebind accesses to fields that 188fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut // are not public, as this might lead to access violation errors. 189fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut if (target != null && target.field != field && isVisibleFromOtherClasses(target)) { 190418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager builder.map(field, validTargetFor(target.field, field, lookupTargetOnClass)); 191418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 192418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 193418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 194418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 195fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut private boolean isVisibleFromOtherClasses(DexEncodedField field) { 196fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut // If the field is not public, the visibility on the class can not be a further constraint. 197fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut if (!field.accessFlags.isPublic()) { 198fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut return true; 199fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut } 200fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut // If the field is public, then a non-public holder class will further constrain visibility. 201fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut return appInfo.definitionFor(field.field.getHolder()).accessFlags.isPublic(); 202fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut } 203fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut 2042da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut private static void privateMethodsCheck(DexProgramClass clazz, DexEncodedMethod method) { 2052da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut throw new Unreachable("Direct invokes should not require forwarding."); 2062da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut } 2072da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut 208418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public GraphLense run() { 209418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager computeMethodRebinding(appInfo.virtualInvokes, this::virtualLookup, 2102da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexClass::findVirtualTarget, DexProgramClass::addVirtualMethod); 2112da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut computeMethodRebinding(appInfo.superInvokes, this::superLookup, DexClass::findVirtualTarget, 2122da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexProgramClass::addVirtualMethod); 213418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager computeMethodRebinding(appInfo.directInvokes, appInfo::lookupDirectTarget, 2142da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexClass::findDirectTarget, MemberRebindingAnalysis::privateMethodsCheck); 215418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager computeMethodRebinding(appInfo.staticInvokes, appInfo::lookupStaticTarget, 2162da874a28e1a98dc5d2500a554f9143d6309a132Stephan Herhut DexClass::findDirectTarget, DexProgramClass::addStaticMethod); 217418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 218fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut computeFieldRebinding(Sets.union(appInfo.staticFieldReads, appInfo.staticFieldWrites), 219418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager appInfo::lookupStaticTarget, DexClass::findStaticTarget); 220fd8a4de5f510bf261a438e050cad712a4321ea82Stephan Herhut computeFieldRebinding(Sets.union(appInfo.instanceFieldReads, appInfo.instanceFieldWrites), 221418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager appInfo::lookupInstanceTarget, DexClass::findInstanceTarget); 222d5aa09296ee17dd3ef20fc07eed18a9708331e5bStephan Herhut return builder.build(lense, appInfo.dexItemFactory); 223418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 224418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager} 225