diff options
| author | 2018-06-24 12:24:48 +0200 | |
|---|---|---|
| committer | 2018-06-24 12:24:48 +0200 | |
| commit | 8a0e350a04e570074557ff0a53d67e82d54d3005 (patch) | |
| tree | 621fb8ab321525eadfd95fdd743cfcfee935d4d8 | |
| parent | Fix array translation in method calls (diff) | |
| download | enigma-8a0e350a04e570074557ff0a53d67e82d54d3005.tar.gz enigma-8a0e350a04e570074557ff0a53d67e82d54d3005.tar.xz enigma-8a0e350a04e570074557ff0a53d67e82d54d3005.zip | |
Fix method reference and bridge detection
7 files changed, 90 insertions, 49 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java b/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java index e37c1d0c..9be8378e 100644 --- a/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java +++ b/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java | |||
| @@ -138,6 +138,13 @@ public class EntryRenamer { | |||
| 138 | renameClassesInThing(renames, methodEntry.getSignature()), | 138 | renameClassesInThing(renames, methodEntry.getSignature()), |
| 139 | methodEntry.getAccess() | 139 | methodEntry.getAccess() |
| 140 | ); | 140 | ); |
| 141 | } else if (thing instanceof MethodEntry) { | ||
| 142 | MethodEntry methodEntry = (MethodEntry) thing; | ||
| 143 | return (T) new MethodEntry( | ||
| 144 | renameClassesInThing(renames, methodEntry.getOwnerClassEntry()), | ||
| 145 | methodEntry.getName(), | ||
| 146 | renameClassesInThing(renames, methodEntry.getDesc()) | ||
| 147 | ); | ||
| 141 | } else if (thing instanceof LocalVariableEntry) { | 148 | } else if (thing instanceof LocalVariableEntry) { |
| 142 | LocalVariableEntry argumentEntry = (LocalVariableEntry) thing; | 149 | LocalVariableEntry argumentEntry = (LocalVariableEntry) thing; |
| 143 | return (T) new LocalVariableEntry(renameClassesInThing(renames, argumentEntry.getOwnerEntry()), argumentEntry.getIndex(), argumentEntry.getName()); | 150 | return (T) new LocalVariableEntry(renameClassesInThing(renames, argumentEntry.getOwnerEntry()), argumentEntry.getIndex(), argumentEntry.getName()); |
diff --git a/src/main/java/cuchaz/enigma/analysis/FieldReferenceTreeNode.java b/src/main/java/cuchaz/enigma/analysis/FieldReferenceTreeNode.java index 3d0e48b4..f63b779a 100644 --- a/src/main/java/cuchaz/enigma/analysis/FieldReferenceTreeNode.java +++ b/src/main/java/cuchaz/enigma/analysis/FieldReferenceTreeNode.java | |||
| @@ -63,7 +63,7 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re | |||
| 63 | add(new FieldReferenceTreeNode(this.deobfuscatingTranslator, reference, index.getAccess(this.entry))); | 63 | add(new FieldReferenceTreeNode(this.deobfuscatingTranslator, reference, index.getAccess(this.entry))); |
| 64 | } | 64 | } |
| 65 | } else { | 65 | } else { |
| 66 | for (EntryReference<MethodEntry, MethodDefEntry> reference : index.getMethodReferences(this.reference.context)) { | 66 | for (EntryReference<MethodEntry, MethodDefEntry> reference : index.getMethodsReferencing(this.reference.context)) { |
| 67 | add(new MethodReferenceTreeNode(this.deobfuscatingTranslator, reference, index.getAccess(this.reference.context))); | 67 | add(new MethodReferenceTreeNode(this.deobfuscatingTranslator, reference, index.getAccess(this.reference.context))); |
| 68 | } | 68 | } |
| 69 | } | 69 | } |
diff --git a/src/main/java/cuchaz/enigma/analysis/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/JarIndex.java index 8172deaa..27a8e07b 100644 --- a/src/main/java/cuchaz/enigma/analysis/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/JarIndex.java | |||
| @@ -29,11 +29,13 @@ public class JarIndex { | |||
| 29 | private Multimap<ClassEntry, FieldDefEntry> fields; | 29 | private Multimap<ClassEntry, FieldDefEntry> fields; |
| 30 | private Multimap<ClassEntry, MethodDefEntry> methods; | 30 | private Multimap<ClassEntry, MethodDefEntry> methods; |
| 31 | private Multimap<String, MethodDefEntry> methodImplementations; | 31 | private Multimap<String, MethodDefEntry> methodImplementations; |
| 32 | private Multimap<MethodEntry, EntryReference<MethodEntry, MethodDefEntry>> methodReferences; | 32 | private Multimap<MethodEntry, EntryReference<MethodEntry, MethodDefEntry>> methodsReferencing; |
| 33 | private Multimap<MethodEntry, MethodEntry> methodReferences; | ||
| 33 | private Multimap<FieldEntry, EntryReference<FieldEntry, MethodDefEntry>> fieldReferences; | 34 | private Multimap<FieldEntry, EntryReference<FieldEntry, MethodDefEntry>> fieldReferences; |
| 34 | private Multimap<ClassEntry, ClassEntry> innerClassesByOuter; | 35 | private Multimap<ClassEntry, ClassEntry> innerClassesByOuter; |
| 35 | private Map<ClassEntry, ClassEntry> outerClassesByInner; | 36 | private Map<ClassEntry, ClassEntry> outerClassesByInner; |
| 36 | private Map<MethodEntry, MethodEntry> bridgedMethods; | 37 | private Map<MethodEntry, MethodEntry> bridgedMethods; |
| 38 | private Map<MethodEntry, MethodEntry> accessMethods; | ||
| 37 | private Set<MethodEntry> syntheticMethods; | 39 | private Set<MethodEntry> syntheticMethods; |
| 38 | 40 | ||
| 39 | public JarIndex(ReferencedEntryPool entryPool) { | 41 | public JarIndex(ReferencedEntryPool entryPool) { |
| @@ -44,11 +46,13 @@ public class JarIndex { | |||
| 44 | this.fields = HashMultimap.create(); | 46 | this.fields = HashMultimap.create(); |
| 45 | this.methods = HashMultimap.create(); | 47 | this.methods = HashMultimap.create(); |
| 46 | this.methodImplementations = HashMultimap.create(); | 48 | this.methodImplementations = HashMultimap.create(); |
| 49 | this.methodsReferencing = HashMultimap.create(); | ||
| 47 | this.methodReferences = HashMultimap.create(); | 50 | this.methodReferences = HashMultimap.create(); |
| 48 | this.fieldReferences = HashMultimap.create(); | 51 | this.fieldReferences = HashMultimap.create(); |
| 49 | this.innerClassesByOuter = HashMultimap.create(); | 52 | this.innerClassesByOuter = HashMultimap.create(); |
| 50 | this.outerClassesByInner = Maps.newHashMap(); | 53 | this.outerClassesByInner = Maps.newHashMap(); |
| 51 | this.bridgedMethods = Maps.newHashMap(); | 54 | this.bridgedMethods = Maps.newHashMap(); |
| 55 | this.accessMethods = Maps.newHashMap(); | ||
| 52 | this.syntheticMethods = Sets.newHashSet(); | 56 | this.syntheticMethods = Sets.newHashSet(); |
| 53 | } | 57 | } |
| 54 | 58 | ||
| @@ -63,12 +67,15 @@ public class JarIndex { | |||
| 63 | // step 3: index field, method, constructor references | 67 | // step 3: index field, method, constructor references |
| 64 | jar.visit(node -> node.accept(new IndexReferenceVisitor(this, Opcodes.ASM5))); | 68 | jar.visit(node -> node.accept(new IndexReferenceVisitor(this, Opcodes.ASM5))); |
| 65 | 69 | ||
| 66 | // step 4: index bridged methods | 70 | // step 4: index access and bridged methods |
| 67 | for (MethodDefEntry methodEntry : methods.values()) { | 71 | for (MethodDefEntry methodEntry : methods.values()) { |
| 68 | // look for bridge and bridged methods | 72 | // look for access and bridged methods |
| 69 | MethodEntry bridgedMethod = findBridgedMethod(methodEntry); | 73 | MethodEntry accessedMethod = findAccessMethod(methodEntry); |
| 70 | if (bridgedMethod != null) { | 74 | if (accessedMethod != null) { |
| 71 | this.bridgedMethods.put(methodEntry, bridgedMethod); | 75 | this.accessMethods.put(methodEntry, accessedMethod); |
| 76 | if (isBridgedMethod(accessedMethod, methodEntry)) { | ||
| 77 | this.bridgedMethods.put(methodEntry, accessedMethod); | ||
| 78 | } | ||
| 72 | } | 79 | } |
| 73 | } | 80 | } |
| 74 | 81 | ||
| @@ -89,6 +96,7 @@ public class JarIndex { | |||
| 89 | EntryRenamer.renameClassesInSet(renames, this.obfClassEntries); | 96 | EntryRenamer.renameClassesInSet(renames, this.obfClassEntries); |
| 90 | this.translationIndex.renameClasses(renames); | 97 | this.translationIndex.renameClasses(renames); |
| 91 | EntryRenamer.renameClassesInMultimap(renames, this.methodImplementations); | 98 | EntryRenamer.renameClassesInMultimap(renames, this.methodImplementations); |
| 99 | EntryRenamer.renameClassesInMultimap(renames, this.methodsReferencing); | ||
| 92 | EntryRenamer.renameClassesInMultimap(renames, this.methodReferences); | 100 | EntryRenamer.renameClassesInMultimap(renames, this.methodReferences); |
| 93 | EntryRenamer.renameClassesInMultimap(renames, this.fieldReferences); | 101 | EntryRenamer.renameClassesInMultimap(renames, this.fieldReferences); |
| 94 | EntryRenamer.renameClassesInMap(renames, this.access); | 102 | EntryRenamer.renameClassesInMap(renames, this.access); |
| @@ -134,7 +142,8 @@ public class JarIndex { | |||
| 134 | if (resolvedClassEntry != null && !resolvedClassEntry.equals(referencedMethod.getOwnerClassEntry())) { | 142 | if (resolvedClassEntry != null && !resolvedClassEntry.equals(referencedMethod.getOwnerClassEntry())) { |
| 135 | referencedMethod = referencedMethod.updateOwnership(resolvedClassEntry); | 143 | referencedMethod = referencedMethod.updateOwnership(resolvedClassEntry); |
| 136 | } | 144 | } |
| 137 | methodReferences.put(referencedMethod, new EntryReference<>(referencedMethod, referencedMethod.getName(), callerEntry)); | 145 | methodsReferencing.put(referencedMethod, new EntryReference<>(referencedMethod, referencedMethod.getName(), callerEntry)); |
| 146 | methodReferences.put(callerEntry, referencedMethod); | ||
| 138 | } | 147 | } |
| 139 | 148 | ||
| 140 | protected void indexFieldAccess(MethodDefEntry callerEntry, String owner, String name, String desc) { | 149 | protected void indexFieldAccess(MethodDefEntry callerEntry, String owner, String name, String desc) { |
| @@ -151,26 +160,54 @@ public class JarIndex { | |||
| 151 | this.outerClassesByInner.putIfAbsent(innerEntry, outerEntry); | 160 | this.outerClassesByInner.putIfAbsent(innerEntry, outerEntry); |
| 152 | } | 161 | } |
| 153 | 162 | ||
| 154 | private MethodEntry findBridgedMethod(MethodDefEntry method) { | 163 | private MethodEntry findAccessMethod(MethodDefEntry method) { |
| 155 | 164 | ||
| 156 | // bridge methods just call another method, cast it to the return desc, and return the result | 165 | // we want to find all compiler-added methods that directly call another with no processing |
| 157 | // let's see if we can detect this scenario | ||
| 158 | 166 | ||
| 159 | // skip non-synthetic methods | 167 | // skip non-synthetic methods |
| 160 | if (!method.getAccess().isSynthetic()) { | 168 | if (!method.getAccess().isSynthetic()) { |
| 161 | return null; | 169 | return null; |
| 162 | } | 170 | } |
| 163 | 171 | ||
| 164 | // get all the called methods | 172 | // get all the methods that we call |
| 165 | final Collection<EntryReference<MethodEntry, MethodDefEntry>> referencedMethods = methodReferences.get(method); | 173 | final Collection<MethodEntry> referencedMethods = methodReferences.get(method); |
| 166 | 174 | ||
| 167 | // is there just one? | 175 | // is there just one? |
| 168 | if (referencedMethods.size() != 1) { | 176 | if (referencedMethods.size() != 1) { |
| 169 | return null; | 177 | return null; |
| 170 | } | 178 | } |
| 171 | 179 | ||
| 172 | // we have a bridge method! | 180 | return referencedMethods.stream().findFirst().orElse(null); |
| 173 | return referencedMethods.stream().map(ref -> ref.context).filter(Objects::nonNull).findFirst().orElse(null); | 181 | } |
| 182 | |||
| 183 | private boolean isBridgedMethod(MethodEntry called, MethodEntry access) { | ||
| 184 | // Bridged methods will always have the same name as the method they are calling | ||
| 185 | // They will also have the same amount of parameters (though equal descriptors cannot be guaranteed) | ||
| 186 | if (!called.getName().equals(access.getName()) || called.getDesc().getArgumentDescs().size() != access.getDesc().getArgumentDescs().size()) { | ||
| 187 | return false; | ||
| 188 | } | ||
| 189 | |||
| 190 | TypeDescriptor accessReturn = access.getDesc().getReturnDesc(); | ||
| 191 | TypeDescriptor calledReturn = called.getDesc().getReturnDesc(); | ||
| 192 | if (calledReturn.isVoid() || calledReturn.isPrimitive() || accessReturn.isVoid() || accessReturn.isPrimitive()) { | ||
| 193 | return false; | ||
| 194 | } | ||
| 195 | |||
| 196 | // Bridged methods will never have the same type as what they are calling | ||
| 197 | if (accessReturn.equals(calledReturn)) { | ||
| 198 | return false; | ||
| 199 | } | ||
| 200 | |||
| 201 | String accessType = accessReturn.toString(); | ||
| 202 | |||
| 203 | // If we're casting down from generic type to type-erased Object we're a bridge method | ||
| 204 | if (accessType.equals("Ljava/lang/Object;")) { | ||
| 205 | return true; | ||
| 206 | } | ||
| 207 | |||
| 208 | // Now we need to detect cases where we are being casted down to a higher type bound | ||
| 209 | List<ClassEntry> calledAncestry = translationIndex.getAncestry(calledReturn.getTypeEntry()); | ||
| 210 | return calledAncestry.contains(accessReturn.getTypeEntry()); | ||
| 174 | } | 211 | } |
| 175 | 212 | ||
| 176 | public Set<ClassEntry> getObfClassEntries() { | 213 | public Set<ClassEntry> getObfClassEntries() { |
| @@ -302,11 +339,11 @@ public class JarIndex { | |||
| 302 | methodEntries.add(methodEntry); | 339 | methodEntries.add(methodEntry); |
| 303 | } | 340 | } |
| 304 | 341 | ||
| 305 | // look at bridged methods! | 342 | // look at access methods! |
| 306 | MethodEntry bridgedEntry = getBridgedMethod(methodEntry); | 343 | MethodEntry accessMethod = getAccessMethod(methodEntry); |
| 307 | while (bridgedEntry != null) { | 344 | while (accessMethod != null) { |
| 308 | methodEntries.addAll(getRelatedMethodImplementations(bridgedEntry)); | 345 | methodEntries.addAll(getRelatedMethodImplementations(accessMethod)); |
| 309 | bridgedEntry = getBridgedMethod(bridgedEntry); | 346 | accessMethod = getAccessMethod(accessMethod); |
| 310 | } | 347 | } |
| 311 | 348 | ||
| 312 | // look at interface methods too | 349 | // look at interface methods too |
| @@ -327,11 +364,11 @@ public class JarIndex { | |||
| 327 | methodEntries.add(methodEntry); | 364 | methodEntries.add(methodEntry); |
| 328 | } | 365 | } |
| 329 | 366 | ||
| 330 | // look at bridged methods! | 367 | // look at access methods! |
| 331 | MethodEntry bridgedEntry = getBridgedMethod(methodEntry); | 368 | MethodEntry accessMethod = getAccessMethod(methodEntry); |
| 332 | while (bridgedEntry != null) { | 369 | while (accessMethod != null) { |
| 333 | methodEntries.addAll(getRelatedMethodImplementations(bridgedEntry)); | 370 | methodEntries.addAll(getRelatedMethodImplementations(accessMethod)); |
| 334 | bridgedEntry = getBridgedMethod(bridgedEntry); | 371 | accessMethod = getAccessMethod(accessMethod); |
| 335 | } | 372 | } |
| 336 | 373 | ||
| 337 | // recurse | 374 | // recurse |
| @@ -355,19 +392,12 @@ public class JarIndex { | |||
| 355 | return fieldEntries; | 392 | return fieldEntries; |
| 356 | } | 393 | } |
| 357 | 394 | ||
| 358 | public Collection<EntryReference<MethodEntry, MethodDefEntry>> getMethodReferences(MethodEntry methodEntry) { | 395 | public Collection<EntryReference<MethodEntry, MethodDefEntry>> getMethodsReferencing(MethodEntry methodEntry) { |
| 359 | return this.methodReferences.get(methodEntry); | 396 | return this.methodsReferencing.get(methodEntry); |
| 360 | } | 397 | } |
| 361 | 398 | ||
| 362 | public Collection<MethodEntry> getReferencedMethods(MethodDefEntry methodEntry) { | 399 | public Collection<MethodEntry> getReferencedMethods(MethodDefEntry methodEntry) { |
| 363 | // linear search is fast enough for now | 400 | return this.methodReferences.get(methodEntry); |
| 364 | Set<MethodEntry> behaviorEntries = Sets.newHashSet(); | ||
| 365 | for (EntryReference<MethodEntry, MethodDefEntry> reference : this.methodReferences.values()) { | ||
| 366 | if (reference.context == methodEntry) { | ||
| 367 | behaviorEntries.add(reference.entry); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | return behaviorEntries; | ||
| 371 | } | 401 | } |
| 372 | 402 | ||
| 373 | public Collection<ClassEntry> getInnerClasses(ClassEntry obfOuterClassEntry) { | 403 | public Collection<ClassEntry> getInnerClasses(ClassEntry obfOuterClassEntry) { |
| @@ -461,6 +491,10 @@ public class JarIndex { | |||
| 461 | return this.bridgedMethods.get(bridgeMethodEntry); | 491 | return this.bridgedMethods.get(bridgeMethodEntry); |
| 462 | } | 492 | } |
| 463 | 493 | ||
| 494 | public MethodEntry getAccessMethod(MethodEntry bridgeMethodEntry) { | ||
| 495 | return this.accessMethods.get(bridgeMethodEntry); | ||
| 496 | } | ||
| 497 | |||
| 464 | public List<ClassEntry> getObfClassChain(ClassEntry obfClassEntry) { | 498 | public List<ClassEntry> getObfClassChain(ClassEntry obfClassEntry) { |
| 465 | 499 | ||
| 466 | // build class chain in inner-to-outer order | 500 | // build class chain in inner-to-outer order |
diff --git a/src/main/java/cuchaz/enigma/analysis/MethodReferenceTreeNode.java b/src/main/java/cuchaz/enigma/analysis/MethodReferenceTreeNode.java index 15ae5153..76c73c15 100644 --- a/src/main/java/cuchaz/enigma/analysis/MethodReferenceTreeNode.java +++ b/src/main/java/cuchaz/enigma/analysis/MethodReferenceTreeNode.java | |||
| @@ -64,7 +64,7 @@ public class MethodReferenceTreeNode extends DefaultMutableTreeNode | |||
| 64 | 64 | ||
| 65 | public void load(JarIndex index, boolean recurse) { | 65 | public void load(JarIndex index, boolean recurse) { |
| 66 | // get all the child nodes | 66 | // get all the child nodes |
| 67 | for (EntryReference<MethodEntry, MethodDefEntry> reference : index.getMethodReferences(this.entry)) { | 67 | for (EntryReference<MethodEntry, MethodDefEntry> reference : index.getMethodsReferencing(this.entry)) { |
| 68 | add(new MethodReferenceTreeNode(this.deobfuscatingTranslator, reference, index.getAccess(this.entry))); | 68 | add(new MethodReferenceTreeNode(this.deobfuscatingTranslator, reference, index.getAccess(this.entry))); |
| 69 | } | 69 | } |
| 70 | 70 | ||
diff --git a/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java b/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java index dd275b38..763639a4 100644 --- a/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java +++ b/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java | |||
| @@ -55,7 +55,7 @@ public class TestJarIndexConstructorReferences { | |||
| 55 | @SuppressWarnings("unchecked") | 55 | @SuppressWarnings("unchecked") |
| 56 | public void baseDefault() { | 56 | public void baseDefault() { |
| 57 | MethodEntry source = newMethod(baseClass, "<init>", "()V"); | 57 | MethodEntry source = newMethod(baseClass, "<init>", "()V"); |
| 58 | Collection<EntryReference<MethodEntry, MethodDefEntry>> references = index.getMethodReferences(source); | 58 | Collection<EntryReference<MethodEntry, MethodDefEntry>> references = index.getMethodsReferencing(source); |
| 59 | assertThat(references, containsInAnyOrder( | 59 | assertThat(references, containsInAnyOrder( |
| 60 | newBehaviorReferenceByMethod(source, callerClass.getName(), "a", "()V"), | 60 | newBehaviorReferenceByMethod(source, callerClass.getName(), "a", "()V"), |
| 61 | newBehaviorReferenceByMethod(source, subClass.getName(), "<init>", "()V"), | 61 | newBehaviorReferenceByMethod(source, subClass.getName(), "<init>", "()V"), |
| @@ -67,7 +67,7 @@ public class TestJarIndexConstructorReferences { | |||
| 67 | @SuppressWarnings("unchecked") | 67 | @SuppressWarnings("unchecked") |
| 68 | public void baseInt() { | 68 | public void baseInt() { |
| 69 | MethodEntry source = newMethod(baseClass, "<init>", "(I)V"); | 69 | MethodEntry source = newMethod(baseClass, "<init>", "(I)V"); |
| 70 | assertThat(index.getMethodReferences(source), containsInAnyOrder( | 70 | assertThat(index.getMethodsReferencing(source), containsInAnyOrder( |
| 71 | newBehaviorReferenceByMethod(source, callerClass.getName(), "b", "()V") | 71 | newBehaviorReferenceByMethod(source, callerClass.getName(), "b", "()V") |
| 72 | )); | 72 | )); |
| 73 | } | 73 | } |
| @@ -76,7 +76,7 @@ public class TestJarIndexConstructorReferences { | |||
| 76 | @SuppressWarnings("unchecked") | 76 | @SuppressWarnings("unchecked") |
| 77 | public void subDefault() { | 77 | public void subDefault() { |
| 78 | MethodEntry source = newMethod(subClass, "<init>", "()V"); | 78 | MethodEntry source = newMethod(subClass, "<init>", "()V"); |
| 79 | assertThat(index.getMethodReferences(source), containsInAnyOrder( | 79 | assertThat(index.getMethodsReferencing(source), containsInAnyOrder( |
| 80 | newBehaviorReferenceByMethod(source, callerClass.getName(), "c", "()V"), | 80 | newBehaviorReferenceByMethod(source, callerClass.getName(), "c", "()V"), |
| 81 | newBehaviorReferenceByMethod(source, subClass.getName(), "<init>", "(I)V") | 81 | newBehaviorReferenceByMethod(source, subClass.getName(), "<init>", "(I)V") |
| 82 | )); | 82 | )); |
| @@ -86,7 +86,7 @@ public class TestJarIndexConstructorReferences { | |||
| 86 | @SuppressWarnings("unchecked") | 86 | @SuppressWarnings("unchecked") |
| 87 | public void subInt() { | 87 | public void subInt() { |
| 88 | MethodEntry source = newMethod(subClass, "<init>", "(I)V"); | 88 | MethodEntry source = newMethod(subClass, "<init>", "(I)V"); |
| 89 | assertThat(index.getMethodReferences(source), containsInAnyOrder( | 89 | assertThat(index.getMethodsReferencing(source), containsInAnyOrder( |
| 90 | newBehaviorReferenceByMethod(source, callerClass.getName(), "d", "()V"), | 90 | newBehaviorReferenceByMethod(source, callerClass.getName(), "d", "()V"), |
| 91 | newBehaviorReferenceByMethod(source, subClass.getName(), "<init>", "(II)V"), | 91 | newBehaviorReferenceByMethod(source, subClass.getName(), "<init>", "(II)V"), |
| 92 | newBehaviorReferenceByMethod(source, subsubClass.getName(), "<init>", "(I)V") | 92 | newBehaviorReferenceByMethod(source, subsubClass.getName(), "<init>", "(I)V") |
| @@ -97,7 +97,7 @@ public class TestJarIndexConstructorReferences { | |||
| 97 | @SuppressWarnings("unchecked") | 97 | @SuppressWarnings("unchecked") |
| 98 | public void subIntInt() { | 98 | public void subIntInt() { |
| 99 | MethodEntry source = newMethod(subClass, "<init>", "(II)V"); | 99 | MethodEntry source = newMethod(subClass, "<init>", "(II)V"); |
| 100 | assertThat(index.getMethodReferences(source), containsInAnyOrder( | 100 | assertThat(index.getMethodsReferencing(source), containsInAnyOrder( |
| 101 | newBehaviorReferenceByMethod(source, callerClass.getName(), "e", "()V") | 101 | newBehaviorReferenceByMethod(source, callerClass.getName(), "e", "()V") |
| 102 | )); | 102 | )); |
| 103 | } | 103 | } |
| @@ -105,14 +105,14 @@ public class TestJarIndexConstructorReferences { | |||
| 105 | @Test | 105 | @Test |
| 106 | public void subIntIntInt() { | 106 | public void subIntIntInt() { |
| 107 | MethodEntry source = newMethod(subClass, "<init>", "(III)V"); | 107 | MethodEntry source = newMethod(subClass, "<init>", "(III)V"); |
| 108 | assertThat(index.getMethodReferences(source), is(empty())); | 108 | assertThat(index.getMethodsReferencing(source), is(empty())); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | @Test | 111 | @Test |
| 112 | @SuppressWarnings("unchecked") | 112 | @SuppressWarnings("unchecked") |
| 113 | public void subsubInt() { | 113 | public void subsubInt() { |
| 114 | MethodEntry source = newMethod(subsubClass, "<init>", "(I)V"); | 114 | MethodEntry source = newMethod(subsubClass, "<init>", "(I)V"); |
| 115 | assertThat(index.getMethodReferences(source), containsInAnyOrder( | 115 | assertThat(index.getMethodsReferencing(source), containsInAnyOrder( |
| 116 | newBehaviorReferenceByMethod(source, callerClass.getName(), "f", "()V") | 116 | newBehaviorReferenceByMethod(source, callerClass.getName(), "f", "()V") |
| 117 | )); | 117 | )); |
| 118 | } | 118 | } |
| @@ -121,7 +121,7 @@ public class TestJarIndexConstructorReferences { | |||
| 121 | @SuppressWarnings("unchecked") | 121 | @SuppressWarnings("unchecked") |
| 122 | public void defaultConstructable() { | 122 | public void defaultConstructable() { |
| 123 | MethodEntry source = newMethod(defaultClass, "<init>", "()V"); | 123 | MethodEntry source = newMethod(defaultClass, "<init>", "()V"); |
| 124 | assertThat(index.getMethodReferences(source), containsInAnyOrder( | 124 | assertThat(index.getMethodsReferencing(source), containsInAnyOrder( |
| 125 | newBehaviorReferenceByMethod(source, callerClass.getName(), "g", "()V") | 125 | newBehaviorReferenceByMethod(source, callerClass.getName(), "g", "()V") |
| 126 | )); | 126 | )); |
| 127 | } | 127 | } |
diff --git a/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java b/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java index 5bef4e57..23df1a99 100644 --- a/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java +++ b/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java | |||
| @@ -152,7 +152,7 @@ public class TestJarIndexInheritanceTree { | |||
| 152 | 152 | ||
| 153 | // baseClass constructor | 153 | // baseClass constructor |
| 154 | source = newMethod(baseClass, "<init>", "(Ljava/lang/String;)V"); | 154 | source = newMethod(baseClass, "<init>", "(Ljava/lang/String;)V"); |
| 155 | references = index.getMethodReferences(source); | 155 | references = index.getMethodsReferencing(source); |
| 156 | assertThat(references, containsInAnyOrder( | 156 | assertThat(references, containsInAnyOrder( |
| 157 | newBehaviorReferenceByMethod(source, subClassA.getName(), "<init>", "(Ljava/lang/String;)V"), | 157 | newBehaviorReferenceByMethod(source, subClassA.getName(), "<init>", "(Ljava/lang/String;)V"), |
| 158 | newBehaviorReferenceByMethod(source, subClassB.getName(), "<init>", "()V") | 158 | newBehaviorReferenceByMethod(source, subClassB.getName(), "<init>", "()V") |
| @@ -160,14 +160,14 @@ public class TestJarIndexInheritanceTree { | |||
| 160 | 160 | ||
| 161 | // subClassA constructor | 161 | // subClassA constructor |
| 162 | source = newMethod(subClassA, "<init>", "(Ljava/lang/String;)V"); | 162 | source = newMethod(subClassA, "<init>", "(Ljava/lang/String;)V"); |
| 163 | references = index.getMethodReferences(source); | 163 | references = index.getMethodsReferencing(source); |
| 164 | assertThat(references, containsInAnyOrder( | 164 | assertThat(references, containsInAnyOrder( |
| 165 | newBehaviorReferenceByMethod(source, subClassAA.getName(), "<init>", "()V") | 165 | newBehaviorReferenceByMethod(source, subClassAA.getName(), "<init>", "()V") |
| 166 | )); | 166 | )); |
| 167 | 167 | ||
| 168 | // baseClass.getName() | 168 | // baseClass.getName() |
| 169 | source = newMethod(baseClass, "a", "()Ljava/lang/String;"); | 169 | source = newMethod(baseClass, "a", "()Ljava/lang/String;"); |
| 170 | references = index.getMethodReferences(source); | 170 | references = index.getMethodsReferencing(source); |
| 171 | assertThat(references, containsInAnyOrder( | 171 | assertThat(references, containsInAnyOrder( |
| 172 | newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()Ljava/lang/String;"), | 172 | newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()Ljava/lang/String;"), |
| 173 | newBehaviorReferenceByMethod(source, subClassB.getName(), "a", "()V") | 173 | newBehaviorReferenceByMethod(source, subClassB.getName(), "a", "()V") |
| @@ -175,7 +175,7 @@ public class TestJarIndexInheritanceTree { | |||
| 175 | 175 | ||
| 176 | // subclassAA.getName() | 176 | // subclassAA.getName() |
| 177 | source = newMethod(subClassAA, "a", "()Ljava/lang/String;"); | 177 | source = newMethod(subClassAA, "a", "()Ljava/lang/String;"); |
| 178 | references = index.getMethodReferences(source); | 178 | references = index.getMethodsReferencing(source); |
| 179 | assertThat(references, containsInAnyOrder( | 179 | assertThat(references, containsInAnyOrder( |
| 180 | newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()V") | 180 | newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()V") |
| 181 | )); | 181 | )); |
diff --git a/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java b/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java index b1c128c2..b4529ddc 100644 --- a/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java +++ b/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java | |||
| @@ -110,7 +110,7 @@ public class TestJarIndexLoneClass { | |||
| 110 | 110 | ||
| 111 | @Test | 111 | @Test |
| 112 | public void behaviorReferences() { | 112 | public void behaviorReferences() { |
| 113 | assertThat(index.getMethodReferences(newMethod("a", "a", "()Ljava/lang/String;")), is(empty())); | 113 | assertThat(index.getMethodsReferencing(newMethod("a", "a", "()Ljava/lang/String;")), is(empty())); |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | @Test | 116 | @Test |