From df8def23dd0336d8a5d2369c5d4c0f4331838ef4 Mon Sep 17 00:00:00 2001 From: Erlend Åmdal Date: Wed, 15 May 2019 12:45:41 +0200 Subject: checkmappings command (#137) * Use expected map sizes for remapped multimaps * Index method and field types * Add package visibility index * Add checkmappings command and use System.err for error messages * Use exit codes for errors * Remove outer class check for package visible only refs * Throw exception on mapping error instead of exiting --- .../cuchaz/enigma/analysis/index/EntryIndex.java | 5 + .../cuchaz/enigma/analysis/index/JarIndex.java | 13 ++- .../analysis/index/PackageVisibilityIndex.java | 127 +++++++++++++++++++++ .../enigma/analysis/index/ReferenceIndex.java | 55 ++++++++- 4 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java (limited to 'src/main/java/cuchaz/enigma/analysis/index') diff --git a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java index 773eaf1..31c6f54 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java @@ -64,6 +64,11 @@ public class EntryIndex implements JarIndexer { return fields.get(entry); } + @Nullable + public AccessFlags getClassAccess(ClassEntry entry) { + return classes.get(entry); + } + @Nullable public AccessFlags getEntryAccess(Entry entry) { if (entry instanceof MethodEntry) { diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java index a429ff6..ac907af 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java @@ -29,18 +29,20 @@ public class JarIndex implements JarIndexer { private final InheritanceIndex inheritanceIndex; private final ReferenceIndex referenceIndex; private final BridgeMethodIndex bridgeMethodIndex; + private final PackageVisibilityIndex packageVisibilityIndex; private final EntryResolver entryResolver; private final Collection indexers; private final Multimap methodImplementations = HashMultimap.create(); - public JarIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex, BridgeMethodIndex bridgeMethodIndex) { + public JarIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex, BridgeMethodIndex bridgeMethodIndex, PackageVisibilityIndex packageVisibilityIndex) { this.entryIndex = entryIndex; this.inheritanceIndex = inheritanceIndex; this.referenceIndex = referenceIndex; this.bridgeMethodIndex = bridgeMethodIndex; - this.indexers = Arrays.asList(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex); + this.packageVisibilityIndex = packageVisibilityIndex; + this.indexers = Arrays.asList(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex); this.entryResolver = new IndexEntryResolver(this); } @@ -49,7 +51,8 @@ public class JarIndex implements JarIndexer { InheritanceIndex inheritanceIndex = new InheritanceIndex(entryIndex); ReferenceIndex referenceIndex = new ReferenceIndex(); BridgeMethodIndex bridgeMethodIndex = new BridgeMethodIndex(entryIndex, inheritanceIndex, referenceIndex); - return new JarIndex(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex); + PackageVisibilityIndex packageVisibilityIndex = new PackageVisibilityIndex(); + return new JarIndex(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex); } public void indexJar(ParsedJar jar, Consumer progress) { @@ -142,6 +145,10 @@ public class JarIndex implements JarIndexer { return bridgeMethodIndex; } + public PackageVisibilityIndex getPackageVisibilityIndex() { + return packageVisibilityIndex; + } + public EntryResolver getEntryResolver() { return entryResolver; } diff --git a/src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java b/src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java new file mode 100644 index 0000000..9e9115f --- /dev/null +++ b/src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java @@ -0,0 +1,127 @@ +package cuchaz.enigma.analysis.index; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import cuchaz.enigma.analysis.EntryReference; +import cuchaz.enigma.translation.representation.AccessFlags; +import cuchaz.enigma.translation.representation.entry.*; + +import java.util.*; + +public class PackageVisibilityIndex implements JarIndexer { + private static boolean isPackageVisibleOnlyRef(AccessFlags entryAcc, EntryReference ref, InheritanceIndex inheritanceIndex) { + if (entryAcc.isPublic()) return false; + if (entryAcc.isProtected()) { + Set callerAncestors = inheritanceIndex.getAncestors(ref.context.getContainingClass()); + return !callerAncestors.contains(ref.entry.getContainingClass()); + } + return !entryAcc.isPrivate(); // if isPrivate is false, it must be package-private + } + + private final HashMultimap connections = HashMultimap.create(); + private final List> partitions = Lists.newArrayList(); + private final Map> classPartitions = Maps.newHashMap(); + + private void addConnection(ClassEntry classA, ClassEntry classB) { + connections.put(classA, classB); + connections.put(classB, classA); + } + + private void buildPartition(Set unassignedClasses, Set partition, ClassEntry member) { + for (ClassEntry connected : connections.get(member)) { + if (unassignedClasses.remove(connected)) { + partition.add(connected); + buildPartition(unassignedClasses, partition, connected); + } + } + } + + private void addConnections(EntryIndex entryIndex, ReferenceIndex referenceIndex, InheritanceIndex inheritanceIndex) { + for (FieldEntry entry : entryIndex.getFields()) { + AccessFlags entryAcc = entryIndex.getFieldAccess(entry); + if (!entryAcc.isPublic() && !entryAcc.isPrivate()) { + for (EntryReference ref : referenceIndex.getReferencesToField(entry)) { + if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); + } + } + } + } + + for (MethodEntry entry : entryIndex.getMethods()) { + AccessFlags entryAcc = entryIndex.getMethodAccess(entry); + if (!entryAcc.isPublic() && !entryAcc.isPrivate()) { + for (EntryReference ref : referenceIndex.getReferencesToMethod(entry)) { + if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); + } + } + } + } + + for (ClassEntry entry : entryIndex.getClasses()) { + AccessFlags entryAcc = entryIndex.getClassAccess(entry); + if (!entryAcc.isPublic() && !entryAcc.isPrivate()) { + for (EntryReference ref : referenceIndex.getFieldTypeReferencesToClass(entry)) { + if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); + } + } + + for (EntryReference ref : referenceIndex.getMethodTypeReferencesToClass(entry)) { + if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); + } + } + } + + for (ClassEntry parent : inheritanceIndex.getParents(entry)) { + AccessFlags parentAcc = entryIndex.getClassAccess(parent); + if (parentAcc != null && !parentAcc.isPublic() && !parentAcc.isPrivate()) { + addConnection(entry, parent); + } + } + + ClassEntry outerClass = entry.getOuterClass(); + if (outerClass != null) { + addConnection(entry, outerClass); + } + } + } + + private void addPartitions(EntryIndex entryIndex) { + Set unassignedClasses = Sets.newHashSet(entryIndex.getClasses()); + while (!unassignedClasses.isEmpty()) { + Iterator iterator = unassignedClasses.iterator(); + ClassEntry initialEntry = iterator.next(); + iterator.remove(); + + HashSet partition = Sets.newHashSet(); + partition.add(initialEntry); + buildPartition(unassignedClasses, partition, initialEntry); + partitions.add(partition); + for (ClassEntry entry : partition) { + classPartitions.put(entry, partition); + } + } + } + + public Collection> getPartitions() { + return partitions; + } + + public Set getPartition(ClassEntry classEntry) { + return classPartitions.get(classEntry); + } + + @Override + public void processIndex(JarIndex index) { + EntryIndex entryIndex = index.getEntryIndex(); + ReferenceIndex referenceIndex = index.getReferenceIndex(); + InheritanceIndex inheritanceIndex = index.getInheritanceIndex(); + addConnections(entryIndex, referenceIndex, inheritanceIndex); + addPartitions(entryIndex); + } +} diff --git a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java index 2b63c5d..6764ac0 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java @@ -4,6 +4,8 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import cuchaz.enigma.analysis.EntryReference; import cuchaz.enigma.translation.mapping.ResolutionStrategy; +import cuchaz.enigma.translation.representation.MethodDescriptor; +import cuchaz.enigma.translation.representation.TypeDescriptor; import cuchaz.enigma.translation.representation.entry.*; import java.util.Collection; @@ -15,6 +17,43 @@ public class ReferenceIndex implements JarIndexer { private Multimap> referencesToMethods = HashMultimap.create(); private Multimap> referencesToClasses = HashMultimap.create(); private Multimap> referencesToFields = HashMultimap.create(); + private Multimap> fieldTypeReferences = HashMultimap.create(); + private Multimap> methodTypeReferences = HashMultimap.create(); + + @Override + public void indexMethod(MethodDefEntry methodEntry) { + indexMethodDescriptor(methodEntry, methodEntry.getDesc()); + } + + private void indexMethodDescriptor(MethodDefEntry entry, MethodDescriptor descriptor) { + for (TypeDescriptor typeDescriptor : descriptor.getArgumentDescs()) { + indexMethodTypeDescriptor(entry, typeDescriptor); + } + indexMethodTypeDescriptor(entry, descriptor.getReturnDesc()); + } + + private void indexMethodTypeDescriptor(MethodDefEntry method, TypeDescriptor typeDescriptor) { + if (typeDescriptor.isType()) { + ClassEntry referencedClass = typeDescriptor.getTypeEntry(); + methodTypeReferences.put(referencedClass, new EntryReference<>(referencedClass, referencedClass.getName(), method)); + } else if (typeDescriptor.isArray()) { + indexMethodTypeDescriptor(method, typeDescriptor.getArrayType()); + } + } + + @Override + public void indexField(FieldDefEntry fieldEntry) { + indexFieldTypeDescriptor(fieldEntry, fieldEntry.getDesc()); + } + + private void indexFieldTypeDescriptor(FieldDefEntry field, TypeDescriptor typeDescriptor) { + if (typeDescriptor.isType()) { + ClassEntry referencedClass = typeDescriptor.getTypeEntry(); + fieldTypeReferences.put(referencedClass, new EntryReference<>(referencedClass, referencedClass.getName(), field)); + } else if (typeDescriptor.isArray()) { + indexFieldTypeDescriptor(field, typeDescriptor.getArrayType()); + } + } @Override public void indexMethodReference(MethodDefEntry callerEntry, MethodEntry referencedEntry) { @@ -25,6 +64,8 @@ public class ReferenceIndex implements JarIndexer { ClassEntry referencedClass = referencedEntry.getParent(); referencesToClasses.put(referencedClass, new EntryReference<>(referencedClass, referencedEntry.getName(), callerEntry)); } + + indexMethodDescriptor(callerEntry, referencedEntry.getDesc()); } @Override @@ -38,10 +79,12 @@ public class ReferenceIndex implements JarIndexer { referencesToMethods = remapReferencesTo(index, referencesToMethods); referencesToClasses = remapReferencesTo(index, referencesToClasses); referencesToFields = remapReferencesTo(index, referencesToFields); + fieldTypeReferences = remapReferencesTo(index, fieldTypeReferences); + methodTypeReferences = remapReferencesTo(index, methodTypeReferences); } private , V extends Entry> Multimap remapReferences(JarIndex index, Multimap multimap) { - Multimap resolved = HashMultimap.create(); + Multimap resolved = HashMultimap.create(multimap.keySet().size(), multimap.size() / multimap.keySet().size()); for (Map.Entry entry : multimap.entries()) { resolved.put(remap(index, entry.getKey()), remap(index, entry.getValue())); } @@ -49,7 +92,7 @@ public class ReferenceIndex implements JarIndexer { } private , C extends Entry> Multimap> remapReferencesTo(JarIndex index, Multimap> multimap) { - Multimap> resolved = HashMultimap.create(); + Multimap> resolved = HashMultimap.create(multimap.keySet().size(), multimap.size() / multimap.keySet().size()); for (Map.Entry> entry : multimap.entries()) { resolved.put(remap(index, entry.getKey()), remap(index, entry.getValue())); } @@ -79,4 +122,12 @@ public class ReferenceIndex implements JarIndexer { public Collection> getReferencesToMethod(MethodEntry entry) { return referencesToMethods.get(entry); } + + public Collection> getFieldTypeReferencesToClass(ClassEntry entry) { + return fieldTypeReferences.get(entry); + } + + public Collection> getMethodTypeReferencesToClass(ClassEntry entry) { + return methodTypeReferences.get(entry); + } } -- cgit v1.2.3 From cb8823eb0b446d5c1b9b580e5578866e691771d8 Mon Sep 17 00:00:00 2001 From: liach Date: Wed, 15 May 2019 22:03:13 -0700 Subject: Feature/weave (#138) * Add weave/stitch style command system to enigma Also fixed divide by zero stupidity Signed-off-by: liach * Add tests for package access index and command Signed-off-by: liach * Minor tweaks Signed-off-by: liach --- .../cuchaz/enigma/analysis/index/PackageVisibilityIndex.java | 10 +++++----- src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/main/java/cuchaz/enigma/analysis/index') diff --git a/src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java b/src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java index 9e9115f..da28ac4 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/PackageVisibilityIndex.java @@ -11,7 +11,7 @@ import cuchaz.enigma.translation.representation.entry.*; import java.util.*; public class PackageVisibilityIndex implements JarIndexer { - private static boolean isPackageVisibleOnlyRef(AccessFlags entryAcc, EntryReference ref, InheritanceIndex inheritanceIndex) { + private static boolean requiresSamePackage(AccessFlags entryAcc, EntryReference ref, InheritanceIndex inheritanceIndex) { if (entryAcc.isPublic()) return false; if (entryAcc.isProtected()) { Set callerAncestors = inheritanceIndex.getAncestors(ref.context.getContainingClass()); @@ -43,7 +43,7 @@ public class PackageVisibilityIndex implements JarIndexer { AccessFlags entryAcc = entryIndex.getFieldAccess(entry); if (!entryAcc.isPublic() && !entryAcc.isPrivate()) { for (EntryReference ref : referenceIndex.getReferencesToField(entry)) { - if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + if (requiresSamePackage(entryAcc, ref, inheritanceIndex)) { addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); } } @@ -54,7 +54,7 @@ public class PackageVisibilityIndex implements JarIndexer { AccessFlags entryAcc = entryIndex.getMethodAccess(entry); if (!entryAcc.isPublic() && !entryAcc.isPrivate()) { for (EntryReference ref : referenceIndex.getReferencesToMethod(entry)) { - if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + if (requiresSamePackage(entryAcc, ref, inheritanceIndex)) { addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); } } @@ -65,13 +65,13 @@ public class PackageVisibilityIndex implements JarIndexer { AccessFlags entryAcc = entryIndex.getClassAccess(entry); if (!entryAcc.isPublic() && !entryAcc.isPrivate()) { for (EntryReference ref : referenceIndex.getFieldTypeReferencesToClass(entry)) { - if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + if (requiresSamePackage(entryAcc, ref, inheritanceIndex)) { addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); } } for (EntryReference ref : referenceIndex.getMethodTypeReferencesToClass(entry)) { - if (isPackageVisibleOnlyRef(entryAcc, ref, inheritanceIndex)) { + if (requiresSamePackage(entryAcc, ref, inheritanceIndex)) { addConnection(ref.entry.getContainingClass(), ref.context.getContainingClass()); } } diff --git a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java index 6764ac0..04306bd 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java @@ -92,7 +92,8 @@ public class ReferenceIndex implements JarIndexer { } private , C extends Entry> Multimap> remapReferencesTo(JarIndex index, Multimap> multimap) { - Multimap> resolved = HashMultimap.create(multimap.keySet().size(), multimap.size() / multimap.keySet().size()); + final int keySetSize = multimap.keySet().size(); + Multimap> resolved = HashMultimap.create(keySetSize, keySetSize == 0 ? 0 : multimap.size() / keySetSize); for (Map.Entry> entry : multimap.entries()) { resolved.put(remap(index, entry.getKey()), remap(index, entry.getValue())); } -- cgit v1.2.3 From 463aee1dfc1222e8f6f0312aa46fb9b9dcfa13a1 Mon Sep 17 00:00:00 2001 From: Erlend Åmdal Date: Sat, 18 May 2019 11:13:24 +0200 Subject: Method type reference corrections (#142) * Add more specific returns for translatables * Only index method descriptors for implemented methods and methods in generated lambda classes --- .../analysis/index/IndexReferenceVisitor.java | 61 ++++++++++++---------- .../cuchaz/enigma/analysis/index/JarIndex.java | 10 ++++ .../cuchaz/enigma/analysis/index/JarIndexer.java | 4 ++ .../enigma/analysis/index/ReferenceIndex.java | 16 +++++- 4 files changed, 60 insertions(+), 31 deletions(-) (limited to 'src/main/java/cuchaz/enigma/analysis/index') diff --git a/src/main/java/cuchaz/enigma/analysis/index/IndexReferenceVisitor.java b/src/main/java/cuchaz/enigma/analysis/index/IndexReferenceVisitor.java index ba5d3b6..b730a8a 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/IndexReferenceVisitor.java +++ b/src/main/java/cuchaz/enigma/analysis/index/IndexReferenceVisitor.java @@ -1,16 +1,11 @@ package cuchaz.enigma.analysis.index; import cuchaz.enigma.translation.representation.AccessFlags; +import cuchaz.enigma.translation.representation.Lambda; import cuchaz.enigma.translation.representation.MethodDescriptor; import cuchaz.enigma.translation.representation.Signature; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.MethodDefEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.Handle; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; +import cuchaz.enigma.translation.representation.entry.*; +import org.objectweb.asm.*; public class IndexReferenceVisitor extends ClassVisitor { private final JarIndexer indexer; @@ -54,29 +49,37 @@ public class IndexReferenceVisitor extends ClassVisitor { this.indexer.indexMethodReference(callerEntry, methodEntry); } + private static ParentedEntry getHandleEntry(Handle handle) { + switch (handle.getTag()) { + case Opcodes.H_GETFIELD: + case Opcodes.H_GETSTATIC: + case Opcodes.H_PUTFIELD: + case Opcodes.H_PUTSTATIC: + return FieldEntry.parse(handle.getOwner(), handle.getName(), handle.getDesc()); + case Opcodes.H_INVOKEINTERFACE: + case Opcodes.H_INVOKESPECIAL: + case Opcodes.H_INVOKESTATIC: + case Opcodes.H_INVOKEVIRTUAL: + case Opcodes.H_NEWINVOKESPECIAL: + return MethodEntry.parse(handle.getOwner(), handle.getName(), handle.getDesc()); + } + throw new RuntimeException("Invalid handle tag " + handle.getTag()); + } + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { - for (Object bsmArg : bsmArgs) { - if (bsmArg instanceof Handle) { - Handle handle = (Handle) bsmArg; - switch (handle.getTag()) { - case Opcodes.H_GETFIELD: - case Opcodes.H_GETSTATIC: - case Opcodes.H_PUTFIELD: - case Opcodes.H_PUTSTATIC: - FieldEntry fieldEntry = FieldEntry.parse(handle.getOwner(), handle.getName(), handle.getDesc()); - this.indexer.indexFieldReference(callerEntry, fieldEntry); - break; - case Opcodes.H_INVOKEINTERFACE: - case Opcodes.H_INVOKESPECIAL: - case Opcodes.H_INVOKESTATIC: - case Opcodes.H_INVOKEVIRTUAL: - case Opcodes.H_NEWINVOKESPECIAL: - MethodEntry methodEntry = MethodEntry.parse(handle.getOwner(), handle.getName(), handle.getDesc()); - this.indexer.indexMethodReference(callerEntry, methodEntry); - break; - } - } + if ("java/lang/invoke/LambdaMetafactory".equals(bsm.getOwner()) && "metafactory".equals(bsm.getName())) { + Type samMethodType = (Type) bsmArgs[0]; + Handle implMethod = (Handle) bsmArgs[1]; + Type instantiatedMethodType = (Type) bsmArgs[2]; + + this.indexer.indexLambda(callerEntry, new Lambda( + name, + new MethodDescriptor(desc), + new MethodDescriptor(samMethodType.getDescriptor()), + getHandleEntry(implMethod), + new MethodDescriptor(instantiatedMethodType.getDescriptor()) + )); } } } diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java index ac907af..fd4e618 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java @@ -16,6 +16,7 @@ import com.google.common.collect.Multimap; import cuchaz.enigma.analysis.ParsedJar; import cuchaz.enigma.translation.mapping.EntryResolver; import cuchaz.enigma.translation.mapping.IndexEntryResolver; +import cuchaz.enigma.translation.representation.Lambda; import cuchaz.enigma.translation.representation.entry.*; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; @@ -129,6 +130,15 @@ public class JarIndex implements JarIndexer { indexers.forEach(indexer -> indexer.indexFieldReference(callerEntry, referencedEntry)); } + @Override + public void indexLambda(MethodDefEntry callerEntry, Lambda lambda) { + if (callerEntry.getParent().isJre()) { + return; + } + + indexers.forEach(indexer -> indexer.indexLambda(callerEntry, lambda)); + } + public EntryIndex getEntryIndex() { return entryIndex; } diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java index 457c223..4f885b3 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java +++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java @@ -1,5 +1,6 @@ package cuchaz.enigma.analysis.index; +import cuchaz.enigma.translation.representation.Lambda; import cuchaz.enigma.translation.representation.entry.*; public interface JarIndexer { @@ -18,6 +19,9 @@ public interface JarIndexer { default void indexFieldReference(MethodDefEntry callerEntry, FieldEntry referencedEntry) { } + default void indexLambda(MethodDefEntry callerEntry, Lambda lambda) { + } + default void processIndex(JarIndex index) { } } diff --git a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java index 04306bd..f54c90d 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java @@ -4,6 +4,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import cuchaz.enigma.analysis.EntryReference; import cuchaz.enigma.translation.mapping.ResolutionStrategy; +import cuchaz.enigma.translation.representation.Lambda; import cuchaz.enigma.translation.representation.MethodDescriptor; import cuchaz.enigma.translation.representation.TypeDescriptor; import cuchaz.enigma.translation.representation.entry.*; @@ -64,8 +65,6 @@ public class ReferenceIndex implements JarIndexer { ClassEntry referencedClass = referencedEntry.getParent(); referencesToClasses.put(referencedClass, new EntryReference<>(referencedClass, referencedEntry.getName(), callerEntry)); } - - indexMethodDescriptor(callerEntry, referencedEntry.getDesc()); } @Override @@ -73,6 +72,19 @@ public class ReferenceIndex implements JarIndexer { referencesToFields.put(referencedEntry, new EntryReference<>(referencedEntry, referencedEntry.getName(), callerEntry)); } + @Override + public void indexLambda(MethodDefEntry callerEntry, Lambda lambda) { + if (lambda.getImplMethod() instanceof MethodEntry) { + indexMethodReference(callerEntry, (MethodEntry) lambda.getImplMethod()); + } else { + indexFieldReference(callerEntry, (FieldEntry) lambda.getImplMethod()); + } + + indexMethodDescriptor(callerEntry, lambda.getInvokedType()); + indexMethodDescriptor(callerEntry, lambda.getSamMethodType()); + indexMethodDescriptor(callerEntry, lambda.getInstantiatedMethodType()); + } + @Override public void processIndex(JarIndex index) { methodReferences = remapReferences(index, methodReferences); -- cgit v1.2.3