blob: e1903d9f06616f056b83d0e34540e0bb5a70f2d7 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
package cuchaz.enigma.analysis.index;
import com.google.common.collect.Maps;
import cuchaz.enigma.translation.Translator;
import cuchaz.enigma.translation.mapping.EntryResolver;
import cuchaz.enigma.translation.representation.AccessFlags;
import cuchaz.enigma.translation.representation.entry.MethodEntry;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map;
public class BridgeMethodIndex implements JarIndexer, RemappableIndex {
private final EntryIndex entryIndex;
private final ReferenceIndex referenceIndex;
private Map<MethodEntry, MethodEntry> accessedToBridge = Maps.newHashMap();
public BridgeMethodIndex(EntryIndex entryIndex, ReferenceIndex referenceIndex) {
this.entryIndex = entryIndex;
this.referenceIndex = referenceIndex;
}
@Override
public void remap(Translator translator) {
accessedToBridge = translator.translate(accessedToBridge);
}
@Override
public BridgeMethodIndex remapped(Translator translator) {
BridgeMethodIndex index = new BridgeMethodIndex(entryIndex, referenceIndex);
index.accessedToBridge = translator.translate(accessedToBridge);
return index;
}
@Override
public void processIndex(EntryResolver resolver) {
// look for access and bridged methods
for (MethodEntry methodEntry : entryIndex.getMethods()) {
AccessFlags access = entryIndex.getMethodAccess(methodEntry);
if (access == null || !access.isSynthetic()) {
continue;
}
indexSyntheticMethod(methodEntry, access);
}
}
private void indexSyntheticMethod(MethodEntry syntheticMethod, AccessFlags access) {
if (access.isBridge()) {
MethodEntry accessedMethod = findAccessMethod(syntheticMethod);
if (accessedMethod != null) {
accessedToBridge.put(accessedMethod, syntheticMethod);
}
}
}
private MethodEntry findAccessMethod(MethodEntry method) {
// we want to find all compiler-added methods that directly call another with no processing
// get all the methods that we call
final Collection<MethodEntry> referencedMethods = referenceIndex.getMethodsReferencedBy(method);
// is there just one?
if (referencedMethods.size() != 1) {
return null;
}
return referencedMethods.stream().findFirst().orElse(null);
}
@Nullable
public MethodEntry getBridgeFromAccessed(MethodEntry entry) {
return accessedToBridge.get(entry);
}
}
|