diff options
| author | 2019-02-23 19:42:00 +0200 | |
|---|---|---|
| committer | 2019-02-23 19:42:00 +0200 | |
| commit | bb20ce047a2e20866b9532c441c7433b1973ba5b (patch) | |
| tree | ed9f5bd596e43a1fffeef0b174c5370c039a9b62 /src/main/java/cuchaz/enigma/translation/mapping | |
| parent | Tweak inheritance and implementation tree generation (diff) | |
| download | enigma-fork-bb20ce047a2e20866b9532c441c7433b1973ba5b.tar.gz enigma-fork-bb20ce047a2e20866b9532c441c7433b1973ba5b.tar.xz enigma-fork-bb20ce047a2e20866b9532c441c7433b1973ba5b.zip | |
Fix #110 and remap indices with matched bridge method names
Diffstat (limited to 'src/main/java/cuchaz/enigma/translation/mapping')
15 files changed, 124 insertions, 105 deletions
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; | |||
| 3 | import cuchaz.enigma.translation.representation.entry.Entry; | 3 | import cuchaz.enigma.translation.representation.entry.Entry; |
| 4 | 4 | ||
| 5 | import javax.annotation.Nullable; | 5 | import javax.annotation.Nullable; |
| 6 | import java.util.Collection; | 6 | import java.util.stream.Stream; |
| 7 | 7 | ||
| 8 | public interface EntryMap<T> { | 8 | public 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 | ||
| 12 | import javax.annotation.Nullable; | 12 | import javax.annotation.Nullable; |
| 13 | import java.util.Collection; | 13 | import java.util.Collection; |
| 14 | import java.util.stream.Stream; | ||
| 14 | 15 | ||
| 15 | public class EntryRemapper { | 16 | public 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 | ||
| 3 | import cuchaz.enigma.translation.Translatable; | 3 | import cuchaz.enigma.translation.Translatable; |
| 4 | import cuchaz.enigma.translation.Translator; | 4 | import cuchaz.enigma.translation.Translator; |
| 5 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | ||
| 6 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 5 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 6 | import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; | ||
| 7 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | ||
| 7 | import cuchaz.enigma.translation.representation.entry.Entry; | 8 | import cuchaz.enigma.translation.representation.entry.Entry; |
| 8 | 9 | ||
| 10 | import java.util.stream.Stream; | ||
| 11 | |||
| 9 | public class MappingDelta<T> implements Translatable { | 12 | public 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 | ||
| 12 | package cuchaz.enigma.translation.mapping; | 12 | package cuchaz.enigma.translation.mapping; |
| 13 | 13 | ||
| 14 | import cuchaz.enigma.ProgressListener; | ||
| 14 | import cuchaz.enigma.analysis.index.JarIndex; | 15 | import cuchaz.enigma.analysis.index.JarIndex; |
| 15 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 16 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 16 | import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; | 17 | import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; |
| @@ -22,6 +23,7 @@ import cuchaz.enigma.translation.representation.entry.MethodEntry; | |||
| 22 | import java.util.Collection; | 23 | import java.util.Collection; |
| 23 | import java.util.HashMap; | 24 | import java.util.HashMap; |
| 24 | import java.util.Map; | 25 | import java.util.Map; |
| 26 | import java.util.stream.Collectors; | ||
| 25 | 27 | ||
| 26 | public class MappingsChecker { | 28 | public 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 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping.serde; | 1 | package cuchaz.enigma.translation.mapping.serde; |
| 2 | 2 | ||
| 3 | import com.google.common.base.Charsets; | 3 | import com.google.common.base.Charsets; |
| 4 | import cuchaz.enigma.ProgressListener; | ||
| 4 | import cuchaz.enigma.throwables.MappingParseException; | 5 | import cuchaz.enigma.throwables.MappingParseException; |
| 5 | import cuchaz.enigma.translation.mapping.AccessModifier; | 6 | import cuchaz.enigma.translation.mapping.AccessModifier; |
| 6 | import cuchaz.enigma.translation.mapping.EntryMapping; | 7 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 7 | import cuchaz.enigma.translation.mapping.MappingPair; | 8 | import cuchaz.enigma.translation.mapping.MappingPair; |
| 8 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | ||
| 9 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 9 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 10 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | ||
| 10 | import cuchaz.enigma.translation.representation.MethodDescriptor; | 11 | import cuchaz.enigma.translation.representation.MethodDescriptor; |
| 11 | import cuchaz.enigma.translation.representation.TypeDescriptor; | 12 | import cuchaz.enigma.translation.representation.TypeDescriptor; |
| 12 | import cuchaz.enigma.translation.representation.entry.*; | 13 | import cuchaz.enigma.translation.representation.entry.*; |
| @@ -24,22 +25,32 @@ import java.util.stream.Collectors; | |||
| 24 | public enum EnigmaMappingsReader implements MappingsReader { | 25 | public 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; | |||
| 28 | import java.nio.file.Paths; | 28 | import java.nio.file.Paths; |
| 29 | import java.util.ArrayList; | 29 | import java.util.ArrayList; |
| 30 | import java.util.Collection; | 30 | import java.util.Collection; |
| 31 | import java.util.Objects; | ||
| 31 | import java.util.concurrent.atomic.AtomicInteger; | 32 | import java.util.concurrent.atomic.AtomicInteger; |
| 32 | import java.util.stream.Collectors; | 33 | import 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 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping.serde; | 1 | package cuchaz.enigma.translation.mapping.serde; |
| 2 | 2 | ||
| 3 | import cuchaz.enigma.ProgressListener; | ||
| 3 | import cuchaz.enigma.throwables.MappingParseException; | 4 | import cuchaz.enigma.throwables.MappingParseException; |
| 4 | import cuchaz.enigma.translation.mapping.EntryMapping; | 5 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 5 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 6 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| @@ -8,5 +9,5 @@ import java.io.IOException; | |||
| 8 | import java.nio.file.Path; | 9 | import java.nio.file.Path; |
| 9 | 10 | ||
| 10 | public interface MappingsReader { | 11 | public 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 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping.serde; | 1 | package cuchaz.enigma.translation.mapping.serde; |
| 2 | 2 | ||
| 3 | import com.google.common.base.Charsets; | 3 | import com.google.common.base.Charsets; |
| 4 | import cuchaz.enigma.ProgressListener; | ||
| 4 | import cuchaz.enigma.throwables.MappingParseException; | 5 | import cuchaz.enigma.throwables.MappingParseException; |
| 5 | import cuchaz.enigma.translation.mapping.EntryMapping; | 6 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 6 | import cuchaz.enigma.translation.mapping.MappingPair; | 7 | import cuchaz.enigma.translation.mapping.MappingPair; |
| 7 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | ||
| 8 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 8 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 9 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | ||
| 9 | import cuchaz.enigma.translation.representation.MethodDescriptor; | 10 | import cuchaz.enigma.translation.representation.MethodDescriptor; |
| 10 | import cuchaz.enigma.translation.representation.TypeDescriptor; | 11 | import cuchaz.enigma.translation.representation.TypeDescriptor; |
| 11 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 12 | import 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; | |||
| 10 | import javax.annotation.Nullable; | 10 | import javax.annotation.Nullable; |
| 11 | import java.util.Collection; | 11 | import java.util.Collection; |
| 12 | import java.util.Iterator; | 12 | import java.util.Iterator; |
| 13 | import java.util.stream.Stream; | ||
| 13 | 14 | ||
| 14 | public class DeltaTrackingTree<T> implements EntryTree<T> { | 15 | public 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 | ||
| 10 | import javax.annotation.Nullable; | 10 | import javax.annotation.Nullable; |
| 11 | import java.util.Collection; | 11 | import java.util.Collection; |
| 12 | import java.util.stream.Stream; | ||
| 12 | 13 | ||
| 13 | public interface EntryTree<T> extends EntryMap<T>, Iterable<EntryTreeNode<T>>, Translatable { | 14 | public 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 | ||
| 9 | import javax.annotation.Nullable; | 9 | import javax.annotation.Nullable; |
| 10 | import java.util.*; | 10 | import java.util.*; |
| 11 | import java.util.stream.Collectors; | 11 | import java.util.function.Function; |
| 12 | import java.util.stream.Stream; | ||
| 13 | import java.util.stream.StreamSupport; | ||
| 12 | 14 | ||
| 13 | public class HashEntryTree<T> implements EntryTree<T> { | 15 | public 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; |