diff options
Diffstat (limited to 'src')
6 files changed, 48 insertions, 80 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java index 649ce25..8a9b459 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java | |||
| @@ -17,8 +17,8 @@ public class BridgeMethodIndex implements JarIndexer { | |||
| 17 | private final InheritanceIndex inheritanceIndex; | 17 | private final InheritanceIndex inheritanceIndex; |
| 18 | private final ReferenceIndex referenceIndex; | 18 | private final ReferenceIndex referenceIndex; |
| 19 | 19 | ||
| 20 | private final Set<MethodEntry> bridgeMethods = Sets.newHashSet(); | 20 | private final Set<MethodEntry> bridgeToSpecialized = Sets.newHashSet(); |
| 21 | private final Map<MethodEntry, MethodEntry> accessedToBridge = Maps.newHashMap(); | 21 | private final Map<MethodEntry, MethodEntry> specializedToBridge = Maps.newHashMap(); |
| 22 | 22 | ||
| 23 | public BridgeMethodIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex) { | 23 | public BridgeMethodIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex) { |
| 24 | this.entryIndex = entryIndex; | 24 | this.entryIndex = entryIndex; |
| @@ -42,34 +42,34 @@ public class BridgeMethodIndex implements JarIndexer { | |||
| 42 | 42 | ||
| 43 | @Override | 43 | @Override |
| 44 | public void processIndex(JarIndex index) { | 44 | public void processIndex(JarIndex index) { |
| 45 | Map<MethodEntry, MethodEntry> copiedAccessToBridge = new HashMap<>(accessedToBridge); | 45 | Map<MethodEntry, MethodEntry> copiedAccessToBridge = new HashMap<>(specializedToBridge); |
| 46 | 46 | ||
| 47 | for (Map.Entry<MethodEntry, MethodEntry> entry : copiedAccessToBridge.entrySet()) { | 47 | for (Map.Entry<MethodEntry, MethodEntry> entry : copiedAccessToBridge.entrySet()) { |
| 48 | MethodEntry accessedEntry = entry.getKey(); | 48 | MethodEntry specializedEntry = entry.getKey(); |
| 49 | MethodEntry bridgeEntry = entry.getValue(); | 49 | MethodEntry bridgeEntry = entry.getValue(); |
| 50 | if (bridgeEntry.getName().equals(accessedEntry.getName())) { | 50 | if (bridgeEntry.getName().equals(specializedEntry.getName())) { |
| 51 | continue; | 51 | continue; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName()); | 54 | MethodEntry renamedSpecializedEntry = specializedEntry.withName(bridgeEntry.getName()); |
| 55 | bridgeMethods.add(renamedAccessedEntry); | 55 | bridgeToSpecialized.add(renamedSpecializedEntry); |
| 56 | accessedToBridge.put(renamedAccessedEntry, accessedToBridge.get(accessedEntry)); | 56 | specializedToBridge.put(renamedSpecializedEntry, specializedToBridge.get(specializedEntry)); |
| 57 | } | 57 | } |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | private void indexSyntheticMethod(MethodDefEntry syntheticMethod, AccessFlags access) { | 60 | private void indexSyntheticMethod(MethodDefEntry syntheticMethod, AccessFlags access) { |
| 61 | MethodEntry accessedMethod = findAccessMethod(syntheticMethod); | 61 | MethodEntry specializedMethod = findSpecializedMethod(syntheticMethod); |
| 62 | if (accessedMethod == null) { | 62 | if (specializedMethod == null) { |
| 63 | return; | 63 | return; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | if (access.isBridge() || isPotentialBridge(syntheticMethod, accessedMethod)) { | 66 | if (access.isBridge() || isPotentialBridge(syntheticMethod, specializedMethod)) { |
| 67 | bridgeMethods.add(syntheticMethod); | 67 | bridgeToSpecialized.add(syntheticMethod); |
| 68 | accessedToBridge.put(accessedMethod, syntheticMethod); | 68 | specializedToBridge.put(specializedMethod, syntheticMethod); |
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | private MethodEntry findAccessMethod(MethodEntry method) { | 72 | private MethodEntry findSpecializedMethod(MethodEntry method) { |
| 73 | // we want to find all compiler-added methods that directly call another with no processing | 73 | // we want to find all compiler-added methods that directly call another with no processing |
| 74 | 74 | ||
| 75 | // get all the methods that we call | 75 | // get all the methods that we call |
| @@ -83,7 +83,7 @@ public class BridgeMethodIndex implements JarIndexer { | |||
| 83 | return referencedMethods.stream().findFirst().orElse(null); | 83 | return referencedMethods.stream().findFirst().orElse(null); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | private boolean isPotentialBridge(MethodDefEntry bridgeMethod, MethodEntry accessedMethod) { | 86 | private boolean isPotentialBridge(MethodDefEntry bridgeMethod, MethodEntry specializedMethod) { |
| 87 | // Bridge methods only exist for inheritance purposes, if we're private, final, or static, we cannot be inherited | 87 | // Bridge methods only exist for inheritance purposes, if we're private, final, or static, we cannot be inherited |
| 88 | AccessFlags bridgeAccess = bridgeMethod.getAccess(); | 88 | AccessFlags bridgeAccess = bridgeMethod.getAccess(); |
| 89 | if (bridgeAccess.isPrivate() || bridgeAccess.isFinal() || bridgeAccess.isStatic()) { | 89 | if (bridgeAccess.isPrivate() || bridgeAccess.isFinal() || bridgeAccess.isStatic()) { |
| @@ -91,35 +91,35 @@ public class BridgeMethodIndex implements JarIndexer { | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | MethodDescriptor bridgeDesc = bridgeMethod.getDesc(); | 93 | MethodDescriptor bridgeDesc = bridgeMethod.getDesc(); |
| 94 | MethodDescriptor accessedDesc = accessedMethod.getDesc(); | 94 | MethodDescriptor specializedDesc = specializedMethod.getDesc(); |
| 95 | List<TypeDescriptor> bridgeArguments = bridgeDesc.getArgumentDescs(); | 95 | List<TypeDescriptor> bridgeArguments = bridgeDesc.getArgumentDescs(); |
| 96 | List<TypeDescriptor> accessedArguments = accessedDesc.getArgumentDescs(); | 96 | List<TypeDescriptor> specializedArguments = specializedDesc.getArgumentDescs(); |
| 97 | 97 | ||
| 98 | // A bridge method will always have the same number of arguments | 98 | // A bridge method will always have the same number of arguments |
| 99 | if (bridgeArguments.size() != accessedArguments.size()) { | 99 | if (bridgeArguments.size() != specializedArguments.size()) { |
| 100 | return false; | 100 | return false; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | // Check that all argument types are bridge-compatible | 103 | // Check that all argument types are bridge-compatible |
| 104 | for (int i = 0; i < bridgeArguments.size(); i++) { | 104 | for (int i = 0; i < bridgeArguments.size(); i++) { |
| 105 | if (!areTypesBridgeCompatible(bridgeArguments.get(i), accessedArguments.get(i))) { | 105 | if (!areTypesBridgeCompatible(bridgeArguments.get(i), specializedArguments.get(i))) { |
| 106 | return false; | 106 | return false; |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | // Check that the return type is bridge-compatible | 110 | // Check that the return type is bridge-compatible |
| 111 | return areTypesBridgeCompatible(bridgeDesc.getReturnDesc(), accessedDesc.getReturnDesc()); | 111 | return areTypesBridgeCompatible(bridgeDesc.getReturnDesc(), specializedDesc.getReturnDesc()); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | private boolean areTypesBridgeCompatible(TypeDescriptor bridgeDesc, TypeDescriptor accessedDesc) { | 114 | private boolean areTypesBridgeCompatible(TypeDescriptor bridgeDesc, TypeDescriptor specializedDesc) { |
| 115 | if (bridgeDesc.equals(accessedDesc)) { | 115 | if (bridgeDesc.equals(specializedDesc)) { |
| 116 | return true; | 116 | return true; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | // Either the descs will be equal, or they are both types and different through a generic | 119 | // Either the descs will be equal, or they are both types and different through a generic |
| 120 | if (bridgeDesc.isType() && accessedDesc.isType()) { | 120 | if (bridgeDesc.isType() && specializedDesc.isType()) { |
| 121 | ClassEntry bridgeType = bridgeDesc.getTypeEntry(); | 121 | ClassEntry bridgeType = bridgeDesc.getTypeEntry(); |
| 122 | ClassEntry accessedType = accessedDesc.getTypeEntry(); | 122 | ClassEntry accessedType = specializedDesc.getTypeEntry(); |
| 123 | 123 | ||
| 124 | // If the given types are completely unrelated to each other, this can't be bridge compatible | 124 | // If the given types are completely unrelated to each other, this can't be bridge compatible |
| 125 | InheritanceIndex.Relation relation = inheritanceIndex.computeClassRelation(accessedType, bridgeType); | 125 | InheritanceIndex.Relation relation = inheritanceIndex.computeClassRelation(accessedType, bridgeType); |
| @@ -130,19 +130,19 @@ public class BridgeMethodIndex implements JarIndexer { | |||
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | public boolean isBridgeMethod(MethodEntry entry) { | 132 | public boolean isBridgeMethod(MethodEntry entry) { |
| 133 | return bridgeMethods.contains(entry); | 133 | return bridgeToSpecialized.contains(entry); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | public boolean isAccessedByBridge(MethodEntry entry) { | 136 | public boolean isSpecializedMethod(MethodEntry entry) { |
| 137 | return accessedToBridge.containsKey(entry); | 137 | return specializedToBridge.containsKey(entry); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | @Nullable | 140 | @Nullable |
| 141 | public MethodEntry getBridgeFromAccessed(MethodEntry entry) { | 141 | public MethodEntry getBridgeFromSpecialized(MethodEntry specialized) { |
| 142 | return accessedToBridge.get(entry); | 142 | return specializedToBridge.get(specialized); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | public Map<MethodEntry, MethodEntry> getAccessedToBridge() { | 145 | public Map<MethodEntry, MethodEntry> getSpecializedToBridge() { |
| 146 | return Collections.unmodifiableMap(accessedToBridge); | 146 | return Collections.unmodifiableMap(specializedToBridge); |
| 147 | } | 147 | } |
| 148 | } | 148 | } |
diff --git a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java index 645110a..773eaf1 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java | |||
| @@ -28,18 +28,6 @@ public class EntryIndex implements JarIndexer { | |||
| 28 | fields.put(fieldEntry, fieldEntry.getAccess()); | 28 | fields.put(fieldEntry, fieldEntry.getAccess()); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | @Override | ||
| 32 | public void processIndex(JarIndex index) { | ||
| 33 | Map<MethodEntry, MethodEntry> accessedToBridge = index.getBridgeMethodIndex().getAccessedToBridge(); | ||
| 34 | for (Map.Entry<MethodEntry, MethodEntry> entry : accessedToBridge.entrySet()) { | ||
| 35 | MethodEntry accessedEntry = entry.getKey(); | ||
| 36 | MethodEntry bridgeEntry = entry.getValue(); | ||
| 37 | |||
| 38 | MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName()); | ||
| 39 | methods.put(renamedAccessedEntry, methods.remove(accessedEntry)); | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | public boolean hasClass(ClassEntry entry) { | 31 | public boolean hasClass(ClassEntry entry) { |
| 44 | return classes.containsKey(entry); | 32 | return classes.containsKey(entry); |
| 45 | } | 33 | } |
diff --git a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java index ee28b3e..2b63c5d 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java | |||
| @@ -8,7 +8,6 @@ import cuchaz.enigma.translation.representation.entry.*; | |||
| 8 | 8 | ||
| 9 | import java.util.Collection; | 9 | import java.util.Collection; |
| 10 | import java.util.Map; | 10 | import java.util.Map; |
| 11 | import java.util.Optional; | ||
| 12 | 11 | ||
| 13 | public class ReferenceIndex implements JarIndexer { | 12 | public class ReferenceIndex implements JarIndexer { |
| 14 | private Multimap<MethodEntry, MethodEntry> methodReferences = HashMultimap.create(); | 13 | private Multimap<MethodEntry, MethodEntry> methodReferences = HashMultimap.create(); |
| @@ -58,30 +57,11 @@ public class ReferenceIndex implements JarIndexer { | |||
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | private <E extends Entry<?>> E remap(JarIndex index, E entry) { | 59 | private <E extends Entry<?>> E remap(JarIndex index, E entry) { |
| 61 | E resolvedEntry = index.getEntryResolver().resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST); | 60 | return index.getEntryResolver().resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST); |
| 62 | |||
| 63 | Optional<E> remappedBridge = getRemappedBridge(index, resolvedEntry); | ||
| 64 | return remappedBridge.orElse(resolvedEntry); | ||
| 65 | } | 61 | } |
| 66 | 62 | ||
| 67 | private <E extends Entry<?>, C extends Entry<?>> EntryReference<E, C> remap(JarIndex index, EntryReference<E, C> reference) { | 63 | private <E extends Entry<?>, C extends Entry<?>> EntryReference<E, C> remap(JarIndex index, EntryReference<E, C> reference) { |
| 68 | EntryReference<E, C> resolvedReference = index.getEntryResolver().resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); | 64 | return index.getEntryResolver().resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); |
| 69 | |||
| 70 | getRemappedBridge(index, resolvedReference.entry).ifPresent(e -> resolvedReference.entry = e); | ||
| 71 | getRemappedBridge(index, resolvedReference.context).ifPresent(e -> resolvedReference.context = e); | ||
| 72 | |||
| 73 | return resolvedReference; | ||
| 74 | } | ||
| 75 | |||
| 76 | @SuppressWarnings("unchecked") | ||
| 77 | private <E extends Entry<?>> Optional<E> getRemappedBridge(JarIndex index, E entry) { | ||
| 78 | if (entry instanceof MethodEntry) { | ||
| 79 | MethodEntry bridgeEntry = index.getBridgeMethodIndex().getBridgeFromAccessed((MethodEntry) entry); | ||
| 80 | if (bridgeEntry != null) { | ||
| 81 | return Optional.of((E) entry.withName(bridgeEntry.getName())); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | return Optional.empty(); | ||
| 85 | } | 65 | } |
| 86 | 66 | ||
| 87 | public Collection<MethodEntry> getMethodsReferencedBy(MethodEntry entry) { | 67 | public Collection<MethodEntry> getMethodsReferencedBy(MethodEntry entry) { |
diff --git a/src/main/java/cuchaz/enigma/bytecode/translators/SourceFixVisitor.java b/src/main/java/cuchaz/enigma/bytecode/translators/SourceFixVisitor.java index 99eef6a..735a65f 100644 --- a/src/main/java/cuchaz/enigma/bytecode/translators/SourceFixVisitor.java +++ b/src/main/java/cuchaz/enigma/bytecode/translators/SourceFixVisitor.java | |||
| @@ -4,7 +4,6 @@ import cuchaz.enigma.analysis.index.BridgeMethodIndex; | |||
| 4 | import cuchaz.enigma.analysis.index.JarIndex; | 4 | import cuchaz.enigma.analysis.index.JarIndex; |
| 5 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; | 5 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; |
| 6 | import cuchaz.enigma.translation.representation.entry.MethodDefEntry; | 6 | import cuchaz.enigma.translation.representation.entry.MethodDefEntry; |
| 7 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 8 | import org.objectweb.asm.ClassVisitor; | 7 | import org.objectweb.asm.ClassVisitor; |
| 9 | import org.objectweb.asm.MethodVisitor; | 8 | import org.objectweb.asm.MethodVisitor; |
| 10 | import org.objectweb.asm.Opcodes; | 9 | import org.objectweb.asm.Opcodes; |
| @@ -31,11 +30,6 @@ public class SourceFixVisitor extends ClassVisitor { | |||
| 31 | BridgeMethodIndex bridgeIndex = index.getBridgeMethodIndex(); | 30 | BridgeMethodIndex bridgeIndex = index.getBridgeMethodIndex(); |
| 32 | if (bridgeIndex.isBridgeMethod(methodEntry)) { | 31 | if (bridgeIndex.isBridgeMethod(methodEntry)) { |
| 33 | access |= Opcodes.ACC_BRIDGE; | 32 | access |= Opcodes.ACC_BRIDGE; |
| 34 | } else { | ||
| 35 | MethodEntry bridgeMethod = bridgeIndex.getBridgeFromAccessed(methodEntry); | ||
| 36 | if (bridgeMethod != null) { | ||
| 37 | name = bridgeMethod.getName(); | ||
| 38 | } | ||
| 39 | } | 33 | } |
| 40 | 34 | ||
| 41 | return super.visitMethod(access, name, descriptor, signature, exceptions); | 35 | return super.visitMethod(access, name, descriptor, signature, exceptions); |
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index e6ecc54..4155062 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java | |||
| @@ -50,8 +50,8 @@ import java.util.stream.Collectors; | |||
| 50 | public class GuiController { | 50 | public class GuiController { |
| 51 | private static final ExecutorService DECOMPILER_SERVICE = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setDaemon(true).setNameFormat("decompiler-thread").build()); | 51 | private static final ExecutorService DECOMPILER_SERVICE = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setDaemon(true).setNameFormat("decompiler-thread").build()); |
| 52 | 52 | ||
| 53 | private final Gui gui; | ||
| 53 | private Deobfuscator deobfuscator; | 54 | private Deobfuscator deobfuscator; |
| 54 | private Gui gui; | ||
| 55 | private DecompiledClassSource currentSource; | 55 | private DecompiledClassSource currentSource; |
| 56 | private Deque<EntryReference<Entry<?>, Entry<?>>> referenceStack; | 56 | private Deque<EntryReference<Entry<?>, Entry<?>>> referenceStack; |
| 57 | 57 | ||
| @@ -60,12 +60,13 @@ public class GuiController { | |||
| 60 | 60 | ||
| 61 | public GuiController(Gui gui) { | 61 | public GuiController(Gui gui) { |
| 62 | this.gui = gui; | 62 | this.gui = gui; |
| 63 | this.deobfuscator = null; | ||
| 64 | this.currentSource = null; | ||
| 65 | this.referenceStack = Queues.newArrayDeque(); | 63 | this.referenceStack = Queues.newArrayDeque(); |
| 66 | } | 64 | } |
| 67 | 65 | ||
| 68 | public boolean isDirty() { | 66 | public boolean isDirty() { |
| 67 | if (deobfuscator == null) { | ||
| 68 | return false; | ||
| 69 | } | ||
| 69 | return deobfuscator.getMapper().isDirty(); | 70 | return deobfuscator.getMapper().isDirty(); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| @@ -82,6 +83,7 @@ public class GuiController { | |||
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | public void openMappings(MappingFormat format, Path path) { | 85 | public void openMappings(MappingFormat format, Path path) { |
| 86 | if (deobfuscator == null) return; | ||
| 85 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> { | 87 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> { |
| 86 | try { | 88 | try { |
| 87 | EntryTree<EntryMapping> mappings = format.read(path, progress); | 89 | EntryTree<EntryMapping> mappings = format.read(path, progress); |
| @@ -104,6 +106,7 @@ public class GuiController { | |||
| 104 | } | 106 | } |
| 105 | 107 | ||
| 106 | public void saveMappings(MappingFormat format, Path path) { | 108 | public void saveMappings(MappingFormat format, Path path) { |
| 109 | if (deobfuscator == null) return; | ||
| 107 | EntryRemapper mapper = deobfuscator.getMapper(); | 110 | EntryRemapper mapper = deobfuscator.getMapper(); |
| 108 | 111 | ||
| 109 | MappingDelta<EntryMapping> delta = mapper.takeMappingDelta(); | 112 | MappingDelta<EntryMapping> delta = mapper.takeMappingDelta(); |
| @@ -122,6 +125,7 @@ public class GuiController { | |||
| 122 | } | 125 | } |
| 123 | 126 | ||
| 124 | public void closeMappings() { | 127 | public void closeMappings() { |
| 128 | if (deobfuscator == null) return; | ||
| 125 | this.deobfuscator.setMappings(null); | 129 | this.deobfuscator.setMappings(null); |
| 126 | this.gui.setMappingsFile(null); | 130 | this.gui.setMappingsFile(null); |
| 127 | refreshClasses(); | 131 | refreshClasses(); |
| @@ -129,10 +133,12 @@ public class GuiController { | |||
| 129 | } | 133 | } |
| 130 | 134 | ||
| 131 | public void exportSource(final File dirOut) { | 135 | public void exportSource(final File dirOut) { |
| 136 | if (deobfuscator == null) return; | ||
| 132 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeSources(dirOut.toPath(), progress)); | 137 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeSources(dirOut.toPath(), progress)); |
| 133 | } | 138 | } |
| 134 | 139 | ||
| 135 | public void exportJar(final File fileOut) { | 140 | public void exportJar(final File fileOut) { |
| 141 | if (deobfuscator == null) return; | ||
| 136 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeTransformedJar(fileOut, progress)); | 142 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeTransformedJar(fileOut, progress)); |
| 137 | } | 143 | } |
| 138 | 144 | ||
| @@ -164,7 +170,7 @@ public class GuiController { | |||
| 164 | } | 170 | } |
| 165 | 171 | ||
| 166 | public boolean entryIsInJar(Entry<?> entry) { | 172 | public boolean entryIsInJar(Entry<?> entry) { |
| 167 | if (entry == null) return false; | 173 | if (entry == null || deobfuscator == null) return false; |
| 168 | return this.deobfuscator.isRenamable(entry); | 174 | return this.deobfuscator.isRenamable(entry); |
| 169 | } | 175 | } |
| 170 | 176 | ||
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java b/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java index 6c8ed76..78231dd 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java | |||
| @@ -86,7 +86,7 @@ public class IndexEntryResolver implements EntryResolver { | |||
| 86 | ClassEntry ownerClass = entry.getParent(); | 86 | ClassEntry ownerClass = entry.getParent(); |
| 87 | 87 | ||
| 88 | if (entry instanceof MethodEntry) { | 88 | if (entry instanceof MethodEntry) { |
| 89 | MethodEntry bridgeMethod = bridgeMethodIndex.getBridgeFromAccessed((MethodEntry) entry); | 89 | MethodEntry bridgeMethod = bridgeMethodIndex.getBridgeFromSpecialized((MethodEntry) entry); |
| 90 | if (bridgeMethod != null && ownerClass.equals(bridgeMethod.getParent())) { | 90 | if (bridgeMethod != null && ownerClass.equals(bridgeMethod.getParent())) { |
| 91 | Set<Entry<ClassEntry>> resolvedBridge = resolveChildEntry(bridgeMethod, strategy); | 91 | Set<Entry<ClassEntry>> resolvedBridge = resolveChildEntry(bridgeMethod, strategy); |
| 92 | if (!resolvedBridge.isEmpty()) { | 92 | if (!resolvedBridge.isEmpty()) { |
| @@ -183,10 +183,10 @@ public class IndexEntryResolver implements EntryResolver { | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | // look at bridge methods! | 185 | // look at bridge methods! |
| 186 | MethodEntry bridgedMethod = bridgeMethodIndex.getBridgeFromAccessed(methodEntry); | 186 | MethodEntry bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(methodEntry); |
| 187 | while (bridgedMethod != null) { | 187 | while (bridgedMethod != null) { |
| 188 | methodEntries.addAll(resolveEquivalentMethods(bridgedMethod)); | 188 | methodEntries.addAll(resolveEquivalentMethods(bridgedMethod)); |
| 189 | bridgedMethod = bridgeMethodIndex.getBridgeFromAccessed(bridgedMethod); | 189 | bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(bridgedMethod); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | // look at interface methods too | 192 | // look at interface methods too |
| @@ -209,10 +209,10 @@ public class IndexEntryResolver implements EntryResolver { | |||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | // look at bridge methods! | 211 | // look at bridge methods! |
| 212 | MethodEntry bridgedMethod = bridgeMethodIndex.getBridgeFromAccessed(methodEntry); | 212 | MethodEntry bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(methodEntry); |
| 213 | while (bridgedMethod != null) { | 213 | while (bridgedMethod != null) { |
| 214 | methodEntries.addAll(resolveEquivalentMethods(bridgedMethod)); | 214 | methodEntries.addAll(resolveEquivalentMethods(bridgedMethod)); |
| 215 | bridgedMethod = bridgeMethodIndex.getBridgeFromAccessed(bridgedMethod); | 215 | bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(bridgedMethod); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | // recurse | 218 | // recurse |