summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/translation
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/translation')
-rw-r--r--src/main/java/cuchaz/enigma/translation/Translator.java7
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java4
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java17
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java7
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java2
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java34
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java17
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java19
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java25
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java4
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java3
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java13
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java46
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java4
-rw-r--r--src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java29
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java12
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java2
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java3
26 files changed, 182 insertions, 106 deletions
diff --git a/src/main/java/cuchaz/enigma/translation/Translator.java b/src/main/java/cuchaz/enigma/translation/Translator.java
index de2003e..c70141f 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;
17import java.util.Collection; 17import java.util.Collection;
18import java.util.HashMap; 18import java.util.HashMap;
19import java.util.Map; 19import java.util.Map;
20import java.util.Set;
20import java.util.stream.Collectors; 21import java.util.stream.Collectors;
21 22
22public interface Translator { 23public interface Translator {
@@ -28,6 +29,12 @@ public interface Translator {
28 .collect(Collectors.toList()); 29 .collect(Collectors.toList());
29 } 30 }
30 31
32 default <T extends Translatable> Set<T> translate(Set<T> translatable) {
33 return translatable.stream()
34 .map(this::translate)
35 .collect(Collectors.toSet());
36 }
37
31 default <T extends Translatable, V> Map<T, V> translateKeys(Map<T, V> translatable) { 38 default <T extends Translatable, V> Map<T, V> translateKeys(Map<T, V> translatable) {
32 Map<T, V> result = new HashMap<>(translatable.size()); 39 Map<T, V> result = new HashMap<>(translatable.size());
33 for (Map.Entry<T, V> entry : translatable.entrySet()) { 40 for (Map.Entry<T, V> 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 6af4846..e1a3253 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;
3import cuchaz.enigma.translation.representation.entry.Entry; 3import cuchaz.enigma.translation.representation.entry.Entry;
4 4
5import javax.annotation.Nullable; 5import javax.annotation.Nullable;
6import java.util.Collection; 6import java.util.stream.Stream;
7 7
8public interface EntryMap<T> { 8public interface EntryMap<T> {
9 void insert(Entry<?> entry, T value); 9 void insert(Entry<?> entry, T value);
@@ -18,7 +18,7 @@ public interface EntryMap<T> {
18 return get(entry) != null; 18 return get(entry) != null;
19 } 19 }
20 20
21 Collection<Entry<?>> getAllEntries(); 21 Stream<Entry<?>> getAllEntries();
22 22
23 boolean isEmpty(); 23 boolean isEmpty();
24} 24}
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java
index f11cdef..b74cc0b 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 {
27 } 27 }
28 return accessModifier; 28 return accessModifier;
29 } 29 }
30
31 @Override
32 public boolean equals(Object obj) {
33 if (obj == this) return true;
34
35 if (obj instanceof EntryMapping) {
36 EntryMapping mapping = (EntryMapping) obj;
37 return mapping.targetName.equals(targetName) && mapping.accessModifier.equals(accessModifier);
38 }
39
40 return false;
41 }
42
43 @Override
44 public int hashCode() {
45 return targetName.hashCode() + accessModifier.hashCode() * 31;
46 }
30} 47}
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java
index fa421b9..ed9f820 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;
11 11
12import javax.annotation.Nullable; 12import javax.annotation.Nullable;
13import java.util.Collection; 13import java.util.Collection;
14import java.util.stream.Stream;
14 15
15public class EntryRemapper { 16public class EntryRemapper {
16 private final DeltaTrackingTree<EntryMapping> obfToDeobf; 17 private final DeltaTrackingTree<EntryMapping> obfToDeobf;
@@ -69,14 +70,10 @@ public class EntryRemapper {
69 return deobfuscator; 70 return deobfuscator;
70 } 71 }
71 72
72 public Collection<Entry<?>> getObfEntries() { 73 public Stream<Entry<?>> getObfEntries() {
73 return obfToDeobf.getAllEntries(); 74 return obfToDeobf.getAllEntries();
74 } 75 }
75 76
76 public Collection<Entry<?>> getObfRootEntries() {
77 return obfToDeobf.getRootEntries();
78 }
79
80 public Collection<Entry<?>> getObfChildren(Entry<?> obfuscatedEntry) { 77 public Collection<Entry<?>> getObfChildren(Entry<?> obfuscatedEntry) {
81 return obfToDeobf.getChildren(obfuscatedEntry); 78 return obfToDeobf.getChildren(obfuscatedEntry);
82 } 79 }
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java b/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java
index 1f2290a..6c8ed76 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 {
91 Set<Entry<ClassEntry>> resolvedBridge = resolveChildEntry(bridgeMethod, strategy); 91 Set<Entry<ClassEntry>> resolvedBridge = resolveChildEntry(bridgeMethod, strategy);
92 if (!resolvedBridge.isEmpty()) { 92 if (!resolvedBridge.isEmpty()) {
93 return resolvedBridge; 93 return resolvedBridge;
94 } else {
95 return Collections.singleton(bridgeMethod);
94 } 96 }
95 } 97 }
96 } 98 }
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java
index 9f1f468..1407bb6 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;
2 2
3import cuchaz.enigma.translation.Translatable; 3import cuchaz.enigma.translation.Translatable;
4import cuchaz.enigma.translation.Translator; 4import cuchaz.enigma.translation.Translator;
5import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
6import cuchaz.enigma.translation.mapping.tree.EntryTree; 5import cuchaz.enigma.translation.mapping.tree.EntryTree;
6import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
7import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
7import cuchaz.enigma.translation.representation.entry.Entry; 8import cuchaz.enigma.translation.representation.entry.Entry;
8 9
10import java.util.stream.Stream;
11
9public class MappingDelta<T> implements Translatable { 12public class MappingDelta<T> implements Translatable {
10 public static final Object PLACEHOLDER = new Object(); 13 public static final Object PLACEHOLDER = new Object();
11 14
12 private final EntryTree<T> baseMappings; 15 private final EntryTree<T> baseMappings;
13 16
14 private final EntryTree<Object> additions; 17 private final EntryTree<Object> changes;
15 private final EntryTree<Object> deletions;
16 18
17 public MappingDelta(EntryTree<T> baseMappings, EntryTree<Object> additions, EntryTree<Object> deletions) { 19 public MappingDelta(EntryTree<T> baseMappings, EntryTree<Object> changes) {
18 this.baseMappings = baseMappings; 20 this.baseMappings = baseMappings;
19 this.additions = additions; 21 this.changes = changes;
20 this.deletions = deletions;
21 } 22 }
22 23
23 public MappingDelta(EntryTree<T> baseMappings) { 24 public MappingDelta(EntryTree<T> baseMappings) {
24 this(baseMappings, new HashEntryTree<>(), new HashEntryTree<>()); 25 this(baseMappings, new HashEntryTree<>());
25 } 26 }
26 27
27 public static <T> MappingDelta<T> added(EntryTree<T> mappings) { 28 public static <T> MappingDelta<T> added(EntryTree<T> mappings) {
28 EntryTree<Object> additions = new HashEntryTree<>(); 29 EntryTree<Object> changes = new HashEntryTree<>();
29 for (Entry<?> entry : mappings.getAllEntries()) { 30 mappings.getAllEntries().forEach(entry -> changes.insert(entry, PLACEHOLDER));
30 additions.insert(entry, PLACEHOLDER);
31 }
32 31
33 return new MappingDelta<>(new HashEntryTree<>(), additions, new HashEntryTree<>()); 32 return new MappingDelta<>(new HashEntryTree<>(), changes);
34 } 33 }
35 34
36 public EntryTree<T> getBaseMappings() { 35 public EntryTree<T> getBaseMappings() {
37 return baseMappings; 36 return baseMappings;
38 } 37 }
39 38
40 public EntryTree<?> getAdditions() { 39 public EntryTree<?> getChanges() {
41 return additions; 40 return changes;
42 } 41 }
43 42
44 public EntryTree<?> getDeletions() { 43 public Stream<Entry<?>> getChangedRoots() {
45 return deletions; 44 return changes.getRootNodes().map(EntryTreeNode::getEntry);
46 } 45 }
47 46
48 @Override 47 @Override
49 public MappingDelta<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { 48 public MappingDelta<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) {
50 return new MappingDelta<>( 49 return new MappingDelta<>(
51 translator.translate(baseMappings), 50 translator.translate(baseMappings),
52 translator.translate(additions), 51 translator.translate(changes)
53 translator.translate(deletions)
54 ); 52 );
55 } 53 }
56} 54}
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java
index 77d75ec..af9e63a 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 @@
11 11
12package cuchaz.enigma.translation.mapping; 12package cuchaz.enigma.translation.mapping;
13 13
14import cuchaz.enigma.ProgressListener;
14import cuchaz.enigma.analysis.index.JarIndex; 15import cuchaz.enigma.analysis.index.JarIndex;
15import cuchaz.enigma.translation.mapping.tree.EntryTree; 16import cuchaz.enigma.translation.mapping.tree.EntryTree;
16import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; 17import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
@@ -22,6 +23,7 @@ import cuchaz.enigma.translation.representation.entry.MethodEntry;
22import java.util.Collection; 23import java.util.Collection;
23import java.util.HashMap; 24import java.util.HashMap;
24import java.util.Map; 25import java.util.Map;
26import java.util.stream.Collectors;
25 27
26public class MappingsChecker { 28public class MappingsChecker {
27 private final JarIndex index; 29 private final JarIndex index;
@@ -32,14 +34,19 @@ public class MappingsChecker {
32 this.mappings = mappings; 34 this.mappings = mappings;
33 } 35 }
34 36
35 public Dropped dropBrokenMappings() { 37 public Dropped dropBrokenMappings(ProgressListener progress) {
36 Dropped dropped = new Dropped(); 38 Dropped dropped = new Dropped();
37 39
38 Collection<Entry<?>> obfEntries = mappings.getAllEntries(); 40 Collection<Entry<?>> obfEntries = mappings.getAllEntries()
41 .filter(e -> e instanceof ClassEntry || e instanceof MethodEntry || e instanceof FieldEntry)
42 .collect(Collectors.toList());
43
44 progress.init(obfEntries.size(), "Checking for dropped mappings");
45
46 int steps = 0;
39 for (Entry<?> entry : obfEntries) { 47 for (Entry<?> entry : obfEntries) {
40 if (entry instanceof ClassEntry || entry instanceof MethodEntry || entry instanceof FieldEntry) { 48 progress.step(steps++, entry.toString());
41 tryDropEntry(dropped, entry); 49 tryDropEntry(dropped, entry);
42 }
43 } 50 }
44 51
45 dropped.apply(mappings); 52 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 d36bc0b..3f61325 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 @@
1package cuchaz.enigma.translation.mapping.serde; 1package cuchaz.enigma.translation.mapping.serde;
2 2
3import com.google.common.base.Charsets; 3import com.google.common.base.Charsets;
4import cuchaz.enigma.ProgressListener;
4import cuchaz.enigma.throwables.MappingParseException; 5import cuchaz.enigma.throwables.MappingParseException;
5import cuchaz.enigma.translation.mapping.AccessModifier; 6import cuchaz.enigma.translation.mapping.AccessModifier;
6import cuchaz.enigma.translation.mapping.EntryMapping; 7import cuchaz.enigma.translation.mapping.EntryMapping;
7import cuchaz.enigma.translation.mapping.MappingPair; 8import cuchaz.enigma.translation.mapping.MappingPair;
8import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
9import cuchaz.enigma.translation.mapping.tree.EntryTree; 9import cuchaz.enigma.translation.mapping.tree.EntryTree;
10import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
10import cuchaz.enigma.translation.representation.MethodDescriptor; 11import cuchaz.enigma.translation.representation.MethodDescriptor;
11import cuchaz.enigma.translation.representation.TypeDescriptor; 12import cuchaz.enigma.translation.representation.TypeDescriptor;
12import cuchaz.enigma.translation.representation.entry.*; 13import cuchaz.enigma.translation.representation.entry.*;
@@ -24,22 +25,32 @@ import java.util.stream.Collectors;
24public enum EnigmaMappingsReader implements MappingsReader { 25public enum EnigmaMappingsReader implements MappingsReader {
25 FILE { 26 FILE {
26 @Override 27 @Override
27 public EntryTree<EntryMapping> read(Path path) throws IOException, MappingParseException { 28 public EntryTree<EntryMapping> read(Path path, ProgressListener progress) throws IOException, MappingParseException {
29 progress.init(1, "Loading mapping file");
30
28 EntryTree<EntryMapping> mappings = new HashEntryTree<>(); 31 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
29 readFile(path, mappings); 32 readFile(path, mappings);
33
34 progress.step(1, "Done!");
35
30 return mappings; 36 return mappings;
31 } 37 }
32 }, 38 },
33 DIRECTORY { 39 DIRECTORY {
34 @Override 40 @Override
35 public EntryTree<EntryMapping> read(Path path) throws IOException, MappingParseException { 41 public EntryTree<EntryMapping> read(Path root, ProgressListener progress) throws IOException, MappingParseException {
36 EntryTree<EntryMapping> mappings = new HashEntryTree<>(); 42 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
37 43
38 List<Path> files = Files.walk(path) 44 List<Path> files = Files.walk(root)
39 .filter(f -> !Files.isDirectory(f)) 45 .filter(f -> !Files.isDirectory(f))
40 .filter(f -> f.toString().endsWith(".mapping")) 46 .filter(f -> f.toString().endsWith(".mapping"))
41 .collect(Collectors.toList()); 47 .collect(Collectors.toList());
48
49 progress.init(files.size(), "Loading mapping files");
50 int step = 0;
51
42 for (Path file : files) { 52 for (Path file : files) {
53 progress.step(step++, root.relativize(file).toString());
43 if (Files.isHidden(file)) { 54 if (Files.isHidden(file)) {
44 continue; 55 continue;
45 } 56 }
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 8c55fa9..618bb0a 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;
28import java.nio.file.Paths; 28import java.nio.file.Paths;
29import java.util.ArrayList; 29import java.util.ArrayList;
30import java.util.Collection; 30import java.util.Collection;
31import java.util.Objects;
31import java.util.concurrent.atomic.AtomicInteger; 32import java.util.concurrent.atomic.AtomicInteger;
32import java.util.stream.Collectors; 33import java.util.stream.Collectors;
33 34
@@ -35,7 +36,7 @@ public enum EnigmaMappingsWriter implements MappingsWriter {
35 FILE { 36 FILE {
36 @Override 37 @Override
37 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress) { 38 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress) {
38 Collection<ClassEntry> classes = mappings.getRootEntries().stream() 39 Collection<ClassEntry> classes = mappings.getRootNodes()
39 .filter(entry -> entry instanceof ClassEntry) 40 .filter(entry -> entry instanceof ClassEntry)
40 .map(entry -> (ClassEntry) entry) 41 .map(entry -> (ClassEntry) entry)
41 .collect(Collectors.toList()); 42 .collect(Collectors.toList());
@@ -56,19 +57,19 @@ public enum EnigmaMappingsWriter implements MappingsWriter {
56 DIRECTORY { 57 DIRECTORY {
57 @Override 58 @Override
58 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress) { 59 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress) {
59 applyDeletions(delta.getBaseMappings(), delta.getDeletions(), path); 60 Collection<ClassEntry> changedClasses = delta.getChangedRoots()
60
61 Collection<ClassEntry> classes = delta.getAdditions().getRootEntries().stream()
62 .filter(entry -> entry instanceof ClassEntry) 61 .filter(entry -> entry instanceof ClassEntry)
63 .map(entry -> (ClassEntry) entry) 62 .map(entry -> (ClassEntry) entry)
64 .collect(Collectors.toList()); 63 .collect(Collectors.toList());
65 64
66 progress.init(classes.size(), "Writing classes"); 65 applyDeletions(path, changedClasses, mappings, delta.getBaseMappings());
66
67 progress.init(changedClasses.size(), "Writing classes");
67 68
68 Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE);
69 AtomicInteger steps = new AtomicInteger(); 69 AtomicInteger steps = new AtomicInteger();
70 70
71 classes.parallelStream().forEach(classEntry -> { 71 Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE);
72 changedClasses.parallelStream().forEach(classEntry -> {
72 progress.step(steps.getAndIncrement(), classEntry.getFullName()); 73 progress.step(steps.getAndIncrement(), classEntry.getFullName());
73 74
74 try { 75 try {
@@ -86,12 +87,12 @@ public enum EnigmaMappingsWriter implements MappingsWriter {
86 }); 87 });
87 } 88 }
88 89
89 private void applyDeletions(EntryTree<EntryMapping> baseMappings, EntryTree<?> deletions, Path root) { 90 private void applyDeletions(Path root, Collection<ClassEntry> changedClasses, EntryTree<EntryMapping> mappings, EntryTree<EntryMapping> oldMappings) {
90 Translator oldMappingTranslator = new MappingTranslator(baseMappings, VoidEntryResolver.INSTANCE); 91 Translator oldMappingTranslator = new MappingTranslator(oldMappings, VoidEntryResolver.INSTANCE);
91 92
92 Collection<ClassEntry> deletedClasses = deletions.getRootEntries().stream() 93 Collection<ClassEntry> deletedClasses = changedClasses.stream()
93 .filter(e -> e instanceof ClassEntry) 94 .filter(e -> !Objects.equals(oldMappings.get(e), mappings.get(e)))
94 .map(e -> oldMappingTranslator.translate((ClassEntry) e)) 95 .map(oldMappingTranslator::translate)
95 .collect(Collectors.toList()); 96 .collect(Collectors.toList());
96 97
97 for (ClassEntry classEntry : deletedClasses) { 98 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 622a0e1..2528352 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 {
35 writer.write(mappings, delta, path, progressListener); 35 writer.write(mappings, delta, path, progressListener);
36 } 36 }
37 37
38 public EntryTree<EntryMapping> read(Path path) throws IOException, MappingParseException { 38 public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener) throws IOException, MappingParseException {
39 if (reader == null) { 39 if (reader == null) {
40 throw new IllegalStateException(name() + " does not support reading"); 40 throw new IllegalStateException(name() + " does not support reading");
41 } 41 }
42 return reader.read(path); 42 return reader.read(path, progressListener);
43 } 43 }
44 44
45 @Nullable 45 @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 f239ee6..af0933f 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 @@
1package cuchaz.enigma.translation.mapping.serde; 1package cuchaz.enigma.translation.mapping.serde;
2 2
3import cuchaz.enigma.ProgressListener;
3import cuchaz.enigma.throwables.MappingParseException; 4import cuchaz.enigma.throwables.MappingParseException;
4import cuchaz.enigma.translation.mapping.EntryMapping; 5import cuchaz.enigma.translation.mapping.EntryMapping;
5import cuchaz.enigma.translation.mapping.tree.EntryTree; 6import cuchaz.enigma.translation.mapping.tree.EntryTree;
@@ -8,5 +9,5 @@ import java.io.IOException;
8import java.nio.file.Path; 9import java.nio.file.Path;
9 10
10public interface MappingsReader { 11public interface MappingsReader {
11 EntryTree<EntryMapping> read(Path path) throws MappingParseException, IOException; 12 EntryTree<EntryMapping> read(Path path, ProgressListener progress) throws MappingParseException, IOException;
12} 13}
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 e0afc3e..69d8235 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 @@
1package cuchaz.enigma.translation.mapping.serde; 1package cuchaz.enigma.translation.mapping.serde;
2 2
3import com.google.common.base.Charsets; 3import com.google.common.base.Charsets;
4import cuchaz.enigma.ProgressListener;
4import cuchaz.enigma.throwables.MappingParseException; 5import cuchaz.enigma.throwables.MappingParseException;
5import cuchaz.enigma.translation.mapping.EntryMapping; 6import cuchaz.enigma.translation.mapping.EntryMapping;
6import cuchaz.enigma.translation.mapping.MappingPair; 7import cuchaz.enigma.translation.mapping.MappingPair;
7import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
8import cuchaz.enigma.translation.mapping.tree.EntryTree; 8import cuchaz.enigma.translation.mapping.tree.EntryTree;
9import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
9import cuchaz.enigma.translation.representation.MethodDescriptor; 10import cuchaz.enigma.translation.representation.MethodDescriptor;
10import cuchaz.enigma.translation.representation.TypeDescriptor; 11import cuchaz.enigma.translation.representation.TypeDescriptor;
11import cuchaz.enigma.translation.representation.entry.ClassEntry; 12import cuchaz.enigma.translation.representation.entry.ClassEntry;
@@ -22,15 +23,19 @@ public enum TinyMappingsReader implements MappingsReader {
22 INSTANCE; 23 INSTANCE;
23 24
24 @Override 25 @Override
25 public EntryTree<EntryMapping> read(Path path) throws IOException, MappingParseException { 26 public EntryTree<EntryMapping> read(Path path, ProgressListener progress) throws IOException, MappingParseException {
26 return read(path, Files.readAllLines(path, Charsets.UTF_8)); 27 return read(path, Files.readAllLines(path, Charsets.UTF_8), progress);
27 } 28 }
28 29
29 private EntryTree<EntryMapping> read(Path path, List<String> lines) throws MappingParseException { 30 private EntryTree<EntryMapping> read(Path path, List<String> lines, ProgressListener progress) throws MappingParseException {
30 EntryTree<EntryMapping> mappings = new HashEntryTree<>(); 31 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
31 lines.remove(0); 32 lines.remove(0);
32 33
34 progress.init(lines.size(), "Loading mapping file");
35
33 for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { 36 for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
37 progress.step(lineNumber, "");
38
34 String line = lines.get(lineNumber); 39 String line = lines.get(lineNumber);
35 40
36 try { 41 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 36be5e1..255fa5f 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;
10import javax.annotation.Nullable; 10import javax.annotation.Nullable;
11import java.util.Collection; 11import java.util.Collection;
12import java.util.Iterator; 12import java.util.Iterator;
13import java.util.stream.Stream;
13 14
14public class DeltaTrackingTree<T> implements EntryTree<T> { 15public class DeltaTrackingTree<T> implements EntryTree<T> {
15 private final EntryTree<T> delegate; 16 private final EntryTree<T> delegate;
16 17
17 private EntryTree<T> deltaReference; 18 private EntryTree<T> deltaReference;
18 private EntryTree<Object> additions = new HashEntryTree<>(); 19 private EntryTree<Object> changes = new HashEntryTree<>();
19 private EntryTree<Object> deletions = new HashEntryTree<>();
20 20
21 public DeltaTrackingTree(EntryTree<T> delegate) { 21 public DeltaTrackingTree(EntryTree<T> delegate) {
22 this.delegate = delegate; 22 this.delegate = delegate;
@@ -29,30 +29,19 @@ public class DeltaTrackingTree<T> implements EntryTree<T> {
29 29
30 @Override 30 @Override
31 public void insert(Entry<?> entry, T value) { 31 public void insert(Entry<?> entry, T value) {
32 if (value != null) { 32 trackChange(entry);
33 trackAddition(entry);
34 } else {
35 trackDeletion(entry);
36 }
37 delegate.insert(entry, value); 33 delegate.insert(entry, value);
38 } 34 }
39 35
40 @Nullable 36 @Nullable
41 @Override 37 @Override
42 public T remove(Entry<?> entry) { 38 public T remove(Entry<?> entry) {
43 T value = delegate.remove(entry); 39 trackChange(entry);
44 trackDeletion(entry); 40 return delegate.remove(entry);
45 return value;
46 } 41 }
47 42
48 public void trackAddition(Entry<?> entry) { 43 public void trackChange(Entry<?> entry) {
49 deletions.insert(entry, MappingDelta.PLACEHOLDER); 44 changes.insert(entry, MappingDelta.PLACEHOLDER);
50 additions.insert(entry, MappingDelta.PLACEHOLDER);
51 }
52
53 public void trackDeletion(Entry<?> entry) {
54 additions.remove(entry);
55 deletions.insert(entry, MappingDelta.PLACEHOLDER);
56 } 45 }
57 46
58 @Nullable 47 @Nullable
@@ -78,25 +67,19 @@ public class DeltaTrackingTree<T> implements EntryTree<T> {
78 } 67 }
79 68
80 @Override 69 @Override
81 public Collection<EntryTreeNode<T>> getAllNodes() { 70 public Stream<EntryTreeNode<T>> getRootNodes() {
82 return delegate.getAllNodes(); 71 return delegate.getRootNodes();
83 }
84
85 @Override
86 public Collection<Entry<?>> getRootEntries() {
87 return delegate.getRootEntries();
88 } 72 }
89 73
90 @Override 74 @Override
91 public DeltaTrackingTree<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { 75 public DeltaTrackingTree<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) {
92 DeltaTrackingTree<T> translatedTree = new DeltaTrackingTree<>(delegate.translate(translator, resolver, mappings)); 76 DeltaTrackingTree<T> translatedTree = new DeltaTrackingTree<>(delegate.translate(translator, resolver, mappings));
93 translatedTree.additions = additions.translate(translator, resolver, mappings); 77 translatedTree.changes = changes.translate(translator, resolver, mappings);
94 translatedTree.deletions = deletions.translate(translator, resolver, mappings);
95 return translatedTree; 78 return translatedTree;
96 } 79 }
97 80
98 @Override 81 @Override
99 public Collection<Entry<?>> getAllEntries() { 82 public Stream<Entry<?>> getAllEntries() {
100 return delegate.getAllEntries(); 83 return delegate.getAllEntries();
101 } 84 }
102 85
@@ -111,18 +94,17 @@ public class DeltaTrackingTree<T> implements EntryTree<T> {
111 } 94 }
112 95
113 public MappingDelta<T> takeDelta() { 96 public MappingDelta<T> takeDelta() {
114 MappingDelta<T> delta = new MappingDelta<>(deltaReference, additions, deletions); 97 MappingDelta<T> delta = new MappingDelta<>(deltaReference, changes);
115 resetDelta(); 98 resetDelta();
116 return delta; 99 return delta;
117 } 100 }
118 101
119 private void resetDelta() { 102 private void resetDelta() {
120 deltaReference = new HashEntryTree<>(delegate); 103 deltaReference = new HashEntryTree<>(delegate);
121 additions = new HashEntryTree<>(); 104 changes = new HashEntryTree<>();
122 deletions = new HashEntryTree<>();
123 } 105 }
124 106
125 public boolean isDirty() { 107 public boolean isDirty() {
126 return !additions.isEmpty() || !deletions.isEmpty(); 108 return !changes.isEmpty();
127 } 109 }
128} 110}
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 4f341f4..daaefcc 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;
9 9
10import javax.annotation.Nullable; 10import javax.annotation.Nullable;
11import java.util.Collection; 11import java.util.Collection;
12import java.util.stream.Stream;
12 13
13public interface EntryTree<T> extends EntryMap<T>, Iterable<EntryTreeNode<T>>, Translatable { 14public interface EntryTree<T> extends EntryMap<T>, Iterable<EntryTreeNode<T>>, Translatable {
14 Collection<Entry<?>> getChildren(Entry<?> entry); 15 Collection<Entry<?>> getChildren(Entry<?> entry);
@@ -18,9 +19,7 @@ public interface EntryTree<T> extends EntryMap<T>, Iterable<EntryTreeNode<T>>, T
18 @Nullable 19 @Nullable
19 EntryTreeNode<T> findNode(Entry<?> entry); 20 EntryTreeNode<T> findNode(Entry<?> entry);
20 21
21 Collection<EntryTreeNode<T>> getAllNodes(); 22 Stream<EntryTreeNode<T>> getRootNodes();
22
23 Collection<Entry<?>> getRootEntries();
24 23
25 @Override 24 @Override
26 EntryTree<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings); 25 EntryTree<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> 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 734b60c..affcd50 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<T> {
33 .map(EntryTreeNode::getEntry) 33 .map(EntryTreeNode::getEntry)
34 .collect(Collectors.toList()); 34 .collect(Collectors.toList());
35 } 35 }
36
37 default boolean hasValue() {
38 return getValue() != null;
39 }
36} 40}
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 c5fc473..bb21de6 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;
8 8
9import javax.annotation.Nullable; 9import javax.annotation.Nullable;
10import java.util.*; 10import java.util.*;
11import java.util.stream.Collectors; 11import java.util.function.Function;
12import java.util.stream.Stream;
13import java.util.stream.StreamSupport;
12 14
13public class HashEntryTree<T> implements EntryTree<T> { 15public class HashEntryTree<T> implements EntryTree<T> {
14 private final Map<Entry<?>, HashTreeNode<T>> root = new HashMap<>(); 16 private final Map<Entry<?>, HashTreeNode<T>> root = new HashMap<>();
@@ -17,7 +19,7 @@ public class HashEntryTree<T> implements EntryTree<T> {
17 } 19 }
18 20
19 public HashEntryTree(EntryTree<T> tree) { 21 public HashEntryTree(EntryTree<T> tree) {
20 for (EntryTreeNode<T> node : tree.getAllNodes()) { 22 for (EntryTreeNode<T> node : tree) {
21 insert(node.getEntry(), node.getValue()); 23 insert(node.getEntry(), node.getValue());
22 } 24 }
23 } 25 }
@@ -151,31 +153,24 @@ public class HashEntryTree<T> implements EntryTree<T> {
151 } 153 }
152 154
153 @Override 155 @Override
154 @SuppressWarnings("unchecked")
155 public Iterator<EntryTreeNode<T>> iterator() { 156 public Iterator<EntryTreeNode<T>> iterator() {
156 Collection<EntryTreeNode<T>> values = (Collection) root.values();
157 return values.iterator();
158 }
159
160 @Override
161 public Collection<EntryTreeNode<T>> getAllNodes() {
162 Collection<EntryTreeNode<T>> nodes = new ArrayList<>(); 157 Collection<EntryTreeNode<T>> nodes = new ArrayList<>();
163 for (EntryTreeNode<T> node : root.values()) { 158 for (EntryTreeNode<T> node : root.values()) {
164 nodes.addAll(node.getNodesRecursively()); 159 nodes.addAll(node.getNodesRecursively());
165 } 160 }
166 return nodes; 161 return nodes.iterator();
167 } 162 }
168 163
169 @Override 164 @Override
170 public Collection<Entry<?>> getAllEntries() { 165 public Stream<Entry<?>> getAllEntries() {
171 return getAllNodes().stream() 166 return StreamSupport.stream(spliterator(), false)
172 .map(EntryTreeNode::getEntry) 167 .filter(EntryTreeNode::hasValue)
173 .collect(Collectors.toList()); 168 .map(EntryTreeNode::getEntry);
174 } 169 }
175 170
176 @Override 171 @Override
177 public Collection<Entry<?>> getRootEntries() { 172 public Stream<EntryTreeNode<T>> getRootNodes() {
178 return root.keySet(); 173 return root.values().stream().map(Function.identity());
179 } 174 }
180 175
181 @Override 176 @Override
@@ -186,7 +181,7 @@ public class HashEntryTree<T> implements EntryTree<T> {
186 @Override 181 @Override
187 public HashEntryTree<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) { 182 public HashEntryTree<T> translate(Translator translator, EntryResolver resolver, EntryMap<EntryMapping> mappings) {
188 HashEntryTree<T> translatedTree = new HashEntryTree<>(); 183 HashEntryTree<T> translatedTree = new HashEntryTree<>();
189 for (EntryTreeNode<T> node : getAllNodes()) { 184 for (EntryTreeNode<T> node : this) {
190 translatedTree.insert(translator.translate(node.getEntry()), node.getValue()); 185 translatedTree.insert(translator.translate(node.getEntry()), node.getValue());
191 } 186 }
192 return translatedTree; 187 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 b9391b0..c4df891 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java
@@ -86,6 +86,11 @@ public class ClassDefEntry extends ClassEntry implements DefEntry<ClassEntry> {
86 } 86 }
87 87
88 @Override 88 @Override
89 public ClassDefEntry withName(String name) {
90 return new ClassDefEntry(parent, name, signature, access, superClass, interfaces);
91 }
92
93 @Override
89 public ClassDefEntry withParent(ClassEntry parent) { 94 public ClassDefEntry withParent(ClassEntry parent) {
90 return new ClassDefEntry(parent, name, signature, access, superClass, interfaces); 95 return new ClassDefEntry(parent, name, signature, access, superClass, interfaces);
91 } 96 }
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 644658f..9bfcd8a 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
@@ -96,6 +96,11 @@ public class ClassEntry extends ParentedEntry<ClassEntry> implements Comparable<
96 } 96 }
97 97
98 @Override 98 @Override
99 public ClassEntry withName(String name) {
100 return new ClassEntry(parent, name);
101 }
102
103 @Override
99 public ClassEntry withParent(ClassEntry parent) { 104 public ClassEntry withParent(ClassEntry parent) {
100 return new ClassEntry(parent, name); 105 return new ClassEntry(parent, name);
101 } 106 }
@@ -193,6 +198,11 @@ public class ClassEntry extends ParentedEntry<ClassEntry> implements Comparable<
193 198
194 @Override 199 @Override
195 public int compareTo(ClassEntry entry) { 200 public int compareTo(ClassEntry entry) {
196 return name.compareTo(entry.name); 201 String fullName = getFullName();
202 String otherFullName = entry.getFullName();
203 if (fullName.length() != otherFullName.length()) {
204 return fullName.length() - otherFullName.length();
205 }
206 return fullName.compareTo(otherFullName);
197 } 207 }
198} 208}
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 227400e..29a55d8 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<P extends Entry<?>> extends Translatable {
31 31
32 Class<P> getParentType(); 32 Class<P> getParentType();
33 33
34 Entry<P> withName(String name);
35
34 Entry<P> withParent(P parent); 36 Entry<P> withParent(P parent);
35 37
36 boolean canConflictWith(Entry<?> entry); 38 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 d487f71..2703301 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java
@@ -55,6 +55,11 @@ public class FieldDefEntry extends FieldEntry implements DefEntry<ClassEntry> {
55 } 55 }
56 56
57 @Override 57 @Override
58 public FieldDefEntry withName(String name) {
59 return new FieldDefEntry(parent, name, desc, signature, access);
60 }
61
62 @Override
58 public FieldDefEntry withParent(ClassEntry owner) { 63 public FieldDefEntry withParent(ClassEntry owner) {
59 return new FieldDefEntry(owner, this.name, this.desc, signature, access); 64 return new FieldDefEntry(owner, this.name, this.desc, signature, access);
60 } 65 }
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 2ec2471..700512e 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java
@@ -45,6 +45,11 @@ public class FieldEntry extends ParentedEntry<ClassEntry> implements Comparable<
45 } 45 }
46 46
47 @Override 47 @Override
48 public FieldEntry withName(String name) {
49 return new FieldEntry(parent, name, desc);
50 }
51
52 @Override
48 public FieldEntry withParent(ClassEntry parent) { 53 public FieldEntry withParent(ClassEntry parent) {
49 return new FieldEntry(parent, this.name, this.desc); 54 return new FieldEntry(parent, this.name, this.desc);
50 } 55 }
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 86bdf61..c6f32b6 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java
@@ -34,6 +34,11 @@ public class LocalVariableDefEntry extends LocalVariableEntry {
34 } 34 }
35 35
36 @Override 36 @Override
37 public LocalVariableDefEntry withName(String name) {
38 return new LocalVariableDefEntry(parent, index, name, parameter, desc);
39 }
40
41 @Override
37 public LocalVariableDefEntry withParent(MethodEntry entry) { 42 public LocalVariableDefEntry withParent(MethodEntry entry) {
38 return new LocalVariableDefEntry(entry, index, name, parameter, desc); 43 return new LocalVariableDefEntry(entry, index, name, parameter, desc);
39 } 44 }
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 0c12f1c..6fdb79f 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java
@@ -52,6 +52,11 @@ public class LocalVariableEntry extends ParentedEntry<MethodEntry> implements Co
52 } 52 }
53 53
54 @Override 54 @Override
55 public LocalVariableEntry withName(String name) {
56 return new LocalVariableEntry(parent, index, name, parameter);
57 }
58
59 @Override
55 public LocalVariableEntry withParent(MethodEntry parent) { 60 public LocalVariableEntry withParent(MethodEntry parent) {
56 return new LocalVariableEntry(parent, index, name, parameter); 61 return new LocalVariableEntry(parent, index, name, parameter);
57 } 62 }
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 3ecd470..5184244 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java
@@ -55,6 +55,11 @@ public class MethodDefEntry extends MethodEntry implements DefEntry<ClassEntry>
55 } 55 }
56 56
57 @Override 57 @Override
58 public MethodDefEntry withName(String name) {
59 return new MethodDefEntry(parent, name, descriptor, signature, access);
60 }
61
62 @Override
58 public MethodDefEntry withParent(ClassEntry parent) { 63 public MethodDefEntry withParent(ClassEntry parent) {
59 return new MethodDefEntry(new ClassEntry(parent.getFullName()), name, descriptor, signature, access); 64 return new MethodDefEntry(new ClassEntry(parent.getFullName()), name, descriptor, signature, access);
60 } 65 }
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 3a1dbb3..f5d5c74 100644
--- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java
+++ b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java
@@ -56,6 +56,11 @@ public class MethodEntry extends ParentedEntry<ClassEntry> implements Comparable
56 } 56 }
57 57
58 @Override 58 @Override
59 public MethodEntry withName(String name) {
60 return new MethodEntry(parent, name, descriptor);
61 }
62
63 @Override
59 public MethodEntry withParent(ClassEntry parent) { 64 public MethodEntry withParent(ClassEntry parent) {
60 return new MethodEntry(new ClassEntry(parent.getFullName()), name, descriptor); 65 return new MethodEntry(new ClassEntry(parent.getFullName()), name, descriptor);
61 } 66 }
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 7ba7c19..834da8d 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<P extends Entry<?>> implements Entry<P> {
35 @Override 35 @Override
36 public abstract ParentedEntry<P> withParent(P parent); 36 public abstract ParentedEntry<P> withParent(P parent);
37 37
38 @Override
39 public abstract ParentedEntry<P> withName(String name);
40
38 protected abstract ParentedEntry<P> translate(Translator translator, @Nullable EntryMapping mapping); 41 protected abstract ParentedEntry<P> translate(Translator translator, @Nullable EntryMapping mapping);
39 42
40 @Override 43 @Override