diff options
| author | 2021-07-08 16:30:39 +0200 | |
|---|---|---|
| committer | 2021-07-08 16:30:39 +0200 | |
| commit | 8efb62490ec153246d467a1a72c513781db887bf (patch) | |
| tree | 0f2eedd97d9c0d95544ff7d24f2b479cf10271fe /enigma/src/main/java/cuchaz | |
| parent | Add --single-class-tree argument that puts all classes into deobf panel & hid... (diff) | |
| download | enigma-fork-8efb62490ec153246d467a1a72c513781db887bf.tar.gz enigma-fork-8efb62490ec153246d467a1a72c513781db887bf.tar.xz enigma-fork-8efb62490ec153246d467a1a72c513781db887bf.zip | |
Entry Changes (#364)
* Initial refactor: Allow EntryMapping to have null targetName, add EntryChange in favor of entry changing methods in GuiController
* Fix resetting name not actually removing it, and renaming a class causing name collisions with itself
Closes #246.
* Use name proposer for setting default deobf name
Closes #314
* Make network protocol use EntryChange directly
* Handle writing other data correctly when the deobf name is null
* b
* Add some new abstraction stuff
* Use pattern matching instanceof
* Move classes out of newabstraction package
* Make EntryChange final
* Regenerate equals and hashCode
* Convert EntryMapping to record
* Make TristateChange final
* Safety guard null accessModifier initialization
Diffstat (limited to 'enigma/src/main/java/cuchaz')
29 files changed, 486 insertions, 256 deletions
diff --git a/enigma/src/main/java/cuchaz/enigma/source/DecompiledClassSource.java b/enigma/src/main/java/cuchaz/enigma/source/DecompiledClassSource.java index 9ac611f..5f371a5 100644 --- a/enigma/src/main/java/cuchaz/enigma/source/DecompiledClassSource.java +++ b/enigma/src/main/java/cuchaz/enigma/source/DecompiledClassSource.java | |||
| @@ -79,7 +79,7 @@ public class DecompiledClassSource { | |||
| 79 | return null; | 79 | return null; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | private Optional<String> proposeName(EnigmaProject project, Entry<?> entry) { | 82 | public static Optional<String> proposeName(EnigmaProject project, Entry<?> entry) { |
| 83 | EnigmaServices services = project.getEnigma().getServices(); | 83 | EnigmaServices services = project.getEnigma().getServices(); |
| 84 | 84 | ||
| 85 | return services.get(NameProposalService.TYPE).stream().flatMap(nameProposalService -> { | 85 | return services.get(NameProposalService.TYPE).stream().flatMap(nameProposalService -> { |
diff --git a/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java b/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java index b85851f..4e8940a 100644 --- a/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java +++ b/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java | |||
| @@ -148,7 +148,7 @@ public class EnigmaDumper extends StringStreamDumper { | |||
| 148 | continue; | 148 | continue; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | String javaDoc = mapping.getJavadoc(); | 151 | String javaDoc = mapping.javadoc(); |
| 152 | if (javaDoc != null) { | 152 | if (javaDoc != null) { |
| 153 | recordComponentDocs.add(String.format("@param %s %s", field.getFieldName(), javaDoc)); | 153 | recordComponentDocs.add(String.format("@param %s %s", field.getFieldName(), javaDoc)); |
| 154 | } | 154 | } |
| @@ -159,7 +159,7 @@ public class EnigmaDumper extends StringStreamDumper { | |||
| 159 | 159 | ||
| 160 | String javadoc = null; | 160 | String javadoc = null; |
| 161 | if (mapping != null) { | 161 | if (mapping != null) { |
| 162 | javadoc = mapping.getJavadoc(); | 162 | javadoc = mapping.javadoc(); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | if (javadoc != null || !recordComponentDocs.isEmpty()) { | 165 | if (javadoc != null || !recordComponentDocs.isEmpty()) { |
| @@ -191,7 +191,7 @@ public class EnigmaDumper extends StringStreamDumper { | |||
| 191 | MethodEntry methodEntry = getMethodEntry(method); | 191 | MethodEntry methodEntry = getMethodEntry(method); |
| 192 | EntryMapping mapping = mapper.getDeobfMapping(methodEntry); | 192 | EntryMapping mapping = mapper.getDeobfMapping(methodEntry); |
| 193 | if (mapping != null) { | 193 | if (mapping != null) { |
| 194 | String javadoc = mapping.getJavadoc(); | 194 | String javadoc = mapping.javadoc(); |
| 195 | if (javadoc != null) { | 195 | if (javadoc != null) { |
| 196 | lines.addAll(Arrays.asList(javadoc.split("\\R"))); | 196 | lines.addAll(Arrays.asList(javadoc.split("\\R"))); |
| 197 | } | 197 | } |
| @@ -204,9 +204,9 @@ public class EnigmaDumper extends StringStreamDumper { | |||
| 204 | if (each instanceof LocalVariableEntry) { | 204 | if (each instanceof LocalVariableEntry) { |
| 205 | EntryMapping paramMapping = mapper.getDeobfMapping(each); | 205 | EntryMapping paramMapping = mapper.getDeobfMapping(each); |
| 206 | if (paramMapping != null) { | 206 | if (paramMapping != null) { |
| 207 | String javadoc = paramMapping.getJavadoc(); | 207 | String javadoc = paramMapping.javadoc(); |
| 208 | if (javadoc != null) { | 208 | if (javadoc != null) { |
| 209 | lines.addAll(Arrays.asList(("@param " + paramMapping.getTargetName() + " " + javadoc).split("\\R"))); | 209 | lines.addAll(Arrays.asList(("@param " + paramMapping.targetName() + " " + javadoc).split("\\R"))); |
| 210 | } | 210 | } |
| 211 | } | 211 | } |
| 212 | } | 212 | } |
| @@ -230,7 +230,7 @@ public class EnigmaDumper extends StringStreamDumper { | |||
| 230 | if (mapper != null && !recordComponent) { | 230 | if (mapper != null && !recordComponent) { |
| 231 | EntryMapping mapping = mapper.getDeobfMapping(getFieldEntry(owner, field.getFieldName(), field.getDescriptor())); | 231 | EntryMapping mapping = mapper.getDeobfMapping(getFieldEntry(owner, field.getFieldName(), field.getDescriptor())); |
| 232 | if (mapping != null) { | 232 | if (mapping != null) { |
| 233 | String javadoc = mapping.getJavadoc(); | 233 | String javadoc = mapping.javadoc(); |
| 234 | if (javadoc != null) { | 234 | if (javadoc != null) { |
| 235 | print("/**").newln(); | 235 | print("/**").newln(); |
| 236 | for (String line : javadoc.split("\\R")) { | 236 | for (String line : javadoc.split("\\R")) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/source/procyon/transformers/AddJavadocsAstTransform.java b/enigma/src/main/java/cuchaz/enigma/source/procyon/transformers/AddJavadocsAstTransform.java index 70fc8c6..1e5beb1 100644 --- a/enigma/src/main/java/cuchaz/enigma/source/procyon/transformers/AddJavadocsAstTransform.java +++ b/enigma/src/main/java/cuchaz/enigma/source/procyon/transformers/AddJavadocsAstTransform.java | |||
| @@ -47,16 +47,17 @@ public final class AddJavadocsAstTransform implements IAstTransform { | |||
| 47 | 47 | ||
| 48 | private <T extends AstNode> Comment[] getComments(T node, Function<T, Entry<?>> retriever) { | 48 | private <T extends AstNode> Comment[] getComments(T node, Function<T, Entry<?>> retriever) { |
| 49 | final EntryMapping mapping = remapper.getDeobfMapping(retriever.apply(node)); | 49 | final EntryMapping mapping = remapper.getDeobfMapping(retriever.apply(node)); |
| 50 | final String docs = mapping == null ? null : Strings.emptyToNull(mapping.getJavadoc()); | 50 | final String docs = Strings.emptyToNull(mapping.javadoc()); |
| 51 | return docs == null ? null : Stream.of(docs.split("\\R")).map(st -> new Comment(st, | 51 | return docs == null ? null : Stream.of(docs.split("\\R")).map(st -> new Comment(st, |
| 52 | CommentType.Documentation)).toArray(Comment[]::new); | 52 | CommentType.Documentation)).toArray(Comment[]::new); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | private Comment[] getParameterComments(ParameterDeclaration node, Function<ParameterDeclaration, Entry<?>> retriever) { | 55 | private Comment[] getParameterComments(ParameterDeclaration node, Function<ParameterDeclaration, Entry<?>> retriever) { |
| 56 | final EntryMapping mapping = remapper.getDeobfMapping(retriever.apply(node)); | 56 | Entry<?> entry = retriever.apply(node); |
| 57 | final EntryMapping mapping = remapper.getDeobfMapping(entry); | ||
| 57 | final Comment[] ret = getComments(node, retriever); | 58 | final Comment[] ret = getComments(node, retriever); |
| 58 | if (ret != null) { | 59 | if (ret != null) { |
| 59 | final String paramPrefix = "@param " + mapping.getTargetName() + " "; | 60 | final String paramPrefix = "@param " + (mapping.targetName() != null ? mapping.targetName() : entry.getName()) + " "; |
| 60 | final String indent = Strings.repeat(" ", paramPrefix.length()); | 61 | final String indent = Strings.repeat(" ", paramPrefix.length()); |
| 61 | ret[0].setContent(paramPrefix + ret[0].getContent()); | 62 | ret[0].setContent(paramPrefix + ret[0].getContent()); |
| 62 | for (int i = 1; i < ret.length; i++) { | 63 | for (int i = 1; i < ret.length; i++) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryChange.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryChange.java new file mode 100644 index 0000000..b5ec855 --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryChange.java | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping; | ||
| 2 | |||
| 3 | import java.util.Objects; | ||
| 4 | import java.util.Optional; | ||
| 5 | |||
| 6 | import javax.annotation.Nullable; | ||
| 7 | |||
| 8 | import cuchaz.enigma.EnigmaProject; | ||
| 9 | import cuchaz.enigma.source.DecompiledClassSource; | ||
| 10 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 11 | import cuchaz.enigma.utils.TristateChange; | ||
| 12 | |||
| 13 | public final class EntryChange<E extends Entry<?>> { | ||
| 14 | |||
| 15 | private final E target; | ||
| 16 | private final TristateChange<String> deobfName; | ||
| 17 | private final TristateChange<String> javadoc; | ||
| 18 | private final TristateChange<AccessModifier> access; | ||
| 19 | |||
| 20 | private EntryChange(E target, TristateChange<String> deobfName, TristateChange<String> javadoc, TristateChange<AccessModifier> access) { | ||
| 21 | this.target = target; | ||
| 22 | this.deobfName = deobfName; | ||
| 23 | this.javadoc = javadoc; | ||
| 24 | this.access = access; | ||
| 25 | } | ||
| 26 | |||
| 27 | public static <E extends Entry<?>> EntryChange<E> modify(E target) { | ||
| 28 | return new EntryChange<>(target, TristateChange.unchanged(), TristateChange.unchanged(), TristateChange.unchanged()); | ||
| 29 | } | ||
| 30 | |||
| 31 | public EntryChange<E> withDeobfName(String name) { | ||
| 32 | return new EntryChange<>(this.target, TristateChange.set(name), this.javadoc, this.access); | ||
| 33 | } | ||
| 34 | |||
| 35 | public EntryChange<E> withDefaultDeobfName(@Nullable EnigmaProject project) { | ||
| 36 | Optional<String> proposed = project != null ? DecompiledClassSource.proposeName(project, this.target) : Optional.empty(); | ||
| 37 | return this.withDeobfName(proposed.orElse(this.target.getName())); | ||
| 38 | } | ||
| 39 | |||
| 40 | public EntryChange<E> clearDeobfName() { | ||
| 41 | return new EntryChange<>(this.target, TristateChange.reset(), this.javadoc, this.access); | ||
| 42 | } | ||
| 43 | |||
| 44 | public EntryChange<E> withJavadoc(String javadoc) { | ||
| 45 | return new EntryChange<>(this.target, this.deobfName, TristateChange.set(javadoc), this.access); | ||
| 46 | } | ||
| 47 | |||
| 48 | public EntryChange<E> clearJavadoc() { | ||
| 49 | return new EntryChange<>(this.target, this.deobfName, TristateChange.reset(), this.access); | ||
| 50 | } | ||
| 51 | |||
| 52 | public EntryChange<E> withAccess(AccessModifier access) { | ||
| 53 | return new EntryChange<>(this.target, this.deobfName, this.javadoc, TristateChange.set(access)); | ||
| 54 | } | ||
| 55 | |||
| 56 | public EntryChange<E> clearAccess() { | ||
| 57 | return new EntryChange<>(this.target, this.deobfName, this.javadoc, TristateChange.reset()); | ||
| 58 | } | ||
| 59 | |||
| 60 | public TristateChange<String> getDeobfName() { | ||
| 61 | return this.deobfName; | ||
| 62 | } | ||
| 63 | |||
| 64 | public TristateChange<String> getJavadoc() { | ||
| 65 | return this.javadoc; | ||
| 66 | } | ||
| 67 | |||
| 68 | public TristateChange<AccessModifier> getAccess() { | ||
| 69 | return this.access; | ||
| 70 | } | ||
| 71 | |||
| 72 | public E getTarget() { | ||
| 73 | return this.target; | ||
| 74 | } | ||
| 75 | |||
| 76 | @Override | ||
| 77 | public boolean equals(Object o) { | ||
| 78 | if (this == o) return true; | ||
| 79 | if (!(o instanceof EntryChange)) return false; | ||
| 80 | EntryChange<?> that = (EntryChange<?>) o; | ||
| 81 | return Objects.equals(this.target, that.target) && | ||
| 82 | Objects.equals(this.deobfName, that.deobfName) && | ||
| 83 | Objects.equals(this.javadoc, that.javadoc) && | ||
| 84 | Objects.equals(this.access, that.access); | ||
| 85 | } | ||
| 86 | |||
| 87 | @Override | ||
| 88 | public int hashCode() { | ||
| 89 | return Objects.hash(this.target, this.deobfName, this.javadoc, this.access); | ||
| 90 | } | ||
| 91 | |||
| 92 | @Override | ||
| 93 | public String toString() { | ||
| 94 | return String.format("EntryChange { target: %s, deobfName: %s, javadoc: %s, access: %s }", this.target, this.deobfName, this.javadoc, this.access); | ||
| 95 | } | ||
| 96 | |||
| 97 | } | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java index c607817..e916bf3 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java | |||
| @@ -1,49 +1,37 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping; | 1 | package cuchaz.enigma.translation.mapping; |
| 2 | 2 | ||
| 3 | import java.util.Arrays; | ||
| 4 | |||
| 3 | import javax.annotation.Nonnull; | 5 | import javax.annotation.Nonnull; |
| 4 | import javax.annotation.Nullable; | 6 | import javax.annotation.Nullable; |
| 5 | 7 | ||
| 6 | public class EntryMapping { | 8 | public record EntryMapping( |
| 7 | private final String targetName; | 9 | @Nullable String targetName, |
| 8 | private final AccessModifier accessModifier; | 10 | @Nonnull AccessModifier accessModifier, |
| 9 | private final @Nullable String javadoc; | 11 | @Nullable String javadoc |
| 12 | ) { | ||
| 13 | public static final EntryMapping DEFAULT = new EntryMapping(null, AccessModifier.UNCHANGED, null); | ||
| 14 | |||
| 15 | public EntryMapping { | ||
| 16 | if (accessModifier == null) { | ||
| 17 | accessModifier = AccessModifier.UNCHANGED; | ||
| 18 | System.err.println("EntryMapping initialized with 'null' accessModifier, assuming UNCHANGED. Please fix."); | ||
| 19 | Arrays.stream(new Exception().getStackTrace()).skip(1).map("\tat %s"::formatted).forEach(System.err::println); | ||
| 20 | } | ||
| 21 | } | ||
| 10 | 22 | ||
| 11 | public EntryMapping(@Nonnull String targetName) { | 23 | public EntryMapping(@Nullable String targetName) { |
| 12 | this(targetName, AccessModifier.UNCHANGED); | 24 | this(targetName, AccessModifier.UNCHANGED); |
| 13 | } | 25 | } |
| 14 | 26 | ||
| 15 | public EntryMapping(@Nonnull String targetName, @Nullable String javadoc) { | 27 | public EntryMapping(@Nullable String targetName, @Nullable String javadoc) { |
| 16 | this(targetName, AccessModifier.UNCHANGED, javadoc); | 28 | this(targetName, AccessModifier.UNCHANGED, javadoc); |
| 17 | } | 29 | } |
| 18 | 30 | ||
| 19 | public EntryMapping(@Nonnull String targetName, AccessModifier accessModifier) { | 31 | public EntryMapping(@Nullable String targetName, AccessModifier accessModifier) { |
| 20 | this(targetName, accessModifier, null); | 32 | this(targetName, accessModifier, null); |
| 21 | } | 33 | } |
| 22 | 34 | ||
| 23 | public EntryMapping(@Nonnull String targetName, AccessModifier accessModifier, @Nullable String javadoc) { | ||
| 24 | this.targetName = targetName; | ||
| 25 | this.accessModifier = accessModifier; | ||
| 26 | this.javadoc = javadoc; | ||
| 27 | } | ||
| 28 | |||
| 29 | @Nonnull | ||
| 30 | public String getTargetName() { | ||
| 31 | return targetName; | ||
| 32 | } | ||
| 33 | |||
| 34 | @Nonnull | ||
| 35 | public AccessModifier getAccessModifier() { | ||
| 36 | if (accessModifier == null) { | ||
| 37 | return AccessModifier.UNCHANGED; | ||
| 38 | } | ||
| 39 | return accessModifier; | ||
| 40 | } | ||
| 41 | |||
| 42 | @Nullable | ||
| 43 | public String getJavadoc() { | ||
| 44 | return javadoc; | ||
| 45 | } | ||
| 46 | |||
| 47 | public EntryMapping withName(String newName) { | 35 | public EntryMapping withName(String newName) { |
| 48 | return new EntryMapping(newName, accessModifier, javadoc); | 36 | return new EntryMapping(newName, accessModifier, javadoc); |
| 49 | } | 37 | } |
| @@ -55,21 +43,4 @@ public class EntryMapping { | |||
| 55 | public EntryMapping withDocs(String newDocs) { | 43 | public EntryMapping withDocs(String newDocs) { |
| 56 | return new EntryMapping(targetName, accessModifier, newDocs); | 44 | return new EntryMapping(targetName, accessModifier, newDocs); |
| 57 | } | 45 | } |
| 58 | |||
| 59 | @Override | ||
| 60 | public boolean equals(Object obj) { | ||
| 61 | if (obj == this) return true; | ||
| 62 | |||
| 63 | if (obj instanceof EntryMapping) { | ||
| 64 | EntryMapping mapping = (EntryMapping) obj; | ||
| 65 | return mapping.targetName.equals(targetName) && mapping.accessModifier.equals(accessModifier); | ||
| 66 | } | ||
| 67 | |||
| 68 | return false; | ||
| 69 | } | ||
| 70 | |||
| 71 | @Override | ||
| 72 | public int hashCode() { | ||
| 73 | return targetName.hashCode() + accessModifier.hashCode() * 31; | ||
| 74 | } | ||
| 75 | } | 46 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java index 8b5490e..0977b74 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping; | 1 | package cuchaz.enigma.translation.mapping; |
| 2 | 2 | ||
| 3 | import java.util.Collection; | 3 | import java.util.Collection; |
| 4 | import java.util.Objects; | ||
| 4 | import java.util.List; | 5 | import java.util.List; |
| 5 | import java.util.stream.Stream; | 6 | import java.util.stream.Stream; |
| 6 | 7 | ||
| 7 | import javax.annotation.Nullable; | 8 | import javax.annotation.Nonnull; |
| 8 | 9 | ||
| 9 | import cuchaz.enigma.analysis.index.JarIndex; | 10 | import cuchaz.enigma.analysis.index.JarIndex; |
| 10 | import cuchaz.enigma.translation.MappingTranslator; | 11 | import cuchaz.enigma.translation.MappingTranslator; |
| @@ -50,15 +51,15 @@ public class EntryRemapper { | |||
| 50 | return new EntryRemapper(index, new HashEntryTree<>()); | 51 | return new EntryRemapper(index, new HashEntryTree<>()); |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | public <E extends Entry<?>> void mapFromObf(ValidationContext vc, E obfuscatedEntry, @Nullable EntryMapping deobfMapping) { | 54 | public void validatePutMapping(ValidationContext vc, Entry<?> obfuscatedEntry, @Nonnull EntryMapping deobfMapping) { |
| 54 | mapFromObf(vc, obfuscatedEntry, deobfMapping, true); | 55 | doPutMapping(vc, obfuscatedEntry, deobfMapping, true); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | public <E extends Entry<?>> void mapFromObf(ValidationContext vc, E obfuscatedEntry, @Nullable EntryMapping deobfMapping, boolean renaming) { | 58 | public void putMapping(ValidationContext vc, Entry<?> obfuscatedEntry, @Nonnull EntryMapping deobfMapping) { |
| 58 | mapFromObf(vc, obfuscatedEntry, deobfMapping, renaming, false); | 59 | doPutMapping(vc, obfuscatedEntry, deobfMapping, false); |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | public <E extends Entry<?>> void mapFromObf(ValidationContext vc, E obfuscatedEntry, @Nullable EntryMapping deobfMapping, boolean renaming, boolean validateOnly) { | 62 | private void doPutMapping(ValidationContext vc, Entry<?> obfuscatedEntry, @Nonnull EntryMapping deobfMapping, boolean validateOnly) { |
| 62 | if (obfuscatedEntry instanceof FieldEntry) { | 63 | if (obfuscatedEntry instanceof FieldEntry) { |
| 63 | FieldEntry fieldEntry = (FieldEntry) obfuscatedEntry; | 64 | FieldEntry fieldEntry = (FieldEntry) obfuscatedEntry; |
| 64 | ClassEntry classEntry = fieldEntry.getParent(); | 65 | ClassEntry classEntry = fieldEntry.getParent(); |
| @@ -66,25 +67,27 @@ public class EntryRemapper { | |||
| 66 | mapRecordComponentGetter(vc, classEntry, fieldEntry, deobfMapping); | 67 | mapRecordComponentGetter(vc, classEntry, fieldEntry, deobfMapping); |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | Collection<E> resolvedEntries = obfResolver.resolveEntry(obfuscatedEntry, renaming ? ResolutionStrategy.RESOLVE_ROOT : ResolutionStrategy.RESOLVE_CLOSEST); | 70 | boolean renaming = !Objects.equals(getDeobfMapping(obfuscatedEntry).targetName(), deobfMapping.targetName()); |
| 70 | 71 | ||
| 71 | if (renaming && deobfMapping != null) { | 72 | Collection<Entry<?>> resolvedEntries = obfResolver.resolveEntry(obfuscatedEntry, renaming ? ResolutionStrategy.RESOLVE_ROOT : ResolutionStrategy.RESOLVE_CLOSEST); |
| 72 | for (E resolvedEntry : resolvedEntries) { | 73 | |
| 73 | validator.validateRename(vc, resolvedEntry, deobfMapping.getTargetName()); | 74 | if (renaming && deobfMapping.targetName() != null) { |
| 75 | for (Entry<?> resolvedEntry : resolvedEntries) { | ||
| 76 | validator.validateRename(vc, resolvedEntry, deobfMapping.targetName()); | ||
| 74 | } | 77 | } |
| 75 | } | 78 | } |
| 76 | 79 | ||
| 77 | if (validateOnly || !vc.canProceed()) return; | 80 | if (validateOnly || !vc.canProceed()) return; |
| 78 | 81 | ||
| 79 | for (E resolvedEntry : resolvedEntries) { | 82 | for (Entry<?> resolvedEntry : resolvedEntries) { |
| 80 | obfToDeobf.insert(resolvedEntry, deobfMapping); | 83 | if (deobfMapping.equals(EntryMapping.DEFAULT)) { |
| 84 | obfToDeobf.insert(resolvedEntry, null); | ||
| 85 | } else { | ||
| 86 | obfToDeobf.insert(resolvedEntry, deobfMapping); | ||
| 87 | } | ||
| 81 | } | 88 | } |
| 82 | } | 89 | } |
| 83 | 90 | ||
| 84 | public void removeByObf(ValidationContext vc, Entry<?> obfuscatedEntry) { | ||
| 85 | mapFromObf(vc, obfuscatedEntry, null); | ||
| 86 | } | ||
| 87 | |||
| 88 | // A little bit of a hack to also map the getter method for record fields/components. | 91 | // A little bit of a hack to also map the getter method for record fields/components. |
| 89 | private void mapRecordComponentGetter(ValidationContext vc, ClassEntry classEntry, FieldEntry fieldEntry, EntryMapping fieldMapping) { | 92 | private void mapRecordComponentGetter(ValidationContext vc, ClassEntry classEntry, FieldEntry fieldEntry, EntryMapping fieldMapping) { |
| 90 | if (!jarIndex.getEntryIndex().getClassAccess(classEntry).isRecord() || jarIndex.getEntryIndex().getFieldAccess(fieldEntry).isStatic()) { | 93 | if (!jarIndex.getEntryIndex().getClassAccess(classEntry).isRecord() || jarIndex.getEntryIndex().getFieldAccess(fieldEntry).isStatic()) { |
| @@ -107,20 +110,17 @@ public class EntryRemapper { | |||
| 107 | } | 110 | } |
| 108 | 111 | ||
| 109 | if (methodEntry == null && fieldMapping != null) { | 112 | if (methodEntry == null && fieldMapping != null) { |
| 110 | vc.raise(Message.UNKNOWN_RECORD_GETTER, fieldMapping.getTargetName()); | 113 | vc.raise(Message.UNKNOWN_RECORD_GETTER, fieldMapping.targetName()); |
| 111 | return; | 114 | return; |
| 112 | } | 115 | } |
| 113 | 116 | ||
| 114 | mapFromObf(vc, methodEntry, fieldMapping != null ? new EntryMapping(fieldMapping.getTargetName()) : null); | 117 | putMapping(vc, methodEntry, fieldMapping != null ? new EntryMapping(fieldMapping.targetName()) : null); |
| 115 | } | 118 | } |
| 116 | 119 | ||
| 117 | @Nullable | 120 | @Nonnull |
| 118 | public EntryMapping getDeobfMapping(Entry<?> entry) { | 121 | public EntryMapping getDeobfMapping(Entry<?> entry) { |
| 119 | return obfToDeobf.get(entry); | 122 | EntryMapping entryMapping = obfToDeobf.get(entry); |
| 120 | } | 123 | return entryMapping == null ? EntryMapping.DEFAULT : entryMapping; |
| 121 | |||
| 122 | public boolean hasDeobfMapping(Entry<?> obfEntry) { | ||
| 123 | return obfToDeobf.contains(obfEntry); | ||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | public <T extends Translatable> TranslateResult<T> extendedDeobfuscate(T translatable) { | 126 | public <T extends Translatable> TranslateResult<T> extendedDeobfuscate(T translatable) { |
| @@ -158,4 +158,9 @@ public class EntryRemapper { | |||
| 158 | public EntryResolver getObfResolver() { | 158 | public EntryResolver getObfResolver() { |
| 159 | return obfResolver; | 159 | return obfResolver; |
| 160 | } | 160 | } |
| 161 | |||
| 162 | public MappingValidator getValidator() { | ||
| 163 | return validator; | ||
| 164 | } | ||
| 165 | |||
| 161 | } | 166 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryUtil.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryUtil.java new file mode 100644 index 0000000..582076c --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/EntryUtil.java | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping; | ||
| 2 | |||
| 3 | import javax.annotation.Nonnull; | ||
| 4 | |||
| 5 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 6 | import cuchaz.enigma.utils.validation.ValidationContext; | ||
| 7 | |||
| 8 | public class EntryUtil { | ||
| 9 | |||
| 10 | public static EntryMapping applyChange(ValidationContext vc, EntryRemapper remapper, EntryChange<?> change) { | ||
| 11 | Entry<?> target = change.getTarget(); | ||
| 12 | EntryMapping prev = remapper.getDeobfMapping(target); | ||
| 13 | EntryMapping mapping = EntryUtil.applyChange(prev, change); | ||
| 14 | |||
| 15 | remapper.putMapping(vc, target, mapping); | ||
| 16 | |||
| 17 | return mapping; | ||
| 18 | } | ||
| 19 | |||
| 20 | public static EntryMapping applyChange(@Nonnull EntryMapping self, EntryChange<?> change) { | ||
| 21 | if (change.getDeobfName().isSet()) { | ||
| 22 | self = self.withName(change.getDeobfName().getNewValue()); | ||
| 23 | } else if (change.getDeobfName().isReset()) { | ||
| 24 | self = self.withName(null); | ||
| 25 | } | ||
| 26 | |||
| 27 | if (change.getJavadoc().isSet()) { | ||
| 28 | self = self.withDocs(change.getJavadoc().getNewValue()); | ||
| 29 | } else if (change.getJavadoc().isReset()) { | ||
| 30 | self = self.withDocs(null); | ||
| 31 | } | ||
| 32 | |||
| 33 | if (change.getAccess().isSet()) { | ||
| 34 | self = self.withModifier(change.getAccess().getNewValue()); | ||
| 35 | } else if (change.getAccess().isReset()) { | ||
| 36 | self = self.withModifier(AccessModifier.UNCHANGED); | ||
| 37 | } | ||
| 38 | |||
| 39 | return self; | ||
| 40 | } | ||
| 41 | |||
| 42 | } | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java index 1615912..065e5c3 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java | |||
| @@ -25,18 +25,22 @@ public class MappingValidator { | |||
| 25 | this.index = index; | 25 | this.index = index; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | public void validateRename(ValidationContext vc, Entry<?> entry, String name) { | 28 | public boolean validateRename(ValidationContext vc, Entry<?> entry, String name) { |
| 29 | Collection<Entry<?>> equivalentEntries = index.getEntryResolver().resolveEquivalentEntries(entry); | 29 | Collection<Entry<?>> equivalentEntries = index.getEntryResolver().resolveEquivalentEntries(entry); |
| 30 | boolean error = false; | ||
| 30 | for (Entry<?> equivalentEntry : equivalentEntries) { | 31 | for (Entry<?> equivalentEntry : equivalentEntries) { |
| 31 | equivalentEntry.validateName(vc, name); | 32 | equivalentEntry.validateName(vc, name); |
| 32 | validateUnique(vc, equivalentEntry, name); | 33 | error |= validateUnique(vc, equivalentEntry, name); |
| 33 | } | 34 | } |
| 35 | return error; | ||
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | private void validateUnique(ValidationContext vc, Entry<?> entry, String name) { | 38 | private boolean validateUnique(ValidationContext vc, Entry<?> entry, String name) { |
| 37 | ClassEntry containingClass = entry.getContainingClass(); | 39 | ClassEntry containingClass = entry.getContainingClass(); |
| 38 | Collection<ClassEntry> relatedClasses = getRelatedClasses(containingClass); | 40 | Collection<ClassEntry> relatedClasses = getRelatedClasses(containingClass); |
| 39 | 41 | ||
| 42 | boolean error = false; | ||
| 43 | |||
| 40 | for (ClassEntry relatedClass : relatedClasses) { | 44 | for (ClassEntry relatedClass : relatedClasses) { |
| 41 | Entry<?> relatedEntry = entry.replaceAncestor(containingClass, relatedClass); | 45 | Entry<?> relatedEntry = entry.replaceAncestor(containingClass, relatedClass); |
| 42 | Entry<?> translatedEntry = deobfuscator.translate(relatedEntry); | 46 | Entry<?> translatedEntry = deobfuscator.translate(relatedEntry); |
| @@ -52,8 +56,11 @@ public class MappingValidator { | |||
| 52 | } else { | 56 | } else { |
| 53 | vc.raise(Message.NONUNIQUE_NAME, name); | 57 | vc.raise(Message.NONUNIQUE_NAME, name); |
| 54 | } | 58 | } |
| 59 | error = true; | ||
| 55 | } | 60 | } |
| 56 | } | 61 | } |
| 62 | |||
| 63 | return error; | ||
| 57 | } | 64 | } |
| 58 | 65 | ||
| 59 | private Collection<ClassEntry> getRelatedClasses(ClassEntry classEntry) { | 66 | private Collection<ClassEntry> getRelatedClasses(ClassEntry classEntry) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java index 141a07c..392b1a6 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java | |||
| @@ -75,7 +75,7 @@ public class MappingsChecker { | |||
| 75 | private final Map<Entry<?>, String> droppedMappings = new HashMap<>(); | 75 | private final Map<Entry<?>, String> droppedMappings = new HashMap<>(); |
| 76 | 76 | ||
| 77 | public void drop(Entry<?> entry, EntryMapping mapping) { | 77 | public void drop(Entry<?> entry, EntryMapping mapping) { |
| 78 | droppedMappings.put(entry, mapping.getTargetName()); | 78 | droppedMappings.put(entry, mapping.targetName() != null ? mapping.targetName() : entry.getName()); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | void apply(EntryTree<EntryMapping> mappings) { | 81 | void apply(EntryTree<EntryMapping> mappings) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java index 79587a0..6465008 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java | |||
| @@ -1,23 +1,23 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping.serde; | 1 | package cuchaz.enigma.translation.mapping.serde; |
| 2 | 2 | ||
| 3 | import cuchaz.enigma.translation.mapping.AccessModifier; | ||
| 4 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 5 | |||
| 6 | import java.util.ArrayList; | 3 | import java.util.ArrayList; |
| 7 | import java.util.List; | 4 | import java.util.List; |
| 8 | 5 | ||
| 6 | import cuchaz.enigma.translation.mapping.AccessModifier; | ||
| 7 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 8 | |||
| 9 | public final class RawEntryMapping { | 9 | public final class RawEntryMapping { |
| 10 | private final String targetName; | 10 | private final String targetName; |
| 11 | private final AccessModifier access; | 11 | private final AccessModifier access; |
| 12 | private List<String> javadocs = new ArrayList<>(); | 12 | private final List<String> javadocs = new ArrayList<>(); |
| 13 | 13 | ||
| 14 | public RawEntryMapping(String targetName) { | 14 | public RawEntryMapping(String targetName) { |
| 15 | this(targetName, null); | 15 | this(targetName, AccessModifier.UNCHANGED); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | public RawEntryMapping(String targetName, AccessModifier access) { | 18 | public RawEntryMapping(String targetName, AccessModifier access) { |
| 19 | this.access = access; | 19 | this.access = access; |
| 20 | this.targetName = targetName; | 20 | this.targetName = targetName != null && !targetName.equals("-") ? targetName : null; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | public void addJavadocLine(String line) { | 23 | public void addJavadocLine(String line) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java index 27545c0..ccc25df 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java | |||
| @@ -1,15 +1,21 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping.serde.enigma; | 1 | package cuchaz.enigma.translation.mapping.serde.enigma; |
| 2 | 2 | ||
| 3 | import java.io.IOException; | ||
| 4 | import java.nio.file.FileSystem; | ||
| 5 | import java.nio.file.FileSystems; | ||
| 6 | import java.nio.file.Files; | ||
| 7 | import java.nio.file.Path; | ||
| 8 | import java.util.*; | ||
| 9 | |||
| 10 | import javax.annotation.Nullable; | ||
| 11 | |||
| 3 | import com.google.common.base.Charsets; | 12 | import com.google.common.base.Charsets; |
| 13 | |||
| 4 | import cuchaz.enigma.ProgressListener; | 14 | import cuchaz.enigma.ProgressListener; |
| 5 | import cuchaz.enigma.translation.mapping.serde.MappingParseException; | ||
| 6 | import cuchaz.enigma.translation.mapping.AccessModifier; | 15 | import cuchaz.enigma.translation.mapping.AccessModifier; |
| 7 | import cuchaz.enigma.translation.mapping.EntryMapping; | 16 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 8 | import cuchaz.enigma.translation.mapping.MappingPair; | 17 | import cuchaz.enigma.translation.mapping.MappingPair; |
| 9 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; | 18 | import cuchaz.enigma.translation.mapping.serde.*; |
| 10 | import cuchaz.enigma.translation.mapping.serde.MappingHelper; | ||
| 11 | import cuchaz.enigma.translation.mapping.serde.MappingsReader; | ||
| 12 | import cuchaz.enigma.translation.mapping.serde.RawEntryMapping; | ||
| 13 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 19 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 14 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | 20 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; |
| 15 | import cuchaz.enigma.translation.representation.MethodDescriptor; | 21 | import cuchaz.enigma.translation.representation.MethodDescriptor; |
| @@ -17,18 +23,6 @@ import cuchaz.enigma.translation.representation.TypeDescriptor; | |||
| 17 | import cuchaz.enigma.translation.representation.entry.*; | 23 | import cuchaz.enigma.translation.representation.entry.*; |
| 18 | import cuchaz.enigma.utils.I18n; | 24 | import cuchaz.enigma.utils.I18n; |
| 19 | 25 | ||
| 20 | import javax.annotation.Nullable; | ||
| 21 | import java.io.IOException; | ||
| 22 | import java.nio.file.FileSystem; | ||
| 23 | import java.nio.file.FileSystems; | ||
| 24 | import java.nio.file.Files; | ||
| 25 | import java.nio.file.Path; | ||
| 26 | import java.util.ArrayDeque; | ||
| 27 | import java.util.Arrays; | ||
| 28 | import java.util.Deque; | ||
| 29 | import java.util.List; | ||
| 30 | import java.util.Locale; | ||
| 31 | |||
| 32 | public enum EnigmaMappingsReader implements MappingsReader { | 26 | public enum EnigmaMappingsReader implements MappingsReader { |
| 33 | FILE { | 27 | FILE { |
| 34 | @Override | 28 | @Override |
| @@ -200,12 +194,12 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 200 | throw new RuntimeException("Unknown token '" + keyToken + "'"); | 194 | throw new RuntimeException("Unknown token '" + keyToken + "'"); |
| 201 | } | 195 | } |
| 202 | } | 196 | } |
| 203 | 197 | ||
| 204 | private static void readJavadoc(MappingPair<?, RawEntryMapping> parent, String[] tokens) { | 198 | private static void readJavadoc(MappingPair<?, RawEntryMapping> parent, String[] tokens) { |
| 205 | if (parent == null) | 199 | if (parent == null) |
| 206 | throw new IllegalStateException("Javadoc has no parent!"); | 200 | throw new IllegalStateException("Javadoc has no parent!"); |
| 207 | // Empty string to concat | 201 | // Empty string to concat |
| 208 | String jdLine = tokens.length > 1 ? String.join(" ", Arrays.copyOfRange(tokens,1,tokens.length)) : ""; | 202 | String jdLine = tokens.length > 1 ? String.join(" ", Arrays.copyOfRange(tokens, 1, tokens.length)) : ""; |
| 209 | if (parent.getMapping() == null) { | 203 | if (parent.getMapping() == null) { |
| 210 | parent.setMapping(new RawEntryMapping(parent.getEntry().getName(), AccessModifier.UNCHANGED)); | 204 | parent.setMapping(new RawEntryMapping(parent.getEntry().getName(), AccessModifier.UNCHANGED)); |
| 211 | } | 205 | } |
| @@ -237,11 +231,7 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 237 | modifier = parseModifier(tokens[3]); | 231 | modifier = parseModifier(tokens[3]); |
| 238 | } | 232 | } |
| 239 | 233 | ||
| 240 | if (mapping != null) { | 234 | return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); |
| 241 | return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); | ||
| 242 | } else { | ||
| 243 | return new MappingPair<>(obfuscatedEntry); | ||
| 244 | } | ||
| 245 | } | 235 | } |
| 246 | 236 | ||
| 247 | private static MappingPair<FieldEntry, RawEntryMapping> parseField(@Nullable Entry<?> parent, String[] tokens) { | 237 | private static MappingPair<FieldEntry, RawEntryMapping> parseField(@Nullable Entry<?> parent, String[] tokens) { |
| @@ -252,7 +242,7 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 252 | ClassEntry ownerEntry = (ClassEntry) parent; | 242 | ClassEntry ownerEntry = (ClassEntry) parent; |
| 253 | 243 | ||
| 254 | String obfuscatedName = tokens[1]; | 244 | String obfuscatedName = tokens[1]; |
| 255 | String mapping = obfuscatedName; | 245 | String mapping = null; |
| 256 | AccessModifier modifier = AccessModifier.UNCHANGED; | 246 | AccessModifier modifier = AccessModifier.UNCHANGED; |
| 257 | TypeDescriptor descriptor; | 247 | TypeDescriptor descriptor; |
| 258 | 248 | ||
| @@ -269,19 +259,15 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 269 | descriptor = new TypeDescriptor(tokens[3]); | 259 | descriptor = new TypeDescriptor(tokens[3]); |
| 270 | } | 260 | } |
| 271 | } else if (tokens.length == 5) { | 261 | } else if (tokens.length == 5) { |
| 272 | descriptor = new TypeDescriptor(tokens[3]); | ||
| 273 | mapping = tokens[2]; | 262 | mapping = tokens[2]; |
| 274 | modifier = parseModifier(tokens[4]); | 263 | modifier = parseModifier(tokens[3]); |
| 264 | descriptor = new TypeDescriptor(tokens[4]); | ||
| 275 | } else { | 265 | } else { |
| 276 | throw new RuntimeException("Invalid field declaration"); | 266 | throw new RuntimeException("Invalid field declaration"); |
| 277 | } | 267 | } |
| 278 | 268 | ||
| 279 | FieldEntry obfuscatedEntry = new FieldEntry(ownerEntry, obfuscatedName, descriptor); | 269 | FieldEntry obfuscatedEntry = new FieldEntry(ownerEntry, obfuscatedName, descriptor); |
| 280 | if (mapping != null) { | 270 | return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); |
| 281 | return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); | ||
| 282 | } else { | ||
| 283 | return new MappingPair<>(obfuscatedEntry); | ||
| 284 | } | ||
| 285 | } | 271 | } |
| 286 | 272 | ||
| 287 | private static MappingPair<MethodEntry, RawEntryMapping> parseMethod(@Nullable Entry<?> parent, String[] tokens) { | 273 | private static MappingPair<MethodEntry, RawEntryMapping> parseMethod(@Nullable Entry<?> parent, String[] tokens) { |
| @@ -317,11 +303,7 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 317 | } | 303 | } |
| 318 | 304 | ||
| 319 | MethodEntry obfuscatedEntry = new MethodEntry(ownerEntry, obfuscatedName, descriptor); | 305 | MethodEntry obfuscatedEntry = new MethodEntry(ownerEntry, obfuscatedName, descriptor); |
| 320 | if (mapping != null) { | 306 | return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); |
| 321 | return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); | ||
| 322 | } else { | ||
| 323 | return new MappingPair<>(obfuscatedEntry); | ||
| 324 | } | ||
| 325 | } | 307 | } |
| 326 | 308 | ||
| 327 | private static MappingPair<LocalVariableEntry, RawEntryMapping> parseArgument(@Nullable Entry<?> parent, String[] tokens) { | 309 | private static MappingPair<LocalVariableEntry, RawEntryMapping> parseArgument(@Nullable Entry<?> parent, String[] tokens) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java index d9f1470..5d7a789 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java | |||
| @@ -15,12 +15,7 @@ import java.io.IOException; | |||
| 15 | import java.io.PrintWriter; | 15 | import java.io.PrintWriter; |
| 16 | import java.net.URI; | 16 | import java.net.URI; |
| 17 | import java.net.URISyntaxException; | 17 | import java.net.URISyntaxException; |
| 18 | import java.nio.file.DirectoryStream; | 18 | import java.nio.file.*; |
| 19 | import java.nio.file.FileSystem; | ||
| 20 | import java.nio.file.FileSystems; | ||
| 21 | import java.nio.file.Files; | ||
| 22 | import java.nio.file.Path; | ||
| 23 | import java.nio.file.Paths; | ||
| 24 | import java.util.ArrayList; | 19 | import java.util.ArrayList; |
| 25 | import java.util.Collection; | 20 | import java.util.Collection; |
| 26 | import java.util.Collections; | 21 | import java.util.Collections; |
| @@ -28,25 +23,19 @@ import java.util.Objects; | |||
| 28 | import java.util.concurrent.atomic.AtomicInteger; | 23 | import java.util.concurrent.atomic.AtomicInteger; |
| 29 | import java.util.stream.Stream; | 24 | import java.util.stream.Stream; |
| 30 | 25 | ||
| 26 | import javax.annotation.Nonnull; | ||
| 27 | |||
| 31 | import cuchaz.enigma.ProgressListener; | 28 | import cuchaz.enigma.ProgressListener; |
| 32 | import cuchaz.enigma.translation.MappingTranslator; | 29 | import cuchaz.enigma.translation.MappingTranslator; |
| 33 | import cuchaz.enigma.translation.Translator; | 30 | import cuchaz.enigma.translation.Translator; |
| 34 | import cuchaz.enigma.translation.mapping.AccessModifier; | 31 | import cuchaz.enigma.translation.mapping.AccessModifier; |
| 35 | import cuchaz.enigma.translation.mapping.EntryMapping; | 32 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 36 | import cuchaz.enigma.translation.mapping.MappingDelta; | 33 | import cuchaz.enigma.translation.mapping.MappingDelta; |
| 37 | import cuchaz.enigma.translation.mapping.serde.MappingFileNameFormat; | ||
| 38 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; | ||
| 39 | import cuchaz.enigma.translation.mapping.VoidEntryResolver; | 34 | import cuchaz.enigma.translation.mapping.VoidEntryResolver; |
| 40 | import cuchaz.enigma.translation.mapping.serde.LfPrintWriter; | 35 | import cuchaz.enigma.translation.mapping.serde.*; |
| 41 | import cuchaz.enigma.translation.mapping.serde.MappingHelper; | ||
| 42 | import cuchaz.enigma.translation.mapping.serde.MappingsWriter; | ||
| 43 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 36 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 44 | import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; | 37 | import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; |
| 45 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 38 | import cuchaz.enigma.translation.representation.entry.*; |
| 46 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 47 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | ||
| 48 | import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; | ||
| 49 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 50 | import cuchaz.enigma.utils.I18n; | 39 | import cuchaz.enigma.utils.I18n; |
| 51 | 40 | ||
| 52 | public enum EnigmaMappingsWriter implements MappingsWriter { | 41 | public enum EnigmaMappingsWriter implements MappingsWriter { |
| @@ -184,19 +173,22 @@ public enum EnigmaMappingsWriter implements MappingsWriter { | |||
| 184 | 173 | ||
| 185 | EntryMapping classEntryMapping = mappings.get(classEntry); | 174 | EntryMapping classEntryMapping = mappings.get(classEntry); |
| 186 | 175 | ||
| 176 | if (classEntryMapping == null) { | ||
| 177 | classEntryMapping = EntryMapping.DEFAULT; | ||
| 178 | } | ||
| 179 | |||
| 187 | writer.println(writeClass(classEntry, classEntryMapping).trim()); | 180 | writer.println(writeClass(classEntry, classEntryMapping).trim()); |
| 188 | if (classEntryMapping != null && classEntryMapping.getJavadoc() != null) { | 181 | if (classEntryMapping.javadoc() != null) { |
| 189 | writeDocs(writer, classEntryMapping, 0); | 182 | writeDocs(writer, classEntryMapping, 0); |
| 190 | } | 183 | } |
| 191 | 184 | ||
| 192 | for (Entry<?> child : children) { | 185 | for (Entry<?> child : children) { |
| 193 | writeEntry(writer, mappings, child, 1); | 186 | writeEntry(writer, mappings, child, 1); |
| 194 | } | 187 | } |
| 195 | |||
| 196 | } | 188 | } |
| 197 | 189 | ||
| 198 | private void writeDocs(PrintWriter writer, EntryMapping mapping, int depth) { | 190 | private void writeDocs(PrintWriter writer, EntryMapping mapping, int depth) { |
| 199 | String jd = mapping.getJavadoc(); | 191 | String jd = mapping.javadoc(); |
| 200 | if (jd != null) { | 192 | if (jd != null) { |
| 201 | for (String line : jd.split("\\R")) { | 193 | for (String line : jd.split("\\R")) { |
| 202 | writer.println(indent(EnigmaFormat.COMMENT + " " + MappingHelper.escape(line), depth + 1)); | 194 | writer.println(indent(EnigmaFormat.COMMENT + " " + MappingHelper.escape(line), depth + 1)); |
| @@ -212,20 +204,26 @@ public enum EnigmaMappingsWriter implements MappingsWriter { | |||
| 212 | 204 | ||
| 213 | EntryMapping mapping = node.getValue(); | 205 | EntryMapping mapping = node.getValue(); |
| 214 | 206 | ||
| 215 | if (entry instanceof ClassEntry) { | 207 | if (mapping == null) { |
| 216 | String line = writeClass((ClassEntry) entry, mapping); | 208 | mapping = EntryMapping.DEFAULT; |
| 217 | writer.println(indent(line, depth)); | 209 | } |
| 218 | } else if (entry instanceof MethodEntry) { | 210 | |
| 219 | String line = writeMethod((MethodEntry) entry, mapping); | 211 | String line = null; |
| 220 | writer.println(indent(line, depth)); | 212 | if (entry instanceof ClassEntry classEntry) { |
| 221 | } else if (entry instanceof FieldEntry) { | 213 | line = writeClass(classEntry, mapping); |
| 222 | String line = writeField((FieldEntry) entry, mapping); | 214 | } else if (entry instanceof MethodEntry methodEntry) { |
| 223 | writer.println(indent(line, depth)); | 215 | line = writeMethod(methodEntry, mapping); |
| 224 | } else if (entry instanceof LocalVariableEntry && mapping != null) { | 216 | } else if (entry instanceof FieldEntry fieldEntry) { |
| 225 | String line = writeArgument((LocalVariableEntry) entry, mapping); | 217 | line = writeField(fieldEntry, mapping); |
| 218 | } else if (entry instanceof LocalVariableEntry varEntry && mapping.targetName() != null) { | ||
| 219 | line = writeArgument(varEntry, mapping); | ||
| 220 | } | ||
| 221 | |||
| 222 | if (line != null) { | ||
| 226 | writer.println(indent(line, depth)); | 223 | writer.println(indent(line, depth)); |
| 227 | } | 224 | } |
| 228 | if (mapping != null && mapping.getJavadoc() != null) { | 225 | |
| 226 | if (mapping.javadoc() != null) { | ||
| 229 | writeDocs(writer, mapping, depth); | 227 | writeDocs(writer, mapping, depth); |
| 230 | } | 228 | } |
| 231 | 229 | ||
| @@ -254,55 +252,53 @@ public enum EnigmaMappingsWriter implements MappingsWriter { | |||
| 254 | .forEach(result::add); | 252 | .forEach(result::add); |
| 255 | 253 | ||
| 256 | children.stream().filter(e -> e instanceof ClassEntry) | 254 | children.stream().filter(e -> e instanceof ClassEntry) |
| 257 | .map(e -> (ClassEntry) e) | 255 | .map(e -> (ClassEntry) e) |
| 258 | .sorted() | 256 | .sorted() |
| 259 | .forEach(result::add); | 257 | .forEach(result::add); |
| 260 | 258 | ||
| 261 | return result; | 259 | return result; |
| 262 | } | 260 | } |
| 263 | 261 | ||
| 264 | protected String writeClass(ClassEntry entry, EntryMapping mapping) { | 262 | protected String writeClass(ClassEntry entry, @Nonnull EntryMapping mapping) { |
| 265 | StringBuilder builder = new StringBuilder(EnigmaFormat.CLASS +" "); | 263 | StringBuilder builder = new StringBuilder(EnigmaFormat.CLASS + " "); |
| 266 | builder.append(entry.getName()).append(' '); | 264 | builder.append(entry.getName()).append(' '); |
| 267 | writeMapping(builder, mapping); | 265 | writeMapping(builder, mapping); |
| 268 | 266 | ||
| 269 | return builder.toString(); | 267 | return builder.toString(); |
| 270 | } | 268 | } |
| 271 | 269 | ||
| 272 | protected String writeMethod(MethodEntry entry, EntryMapping mapping) { | 270 | protected String writeMethod(MethodEntry entry, @Nonnull EntryMapping mapping) { |
| 273 | StringBuilder builder = new StringBuilder(EnigmaFormat.METHOD + " "); | 271 | StringBuilder builder = new StringBuilder(EnigmaFormat.METHOD + " "); |
| 274 | builder.append(entry.getName()).append(' '); | 272 | builder.append(entry.getName()).append(' '); |
| 275 | if (mapping != null && !mapping.getTargetName().equals(entry.getName())) { | 273 | writeMapping(builder, mapping); |
| 276 | writeMapping(builder, mapping); | ||
| 277 | } | ||
| 278 | 274 | ||
| 279 | builder.append(entry.getDesc().toString()); | 275 | builder.append(entry.getDesc().toString()); |
| 280 | 276 | ||
| 281 | return builder.toString(); | 277 | return builder.toString(); |
| 282 | } | 278 | } |
| 283 | 279 | ||
| 284 | protected String writeField(FieldEntry entry, EntryMapping mapping) { | 280 | protected String writeField(FieldEntry entry, @Nonnull EntryMapping mapping) { |
| 285 | StringBuilder builder = new StringBuilder(EnigmaFormat.FIELD + " "); | 281 | StringBuilder builder = new StringBuilder(EnigmaFormat.FIELD + " "); |
| 286 | builder.append(entry.getName()).append(' '); | 282 | builder.append(entry.getName()).append(' '); |
| 287 | if (mapping != null && !mapping.getTargetName().equals(entry.getName())) { | 283 | writeMapping(builder, mapping); |
| 288 | writeMapping(builder, mapping); | ||
| 289 | } | ||
| 290 | 284 | ||
| 291 | builder.append(entry.getDesc().toString()); | 285 | builder.append(entry.getDesc().toString()); |
| 292 | 286 | ||
| 293 | return builder.toString(); | 287 | return builder.toString(); |
| 294 | } | 288 | } |
| 295 | 289 | ||
| 296 | protected String writeArgument(LocalVariableEntry entry, EntryMapping mapping) { | 290 | protected String writeArgument(LocalVariableEntry entry, @Nonnull EntryMapping mapping) { |
| 297 | return EnigmaFormat.PARAMETER + " " + entry.getIndex() + ' ' + mapping.getTargetName(); | 291 | return EnigmaFormat.PARAMETER + " " + entry.getIndex() + ' ' + mapping.targetName(); |
| 298 | } | 292 | } |
| 299 | 293 | ||
| 300 | private void writeMapping(StringBuilder builder, EntryMapping mapping) { | 294 | private void writeMapping(StringBuilder builder, EntryMapping mapping) { |
| 301 | if (mapping != null) { | 295 | if (mapping.targetName() != null) { |
| 302 | builder.append(mapping.getTargetName()).append(' '); | 296 | builder.append(mapping.targetName()).append(' '); |
| 303 | if (mapping.getAccessModifier() != AccessModifier.UNCHANGED) { | 297 | if (mapping.accessModifier() != AccessModifier.UNCHANGED) { |
| 304 | builder.append(mapping.getAccessModifier().getFormattedName()).append(' '); | 298 | builder.append(mapping.accessModifier().getFormattedName()).append(' '); |
| 305 | } | 299 | } |
| 300 | } else if (mapping.accessModifier() != AccessModifier.UNCHANGED) { | ||
| 301 | builder.append("- ").append(mapping.accessModifier().getFormattedName()).append(' '); | ||
| 306 | } | 302 | } |
| 307 | } | 303 | } |
| 308 | 304 | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java index 4f78e6f..1f785e1 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsWriter.java | |||
| @@ -73,13 +73,16 @@ public class TinyMappingsWriter implements MappingsWriter { | |||
| 73 | Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); | 73 | Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); |
| 74 | 74 | ||
| 75 | EntryMapping mapping = mappings.get(entry); | 75 | EntryMapping mapping = mappings.get(entry); |
| 76 | if (mapping != null && !entry.getName().equals(mapping.getTargetName())) { | 76 | |
| 77 | // Do not write mappings without deobfuscated name since tiny v1 doesn't | ||
| 78 | // support comments anyway | ||
| 79 | if (mapping != null && mapping.targetName() != null) { | ||
| 77 | if (entry instanceof ClassEntry) { | 80 | if (entry instanceof ClassEntry) { |
| 78 | writeClass(writer, (ClassEntry) entry, translator); | 81 | writeClass(writer, (ClassEntry) entry, translator); |
| 79 | } else if (entry instanceof FieldEntry) { | 82 | } else if (entry instanceof FieldEntry) { |
| 80 | writeLine(writer, serializeEntry(entry, mapping.getTargetName())); | 83 | writeLine(writer, serializeEntry(entry, mapping.targetName())); |
| 81 | } else if (entry instanceof MethodEntry) { | 84 | } else if (entry instanceof MethodEntry) { |
| 82 | writeLine(writer, serializeEntry(entry, mapping.getTargetName())); | 85 | writeLine(writer, serializeEntry(entry, mapping.targetName())); |
| 83 | } | 86 | } |
| 84 | } | 87 | } |
| 85 | 88 | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java index 5160eda..c400568 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Writer.java | |||
| @@ -62,8 +62,8 @@ public final class TinyV2Writer implements MappingsWriter { | |||
| 62 | Deque<String> parts = new LinkedList<>(); | 62 | Deque<String> parts = new LinkedList<>(); |
| 63 | do { | 63 | do { |
| 64 | EntryMapping mapping = tree.get(classEntry); | 64 | EntryMapping mapping = tree.get(classEntry); |
| 65 | if (mapping != null) { | 65 | if (mapping != null && mapping.targetName() != null) { |
| 66 | parts.addFirst(mapping.getTargetName()); | 66 | parts.addFirst(mapping.targetName()); |
| 67 | } else { | 67 | } else { |
| 68 | parts.addFirst(classEntry.getName()); | 68 | parts.addFirst(classEntry.getName()); |
| 69 | } | 69 | } |
| @@ -81,7 +81,7 @@ public final class TinyV2Writer implements MappingsWriter { | |||
| 81 | writeComment(writer, node.getValue(), 1); | 81 | writeComment(writer, node.getValue(), 1); |
| 82 | 82 | ||
| 83 | for (EntryTreeNode<EntryMapping> child : node.getChildNodes()) { | 83 | for (EntryTreeNode<EntryMapping> child : node.getChildNodes()) { |
| 84 | Entry entry = child.getEntry(); | 84 | Entry<?> entry = child.getEntry(); |
| 85 | if (entry instanceof FieldEntry) { | 85 | if (entry instanceof FieldEntry) { |
| 86 | writeField(writer, child); | 86 | writeField(writer, child); |
| 87 | } else if (entry instanceof MethodEntry) { | 87 | } else if (entry instanceof MethodEntry) { |
| @@ -98,16 +98,21 @@ public final class TinyV2Writer implements MappingsWriter { | |||
| 98 | writer.print(node.getEntry().getName()); | 98 | writer.print(node.getEntry().getName()); |
| 99 | writer.print("\t"); | 99 | writer.print("\t"); |
| 100 | EntryMapping mapping = node.getValue(); | 100 | EntryMapping mapping = node.getValue(); |
| 101 | |||
| 101 | if (mapping == null) { | 102 | if (mapping == null) { |
| 102 | writer.println(node.getEntry().getName()); // todo fix v2 name inference | 103 | mapping = EntryMapping.DEFAULT; |
| 103 | } else { | 104 | } |
| 104 | writer.println(mapping.getTargetName()); | ||
| 105 | 105 | ||
| 106 | writeComment(writer, mapping, 2); | 106 | if (mapping.targetName() != null) { |
| 107 | writer.println(mapping.targetName()); | ||
| 108 | } else { | ||
| 109 | writer.println(node.getEntry().getName()); // todo fix v2 name inference | ||
| 107 | } | 110 | } |
| 108 | 111 | ||
| 112 | writeComment(writer, mapping, 2); | ||
| 113 | |||
| 109 | for (EntryTreeNode<EntryMapping> child : node.getChildNodes()) { | 114 | for (EntryTreeNode<EntryMapping> child : node.getChildNodes()) { |
| 110 | Entry entry = child.getEntry(); | 115 | Entry<?> entry = child.getEntry(); |
| 111 | if (entry instanceof LocalVariableEntry) { | 116 | if (entry instanceof LocalVariableEntry) { |
| 112 | writeParameter(writer, child); | 117 | writeParameter(writer, child); |
| 113 | } | 118 | } |
| @@ -116,7 +121,7 @@ public final class TinyV2Writer implements MappingsWriter { | |||
| 116 | } | 121 | } |
| 117 | 122 | ||
| 118 | private void writeField(PrintWriter writer, EntryTreeNode<EntryMapping> node) { | 123 | private void writeField(PrintWriter writer, EntryTreeNode<EntryMapping> node) { |
| 119 | if (node.getValue() == null) | 124 | if (node.getValue() == null || node.getValue().equals(EntryMapping.DEFAULT)) |
| 120 | return; // Shortcut | 125 | return; // Shortcut |
| 121 | 126 | ||
| 122 | writer.print(indent(1)); | 127 | writer.print(indent(1)); |
| @@ -126,17 +131,22 @@ public final class TinyV2Writer implements MappingsWriter { | |||
| 126 | writer.print(node.getEntry().getName()); | 131 | writer.print(node.getEntry().getName()); |
| 127 | writer.print("\t"); | 132 | writer.print("\t"); |
| 128 | EntryMapping mapping = node.getValue(); | 133 | EntryMapping mapping = node.getValue(); |
| 134 | |||
| 129 | if (mapping == null) { | 135 | if (mapping == null) { |
| 130 | writer.println(node.getEntry().getName()); // todo fix v2 name inference | 136 | mapping = EntryMapping.DEFAULT; |
| 131 | } else { | 137 | } |
| 132 | writer.println(mapping.getTargetName()); | ||
| 133 | 138 | ||
| 134 | writeComment(writer, mapping, 2); | 139 | if (mapping.targetName() != null) { |
| 140 | writer.println(mapping.targetName()); | ||
| 141 | } else { | ||
| 142 | writer.println(node.getEntry().getName()); // todo fix v2 name inference | ||
| 135 | } | 143 | } |
| 144 | |||
| 145 | writeComment(writer, mapping, 2); | ||
| 136 | } | 146 | } |
| 137 | 147 | ||
| 138 | private void writeParameter(PrintWriter writer, EntryTreeNode<EntryMapping> node) { | 148 | private void writeParameter(PrintWriter writer, EntryTreeNode<EntryMapping> node) { |
| 139 | if (node.getValue() == null) | 149 | if (node.getValue() == null || node.getValue().equals(EntryMapping.DEFAULT)) |
| 140 | return; // Shortcut | 150 | return; // Shortcut |
| 141 | 151 | ||
| 142 | writer.print(indent(2)); | 152 | writer.print(indent(2)); |
| @@ -146,20 +156,20 @@ public final class TinyV2Writer implements MappingsWriter { | |||
| 146 | writer.print(node.getEntry().getName()); | 156 | writer.print(node.getEntry().getName()); |
| 147 | writer.print("\t"); | 157 | writer.print("\t"); |
| 148 | EntryMapping mapping = node.getValue(); | 158 | EntryMapping mapping = node.getValue(); |
| 149 | if (mapping == null) { | 159 | if (mapping == null || mapping.targetName() == null) { |
| 150 | writer.println(); // todo ??? | 160 | writer.println(); // todo ??? |
| 151 | } else { | 161 | } else { |
| 152 | writer.println(mapping.getTargetName()); | 162 | writer.println(mapping.targetName()); |
| 153 | 163 | ||
| 154 | writeComment(writer, mapping, 3); | 164 | writeComment(writer, mapping, 3); |
| 155 | } | 165 | } |
| 156 | } | 166 | } |
| 157 | 167 | ||
| 158 | private void writeComment(PrintWriter writer, EntryMapping mapping, int indent) { | 168 | private void writeComment(PrintWriter writer, EntryMapping mapping, int indent) { |
| 159 | if (mapping != null && mapping.getJavadoc() != null) { | 169 | if (mapping != null && mapping.javadoc() != null) { |
| 160 | writer.print(indent(indent)); | 170 | writer.print(indent(indent)); |
| 161 | writer.print("c\t"); | 171 | writer.print("c\t"); |
| 162 | writer.print(MappingHelper.escape(mapping.getJavadoc())); | 172 | writer.print(MappingHelper.escape(mapping.javadoc())); |
| 163 | writer.println(); | 173 | writer.println(); |
| 164 | } | 174 | } |
| 165 | } | 175 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java index 570941c..0992d34 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java | |||
| @@ -6,6 +6,7 @@ import cuchaz.enigma.translation.mapping.EntryMapping; | |||
| 6 | import cuchaz.enigma.translation.mapping.EntryResolver; | 6 | import cuchaz.enigma.translation.mapping.EntryResolver; |
| 7 | import cuchaz.enigma.translation.representation.entry.Entry; | 7 | import cuchaz.enigma.translation.representation.entry.Entry; |
| 8 | 8 | ||
| 9 | import javax.annotation.Nonnull; | ||
| 9 | import javax.annotation.Nullable; | 10 | import javax.annotation.Nullable; |
| 10 | import java.util.*; | 11 | import java.util.*; |
| 11 | import java.util.function.Function; | 12 | import java.util.function.Function; |
| @@ -152,6 +153,7 @@ public class HashEntryTree<T> implements EntryTree<T> { | |||
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | @Override | 155 | @Override |
| 156 | @Nonnull | ||
| 155 | public Iterator<EntryTreeNode<T>> iterator() { | 157 | public Iterator<EntryTreeNode<T>> iterator() { |
| 156 | Collection<EntryTreeNode<T>> nodes = new ArrayList<>(); | 158 | Collection<EntryTreeNode<T>> nodes = new ArrayList<>(); |
| 157 | for (EntryTreeNode<T> node : root.values()) { | 159 | for (EntryTreeNode<T> node : root.values()) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/Lambda.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/Lambda.java index a6aed73..13c7cd4 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/Lambda.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/Lambda.java | |||
| @@ -35,9 +35,9 @@ public class Lambda implements Translatable { | |||
| 35 | EntryMapping samMethodMapping = resolveMapping(resolver, mappings, samMethod); | 35 | EntryMapping samMethodMapping = resolveMapping(resolver, mappings, samMethod); |
| 36 | 36 | ||
| 37 | return TranslateResult.of( | 37 | return TranslateResult.of( |
| 38 | samMethodMapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 38 | samMethodMapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 39 | new Lambda( | 39 | new Lambda( |
| 40 | samMethodMapping != null ? samMethodMapping.getTargetName() : invokedName, | 40 | samMethodMapping.targetName() != null ? samMethodMapping.targetName() : invokedName, |
| 41 | invokedType.extendedTranslate(translator, resolver, mappings).getValue(), | 41 | invokedType.extendedTranslate(translator, resolver, mappings).getValue(), |
| 42 | samMethodType.extendedTranslate(translator, resolver, mappings).getValue(), | 42 | samMethodType.extendedTranslate(translator, resolver, mappings).getValue(), |
| 43 | implMethod.extendedTranslate(translator, resolver, mappings).getValue(), | 43 | implMethod.extendedTranslate(translator, resolver, mappings).getValue(), |
| @@ -53,7 +53,7 @@ public class Lambda implements Translatable { | |||
| 53 | return mapping; | 53 | return mapping; |
| 54 | } | 54 | } |
| 55 | } | 55 | } |
| 56 | return null; | 56 | return EntryMapping.DEFAULT; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | public ClassEntry getInterface() { | 59 | public ClassEntry getInterface() { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java index b0fd286..237c93d 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java | |||
| @@ -13,6 +13,7 @@ package cuchaz.enigma.translation.representation.entry; | |||
| 13 | 13 | ||
| 14 | import java.util.Arrays; | 14 | import java.util.Arrays; |
| 15 | 15 | ||
| 16 | import javax.annotation.Nonnull; | ||
| 16 | import javax.annotation.Nullable; | 17 | import javax.annotation.Nullable; |
| 17 | 18 | ||
| 18 | import com.google.common.base.Preconditions; | 19 | import com.google.common.base.Preconditions; |
| @@ -75,15 +76,15 @@ public class ClassDefEntry extends ClassEntry implements DefEntry<ClassEntry> { | |||
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | @Override | 78 | @Override |
| 78 | public TranslateResult<ClassDefEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 79 | public TranslateResult<ClassDefEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 79 | Signature translatedSignature = translator.translate(signature); | 80 | Signature translatedSignature = translator.translate(signature); |
| 80 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 81 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 81 | AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; | 82 | AccessFlags translatedAccess = mapping.accessModifier().transform(access); |
| 82 | ClassEntry translatedSuper = translator.translate(superClass); | 83 | ClassEntry translatedSuper = translator.translate(superClass); |
| 83 | ClassEntry[] translatedInterfaces = Arrays.stream(interfaces).map(translator::translate).toArray(ClassEntry[]::new); | 84 | ClassEntry[] translatedInterfaces = Arrays.stream(interfaces).map(translator::translate).toArray(ClassEntry[]::new); |
| 84 | String docs = mapping != null ? mapping.getJavadoc() : null; | 85 | String docs = mapping.javadoc(); |
| 85 | return TranslateResult.of( | 86 | return TranslateResult.of( |
| 86 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 87 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 87 | new ClassDefEntry(parent, translatedName, translatedSignature, translatedAccess, translatedSuper, translatedInterfaces, docs) | 88 | new ClassDefEntry(parent, translatedName, translatedSignature, translatedAccess, translatedSuper, translatedInterfaces, docs) |
| 88 | ); | 89 | ); |
| 89 | } | 90 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java index fe56611..ec5294e 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java | |||
| @@ -82,16 +82,16 @@ public class ClassEntry extends ParentedEntry<ClassEntry> implements Comparable< | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | @Override | 84 | @Override |
| 85 | public TranslateResult<? extends ClassEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 85 | public TranslateResult<? extends ClassEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 86 | if (name.charAt(0) == '[') { | 86 | if (name.charAt(0) == '[') { |
| 87 | TranslateResult<TypeDescriptor> translatedName = translator.extendedTranslate(new TypeDescriptor(name)); | 87 | TranslateResult<TypeDescriptor> translatedName = translator.extendedTranslate(new TypeDescriptor(name)); |
| 88 | return translatedName.map(desc -> new ClassEntry(parent, desc.toString())); | 88 | return translatedName.map(desc -> new ClassEntry(parent, desc.toString())); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 91 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 92 | String docs = mapping != null ? mapping.getJavadoc() : null; | 92 | String docs = mapping.javadoc(); |
| 93 | return TranslateResult.of( | 93 | return TranslateResult.of( |
| 94 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 94 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 95 | new ClassEntry(parent, translatedName, docs) | 95 | new ClassEntry(parent, translatedName, docs) |
| 96 | ); | 96 | ); |
| 97 | } | 97 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java index 8a81c54..956f32c 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java | |||
| @@ -13,6 +13,7 @@ package cuchaz.enigma.translation.representation.entry; | |||
| 13 | 13 | ||
| 14 | import java.util.ArrayList; | 14 | import java.util.ArrayList; |
| 15 | import java.util.List; | 15 | import java.util.List; |
| 16 | import java.util.Objects; | ||
| 16 | 17 | ||
| 17 | import javax.annotation.Nullable; | 18 | import javax.annotation.Nullable; |
| 18 | 19 | ||
| @@ -107,16 +108,29 @@ public interface Entry<P extends Entry<?>> extends Translatable { | |||
| 107 | 108 | ||
| 108 | boolean canConflictWith(Entry<?> entry); | 109 | boolean canConflictWith(Entry<?> entry); |
| 109 | 110 | ||
| 110 | @Nullable | ||
| 111 | default ClassEntry getContainingClass() { | 111 | default ClassEntry getContainingClass() { |
| 112 | P parent = getParent(); | 112 | ClassEntry last = null; |
| 113 | if (parent == null) { | 113 | Entry<?> current = this; |
| 114 | return null; | 114 | while (current != null) { |
| 115 | if (current instanceof ClassEntry) { | ||
| 116 | last = (ClassEntry) current; | ||
| 117 | break; | ||
| 118 | } | ||
| 119 | current = current.getParent(); | ||
| 115 | } | 120 | } |
| 116 | if (parent instanceof ClassEntry) { | 121 | return Objects.requireNonNull(last, () -> String.format("%s has no containing class?", this)); |
| 117 | return (ClassEntry) parent; | 122 | } |
| 123 | |||
| 124 | default ClassEntry getTopLevelClass() { | ||
| 125 | ClassEntry last = null; | ||
| 126 | Entry<?> current = this; | ||
| 127 | while (current != null) { | ||
| 128 | if (current instanceof ClassEntry) { | ||
| 129 | last = (ClassEntry) current; | ||
| 130 | } | ||
| 131 | current = current.getParent(); | ||
| 118 | } | 132 | } |
| 119 | return parent.getContainingClass(); | 133 | return Objects.requireNonNull(last, () -> String.format("%s has no top level class?", this)); |
| 120 | } | 134 | } |
| 121 | 135 | ||
| 122 | default List<Entry<?>> getAncestry() { | 136 | default List<Entry<?>> getAncestry() { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java index b9da6cc..0efb6a9 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java | |||
| @@ -11,8 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | package cuchaz.enigma.translation.representation.entry; | 12 | package cuchaz.enigma.translation.representation.entry; |
| 13 | 13 | ||
| 14 | import javax.annotation.Nullable; | ||
| 15 | |||
| 16 | import com.google.common.base.Preconditions; | 14 | import com.google.common.base.Preconditions; |
| 17 | 15 | ||
| 18 | import cuchaz.enigma.source.RenamableTokenType; | 16 | import cuchaz.enigma.source.RenamableTokenType; |
| @@ -23,6 +21,8 @@ import cuchaz.enigma.translation.representation.AccessFlags; | |||
| 23 | import cuchaz.enigma.translation.representation.Signature; | 21 | import cuchaz.enigma.translation.representation.Signature; |
| 24 | import cuchaz.enigma.translation.representation.TypeDescriptor; | 22 | import cuchaz.enigma.translation.representation.TypeDescriptor; |
| 25 | 23 | ||
| 24 | import javax.annotation.Nonnull; | ||
| 25 | |||
| 26 | public class FieldDefEntry extends FieldEntry implements DefEntry<ClassEntry> { | 26 | public class FieldDefEntry extends FieldEntry implements DefEntry<ClassEntry> { |
| 27 | private final AccessFlags access; | 27 | private final AccessFlags access; |
| 28 | private final Signature signature; | 28 | private final Signature signature; |
| @@ -53,14 +53,14 @@ public class FieldDefEntry extends FieldEntry implements DefEntry<ClassEntry> { | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | @Override | 55 | @Override |
| 56 | protected TranslateResult<FieldEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 56 | protected TranslateResult<FieldEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 57 | TypeDescriptor translatedDesc = translator.translate(desc); | 57 | TypeDescriptor translatedDesc = translator.translate(desc); |
| 58 | Signature translatedSignature = translator.translate(signature); | 58 | Signature translatedSignature = translator.translate(signature); |
| 59 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 59 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 60 | AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; | 60 | AccessFlags translatedAccess = mapping.accessModifier().transform(access); |
| 61 | String docs = mapping != null ? mapping.getJavadoc() : null; | 61 | String docs = mapping.javadoc(); |
| 62 | return TranslateResult.of( | 62 | return TranslateResult.of( |
| 63 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 63 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 64 | new FieldDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs) | 64 | new FieldDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs) |
| 65 | ); | 65 | ); |
| 66 | } | 66 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java index 5ddd33d..db94011 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java | |||
| @@ -13,7 +13,7 @@ package cuchaz.enigma.translation.representation.entry; | |||
| 13 | 13 | ||
| 14 | import java.util.Objects; | 14 | import java.util.Objects; |
| 15 | 15 | ||
| 16 | import javax.annotation.Nullable; | 16 | import javax.annotation.Nonnull; |
| 17 | 17 | ||
| 18 | import com.google.common.base.Preconditions; | 18 | import com.google.common.base.Preconditions; |
| 19 | 19 | ||
| @@ -63,11 +63,11 @@ public class FieldEntry extends ParentedEntry<ClassEntry> implements Comparable< | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | @Override | 65 | @Override |
| 66 | protected TranslateResult<FieldEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 66 | protected TranslateResult<FieldEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 67 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 67 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 68 | String docs = mapping != null ? mapping.getJavadoc() : null; | 68 | String docs = mapping.javadoc(); |
| 69 | return TranslateResult.of( | 69 | return TranslateResult.of( |
| 70 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 70 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 71 | new FieldEntry(parent, translatedName, translator.translate(desc), docs) | 71 | new FieldEntry(parent, translatedName, translator.translate(desc), docs) |
| 72 | ); | 72 | ); |
| 73 | } | 73 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java index 2712c65..c151de4 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | package cuchaz.enigma.translation.representation.entry; | 1 | package cuchaz.enigma.translation.representation.entry; |
| 2 | 2 | ||
| 3 | import javax.annotation.Nullable; | 3 | import javax.annotation.Nonnull; |
| 4 | 4 | ||
| 5 | import com.google.common.base.Preconditions; | 5 | import com.google.common.base.Preconditions; |
| 6 | 6 | ||
| @@ -30,12 +30,12 @@ public class LocalVariableDefEntry extends LocalVariableEntry { | |||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | @Override | 32 | @Override |
| 33 | protected TranslateResult<LocalVariableEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 33 | protected TranslateResult<LocalVariableEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 34 | TypeDescriptor translatedDesc = translator.translate(desc); | 34 | TypeDescriptor translatedDesc = translator.translate(desc); |
| 35 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 35 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 36 | String javadoc = mapping != null ? mapping.getJavadoc() : javadocs; | 36 | String javadoc = mapping.javadoc(); |
| 37 | return TranslateResult.of( | 37 | return TranslateResult.of( |
| 38 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 38 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 39 | new LocalVariableDefEntry(parent, index, translatedName, parameter, translatedDesc, javadoc) | 39 | new LocalVariableDefEntry(parent, index, translatedName, parameter, translatedDesc, javadoc) |
| 40 | ); | 40 | ); |
| 41 | } | 41 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java index 154f11f..1cf1a83 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java | |||
| @@ -2,7 +2,7 @@ package cuchaz.enigma.translation.representation.entry; | |||
| 2 | 2 | ||
| 3 | import java.util.Objects; | 3 | import java.util.Objects; |
| 4 | 4 | ||
| 5 | import javax.annotation.Nullable; | 5 | import javax.annotation.Nonnull; |
| 6 | 6 | ||
| 7 | import com.google.common.base.Preconditions; | 7 | import com.google.common.base.Preconditions; |
| 8 | 8 | ||
| @@ -50,11 +50,11 @@ public class LocalVariableEntry extends ParentedEntry<MethodEntry> implements Co | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | @Override | 52 | @Override |
| 53 | protected TranslateResult<LocalVariableEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 53 | protected TranslateResult<LocalVariableEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 54 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 54 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 55 | String javadoc = mapping != null ? mapping.getJavadoc() : null; | 55 | String javadoc = mapping.javadoc(); |
| 56 | return TranslateResult.of( | 56 | return TranslateResult.of( |
| 57 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 57 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 58 | new LocalVariableEntry(parent, index, translatedName, parameter, javadoc) | 58 | new LocalVariableEntry(parent, index, translatedName, parameter, javadoc) |
| 59 | ); | 59 | ); |
| 60 | } | 60 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java index cc326d6..30ef706 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | package cuchaz.enigma.translation.representation.entry; | 12 | package cuchaz.enigma.translation.representation.entry; |
| 13 | 13 | ||
| 14 | import javax.annotation.Nullable; | 14 | import javax.annotation.Nonnull; |
| 15 | 15 | ||
| 16 | import com.google.common.base.Preconditions; | 16 | import com.google.common.base.Preconditions; |
| 17 | 17 | ||
| @@ -53,14 +53,14 @@ public class MethodDefEntry extends MethodEntry implements DefEntry<ClassEntry> | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | @Override | 55 | @Override |
| 56 | protected TranslateResult<MethodDefEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 56 | protected TranslateResult<MethodDefEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 57 | MethodDescriptor translatedDesc = translator.translate(descriptor); | 57 | MethodDescriptor translatedDesc = translator.translate(descriptor); |
| 58 | Signature translatedSignature = translator.translate(signature); | 58 | Signature translatedSignature = translator.translate(signature); |
| 59 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 59 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 60 | AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; | 60 | AccessFlags translatedAccess = mapping.accessModifier().transform(access); |
| 61 | String docs = mapping != null ? mapping.getJavadoc() : null; | 61 | String docs = mapping.javadoc(); |
| 62 | return TranslateResult.of( | 62 | return TranslateResult.of( |
| 63 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 63 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 64 | new MethodDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs) | 64 | new MethodDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs) |
| 65 | ); | 65 | ); |
| 66 | } | 66 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java index 864a580..ab9c2d1 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java | |||
| @@ -13,7 +13,7 @@ package cuchaz.enigma.translation.representation.entry; | |||
| 13 | 13 | ||
| 14 | import java.util.Objects; | 14 | import java.util.Objects; |
| 15 | 15 | ||
| 16 | import javax.annotation.Nullable; | 16 | import javax.annotation.Nonnull; |
| 17 | 17 | ||
| 18 | import com.google.common.base.Preconditions; | 18 | import com.google.common.base.Preconditions; |
| 19 | 19 | ||
| @@ -58,11 +58,11 @@ public class MethodEntry extends ParentedEntry<ClassEntry> implements Comparable | |||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | @Override | 60 | @Override |
| 61 | protected TranslateResult<? extends MethodEntry> extendedTranslate(Translator translator, @Nullable EntryMapping mapping) { | 61 | protected TranslateResult<? extends MethodEntry> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { |
| 62 | String translatedName = mapping != null ? mapping.getTargetName() : name; | 62 | String translatedName = mapping.targetName() != null ? mapping.targetName() : name; |
| 63 | String docs = mapping != null ? mapping.getJavadoc() : null; | 63 | String docs = mapping.javadoc(); |
| 64 | return TranslateResult.of( | 64 | return TranslateResult.of( |
| 65 | mapping == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, | 65 | mapping.targetName() == null ? RenamableTokenType.OBFUSCATED : RenamableTokenType.DEOBFUSCATED, |
| 66 | new MethodEntry(parent, translatedName, translator.translate(descriptor), docs) | 66 | new MethodEntry(parent, translatedName, translator.translate(descriptor), docs) |
| 67 | ); | 67 | ); |
| 68 | } | 68 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java index 5634891..267bc11 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | package cuchaz.enigma.translation.representation.entry; | 12 | package cuchaz.enigma.translation.representation.entry; |
| 13 | 13 | ||
| 14 | import javax.annotation.Nonnull; | ||
| 14 | import javax.annotation.Nullable; | 15 | import javax.annotation.Nullable; |
| 15 | 16 | ||
| 16 | import com.google.common.base.Preconditions; | 17 | import com.google.common.base.Preconditions; |
| @@ -41,7 +42,7 @@ public abstract class ParentedEntry<P extends Entry<?>> implements Entry<P> { | |||
| 41 | @Override | 42 | @Override |
| 42 | public abstract ParentedEntry<P> withName(String name); | 43 | public abstract ParentedEntry<P> withName(String name); |
| 43 | 44 | ||
| 44 | protected abstract TranslateResult<? extends ParentedEntry<P>> extendedTranslate(Translator translator, @Nullable EntryMapping mapping); | 45 | protected abstract TranslateResult<? extends ParentedEntry<P>> extendedTranslate(Translator translator, @Nonnull EntryMapping mapping); |
| 45 | 46 | ||
| 46 | @Override | 47 | @Override |
| 47 | public String getName() { | 48 | public String getName() { |
| @@ -93,6 +94,6 @@ public abstract class ParentedEntry<P extends Entry<?>> implements Entry<P> { | |||
| 93 | return mapping; | 94 | return mapping; |
| 94 | } | 95 | } |
| 95 | } | 96 | } |
| 96 | return null; | 97 | return EntryMapping.DEFAULT; |
| 97 | } | 98 | } |
| 98 | } | 99 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/utils/TristateChange.java b/enigma/src/main/java/cuchaz/enigma/utils/TristateChange.java new file mode 100644 index 0000000..864154c --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/utils/TristateChange.java | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | package cuchaz.enigma.utils; | ||
| 2 | |||
| 3 | import java.util.Objects; | ||
| 4 | |||
| 5 | public final class TristateChange<T> { | ||
| 6 | |||
| 7 | private static final TristateChange<?> UNCHANGED = new TristateChange<>(Type.UNCHANGED, null); | ||
| 8 | private static final TristateChange<?> RESET = new TristateChange<>(Type.RESET, null); | ||
| 9 | |||
| 10 | private final Type type; | ||
| 11 | private final T val; | ||
| 12 | |||
| 13 | @SuppressWarnings("unchecked") | ||
| 14 | public static <T> TristateChange<T> unchanged() { | ||
| 15 | return (TristateChange<T>) TristateChange.UNCHANGED; | ||
| 16 | } | ||
| 17 | |||
| 18 | @SuppressWarnings("unchecked") | ||
| 19 | public static <T> TristateChange<T> reset() { | ||
| 20 | return (TristateChange<T>) TristateChange.RESET; | ||
| 21 | } | ||
| 22 | |||
| 23 | public static <T> TristateChange<T> set(T value) { | ||
| 24 | return new TristateChange<>(Type.SET, value); | ||
| 25 | } | ||
| 26 | |||
| 27 | private TristateChange(Type type, T val) { | ||
| 28 | this.type = type; | ||
| 29 | this.val = val; | ||
| 30 | } | ||
| 31 | |||
| 32 | public Type getType() { | ||
| 33 | return this.type; | ||
| 34 | } | ||
| 35 | |||
| 36 | public boolean isUnchanged() { | ||
| 37 | return this.type == Type.UNCHANGED; | ||
| 38 | } | ||
| 39 | |||
| 40 | public boolean isReset() { | ||
| 41 | return this.type == Type.RESET; | ||
| 42 | } | ||
| 43 | |||
| 44 | public boolean isSet() { | ||
| 45 | return this.type == Type.SET; | ||
| 46 | } | ||
| 47 | |||
| 48 | public T getNewValue() { | ||
| 49 | if (this.type != Type.SET) throw new IllegalStateException(String.format("No concrete value in %s", this)); | ||
| 50 | return this.val; | ||
| 51 | } | ||
| 52 | |||
| 53 | @Override | ||
| 54 | public boolean equals(Object o) { | ||
| 55 | if (this == o) return true; | ||
| 56 | if (o == null || getClass() != o.getClass()) return false; | ||
| 57 | TristateChange<?> that = (TristateChange<?>) o; | ||
| 58 | return type == that.type && | ||
| 59 | Objects.equals(val, that.val); | ||
| 60 | } | ||
| 61 | |||
| 62 | @Override | ||
| 63 | public int hashCode() { | ||
| 64 | return Objects.hash(type, val); | ||
| 65 | } | ||
| 66 | |||
| 67 | @Override | ||
| 68 | public String toString() { | ||
| 69 | return String.format("TristateChange { type: %s, val: %s }", type, val); | ||
| 70 | } | ||
| 71 | |||
| 72 | public enum Type { | ||
| 73 | UNCHANGED, | ||
| 74 | RESET, | ||
| 75 | SET, | ||
| 76 | } | ||
| 77 | |||
| 78 | } | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/utils/validation/PrintValidatable.java b/enigma/src/main/java/cuchaz/enigma/utils/validation/PrintValidatable.java index 81b6c43..5067d7e 100644 --- a/enigma/src/main/java/cuchaz/enigma/utils/validation/PrintValidatable.java +++ b/enigma/src/main/java/cuchaz/enigma/utils/validation/PrintValidatable.java | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | package cuchaz.enigma.utils.validation; | 1 | package cuchaz.enigma.utils.validation; |
| 2 | 2 | ||
| 3 | import java.io.PrintStream; | ||
| 3 | import java.util.Arrays; | 4 | import java.util.Arrays; |
| 4 | 5 | ||
| 5 | public class PrintValidatable implements Validatable { | 6 | public class PrintValidatable implements Validatable { |
| @@ -8,6 +9,10 @@ public class PrintValidatable implements Validatable { | |||
| 8 | 9 | ||
| 9 | @Override | 10 | @Override |
| 10 | public void addMessage(ParameterizedMessage message) { | 11 | public void addMessage(ParameterizedMessage message) { |
| 12 | formatMessage(System.out, message); | ||
| 13 | } | ||
| 14 | |||
| 15 | public static void formatMessage(PrintStream w, ParameterizedMessage message) { | ||
| 11 | String text = message.getText(); | 16 | String text = message.getText(); |
| 12 | String longText = message.getLongText(); | 17 | String longText = message.getLongText(); |
| 13 | String type = switch (message.message.type) { | 18 | String type = switch (message.message.type) { |
| @@ -15,9 +20,10 @@ public class PrintValidatable implements Validatable { | |||
| 15 | case WARNING -> "warning"; | 20 | case WARNING -> "warning"; |
| 16 | case ERROR -> "error"; | 21 | case ERROR -> "error"; |
| 17 | }; | 22 | }; |
| 18 | System.out.printf("%s: %s\n", type, text); | 23 | w.printf("%s: %s\n", type, text); |
| 24 | |||
| 19 | if (!longText.isEmpty()) { | 25 | if (!longText.isEmpty()) { |
| 20 | Arrays.stream(longText.split("\n")).forEach(s -> System.out.printf(" %s\n", s)); | 26 | Arrays.stream(longText.split("\n")).forEach(s -> w.printf(" %s\n", s)); |
| 21 | } | 27 | } |
| 22 | } | 28 | } |
| 23 | 29 | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/utils/validation/ValidationContext.java b/enigma/src/main/java/cuchaz/enigma/utils/validation/ValidationContext.java index ee2b595..0ecb9fb 100644 --- a/enigma/src/main/java/cuchaz/enigma/utils/validation/ValidationContext.java +++ b/enigma/src/main/java/cuchaz/enigma/utils/validation/ValidationContext.java | |||
| @@ -62,6 +62,20 @@ public class ValidationContext { | |||
| 62 | return messages.stream().noneMatch(m -> m.message.type == Type.ERROR); | 62 | return messages.stream().noneMatch(m -> m.message.type == Type.ERROR); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /** | ||
| 66 | * If this validation context has at least one error, throw an exception. | ||
| 67 | * | ||
| 68 | * @throws IllegalStateException if errors are present | ||
| 69 | */ | ||
| 70 | public void throwOnError() { | ||
| 71 | if (!this.canProceed()) { | ||
| 72 | for (ParameterizedMessage message : this.messages) { | ||
| 73 | PrintValidatable.formatMessage(System.err, message); | ||
| 74 | } | ||
| 75 | throw new IllegalStateException("Errors encountered; cannot continue! Check error log for details."); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 65 | public List<ParameterizedMessage> getMessages() { | 79 | public List<ParameterizedMessage> getMessages() { |
| 66 | return Collections.unmodifiableList(messages); | 80 | return Collections.unmodifiableList(messages); |
| 67 | } | 81 | } |