From bb20ce047a2e20866b9532c441c7433b1973ba5b Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Sat, 23 Feb 2019 19:42:00 +0200 Subject: Fix #110 and remap indices with matched bridge method names --- src/main/java/cuchaz/enigma/CommandMain.java | 4 +- src/main/java/cuchaz/enigma/Deobfuscator.java | 12 ++++-- .../enigma/analysis/index/BridgeMethodIndex.java | 30 ++++++++++---- .../cuchaz/enigma/analysis/index/EntryIndex.java | 12 ++++++ .../cuchaz/enigma/analysis/index/JarIndex.java | 15 ++++--- .../cuchaz/enigma/analysis/index/JarIndexer.java | 3 +- .../enigma/analysis/index/ReferenceIndex.java | 47 +++++++++++++++------- src/main/java/cuchaz/enigma/gui/GuiController.java | 23 +++++++---- .../java/cuchaz/enigma/gui/elements/MenuBar.java | 21 ++-------- .../java/cuchaz/enigma/translation/Translator.java | 7 ++++ .../enigma/translation/mapping/EntryMap.java | 4 +- .../enigma/translation/mapping/EntryMapping.java | 17 ++++++++ .../enigma/translation/mapping/EntryRemapper.java | 7 +--- .../translation/mapping/IndexEntryResolver.java | 2 + .../enigma/translation/mapping/MappingDelta.java | 34 ++++++++-------- .../translation/mapping/MappingsChecker.java | 17 +++++--- .../mapping/serde/EnigmaMappingsReader.java | 19 +++++++-- .../mapping/serde/EnigmaMappingsWriter.java | 25 ++++++------ .../translation/mapping/serde/MappingFormat.java | 4 +- .../translation/mapping/serde/MappingsReader.java | 3 +- .../mapping/serde/TinyMappingsReader.java | 13 ++++-- .../mapping/tree/DeltaTrackingTree.java | 46 +++++++-------------- .../enigma/translation/mapping/tree/EntryTree.java | 5 +-- .../translation/mapping/tree/EntryTreeNode.java | 4 ++ .../translation/mapping/tree/HashEntryTree.java | 29 ++++++------- .../representation/entry/ClassDefEntry.java | 5 +++ .../representation/entry/ClassEntry.java | 12 +++++- .../translation/representation/entry/Entry.java | 2 + .../representation/entry/FieldDefEntry.java | 5 +++ .../representation/entry/FieldEntry.java | 5 +++ .../entry/LocalVariableDefEntry.java | 5 +++ .../representation/entry/LocalVariableEntry.java | 5 +++ .../representation/entry/MethodDefEntry.java | 5 +++ .../representation/entry/MethodEntry.java | 5 +++ .../representation/entry/ParentedEntry.java | 3 ++ 35 files changed, 289 insertions(+), 166 deletions(-) diff --git a/src/main/java/cuchaz/enigma/CommandMain.java b/src/main/java/cuchaz/enigma/CommandMain.java index 7c0a3d53..c9f83828 100644 --- a/src/main/java/cuchaz/enigma/CommandMain.java +++ b/src/main/java/cuchaz/enigma/CommandMain.java @@ -74,7 +74,7 @@ public class CommandMain { Deobfuscator deobfuscator = new Deobfuscator(jar); if (fileMappings != null) { System.out.println("Reading mappings..."); - EntryTree mappings = chooseEnigmaFormat(fileMappings).read(fileMappings); + EntryTree mappings = chooseEnigmaFormat(fileMappings).read(fileMappings, new ConsoleProgressListener()); deobfuscator.setMappings(mappings); } return deobfuscator; @@ -94,7 +94,7 @@ public class CommandMain { System.out.println("Reading mappings..."); MappingFormat readFormat = chooseEnigmaFormat(fileMappings); - EntryTree mappings = readFormat.read(fileMappings); + EntryTree mappings = readFormat.read(fileMappings, new ConsoleProgressListener()); System.out.println("Saving new mappings..."); saveFormat.write(mappings, result.toPath(), new ConsoleProgressListener()); diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java index 47cd05ce..b4736d8f 100644 --- a/src/main/java/cuchaz/enigma/Deobfuscator.java +++ b/src/main/java/cuchaz/enigma/Deobfuscator.java @@ -126,23 +126,27 @@ public class Deobfuscator { } public void setMappings(EntryTree mappings) { + setMappings(mappings, ProgressListener.VOID); + } + + public void setMappings(EntryTree mappings, ProgressListener progress) { if (mappings != null) { - Collection> dropped = dropMappings(mappings); + Collection> dropped = dropMappings(mappings, progress); mapper = new EntryRemapper(jarIndex, mappings); DeltaTrackingTree obfToDeobf = mapper.getObfToDeobf(); for (Entry entry : dropped) { - obfToDeobf.trackDeletion(entry); + obfToDeobf.trackChange(entry); } } else { mapper = new EntryRemapper(jarIndex); } } - private Collection> dropMappings(EntryTree mappings) { + private Collection> dropMappings(EntryTree mappings, ProgressListener progress) { // drop mappings that don't match the jar MappingsChecker checker = new MappingsChecker(jarIndex, mappings); - MappingsChecker.Dropped dropped = checker.dropBrokenMappings(); + MappingsChecker.Dropped dropped = checker.dropBrokenMappings(progress); Map, String> droppedMappings = dropped.getDroppedMappings(); for (Map.Entry, String> mapping : droppedMappings.entrySet()) { diff --git a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java index de2ba1e5..649ce254 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java @@ -2,7 +2,6 @@ package cuchaz.enigma.analysis.index; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import cuchaz.enigma.translation.mapping.EntryResolver; import cuchaz.enigma.translation.representation.AccessFlags; import cuchaz.enigma.translation.representation.MethodDescriptor; import cuchaz.enigma.translation.representation.TypeDescriptor; @@ -11,10 +10,7 @@ import cuchaz.enigma.translation.representation.entry.MethodDefEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; import javax.annotation.Nullable; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class BridgeMethodIndex implements JarIndexer { private final EntryIndex entryIndex; @@ -30,8 +26,7 @@ public class BridgeMethodIndex implements JarIndexer { this.referenceIndex = referenceIndex; } - @Override - public void processIndex(EntryResolver resolver) { + public void findBridgeMethods() { // look for access and bridged methods for (MethodEntry methodEntry : entryIndex.getMethods()) { MethodDefEntry methodDefEntry = (MethodDefEntry) methodEntry; @@ -45,6 +40,23 @@ public class BridgeMethodIndex implements JarIndexer { } } + @Override + public void processIndex(JarIndex index) { + Map copiedAccessToBridge = new HashMap<>(accessedToBridge); + + for (Map.Entry entry : copiedAccessToBridge.entrySet()) { + MethodEntry accessedEntry = entry.getKey(); + MethodEntry bridgeEntry = entry.getValue(); + if (bridgeEntry.getName().equals(accessedEntry.getName())) { + continue; + } + + MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName()); + bridgeMethods.add(renamedAccessedEntry); + accessedToBridge.put(renamedAccessedEntry, accessedToBridge.get(accessedEntry)); + } + } + private void indexSyntheticMethod(MethodDefEntry syntheticMethod, AccessFlags access) { MethodEntry accessedMethod = findAccessMethod(syntheticMethod); if (accessedMethod == null) { @@ -129,4 +141,8 @@ public class BridgeMethodIndex implements JarIndexer { public MethodEntry getBridgeFromAccessed(MethodEntry entry) { return accessedToBridge.get(entry); } + + public Map getAccessedToBridge() { + return Collections.unmodifiableMap(accessedToBridge); + } } diff --git a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java index 773eaf18..645110a7 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java @@ -28,6 +28,18 @@ public class EntryIndex implements JarIndexer { fields.put(fieldEntry, fieldEntry.getAccess()); } + @Override + public void processIndex(JarIndex index) { + Map accessedToBridge = index.getBridgeMethodIndex().getAccessedToBridge(); + for (Map.Entry entry : accessedToBridge.entrySet()) { + MethodEntry accessedEntry = entry.getKey(); + MethodEntry bridgeEntry = entry.getValue(); + + MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName()); + methods.put(renamedAccessedEntry, methods.remove(accessedEntry)); + } + } + public boolean hasClass(ClassEntry entry) { return classes.containsKey(entry); } diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java index cb58fced..a429ff6e 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java @@ -53,19 +53,22 @@ public class JarIndex implements JarIndexer { } public void indexJar(ParsedJar jar, Consumer progress) { - progress.accept("Indexing entries (1/3)"); + progress.accept("Indexing entries (1/4)"); jar.visitReader(name -> new IndexClassVisitor(this, Opcodes.ASM5), ClassReader.SKIP_CODE); - progress.accept("Indexing entry references (2/3)"); + progress.accept("Indexing entry references (2/4)"); jar.visitReader(name -> new IndexReferenceVisitor(this, Opcodes.ASM5), ClassReader.SKIP_FRAMES); - progress.accept("Processing index (3/3)"); - processIndex(entryResolver); + progress.accept("Finding bridge methods (3/4)"); + bridgeMethodIndex.findBridgeMethods(); + + progress.accept("Processing index (4/4)"); + processIndex(this); } @Override - public void processIndex(EntryResolver resolver) { - indexers.forEach(indexer -> indexer.processIndex(entryResolver)); + public void processIndex(JarIndex index) { + indexers.forEach(indexer -> indexer.processIndex(index)); } @Override diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java index a087e598..457c2237 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java +++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java @@ -1,6 +1,5 @@ package cuchaz.enigma.analysis.index; -import cuchaz.enigma.translation.mapping.EntryResolver; import cuchaz.enigma.translation.representation.entry.*; public interface JarIndexer { @@ -19,6 +18,6 @@ public interface JarIndexer { default void indexFieldReference(MethodDefEntry callerEntry, FieldEntry referencedEntry) { } - default void processIndex(EntryResolver resolver) { + 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 ac11da46..ee28b3e7 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java @@ -3,12 +3,12 @@ package cuchaz.enigma.analysis.index; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import cuchaz.enigma.analysis.EntryReference; -import cuchaz.enigma.translation.mapping.EntryResolver; import cuchaz.enigma.translation.mapping.ResolutionStrategy; import cuchaz.enigma.translation.representation.entry.*; import java.util.Collection; import java.util.Map; +import java.util.Optional; public class ReferenceIndex implements JarIndexer { private Multimap methodReferences = HashMultimap.create(); @@ -34,35 +34,54 @@ public class ReferenceIndex implements JarIndexer { } @Override - public void processIndex(EntryResolver resolver) { - methodReferences = resolveReferences(resolver, methodReferences); - referencesToMethods = resolveReferencesTo(resolver, referencesToMethods); - referencesToClasses = resolveReferencesTo(resolver, referencesToClasses); - referencesToFields = resolveReferencesTo(resolver, referencesToFields); + public void processIndex(JarIndex index) { + methodReferences = remapReferences(index, methodReferences); + referencesToMethods = remapReferencesTo(index, referencesToMethods); + referencesToClasses = remapReferencesTo(index, referencesToClasses); + referencesToFields = remapReferencesTo(index, referencesToFields); } - private , V extends Entry> Multimap resolveReferences(EntryResolver resolver, Multimap multimap) { + private , V extends Entry> Multimap remapReferences(JarIndex index, Multimap multimap) { Multimap resolved = HashMultimap.create(); for (Map.Entry entry : multimap.entries()) { - resolved.put(resolve(resolver, entry.getKey()), resolve(resolver, entry.getValue())); + resolved.put(remap(index, entry.getKey()), remap(index, entry.getValue())); } return resolved; } - private , C extends Entry> Multimap> resolveReferencesTo(EntryResolver resolver, Multimap> multimap) { + private , C extends Entry> Multimap> remapReferencesTo(JarIndex index, Multimap> multimap) { Multimap> resolved = HashMultimap.create(); for (Map.Entry> entry : multimap.entries()) { - resolved.put(resolve(resolver, entry.getKey()), resolve(resolver, entry.getValue())); + resolved.put(remap(index, entry.getKey()), remap(index, entry.getValue())); } return resolved; } - private > E resolve(EntryResolver resolver, E entry) { - return resolver.resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST); + private > E remap(JarIndex index, E entry) { + E resolvedEntry = index.getEntryResolver().resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST); + + Optional remappedBridge = getRemappedBridge(index, resolvedEntry); + return remappedBridge.orElse(resolvedEntry); + } + + private , C extends Entry> EntryReference remap(JarIndex index, EntryReference reference) { + EntryReference resolvedReference = index.getEntryResolver().resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); + + getRemappedBridge(index, resolvedReference.entry).ifPresent(e -> resolvedReference.entry = e); + getRemappedBridge(index, resolvedReference.context).ifPresent(e -> resolvedReference.context = e); + + return resolvedReference; } - private , C extends Entry> EntryReference resolve(EntryResolver resolver, EntryReference reference) { - return resolver.resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); + @SuppressWarnings("unchecked") + private > Optional getRemappedBridge(JarIndex index, E entry) { + if (entry instanceof MethodEntry) { + MethodEntry bridgeEntry = index.getBridgeMethodIndex().getBridgeFromAccessed((MethodEntry) entry); + if (bridgeEntry != null) { + return Optional.of((E) entry.withName(bridgeEntry.getName())); + } + } + return Optional.empty(); } public Collection getMethodsReferencedBy(MethodEntry entry) { diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index 45c61319..15211e01 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -32,6 +32,7 @@ import cuchaz.enigma.translation.representation.entry.MethodEntry; import cuchaz.enigma.utils.ReadableToken; import javax.annotation.Nullable; +import javax.swing.*; import java.awt.event.ItemEvent; import java.io.File; import java.io.IOException; @@ -80,16 +81,22 @@ public class GuiController { this.gui.onCloseJar(); } - public void openMappings(MappingFormat format, Path path) throws IOException, MappingParseException { - EntryTree mappings = format.read(path); - deobfuscator.setMappings(mappings); + public void openMappings(MappingFormat format, Path path) { + ProgressDialog.runInThread(this.gui.getFrame(), progress -> { + try { + EntryTree mappings = format.read(path, progress); + deobfuscator.setMappings(mappings, progress); - gui.setMappingsFile(path); - loadedMappingFormat = format; - loadedMappingPath = path; + gui.setMappingsFile(path); + loadedMappingFormat = format; + loadedMappingPath = path; - refreshClasses(); - refreshCurrentClass(); + refreshClasses(); + refreshCurrentClass(); + } catch (MappingParseException e) { + JOptionPane.showMessageDialog(this.gui.getFrame(), e.getMessage()); + } + }); } public void saveMappings(Path path) { diff --git a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index 14ad53dc..d7be1a9d 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java @@ -5,7 +5,6 @@ import cuchaz.enigma.config.Themes; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.gui.dialog.AboutDialog; import cuchaz.enigma.gui.dialog.SearchDialog; -import cuchaz.enigma.throwables.MappingParseException; import cuchaz.enigma.translation.mapping.serde.MappingFormat; import javax.swing.*; @@ -68,15 +67,9 @@ public class MenuBar extends JMenuBar { openMenu.add(item); item.addActionListener(event -> { if (this.gui.enigmaMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { - try { - File selectedFile = this.gui.enigmaMappingsFileChooser.getSelectedFile(); - MappingFormat format = selectedFile.isDirectory() ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_FILE; - this.gui.getController().openMappings(format, selectedFile.toPath()); - } catch (IOException ex) { - throw new Error(ex); - } catch (MappingParseException ex) { - JOptionPane.showMessageDialog(this.gui.getFrame(), ex.getMessage()); - } + File selectedFile = this.gui.enigmaMappingsFileChooser.getSelectedFile(); + MappingFormat format = selectedFile.isDirectory() ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_FILE; + this.gui.getController().openMappings(format, selectedFile.toPath()); } }); this.openEnigmaMappingsMenu = item; @@ -87,13 +80,7 @@ public class MenuBar extends JMenuBar { this.gui.tinyMappingsFileChooser.setVisible(true); File file = new File(this.gui.tinyMappingsFileChooser.getDirectory() + File.separator + this.gui.tinyMappingsFileChooser.getFile()); if (file.exists()) { - try { - this.gui.getController().openMappings(MappingFormat.TINY_FILE, file.toPath()); - } catch (IOException ex) { - throw new Error(ex); - } catch (MappingParseException ex) { - JOptionPane.showMessageDialog(this.gui.getFrame(), ex.getMessage()); - } + this.gui.getController().openMappings(MappingFormat.TINY_FILE, file.toPath()); } }); this.openTinyMappingsMenu = item; diff --git a/src/main/java/cuchaz/enigma/translation/Translator.java b/src/main/java/cuchaz/enigma/translation/Translator.java index de2003e8..c70141f2 100644 --- a/src/main/java/cuchaz/enigma/translation/Translator.java +++ b/src/main/java/cuchaz/enigma/translation/Translator.java @@ -17,6 +17,7 @@ import com.google.common.collect.Multimap; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; public interface Translator { @@ -28,6 +29,12 @@ public interface Translator { .collect(Collectors.toList()); } + default Set translate(Set translatable) { + return translatable.stream() + .map(this::translate) + .collect(Collectors.toSet()); + } + default Map translateKeys(Map translatable) { Map result = new HashMap<>(translatable.size()); for (Map.Entry entry : translatable.entrySet()) { diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java index 6af48466..e1a32533 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java @@ -3,7 +3,7 @@ package cuchaz.enigma.translation.mapping; import cuchaz.enigma.translation.representation.entry.Entry; import javax.annotation.Nullable; -import java.util.Collection; +import java.util.stream.Stream; public interface EntryMap { void insert(Entry entry, T value); @@ -18,7 +18,7 @@ public interface EntryMap { return get(entry) != null; } - Collection> getAllEntries(); + Stream> getAllEntries(); boolean isEmpty(); } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java index f11cdefb..b74cc0b3 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java @@ -27,4 +27,21 @@ public class EntryMapping { } return accessModifier; } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof EntryMapping) { + EntryMapping mapping = (EntryMapping) obj; + return mapping.targetName.equals(targetName) && mapping.accessModifier.equals(accessModifier); + } + + return false; + } + + @Override + public int hashCode() { + return targetName.hashCode() + accessModifier.hashCode() * 31; + } } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java index fa421b9f..ed9f8202 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java @@ -11,6 +11,7 @@ import cuchaz.enigma.translation.representation.entry.Entry; import javax.annotation.Nullable; import java.util.Collection; +import java.util.stream.Stream; public class EntryRemapper { private final DeltaTrackingTree obfToDeobf; @@ -69,14 +70,10 @@ public class EntryRemapper { return deobfuscator; } - public Collection> getObfEntries() { + public Stream> getObfEntries() { return obfToDeobf.getAllEntries(); } - public Collection> getObfRootEntries() { - return obfToDeobf.getRootEntries(); - } - public Collection> getObfChildren(Entry obfuscatedEntry) { return obfToDeobf.getChildren(obfuscatedEntry); } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java b/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java index 1f2290a0..6c8ed76d 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java @@ -91,6 +91,8 @@ public class IndexEntryResolver implements EntryResolver { Set> resolvedBridge = resolveChildEntry(bridgeMethod, strategy); if (!resolvedBridge.isEmpty()) { return resolvedBridge; + } else { + return Collections.singleton(bridgeMethod); } } } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java index 9f1f468b..1407bb60 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java @@ -2,55 +2,53 @@ package cuchaz.enigma.translation.mapping; import cuchaz.enigma.translation.Translatable; import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; import cuchaz.enigma.translation.mapping.tree.EntryTree; +import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; +import cuchaz.enigma.translation.mapping.tree.HashEntryTree; import cuchaz.enigma.translation.representation.entry.Entry; +import java.util.stream.Stream; + public class MappingDelta implements Translatable { public static final Object PLACEHOLDER = new Object(); private final EntryTree baseMappings; - private final EntryTree additions; - private final EntryTree deletions; + private final EntryTree changes; - public MappingDelta(EntryTree baseMappings, EntryTree additions, EntryTree deletions) { + public MappingDelta(EntryTree baseMappings, EntryTree changes) { this.baseMappings = baseMappings; - this.additions = additions; - this.deletions = deletions; + this.changes = changes; } public MappingDelta(EntryTree baseMappings) { - this(baseMappings, new HashEntryTree<>(), new HashEntryTree<>()); + this(baseMappings, new HashEntryTree<>()); } public static MappingDelta added(EntryTree mappings) { - EntryTree additions = new HashEntryTree<>(); - for (Entry entry : mappings.getAllEntries()) { - additions.insert(entry, PLACEHOLDER); - } + EntryTree changes = new HashEntryTree<>(); + mappings.getAllEntries().forEach(entry -> changes.insert(entry, PLACEHOLDER)); - return new MappingDelta<>(new HashEntryTree<>(), additions, new HashEntryTree<>()); + return new MappingDelta<>(new HashEntryTree<>(), changes); } public EntryTree getBaseMappings() { return baseMappings; } - public EntryTree getAdditions() { - return additions; + public EntryTree getChanges() { + return changes; } - public EntryTree getDeletions() { - return deletions; + public Stream> getChangedRoots() { + return changes.getRootNodes().map(EntryTreeNode::getEntry); } @Override public MappingDelta translate(Translator translator, EntryResolver resolver, EntryMap mappings) { return new MappingDelta<>( translator.translate(baseMappings), - translator.translate(additions), - translator.translate(deletions) + translator.translate(changes) ); } } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java index 77d75ecb..af9e63a2 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java @@ -11,6 +11,7 @@ package cuchaz.enigma.translation.mapping; +import cuchaz.enigma.ProgressListener; import cuchaz.enigma.analysis.index.JarIndex; import cuchaz.enigma.translation.mapping.tree.EntryTree; import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; @@ -22,6 +23,7 @@ import cuchaz.enigma.translation.representation.entry.MethodEntry; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.stream.Collectors; public class MappingsChecker { private final JarIndex index; @@ -32,14 +34,19 @@ public class MappingsChecker { this.mappings = mappings; } - public Dropped dropBrokenMappings() { + public Dropped dropBrokenMappings(ProgressListener progress) { Dropped dropped = new Dropped(); - Collection> obfEntries = mappings.getAllEntries(); + Collection> obfEntries = mappings.getAllEntries() + .filter(e -> e instanceof ClassEntry || e instanceof MethodEntry || e instanceof FieldEntry) + .collect(Collectors.toList()); + + progress.init(obfEntries.size(), "Checking for dropped mappings"); + + int steps = 0; for (Entry entry : obfEntries) { - if (entry instanceof ClassEntry || entry instanceof MethodEntry || entry instanceof FieldEntry) { - tryDropEntry(dropped, entry); - } + progress.step(steps++, entry.toString()); + tryDropEntry(dropped, entry); } dropped.apply(mappings); diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java index d36bc0bc..3f61325d 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java @@ -1,12 +1,13 @@ package cuchaz.enigma.translation.mapping.serde; import com.google.common.base.Charsets; +import cuchaz.enigma.ProgressListener; import cuchaz.enigma.throwables.MappingParseException; import cuchaz.enigma.translation.mapping.AccessModifier; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.MappingPair; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; import cuchaz.enigma.translation.mapping.tree.EntryTree; +import cuchaz.enigma.translation.mapping.tree.HashEntryTree; import cuchaz.enigma.translation.representation.MethodDescriptor; import cuchaz.enigma.translation.representation.TypeDescriptor; import cuchaz.enigma.translation.representation.entry.*; @@ -24,22 +25,32 @@ import java.util.stream.Collectors; public enum EnigmaMappingsReader implements MappingsReader { FILE { @Override - public EntryTree read(Path path) throws IOException, MappingParseException { + public EntryTree read(Path path, ProgressListener progress) throws IOException, MappingParseException { + progress.init(1, "Loading mapping file"); + EntryTree mappings = new HashEntryTree<>(); readFile(path, mappings); + + progress.step(1, "Done!"); + return mappings; } }, DIRECTORY { @Override - public EntryTree read(Path path) throws IOException, MappingParseException { + public EntryTree read(Path root, ProgressListener progress) throws IOException, MappingParseException { EntryTree mappings = new HashEntryTree<>(); - List files = Files.walk(path) + List files = Files.walk(root) .filter(f -> !Files.isDirectory(f)) .filter(f -> f.toString().endsWith(".mapping")) .collect(Collectors.toList()); + + progress.init(files.size(), "Loading mapping files"); + int step = 0; + for (Path file : files) { + progress.step(step++, root.relativize(file).toString()); if (Files.isHidden(file)) { continue; } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java index 8c55fa99..618bb0a7 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java @@ -28,6 +28,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; +import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -35,7 +36,7 @@ public enum EnigmaMappingsWriter implements MappingsWriter { FILE { @Override public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress) { - Collection classes = mappings.getRootEntries().stream() + Collection classes = mappings.getRootNodes() .filter(entry -> entry instanceof ClassEntry) .map(entry -> (ClassEntry) entry) .collect(Collectors.toList()); @@ -56,19 +57,19 @@ public enum EnigmaMappingsWriter implements MappingsWriter { DIRECTORY { @Override public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress) { - applyDeletions(delta.getBaseMappings(), delta.getDeletions(), path); - - Collection classes = delta.getAdditions().getRootEntries().stream() + Collection changedClasses = delta.getChangedRoots() .filter(entry -> entry instanceof ClassEntry) .map(entry -> (ClassEntry) entry) .collect(Collectors.toList()); - progress.init(classes.size(), "Writing classes"); + applyDeletions(path, changedClasses, mappings, delta.getBaseMappings()); + + progress.init(changedClasses.size(), "Writing classes"); - Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); AtomicInteger steps = new AtomicInteger(); - classes.parallelStream().forEach(classEntry -> { + Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); + changedClasses.parallelStream().forEach(classEntry -> { progress.step(steps.getAndIncrement(), classEntry.getFullName()); try { @@ -86,12 +87,12 @@ public enum EnigmaMappingsWriter implements MappingsWriter { }); } - private void applyDeletions(EntryTree baseMappings, EntryTree deletions, Path root) { - Translator oldMappingTranslator = new MappingTranslator(baseMappings, VoidEntryResolver.INSTANCE); + private void applyDeletions(Path root, Collection changedClasses, EntryTree mappings, EntryTree oldMappings) { + Translator oldMappingTranslator = new MappingTranslator(oldMappings, VoidEntryResolver.INSTANCE); - Collection deletedClasses = deletions.getRootEntries().stream() - .filter(e -> e instanceof ClassEntry) - .map(e -> oldMappingTranslator.translate((ClassEntry) e)) + Collection deletedClasses = changedClasses.stream() + .filter(e -> !Objects.equals(oldMappings.get(e), mappings.get(e))) + .map(oldMappingTranslator::translate) .collect(Collectors.toList()); for (ClassEntry classEntry : deletedClasses) { diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 622a0e15..25283523 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -35,11 +35,11 @@ public enum MappingFormat { writer.write(mappings, delta, path, progressListener); } - public EntryTree read(Path path) throws IOException, MappingParseException { + public EntryTree read(Path path, ProgressListener progressListener) throws IOException, MappingParseException { if (reader == null) { throw new IllegalStateException(name() + " does not support reading"); } - return reader.read(path); + return reader.read(path, progressListener); } @Nullable diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java index f239ee67..af0933f6 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java @@ -1,5 +1,6 @@ package cuchaz.enigma.translation.mapping.serde; +import cuchaz.enigma.ProgressListener; import cuchaz.enigma.throwables.MappingParseException; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.tree.EntryTree; @@ -8,5 +9,5 @@ import java.io.IOException; import java.nio.file.Path; public interface MappingsReader { - EntryTree read(Path path) throws MappingParseException, IOException; + EntryTree read(Path path, ProgressListener progress) throws MappingParseException, IOException; } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java index e0afc3e8..69d82354 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java @@ -1,11 +1,12 @@ package cuchaz.enigma.translation.mapping.serde; import com.google.common.base.Charsets; +import cuchaz.enigma.ProgressListener; import cuchaz.enigma.throwables.MappingParseException; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.MappingPair; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; import cuchaz.enigma.translation.mapping.tree.EntryTree; +import cuchaz.enigma.translation.mapping.tree.HashEntryTree; import cuchaz.enigma.translation.representation.MethodDescriptor; import cuchaz.enigma.translation.representation.TypeDescriptor; import cuchaz.enigma.translation.representation.entry.ClassEntry; @@ -22,15 +23,19 @@ public enum TinyMappingsReader implements MappingsReader { INSTANCE; @Override - public EntryTree read(Path path) throws IOException, MappingParseException { - return read(path, Files.readAllLines(path, Charsets.UTF_8)); + public EntryTree read(Path path, ProgressListener progress) throws IOException, MappingParseException { + return read(path, Files.readAllLines(path, Charsets.UTF_8), progress); } - private EntryTree read(Path path, List lines) throws MappingParseException { + private EntryTree read(Path path, List lines, ProgressListener progress) throws MappingParseException { EntryTree mappings = new HashEntryTree<>(); lines.remove(0); + progress.init(lines.size(), "Loading mapping file"); + for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { + progress.step(lineNumber, ""); + String line = lines.get(lineNumber); try { diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java index 36be5e1e..255fa5fb 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java @@ -10,13 +10,13 @@ import cuchaz.enigma.translation.representation.entry.Entry; import javax.annotation.Nullable; import java.util.Collection; import java.util.Iterator; +import java.util.stream.Stream; public class DeltaTrackingTree implements EntryTree { private final EntryTree delegate; private EntryTree deltaReference; - private EntryTree additions = new HashEntryTree<>(); - private EntryTree deletions = new HashEntryTree<>(); + private EntryTree changes = new HashEntryTree<>(); public DeltaTrackingTree(EntryTree delegate) { this.delegate = delegate; @@ -29,30 +29,19 @@ public class DeltaTrackingTree implements EntryTree { @Override public void insert(Entry entry, T value) { - if (value != null) { - trackAddition(entry); - } else { - trackDeletion(entry); - } + trackChange(entry); delegate.insert(entry, value); } @Nullable @Override public T remove(Entry entry) { - T value = delegate.remove(entry); - trackDeletion(entry); - return value; + trackChange(entry); + return delegate.remove(entry); } - public void trackAddition(Entry entry) { - deletions.insert(entry, MappingDelta.PLACEHOLDER); - additions.insert(entry, MappingDelta.PLACEHOLDER); - } - - public void trackDeletion(Entry entry) { - additions.remove(entry); - deletions.insert(entry, MappingDelta.PLACEHOLDER); + public void trackChange(Entry entry) { + changes.insert(entry, MappingDelta.PLACEHOLDER); } @Nullable @@ -78,25 +67,19 @@ public class DeltaTrackingTree implements EntryTree { } @Override - public Collection> getAllNodes() { - return delegate.getAllNodes(); - } - - @Override - public Collection> getRootEntries() { - return delegate.getRootEntries(); + public Stream> getRootNodes() { + return delegate.getRootNodes(); } @Override public DeltaTrackingTree translate(Translator translator, EntryResolver resolver, EntryMap mappings) { DeltaTrackingTree translatedTree = new DeltaTrackingTree<>(delegate.translate(translator, resolver, mappings)); - translatedTree.additions = additions.translate(translator, resolver, mappings); - translatedTree.deletions = deletions.translate(translator, resolver, mappings); + translatedTree.changes = changes.translate(translator, resolver, mappings); return translatedTree; } @Override - public Collection> getAllEntries() { + public Stream> getAllEntries() { return delegate.getAllEntries(); } @@ -111,18 +94,17 @@ public class DeltaTrackingTree implements EntryTree { } public MappingDelta takeDelta() { - MappingDelta delta = new MappingDelta<>(deltaReference, additions, deletions); + MappingDelta delta = new MappingDelta<>(deltaReference, changes); resetDelta(); return delta; } private void resetDelta() { deltaReference = new HashEntryTree<>(delegate); - additions = new HashEntryTree<>(); - deletions = new HashEntryTree<>(); + changes = new HashEntryTree<>(); } public boolean isDirty() { - return !additions.isEmpty() || !deletions.isEmpty(); + return !changes.isEmpty(); } } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java index 4f341f45..daaefcc1 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java @@ -9,6 +9,7 @@ import cuchaz.enigma.translation.representation.entry.Entry; import javax.annotation.Nullable; import java.util.Collection; +import java.util.stream.Stream; public interface EntryTree extends EntryMap, Iterable>, Translatable { Collection> getChildren(Entry entry); @@ -18,9 +19,7 @@ public interface EntryTree extends EntryMap, Iterable>, T @Nullable EntryTreeNode findNode(Entry entry); - Collection> getAllNodes(); - - Collection> getRootEntries(); + Stream> getRootNodes(); @Override EntryTree translate(Translator translator, EntryResolver resolver, EntryMap mappings); diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java index 734b60ce..affcd504 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java @@ -33,4 +33,8 @@ public interface EntryTreeNode { .map(EntryTreeNode::getEntry) .collect(Collectors.toList()); } + + default boolean hasValue() { + return getValue() != null; + } } diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java index c5fc473d..bb21de6f 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java @@ -8,7 +8,9 @@ import cuchaz.enigma.translation.representation.entry.Entry; import javax.annotation.Nullable; import java.util.*; -import java.util.stream.Collectors; +import java.util.function.Function; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; public class HashEntryTree implements EntryTree { private final Map, HashTreeNode> root = new HashMap<>(); @@ -17,7 +19,7 @@ public class HashEntryTree implements EntryTree { } public HashEntryTree(EntryTree tree) { - for (EntryTreeNode node : tree.getAllNodes()) { + for (EntryTreeNode node : tree) { insert(node.getEntry(), node.getValue()); } } @@ -151,31 +153,24 @@ public class HashEntryTree implements EntryTree { } @Override - @SuppressWarnings("unchecked") public Iterator> iterator() { - Collection> values = (Collection) root.values(); - return values.iterator(); - } - - @Override - public Collection> getAllNodes() { Collection> nodes = new ArrayList<>(); for (EntryTreeNode node : root.values()) { nodes.addAll(node.getNodesRecursively()); } - return nodes; + return nodes.iterator(); } @Override - public Collection> getAllEntries() { - return getAllNodes().stream() - .map(EntryTreeNode::getEntry) - .collect(Collectors.toList()); + public Stream> getAllEntries() { + return StreamSupport.stream(spliterator(), false) + .filter(EntryTreeNode::hasValue) + .map(EntryTreeNode::getEntry); } @Override - public Collection> getRootEntries() { - return root.keySet(); + public Stream> getRootNodes() { + return root.values().stream().map(Function.identity()); } @Override @@ -186,7 +181,7 @@ public class HashEntryTree implements EntryTree { @Override public HashEntryTree translate(Translator translator, EntryResolver resolver, EntryMap mappings) { HashEntryTree translatedTree = new HashEntryTree<>(); - for (EntryTreeNode node : getAllNodes()) { + for (EntryTreeNode node : this) { translatedTree.insert(translator.translate(node.getEntry()), node.getValue()); } return translatedTree; diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java index b9391b04..c4df891c 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java @@ -85,6 +85,11 @@ public class ClassDefEntry extends ClassEntry implements DefEntry { return new ClassDefEntry(parent, translatedName, translatedSignature, translatedAccess, translatedSuper, translatedInterfaces); } + @Override + public ClassDefEntry withName(String name) { + return new ClassDefEntry(parent, name, signature, access, superClass, interfaces); + } + @Override public ClassDefEntry withParent(ClassEntry parent) { return new ClassDefEntry(parent, name, signature, access, superClass, interfaces); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java index 644658fd..9bfcd8a8 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java @@ -95,6 +95,11 @@ public class ClassEntry extends ParentedEntry implements Comparable< NameValidator.validateClassName(name, !isInnerClass()); } + @Override + public ClassEntry withName(String name) { + return new ClassEntry(parent, name); + } + @Override public ClassEntry withParent(ClassEntry parent) { return new ClassEntry(parent, name); @@ -193,6 +198,11 @@ public class ClassEntry extends ParentedEntry implements Comparable< @Override public int compareTo(ClassEntry entry) { - return name.compareTo(entry.name); + String fullName = getFullName(); + String otherFullName = entry.getFullName(); + if (fullName.length() != otherFullName.length()) { + return fullName.length() - otherFullName.length(); + } + return fullName.compareTo(otherFullName); } } diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java index 227400eb..29a55d89 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java @@ -31,6 +31,8 @@ public interface Entry

> extends Translatable { Class

getParentType(); + Entry

withName(String name); + Entry

withParent(P parent); boolean canConflictWith(Entry entry); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java index d487f71f..27033015 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java @@ -54,6 +54,11 @@ public class FieldDefEntry extends FieldEntry implements DefEntry { return new FieldDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess); } + @Override + public FieldDefEntry withName(String name) { + return new FieldDefEntry(parent, name, desc, signature, access); + } + @Override public FieldDefEntry withParent(ClassEntry owner) { return new FieldDefEntry(owner, this.name, this.desc, signature, access); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java index 2ec24719..700512e2 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java @@ -44,6 +44,11 @@ public class FieldEntry extends ParentedEntry implements Comparable< return this.desc; } + @Override + public FieldEntry withName(String name) { + return new FieldEntry(parent, name, desc); + } + @Override public FieldEntry withParent(ClassEntry parent) { return new FieldEntry(parent, this.name, this.desc); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java index 86bdf61c..c6f32b62 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java @@ -33,6 +33,11 @@ public class LocalVariableDefEntry extends LocalVariableEntry { return new LocalVariableDefEntry(parent, index, translatedName, parameter, translatedDesc); } + @Override + public LocalVariableDefEntry withName(String name) { + return new LocalVariableDefEntry(parent, index, name, parameter, desc); + } + @Override public LocalVariableDefEntry withParent(MethodEntry entry) { return new LocalVariableDefEntry(entry, index, name, parameter, desc); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java index 0c12f1c8..6fdb79fe 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java @@ -51,6 +51,11 @@ public class LocalVariableEntry extends ParentedEntry implements Co return new LocalVariableEntry(parent, index, translatedName, parameter); } + @Override + public LocalVariableEntry withName(String name) { + return new LocalVariableEntry(parent, index, name, parameter); + } + @Override public LocalVariableEntry withParent(MethodEntry parent) { return new LocalVariableEntry(parent, index, name, parameter); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java index 3ecd470f..51842443 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java @@ -54,6 +54,11 @@ public class MethodDefEntry extends MethodEntry implements DefEntry return new MethodDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess); } + @Override + public MethodDefEntry withName(String name) { + return new MethodDefEntry(parent, name, descriptor, signature, access); + } + @Override public MethodDefEntry withParent(ClassEntry parent) { return new MethodDefEntry(new ClassEntry(parent.getFullName()), name, descriptor, signature, access); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java index 3a1dbb32..f5d5c744 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java @@ -55,6 +55,11 @@ public class MethodEntry extends ParentedEntry implements Comparable return new MethodEntry(parent, translatedName, translator.translate(descriptor)); } + @Override + public MethodEntry withName(String name) { + return new MethodEntry(parent, name, descriptor); + } + @Override public MethodEntry withParent(ClassEntry parent) { return new MethodEntry(new ClassEntry(parent.getFullName()), name, descriptor); diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java index 7ba7c196..834da8de 100644 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java +++ b/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java @@ -35,6 +35,9 @@ public abstract class ParentedEntry

> implements Entry

{ @Override public abstract ParentedEntry

withParent(P parent); + @Override + public abstract ParentedEntry

withName(String name); + protected abstract ParentedEntry

translate(Translator translator, @Nullable EntryMapping mapping); @Override -- cgit v1.2.3