From 0f47403d0220757fed189b76e2071e25b1025cb8 Mon Sep 17 00:00:00 2001 From: Runemoro Date: Wed, 3 Jun 2020 13:39:42 -0400 Subject: Split GUI code to separate module (#242) * Split into modules * Post merge compile fixes Co-authored-by: modmuss50 --- .../enigma/translation/LocalNameGenerator.java | 44 --- .../enigma/translation/MappingTranslator.java | 24 -- .../enigma/translation/SignatureUpdater.java | 92 ------ .../cuchaz/enigma/translation/Translatable.java | 9 - .../enigma/translation/TranslationDirection.java | 36 --- .../java/cuchaz/enigma/translation/Translator.java | 61 ---- .../cuchaz/enigma/translation/VoidTranslator.java | 10 - .../enigma/translation/mapping/AccessModifier.java | 25 -- .../enigma/translation/mapping/EntryMap.java | 24 -- .../enigma/translation/mapping/EntryMapping.java | 75 ----- .../enigma/translation/mapping/EntryRemapper.java | 105 ------- .../enigma/translation/mapping/EntryResolver.java | 41 --- .../translation/mapping/IndexEntryResolver.java | 227 --------------- .../enigma/translation/mapping/MappingDelta.java | 54 ---- .../translation/mapping/MappingFileNameFormat.java | 10 - .../enigma/translation/mapping/MappingPair.java | 32 --- .../translation/mapping/MappingSaveParameters.java | 16 -- .../translation/mapping/MappingValidator.java | 76 ----- .../translation/mapping/MappingsChecker.java | 99 ------- .../enigma/translation/mapping/NameValidator.java | 53 ---- .../translation/mapping/ResolutionStrategy.java | 6 - .../translation/mapping/VoidEntryResolver.java | 27 -- .../translation/mapping/serde/EnigmaFormat.java | 9 - .../mapping/serde/EnigmaMappingsReader.java | 319 --------------------- .../mapping/serde/EnigmaMappingsWriter.java | 316 -------------------- .../translation/mapping/serde/MappingFormat.java | 59 ---- .../translation/mapping/serde/MappingHelper.java | 51 ---- .../translation/mapping/serde/MappingsReader.java | 14 - .../translation/mapping/serde/MappingsWriter.java | 17 -- .../mapping/serde/ProguardMappingsReader.java | 134 --------- .../translation/mapping/serde/RawEntryMapping.java | 30 -- .../mapping/serde/SrgMappingsWriter.java | 118 -------- .../mapping/serde/TinyMappingsReader.java | 115 -------- .../mapping/serde/TinyMappingsWriter.java | 148 ---------- .../translation/mapping/serde/TinyV2Reader.java | 295 ------------------- .../translation/mapping/serde/TinyV2Writer.java | 169 ----------- .../mapping/tree/DeltaTrackingTree.java | 110 ------- .../enigma/translation/mapping/tree/EntryTree.java | 26 -- .../translation/mapping/tree/EntryTreeNode.java | 40 --- .../translation/mapping/tree/HashEntryTree.java | 188 ------------ .../translation/mapping/tree/HashTreeNode.java | 75 ----- .../translation/representation/AccessFlags.java | 116 -------- .../enigma/translation/representation/Lambda.java | 105 ------- .../representation/MethodDescriptor.java | 132 --------- .../translation/representation/Signature.java | 98 ------- .../translation/representation/TypeDescriptor.java | 268 ----------------- .../representation/entry/ClassDefEntry.java | 93 ------ .../representation/entry/ClassEntry.java | 214 -------------- .../translation/representation/entry/DefEntry.java | 7 - .../translation/representation/entry/Entry.java | 107 ------- .../representation/entry/FieldDefEntry.java | 71 ----- .../representation/entry/FieldEntry.java | 96 ------- .../entry/LocalVariableDefEntry.java | 51 ---- .../representation/entry/LocalVariableEntry.java | 93 ------ .../representation/entry/MethodDefEntry.java | 71 ----- .../representation/entry/MethodEntry.java | 105 ------- .../representation/entry/ParentedEntry.java | 82 ------ 57 files changed, 5088 deletions(-) delete mode 100644 src/main/java/cuchaz/enigma/translation/LocalNameGenerator.java delete mode 100644 src/main/java/cuchaz/enigma/translation/MappingTranslator.java delete mode 100644 src/main/java/cuchaz/enigma/translation/SignatureUpdater.java delete mode 100644 src/main/java/cuchaz/enigma/translation/Translatable.java delete mode 100644 src/main/java/cuchaz/enigma/translation/TranslationDirection.java delete mode 100644 src/main/java/cuchaz/enigma/translation/Translator.java delete mode 100644 src/main/java/cuchaz/enigma/translation/VoidTranslator.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/AccessModifier.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/EntryResolver.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/MappingFileNameFormat.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/MappingPair.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/MappingSaveParameters.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/NameValidator.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/ResolutionStrategy.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/VoidEntryResolver.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaFormat.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/ProguardMappingsReader.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsWriter.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Writer.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java delete mode 100644 src/main/java/cuchaz/enigma/translation/mapping/tree/HashTreeNode.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/AccessFlags.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/Lambda.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/MethodDescriptor.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/Signature.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/DefEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java delete mode 100644 src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java (limited to 'src/main/java/cuchaz/enigma/translation') diff --git a/src/main/java/cuchaz/enigma/translation/LocalNameGenerator.java b/src/main/java/cuchaz/enigma/translation/LocalNameGenerator.java deleted file mode 100644 index 18c966c..0000000 --- a/src/main/java/cuchaz/enigma/translation/LocalNameGenerator.java +++ /dev/null @@ -1,44 +0,0 @@ -package cuchaz.enigma.translation; - -import cuchaz.enigma.translation.mapping.NameValidator; -import cuchaz.enigma.translation.representation.TypeDescriptor; - -import java.util.Collection; -import java.util.Locale; - -public class LocalNameGenerator { - public static String generateArgumentName(int index, TypeDescriptor desc, Collection arguments) { - boolean uniqueType = arguments.stream().filter(desc::equals).count() <= 1; - String translatedName; - int nameIndex = index + 1; - StringBuilder nameBuilder = new StringBuilder(getTypeName(desc)); - if (!uniqueType || NameValidator.isReserved(nameBuilder.toString())) { - nameBuilder.append(nameIndex); - } - translatedName = nameBuilder.toString(); - return translatedName; - } - - public static String generateLocalVariableName(int index, TypeDescriptor desc) { - int nameIndex = index + 1; - return getTypeName(desc) + nameIndex; - } - - private static String getTypeName(TypeDescriptor desc) { - // Unfortunately each of these have different name getters, so they have different code paths - if (desc.isPrimitive()) { - TypeDescriptor.Primitive argCls = desc.getPrimitive(); - return argCls.name().toLowerCase(Locale.ROOT); - } else if (desc.isArray()) { - // List types would require this whole block again, so just go with aListx - return "arr"; - } else if (desc.isType()) { - String typeName = desc.getTypeEntry().getSimpleName().replace("$", ""); - typeName = typeName.substring(0, 1).toLowerCase(Locale.ROOT) + typeName.substring(1); - return typeName; - } else { - System.err.println("Encountered invalid argument type descriptor " + desc.toString()); - return "var"; - } - } -} diff --git a/src/main/java/cuchaz/enigma/translation/MappingTranslator.java b/src/main/java/cuchaz/enigma/translation/MappingTranslator.java deleted file mode 100644 index 529d0ed..0000000 --- a/src/main/java/cuchaz/enigma/translation/MappingTranslator.java +++ /dev/null @@ -1,24 +0,0 @@ -package cuchaz.enigma.translation; - -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.mapping.EntryMap; - -public class MappingTranslator implements Translator { - private final EntryMap mappings; - private final EntryResolver resolver; - - public MappingTranslator(EntryMap mappings, EntryResolver resolver) { - this.mappings = mappings; - this.resolver = resolver; - } - - @SuppressWarnings("unchecked") - @Override - public T translate(T translatable) { - if (translatable == null) { - return null; - } - return (T) translatable.translate(this, resolver, mappings); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/SignatureUpdater.java b/src/main/java/cuchaz/enigma/translation/SignatureUpdater.java deleted file mode 100644 index 3783053..0000000 --- a/src/main/java/cuchaz/enigma/translation/SignatureUpdater.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation; - -import com.google.common.collect.Lists; - -import java.io.IOException; -import java.io.StringReader; -import java.util.List; - -public class SignatureUpdater { - - public static String update(String signature, ClassNameUpdater updater) { - try { - StringBuilder buf = new StringBuilder(); - - // read the signature character-by-character - StringReader reader = new StringReader(signature); - int i; - while ((i = reader.read()) != -1) { - char c = (char) i; - - // does this character start a class name? - if (c == 'L') { - // update the class name and add it to the buffer - buf.append('L'); - String className = readClass(reader); - if (className == null) { - throw new IllegalArgumentException("Malformed signature: " + signature); - } - buf.append(updater.update(className)); - buf.append(';'); - } else { - // copy the character into the buffer - buf.append(c); - } - } - - return buf.toString(); - } catch (IOException ex) { - // I'm pretty sure a StringReader will never throw one of these - throw new Error(ex); - } - } - - private static String readClass(StringReader reader) throws IOException { - // read all the characters in the buffer until we hit a ';' - // remember to treat generics correctly - StringBuilder buf = new StringBuilder(); - int depth = 0; - int i; - while ((i = reader.read()) != -1) { - char c = (char) i; - - if (c == '<') { - depth++; - } else if (c == '>') { - depth--; - } else if (depth == 0) { - if (c == ';') { - return buf.toString(); - } else { - buf.append(c); - } - } - } - - return null; - } - - public static List getClasses(String signature) { - final List classNames = Lists.newArrayList(); - update(signature, className -> { - classNames.add(className); - return className; - }); - return classNames; - } - - public interface ClassNameUpdater { - String update(String className); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/Translatable.java b/src/main/java/cuchaz/enigma/translation/Translatable.java deleted file mode 100644 index 0370ef1..0000000 --- a/src/main/java/cuchaz/enigma/translation/Translatable.java +++ /dev/null @@ -1,9 +0,0 @@ -package cuchaz.enigma.translation; - -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.mapping.EntryMap; - -public interface Translatable { - Translatable translate(Translator translator, EntryResolver resolver, EntryMap mappings); -} diff --git a/src/main/java/cuchaz/enigma/translation/TranslationDirection.java b/src/main/java/cuchaz/enigma/translation/TranslationDirection.java deleted file mode 100644 index 2ecb30b..0000000 --- a/src/main/java/cuchaz/enigma/translation/TranslationDirection.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation; - -public enum TranslationDirection { - - DEOBFUSCATING { - @Override - public T choose(T deobfChoice, T obfChoice) { - if (deobfChoice == null) { - return obfChoice; - } - return deobfChoice; - } - }, - OBFUSCATING { - @Override - public T choose(T deobfChoice, T obfChoice) { - if (obfChoice == null) { - return deobfChoice; - } - return obfChoice; - } - }; - - public abstract T choose(T deobfChoice, T obfChoice); -} diff --git a/src/main/java/cuchaz/enigma/translation/Translator.java b/src/main/java/cuchaz/enigma/translation/Translator.java deleted file mode 100644 index c70141f..0000000 --- a/src/main/java/cuchaz/enigma/translation/Translator.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -public interface Translator { - T translate(T translatable); - - default Collection translate(Collection translatable) { - return translatable.stream() - .map(this::translate) - .collect(Collectors.toList()); - } - - default Set translate(Set translatable) { - return translatable.stream() - .map(this::translate) - .collect(Collectors.toSet()); - } - - default Map translateKeys(Map translatable) { - Map result = new HashMap<>(translatable.size()); - for (Map.Entry entry : translatable.entrySet()) { - result.put(translate(entry.getKey()), entry.getValue()); - } - return result; - } - - default Map translate(Map translatable) { - Map result = new HashMap<>(translatable.size()); - for (Map.Entry entry : translatable.entrySet()) { - result.put(translate(entry.getKey()), translate(entry.getValue())); - } - return result; - } - - default Multimap translate(Multimap translatable) { - Multimap result = HashMultimap.create(translatable.size(), 1); - for (Map.Entry> entry : translatable.asMap().entrySet()) { - result.putAll(translate(entry.getKey()), translate(entry.getValue())); - } - return result; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/VoidTranslator.java b/src/main/java/cuchaz/enigma/translation/VoidTranslator.java deleted file mode 100644 index c010833..0000000 --- a/src/main/java/cuchaz/enigma/translation/VoidTranslator.java +++ /dev/null @@ -1,10 +0,0 @@ -package cuchaz.enigma.translation; - -public enum VoidTranslator implements Translator { - INSTANCE; - - @Override - public T translate(T translatable) { - return translatable; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/AccessModifier.java b/src/main/java/cuchaz/enigma/translation/mapping/AccessModifier.java deleted file mode 100644 index 5b79b79..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/AccessModifier.java +++ /dev/null @@ -1,25 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.translation.representation.AccessFlags; - -public enum AccessModifier { - UNCHANGED, PUBLIC, PROTECTED, PRIVATE; - - public String getFormattedName() { - return "ACC:" + super.toString(); - } - - public AccessFlags transform(AccessFlags access) { - switch (this) { - case PUBLIC: - return access.setPublic(); - case PROTECTED: - return access.setProtected(); - case PRIVATE: - return access.setPrivate(); - case UNCHANGED: - default: - return access; - } - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java deleted file mode 100644 index e1a3253..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/EntryMap.java +++ /dev/null @@ -1,24 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nullable; -import java.util.stream.Stream; - -public interface EntryMap { - void insert(Entry entry, T value); - - @Nullable - T remove(Entry entry); - - @Nullable - T get(Entry entry); - - default boolean contains(Entry entry) { - return get(entry) != null; - } - - Stream> getAllEntries(); - - boolean isEmpty(); -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java deleted file mode 100644 index c607817..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/EntryMapping.java +++ /dev/null @@ -1,75 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class EntryMapping { - private final String targetName; - private final AccessModifier accessModifier; - private final @Nullable String javadoc; - - public EntryMapping(@Nonnull String targetName) { - this(targetName, AccessModifier.UNCHANGED); - } - - public EntryMapping(@Nonnull String targetName, @Nullable String javadoc) { - this(targetName, AccessModifier.UNCHANGED, javadoc); - } - - public EntryMapping(@Nonnull String targetName, AccessModifier accessModifier) { - this(targetName, accessModifier, null); - } - - public EntryMapping(@Nonnull String targetName, AccessModifier accessModifier, @Nullable String javadoc) { - this.targetName = targetName; - this.accessModifier = accessModifier; - this.javadoc = javadoc; - } - - @Nonnull - public String getTargetName() { - return targetName; - } - - @Nonnull - public AccessModifier getAccessModifier() { - if (accessModifier == null) { - return AccessModifier.UNCHANGED; - } - return accessModifier; - } - - @Nullable - public String getJavadoc() { - return javadoc; - } - - public EntryMapping withName(String newName) { - return new EntryMapping(newName, accessModifier, javadoc); - } - - public EntryMapping withModifier(AccessModifier newModifier) { - return new EntryMapping(targetName, newModifier, javadoc); - } - - public EntryMapping withDocs(String newDocs) { - return new EntryMapping(targetName, accessModifier, newDocs); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - - if (obj instanceof EntryMapping) { - EntryMapping mapping = (EntryMapping) obj; - return mapping.targetName.equals(targetName) && mapping.accessModifier.equals(accessModifier); - } - - return false; - } - - @Override - public int hashCode() { - return targetName.hashCode() + accessModifier.hashCode() * 31; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java deleted file mode 100644 index ad36c97..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/EntryRemapper.java +++ /dev/null @@ -1,105 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.analysis.index.JarIndex; -import cuchaz.enigma.translation.MappingTranslator; -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.tree.DeltaTrackingTree; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nullable; -import java.util.Collection; -import java.util.function.UnaryOperator; -import java.util.stream.Stream; - -public class EntryRemapper { - private final DeltaTrackingTree obfToDeobf; - - private final EntryResolver obfResolver; - private final Translator deobfuscator; - - private final MappingValidator validator; - - private EntryRemapper(JarIndex jarIndex, EntryTree obfToDeobf) { - this.obfToDeobf = new DeltaTrackingTree<>(obfToDeobf); - - this.obfResolver = jarIndex.getEntryResolver(); - - this.deobfuscator = new MappingTranslator(obfToDeobf, obfResolver); - - this.validator = new MappingValidator(obfToDeobf, deobfuscator, jarIndex); - } - - public static EntryRemapper mapped(JarIndex index, EntryTree obfToDeobf) { - return new EntryRemapper(index, obfToDeobf); - } - - public static EntryRemapper empty(JarIndex index) { - return new EntryRemapper(index, new HashEntryTree<>()); - } - - public > void mapFromObf(E obfuscatedEntry, @Nullable EntryMapping deobfMapping) { - mapFromObf(obfuscatedEntry, deobfMapping, true); - } - - public > void mapFromObf(E obfuscatedEntry, @Nullable EntryMapping deobfMapping, boolean renaming) { - Collection resolvedEntries = obfResolver.resolveEntry(obfuscatedEntry, renaming ? ResolutionStrategy.RESOLVE_ROOT : ResolutionStrategy.RESOLVE_CLOSEST); - - if (renaming && deobfMapping != null) { - for (E resolvedEntry : resolvedEntries) { - validator.validateRename(resolvedEntry, deobfMapping.getTargetName()); - } - } - - for (E resolvedEntry : resolvedEntries) { - obfToDeobf.insert(resolvedEntry, deobfMapping); - } - } - - public void removeByObf(Entry obfuscatedEntry) { - mapFromObf(obfuscatedEntry, null); - } - - @Nullable - public EntryMapping getDeobfMapping(Entry entry) { - return obfToDeobf.get(entry); - } - - public boolean hasDeobfMapping(Entry obfEntry) { - return obfToDeobf.contains(obfEntry); - } - - public T deobfuscate(T translatable) { - return deobfuscator.translate(translatable); - } - - public Translator getDeobfuscator() { - return deobfuscator; - } - - public Stream> getObfEntries() { - return obfToDeobf.getAllEntries(); - } - - public Collection> getObfChildren(Entry obfuscatedEntry) { - return obfToDeobf.getChildren(obfuscatedEntry); - } - - public DeltaTrackingTree getObfToDeobf() { - return obfToDeobf; - } - - public MappingDelta takeMappingDelta() { - return obfToDeobf.takeDelta(); - } - - public boolean isDirty() { - return obfToDeobf.isDirty(); - } - - public EntryResolver getObfResolver() { - return obfResolver; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/EntryResolver.java b/src/main/java/cuchaz/enigma/translation/mapping/EntryResolver.java deleted file mode 100644 index 521f72d..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/EntryResolver.java +++ /dev/null @@ -1,41 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import com.google.common.collect.Streams; -import cuchaz.enigma.analysis.EntryReference; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; - -import java.util.Collection; -import java.util.Set; -import java.util.stream.Collectors; - -public interface EntryResolver { - > Collection resolveEntry(E entry, ResolutionStrategy strategy); - - default > E resolveFirstEntry(E entry, ResolutionStrategy strategy) { - return resolveEntry(entry, strategy).stream().findFirst().orElse(entry); - } - - default , C extends Entry> Collection> resolveReference(EntryReference reference, ResolutionStrategy strategy) { - Collection entry = resolveEntry(reference.entry, strategy); - if (reference.context != null) { - Collection context = resolveEntry(reference.context, strategy); - return Streams.zip(entry.stream(), context.stream(), (e, c) -> new EntryReference<>(e, c, reference)) - .collect(Collectors.toList()); - } else { - return entry.stream() - .map(e -> new EntryReference<>(e, null, reference)) - .collect(Collectors.toList()); - } - } - - default , C extends Entry> EntryReference resolveFirstReference(EntryReference reference, ResolutionStrategy strategy) { - E entry = resolveFirstEntry(reference.entry, strategy); - C context = resolveFirstEntry(reference.context, strategy); - return new EntryReference<>(entry, context, reference); - } - - Set> resolveEquivalentEntries(Entry entry); - - Set resolveEquivalentMethods(MethodEntry methodEntry); -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java b/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java deleted file mode 100644 index 78231dd..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/IndexEntryResolver.java +++ /dev/null @@ -1,227 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import com.google.common.collect.Sets; -import cuchaz.enigma.analysis.IndexTreeBuilder; -import cuchaz.enigma.analysis.MethodImplementationsTreeNode; -import cuchaz.enigma.analysis.MethodInheritanceTreeNode; -import cuchaz.enigma.analysis.index.BridgeMethodIndex; -import cuchaz.enigma.analysis.index.EntryIndex; -import cuchaz.enigma.analysis.index.InheritanceIndex; -import cuchaz.enigma.analysis.index.JarIndex; -import cuchaz.enigma.translation.VoidTranslator; -import cuchaz.enigma.translation.representation.AccessFlags; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; - -import javax.annotation.Nullable; -import java.util.*; -import java.util.stream.Collectors; - -public class IndexEntryResolver implements EntryResolver { - private final EntryIndex entryIndex; - private final InheritanceIndex inheritanceIndex; - private final BridgeMethodIndex bridgeMethodIndex; - - private final IndexTreeBuilder treeBuilder; - - public IndexEntryResolver(JarIndex index) { - this.entryIndex = index.getEntryIndex(); - this.inheritanceIndex = index.getInheritanceIndex(); - this.bridgeMethodIndex = index.getBridgeMethodIndex(); - - this.treeBuilder = new IndexTreeBuilder(index); - } - - @Override - @SuppressWarnings("unchecked") - public > Collection resolveEntry(E entry, ResolutionStrategy strategy) { - if (entry == null) { - return Collections.emptySet(); - } - - Entry classChild = getClassChild(entry); - if (classChild != null && !(classChild instanceof ClassEntry)) { - AccessFlags access = entryIndex.getEntryAccess(classChild); - - // If we're looking for the closest and this entry exists, we're done looking - if (strategy == ResolutionStrategy.RESOLVE_CLOSEST && access != null) { - return Collections.singleton(entry); - } - - if (access == null || !access.isPrivate()) { - Collection> resolvedChildren = resolveChildEntry(classChild, strategy); - if (!resolvedChildren.isEmpty()) { - return resolvedChildren.stream() - .map(resolvedChild -> (E) entry.replaceAncestor(classChild, resolvedChild)) - .collect(Collectors.toList()); - } - } - } - - return Collections.singleton(entry); - } - - @Nullable - private Entry getClassChild(Entry entry) { - if (entry instanceof ClassEntry) { - return null; - } - - // get the entry in the hierarchy that is the child of a class - List> ancestry = entry.getAncestry(); - for (int i = ancestry.size() - 1; i > 0; i--) { - Entry child = ancestry.get(i); - Entry cast = child.castParent(ClassEntry.class); - if (cast != null && !(cast instanceof ClassEntry)) { - // we found the entry which is a child of a class, we are now able to resolve the owner of this entry - return cast; - } - } - - return null; - } - - private Set> resolveChildEntry(Entry entry, ResolutionStrategy strategy) { - ClassEntry ownerClass = entry.getParent(); - - if (entry instanceof MethodEntry) { - MethodEntry bridgeMethod = bridgeMethodIndex.getBridgeFromSpecialized((MethodEntry) entry); - if (bridgeMethod != null && ownerClass.equals(bridgeMethod.getParent())) { - Set> resolvedBridge = resolveChildEntry(bridgeMethod, strategy); - if (!resolvedBridge.isEmpty()) { - return resolvedBridge; - } else { - return Collections.singleton(bridgeMethod); - } - } - } - - Set> resolvedEntries = new HashSet<>(); - - for (ClassEntry parentClass : inheritanceIndex.getParents(ownerClass)) { - Entry parentEntry = entry.withParent(parentClass); - - if (strategy == ResolutionStrategy.RESOLVE_ROOT) { - resolvedEntries.addAll(resolveRoot(parentEntry, strategy)); - } else { - resolvedEntries.addAll(resolveClosest(parentEntry, strategy)); - } - } - - return resolvedEntries; - } - - private Collection> resolveRoot(Entry entry, ResolutionStrategy strategy) { - // When resolving root, we want to first look for the lowest entry before returning ourselves - Set> parentResolution = resolveChildEntry(entry, strategy); - - if (parentResolution.isEmpty()) { - AccessFlags parentAccess = entryIndex.getEntryAccess(entry); - if (parentAccess != null && !parentAccess.isPrivate()) { - return Collections.singleton(entry); - } - } - - return parentResolution; - } - - private Collection> resolveClosest(Entry entry, ResolutionStrategy strategy) { - // When resolving closest, we want to first check if we exist before looking further down - AccessFlags parentAccess = entryIndex.getEntryAccess(entry); - if (parentAccess != null && !parentAccess.isPrivate()) { - return Collections.singleton(entry); - } else { - return resolveChildEntry(entry, strategy); - } - } - - @Override - public Set> resolveEquivalentEntries(Entry entry) { - MethodEntry relevantMethod = entry.findAncestor(MethodEntry.class); - if (relevantMethod == null || !entryIndex.hasMethod(relevantMethod)) { - return Collections.singleton(entry); - } - - Set equivalentMethods = resolveEquivalentMethods(relevantMethod); - Set> equivalentEntries = new HashSet<>(equivalentMethods.size()); - - for (MethodEntry equivalentMethod : equivalentMethods) { - Entry equivalentEntry = entry.replaceAncestor(relevantMethod, equivalentMethod); - equivalentEntries.add(equivalentEntry); - } - - return equivalentEntries; - } - - @Override - public Set resolveEquivalentMethods(MethodEntry methodEntry) { - AccessFlags access = entryIndex.getMethodAccess(methodEntry); - if (access == null) { - throw new IllegalArgumentException("Could not find method " + methodEntry); - } - - if (!canInherit(methodEntry, access)) { - return Collections.singleton(methodEntry); - } - - Set methodEntries = Sets.newHashSet(); - resolveEquivalentMethods(methodEntries, treeBuilder.buildMethodInheritance(VoidTranslator.INSTANCE, methodEntry)); - return methodEntries; - } - - private void resolveEquivalentMethods(Set methodEntries, MethodInheritanceTreeNode node) { - MethodEntry methodEntry = node.getMethodEntry(); - if (methodEntries.contains(methodEntry)) { - return; - } - - AccessFlags flags = entryIndex.getMethodAccess(methodEntry); - if (flags != null && canInherit(methodEntry, flags)) { - // collect the entry - methodEntries.add(methodEntry); - } - - // look at bridge methods! - MethodEntry bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(methodEntry); - while (bridgedMethod != null) { - methodEntries.addAll(resolveEquivalentMethods(bridgedMethod)); - bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(bridgedMethod); - } - - // look at interface methods too - for (MethodImplementationsTreeNode implementationsNode : treeBuilder.buildMethodImplementations(VoidTranslator.INSTANCE, methodEntry)) { - resolveEquivalentMethods(methodEntries, implementationsNode); - } - - // recurse - for (int i = 0; i < node.getChildCount(); i++) { - resolveEquivalentMethods(methodEntries, (MethodInheritanceTreeNode) node.getChildAt(i)); - } - } - - private void resolveEquivalentMethods(Set methodEntries, MethodImplementationsTreeNode node) { - MethodEntry methodEntry = node.getMethodEntry(); - AccessFlags flags = entryIndex.getMethodAccess(methodEntry); - if (flags != null && !flags.isPrivate() && !flags.isStatic()) { - // collect the entry - methodEntries.add(methodEntry); - } - - // look at bridge methods! - MethodEntry bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(methodEntry); - while (bridgedMethod != null) { - methodEntries.addAll(resolveEquivalentMethods(bridgedMethod)); - bridgedMethod = bridgeMethodIndex.getBridgeFromSpecialized(bridgedMethod); - } - - // recurse - for (int i = 0; i < node.getChildCount(); i++) { - resolveEquivalentMethods(methodEntries, (MethodImplementationsTreeNode) node.getChildAt(i)); - } - } - - private boolean canInherit(MethodEntry entry, AccessFlags access) { - return !entry.isConstructor() && !access.isPrivate() && !access.isStatic() && !access.isFinal(); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java deleted file mode 100644 index 1407bb6..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingDelta.java +++ /dev/null @@ -1,54 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; -import cuchaz.enigma.translation.representation.entry.Entry; - -import java.util.stream.Stream; - -public class MappingDelta implements Translatable { - public static final Object PLACEHOLDER = new Object(); - - private final EntryTree baseMappings; - - private final EntryTree changes; - - public MappingDelta(EntryTree baseMappings, EntryTree changes) { - this.baseMappings = baseMappings; - this.changes = changes; - } - - public MappingDelta(EntryTree baseMappings) { - this(baseMappings, new HashEntryTree<>()); - } - - public static MappingDelta added(EntryTree mappings) { - EntryTree changes = new HashEntryTree<>(); - mappings.getAllEntries().forEach(entry -> changes.insert(entry, PLACEHOLDER)); - - return new MappingDelta<>(new HashEntryTree<>(), changes); - } - - public EntryTree getBaseMappings() { - return baseMappings; - } - - public EntryTree getChanges() { - return changes; - } - - public Stream> getChangedRoots() { - return changes.getRootNodes().map(EntryTreeNode::getEntry); - } - - @Override - public MappingDelta translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - return new MappingDelta<>( - translator.translate(baseMappings), - translator.translate(changes) - ); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingFileNameFormat.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingFileNameFormat.java deleted file mode 100644 index e40bfe7..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingFileNameFormat.java +++ /dev/null @@ -1,10 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import com.google.gson.annotations.SerializedName; - -public enum MappingFileNameFormat { - @SerializedName("by_obf") - BY_OBF, - @SerializedName("by_deobf") - BY_DEOBF -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingPair.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingPair.java deleted file mode 100644 index 5d39e3d..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingPair.java +++ /dev/null @@ -1,32 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nullable; - -public class MappingPair, M> { - private final E entry; - private M mapping; - - public MappingPair(E entry, @Nullable M mapping) { - this.entry = entry; - this.mapping = mapping; - } - - public MappingPair(E entry) { - this(entry, null); - } - - public E getEntry() { - return entry; - } - - @Nullable - public M getMapping() { - return mapping; - } - - public void setMapping(M mapping) { - this.mapping = mapping; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingSaveParameters.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingSaveParameters.java deleted file mode 100644 index 07065d6..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingSaveParameters.java +++ /dev/null @@ -1,16 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import com.google.gson.annotations.SerializedName; - -public class MappingSaveParameters { - @SerializedName("file_name_format") - private final MappingFileNameFormat fileNameFormat; - - public MappingSaveParameters(MappingFileNameFormat fileNameFormat) { - this.fileNameFormat = fileNameFormat; - } - - public MappingFileNameFormat getFileNameFormat() { - return fileNameFormat; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java deleted file mode 100644 index dffcb0c..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingValidator.java +++ /dev/null @@ -1,76 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.analysis.index.InheritanceIndex; -import cuchaz.enigma.analysis.index.JarIndex; -import cuchaz.enigma.throwables.IllegalNameException; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; - -import java.util.Collection; -import java.util.HashSet; -import java.util.stream.Collectors; - -public class MappingValidator { - private final EntryTree obfToDeobf; - private final Translator deobfuscator; - private final JarIndex index; - - public MappingValidator(EntryTree obfToDeobf, Translator deobfuscator, JarIndex index) { - this.obfToDeobf = obfToDeobf; - this.deobfuscator = deobfuscator; - this.index = index; - } - - public void validateRename(Entry entry, String name) throws IllegalNameException { - Collection> equivalentEntries = index.getEntryResolver().resolveEquivalentEntries(entry); - for (Entry equivalentEntry : equivalentEntries) { - equivalentEntry.validateName(name); - validateUnique(equivalentEntry, name); - } - } - - private void validateUnique(Entry entry, String name) { - ClassEntry containingClass = entry.getContainingClass(); - Collection relatedClasses = getRelatedClasses(containingClass); - - for (ClassEntry relatedClass : relatedClasses) { - Entry relatedEntry = entry.replaceAncestor(containingClass, relatedClass); - Entry translatedEntry = deobfuscator.translate(relatedEntry); - - Collection> translatedSiblings = obfToDeobf.getSiblings(relatedEntry).stream() - .map(deobfuscator::translate) - .collect(Collectors.toList()); - - if (!isUnique(translatedEntry, translatedSiblings, name)) { - Entry parent = translatedEntry.getParent(); - if (parent != null) { - throw new IllegalNameException(name, "Name is not unique in " + parent + "!"); - } else { - throw new IllegalNameException(name, "Name is not unique!"); - } - } - } - } - - private Collection getRelatedClasses(ClassEntry classEntry) { - InheritanceIndex inheritanceIndex = index.getInheritanceIndex(); - - Collection relatedClasses = new HashSet<>(); - relatedClasses.add(classEntry); - relatedClasses.addAll(inheritanceIndex.getChildren(classEntry)); - relatedClasses.addAll(inheritanceIndex.getAncestors(classEntry)); - - return relatedClasses; - } - - private boolean isUnique(Entry entry, Collection> siblings, String name) { - for (Entry sibling : siblings) { - if (entry.canConflictWith(sibling) && sibling.getName().equals(name)) { - return false; - } - } - return true; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java b/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java deleted file mode 100644 index 5d9794f..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/MappingsChecker.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.analysis.index.JarIndex; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -public class MappingsChecker { - private final JarIndex index; - private final EntryTree mappings; - - public MappingsChecker(JarIndex index, EntryTree mappings) { - this.index = index; - this.mappings = mappings; - } - - public Dropped dropBrokenMappings(ProgressListener progress) { - Dropped dropped = new Dropped(); - - Collection> obfEntries = mappings.getAllEntries() - .filter(e -> e instanceof ClassEntry || e instanceof MethodEntry || e instanceof FieldEntry || e instanceof LocalVariableEntry) - .collect(Collectors.toList()); - - progress.init(obfEntries.size(), "Checking for dropped mappings"); - - int steps = 0; - for (Entry entry : obfEntries) { - progress.step(steps++, entry.toString()); - tryDropEntry(dropped, entry); - } - - dropped.apply(mappings); - - return dropped; - } - - private void tryDropEntry(Dropped dropped, Entry entry) { - if (shouldDropEntry(entry)) { - EntryMapping mapping = mappings.get(entry); - if (mapping != null) { - dropped.drop(entry, mapping); - } - } - } - - private boolean shouldDropEntry(Entry entry) { - if (!index.getEntryIndex().hasEntry(entry)) { - return true; - } - Collection> resolvedEntries = index.getEntryResolver().resolveEntry(entry, ResolutionStrategy.RESOLVE_ROOT); - return !resolvedEntries.contains(entry); - } - - public static class Dropped { - private final Map, String> droppedMappings = new HashMap<>(); - - public void drop(Entry entry, EntryMapping mapping) { - droppedMappings.put(entry, mapping.getTargetName()); - } - - void apply(EntryTree mappings) { - for (Entry entry : droppedMappings.keySet()) { - EntryTreeNode node = mappings.findNode(entry); - if (node == null) { - continue; - } - - for (Entry childEntry : node.getChildrenRecursively()) { - mappings.remove(childEntry); - } - } - } - - public Map, String> getDroppedMappings() { - return droppedMappings; - } - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/NameValidator.java b/src/main/java/cuchaz/enigma/translation/mapping/NameValidator.java deleted file mode 100644 index 5bc2f67..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/NameValidator.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.throwables.IllegalNameException; -import cuchaz.enigma.translation.representation.entry.ClassEntry; - -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -public class NameValidator { - private static final Pattern IDENTIFIER_PATTERN; - private static final Pattern CLASS_PATTERN; - private static final List ILLEGAL_IDENTIFIERS = Arrays.asList( - "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", - "boolean", "do", "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte", - "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", "catch", - "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", - "long", "strictfp", "volatile", "const", "float", "native", "super", "while", "_" - ); - - static { - String identifierRegex = "[A-Za-z_<][A-Za-z0-9_>]*"; - IDENTIFIER_PATTERN = Pattern.compile(identifierRegex); - CLASS_PATTERN = Pattern.compile(String.format("^(%s(\\.|/))*(%s)$", identifierRegex, identifierRegex)); - } - - public static void validateClassName(String name) { - if (!CLASS_PATTERN.matcher(name).matches() || ILLEGAL_IDENTIFIERS.contains(name)) { - throw new IllegalNameException(name, "This doesn't look like a legal class name"); - } - } - - public static void validateIdentifier(String name) { - if (!IDENTIFIER_PATTERN.matcher(name).matches() || ILLEGAL_IDENTIFIERS.contains(name)) { - throw new IllegalNameException(name, "This doesn't look like a legal identifier"); - } - } - - public static boolean isReserved(String name) { - return ILLEGAL_IDENTIFIERS.contains(name); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/ResolutionStrategy.java b/src/main/java/cuchaz/enigma/translation/mapping/ResolutionStrategy.java deleted file mode 100644 index 1c28e02..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/ResolutionStrategy.java +++ /dev/null @@ -1,6 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -public enum ResolutionStrategy { - RESOLVE_ROOT, - RESOLVE_CLOSEST -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/VoidEntryResolver.java b/src/main/java/cuchaz/enigma/translation/mapping/VoidEntryResolver.java deleted file mode 100644 index 2eab55f..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/VoidEntryResolver.java +++ /dev/null @@ -1,27 +0,0 @@ -package cuchaz.enigma.translation.mapping; - -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; - -import java.util.Collection; -import java.util.Collections; -import java.util.Set; - -public enum VoidEntryResolver implements EntryResolver { - INSTANCE; - - @Override - public > Collection resolveEntry(E entry, ResolutionStrategy strategy) { - return Collections.singleton(entry); - } - - @Override - public Set> resolveEquivalentEntries(Entry entry) { - return Collections.singleton(entry); - } - - @Override - public Set resolveEquivalentMethods(MethodEntry methodEntry) { - return Collections.singleton(methodEntry); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaFormat.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaFormat.java deleted file mode 100644 index af92ffb..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaFormat.java +++ /dev/null @@ -1,9 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -public class EnigmaFormat { - public static final String COMMENT = "COMMENT"; - public static final String CLASS = "CLASS"; - public static final String FIELD = "FIELD"; - public static final String METHOD = "METHOD"; - public static final String PARAMETER = "ARG"; -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java deleted file mode 100644 index 53bbaa3..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java +++ /dev/null @@ -1,319 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import com.google.common.base.Charsets; -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.throwables.MappingParseException; -import cuchaz.enigma.translation.mapping.AccessModifier; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingPair; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; -import cuchaz.enigma.translation.representation.MethodDescriptor; -import cuchaz.enigma.translation.representation.TypeDescriptor; -import cuchaz.enigma.translation.representation.entry.*; -import cuchaz.enigma.utils.I18n; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayDeque; -import java.util.Arrays; -import java.util.Deque; -import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; - -public enum EnigmaMappingsReader implements MappingsReader { - FILE { - @Override - public EntryTree read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - progress.init(1, I18n.translate("progress.mappings.enigma_file.loading")); - - EntryTree mappings = new HashEntryTree<>(); - readFile(path, mappings); - - progress.step(1, I18n.translate("progress.mappings.enigma_file.done")); - - return mappings; - } - }, - DIRECTORY { - @Override - public EntryTree read(Path root, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - EntryTree mappings = new HashEntryTree<>(); - - List files = Files.walk(root) - .filter(f -> !Files.isDirectory(f)) - .filter(f -> f.toString().endsWith(".mapping")) - .collect(Collectors.toList()); - - progress.init(files.size(), I18n.translate("progress.mappings.enigma_directory.loading")); - int step = 0; - - for (Path file : files) { - progress.step(step++, root.relativize(file).toString()); - if (Files.isHidden(file)) { - continue; - } - readFile(file, mappings); - } - - return mappings; - } - }, - ZIP { - @Override - public EntryTree read(Path zip, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException { - try (FileSystem fs = FileSystems.newFileSystem(zip, (ClassLoader) null)) { - return DIRECTORY.read(fs.getPath("/"), progress, saveParameters); - } - } - }; - - protected void readFile(Path path, EntryTree mappings) throws IOException, MappingParseException { - List lines = Files.readAllLines(path, Charsets.UTF_8); - Deque> mappingStack = new ArrayDeque<>(); - - for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { - String line = lines.get(lineNumber); - int indentation = countIndentation(line); - - line = formatLine(line); - if (line == null) { - continue; - } - - cleanMappingStack(indentation, mappingStack, mappings); - - try { - MappingPair pair = parseLine(mappingStack.peek(), line); - if (pair != null) { - mappingStack.push(pair); - if (pair.getMapping() != null) { - - } - } - } catch (Throwable t) { - t.printStackTrace(); - throw new MappingParseException(path::toString, lineNumber, t.toString()); - } - } - - // Clean up rest - cleanMappingStack(0, mappingStack, mappings); - } - - private void cleanMappingStack(int indentation, Deque> mappingStack, EntryTree mappings) { - while (indentation < mappingStack.size()) { - MappingPair pair = mappingStack.pop(); - if (pair.getMapping() != null) { - mappings.insert(pair.getEntry(), pair.getMapping().bake()); - } - } - } - - @Nullable - private String formatLine(String line) { - line = stripComment(line); - line = line.trim(); - - if (line.isEmpty()) { - return null; - } - - return line; - } - - private String stripComment(String line) { - //Dont support comments on javadoc lines - if (line.trim().startsWith(EnigmaFormat.COMMENT)) { - return line; - } - - int commentPos = line.indexOf('#'); - if (commentPos >= 0) { - return line.substring(0, commentPos); - } - return line; - } - - private int countIndentation(String line) { - int indent = 0; - for (int i = 0; i < line.length(); i++) { - if (line.charAt(i) != '\t') { - break; - } - indent++; - } - return indent; - } - - private MappingPair parseLine(@Nullable MappingPair parent, String line) { - String[] tokens = line.trim().split("\\s"); - String keyToken = tokens[0].toUpperCase(Locale.ROOT); - Entry parentEntry = parent == null ? null : parent.getEntry(); - - switch (keyToken) { - case EnigmaFormat.CLASS: - return parseClass(parentEntry, tokens); - case EnigmaFormat.FIELD: - return parseField(parentEntry, tokens); - case EnigmaFormat.METHOD: - return parseMethod(parentEntry, tokens); - case EnigmaFormat.PARAMETER: - return parseArgument(parentEntry, tokens); - case EnigmaFormat.COMMENT: - readJavadoc(parent, tokens); - return null; - default: - throw new RuntimeException("Unknown token '" + keyToken + "'"); - } - } - - private void readJavadoc(MappingPair parent, String[] tokens) { - if (parent == null) - throw new IllegalStateException("Javadoc has no parent!"); - // Empty string to concat - String jdLine = tokens.length > 1 ? String.join(" ", Arrays.copyOfRange(tokens,1,tokens.length)) : ""; - if (parent.getMapping() == null) { - parent.setMapping(new RawEntryMapping(parent.getEntry().getName(), AccessModifier.UNCHANGED)); - } - parent.getMapping().addJavadocLine(MappingHelper.unescape(jdLine)); - } - - private MappingPair parseClass(@Nullable Entry parent, String[] tokens) { - String obfuscatedName = ClassEntry.getInnerName(tokens[1]); - ClassEntry obfuscatedEntry; - if (parent instanceof ClassEntry) { - obfuscatedEntry = new ClassEntry((ClassEntry) parent, obfuscatedName); - } else { - obfuscatedEntry = new ClassEntry(obfuscatedName); - } - - String mapping = null; - AccessModifier modifier = AccessModifier.UNCHANGED; - - if (tokens.length == 3) { - AccessModifier parsedModifier = parseModifier(tokens[2]); - if (parsedModifier != null) { - modifier = parsedModifier; - mapping = obfuscatedName; - } else { - mapping = tokens[2]; - } - } else if (tokens.length == 4) { - mapping = tokens[2]; - modifier = parseModifier(tokens[3]); - } - - if (mapping != null) { - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); - } else { - return new MappingPair<>(obfuscatedEntry); - } - } - - private MappingPair parseField(@Nullable Entry parent, String[] tokens) { - if (!(parent instanceof ClassEntry)) { - throw new RuntimeException("Field must be a child of a class!"); - } - - ClassEntry ownerEntry = (ClassEntry) parent; - - String obfuscatedName = tokens[1]; - String mapping = obfuscatedName; - AccessModifier modifier = AccessModifier.UNCHANGED; - TypeDescriptor descriptor; - - if (tokens.length == 3) { - mapping = tokens[1]; - descriptor = new TypeDescriptor(tokens[2]); - } else if (tokens.length == 4) { - AccessModifier parsedModifier = parseModifier(tokens[3]); - if (parsedModifier != null) { - descriptor = new TypeDescriptor(tokens[2]); - modifier = parsedModifier; - } else { - mapping = tokens[2]; - descriptor = new TypeDescriptor(tokens[3]); - } - } else if (tokens.length == 5) { - descriptor = new TypeDescriptor(tokens[3]); - mapping = tokens[2]; - modifier = parseModifier(tokens[4]); - } else { - throw new RuntimeException("Invalid field declaration"); - } - - FieldEntry obfuscatedEntry = new FieldEntry(ownerEntry, obfuscatedName, descriptor); - if (mapping != null) { - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); - } else { - return new MappingPair<>(obfuscatedEntry); - } - } - - private MappingPair parseMethod(@Nullable Entry parent, String[] tokens) { - if (!(parent instanceof ClassEntry)) { - throw new RuntimeException("Method must be a child of a class!"); - } - - ClassEntry ownerEntry = (ClassEntry) parent; - - String obfuscatedName = tokens[1]; - String mapping = null; - AccessModifier modifier = AccessModifier.UNCHANGED; - MethodDescriptor descriptor; - - if (tokens.length == 3) { - descriptor = new MethodDescriptor(tokens[2]); - } else if (tokens.length == 4) { - AccessModifier parsedModifier = parseModifier(tokens[3]); - if (parsedModifier != null) { - modifier = parsedModifier; - mapping = obfuscatedName; - descriptor = new MethodDescriptor(tokens[2]); - } else { - mapping = tokens[2]; - descriptor = new MethodDescriptor(tokens[3]); - } - } else if (tokens.length == 5) { - mapping = tokens[2]; - modifier = parseModifier(tokens[4]); - descriptor = new MethodDescriptor(tokens[3]); - } else { - throw new RuntimeException("Invalid method declaration"); - } - - MethodEntry obfuscatedEntry = new MethodEntry(ownerEntry, obfuscatedName, descriptor); - if (mapping != null) { - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping, modifier)); - } else { - return new MappingPair<>(obfuscatedEntry); - } - } - - private MappingPair parseArgument(@Nullable Entry parent, String[] tokens) { - if (!(parent instanceof MethodEntry)) { - throw new RuntimeException("Method arg must be a child of a method!"); - } - - MethodEntry ownerEntry = (MethodEntry) parent; - LocalVariableEntry obfuscatedEntry = new LocalVariableEntry(ownerEntry, Integer.parseInt(tokens[1]), "", true, null); - String mapping = tokens[2]; - - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping)); - } - - @Nullable - private AccessModifier parseModifier(String token) { - if (token.startsWith("ACC:")) { - return AccessModifier.valueOf(token.substring(4)); - } - return null; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java deleted file mode 100644 index be0fceb..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java +++ /dev/null @@ -1,316 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.mapping.serde; - -import java.io.IOException; -import java.io.PrintWriter; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.DirectoryStream; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.translation.MappingTranslator; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.AccessModifier; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingDelta; -import cuchaz.enigma.translation.mapping.MappingFileNameFormat; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.VoidEntryResolver; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; -import cuchaz.enigma.utils.I18n; -import cuchaz.enigma.utils.LFPrintWriter; - -public enum EnigmaMappingsWriter implements MappingsWriter { - FILE { - @Override - public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { - Collection classes = mappings.getRootNodes() - .filter(entry -> entry instanceof ClassEntry) - .map(entry -> (ClassEntry) entry) - .collect(Collectors.toList()); - - progress.init(classes.size(), I18n.translate("progress.mappings.enigma_file.writing")); - - int steps = 0; - try (PrintWriter writer = new LFPrintWriter(Files.newBufferedWriter(path))) { - for (ClassEntry classEntry : classes) { - progress.step(steps++, classEntry.getFullName()); - writeRoot(writer, mappings, classEntry); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - }, - DIRECTORY { - @Override - public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { - Collection changedClasses = delta.getChangedRoots() - .filter(entry -> entry instanceof ClassEntry) - .map(entry -> (ClassEntry) entry) - .collect(Collectors.toList()); - - applyDeletions(path, changedClasses, mappings, delta.getBaseMappings(), saveParameters.getFileNameFormat()); - - progress.init(changedClasses.size(), I18n.translate("progress.mappings.enigma_directory.writing")); - - AtomicInteger steps = new AtomicInteger(); - - Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); - changedClasses.parallelStream().forEach(classEntry -> { - progress.step(steps.getAndIncrement(), classEntry.getFullName()); - - try { - ClassEntry fileEntry = classEntry; - if (saveParameters.getFileNameFormat() == MappingFileNameFormat.BY_DEOBF) { - fileEntry = translator.translate(fileEntry); - } - - Path classPath = resolve(path, fileEntry); - Files.createDirectories(classPath.getParent()); - Files.deleteIfExists(classPath); - - try (PrintWriter writer = new LFPrintWriter(Files.newBufferedWriter(classPath))) { - writeRoot(writer, mappings, classEntry); - } - } catch (Throwable t) { - System.err.println("Failed to write class '" + classEntry.getFullName() + "'"); - t.printStackTrace(); - } - }); - } - - private void applyDeletions(Path root, Collection changedClasses, EntryTree mappings, EntryTree oldMappings, MappingFileNameFormat fileNameFormat) { - Translator oldMappingTranslator = new MappingTranslator(oldMappings, VoidEntryResolver.INSTANCE); - - Stream deletedClassStream = changedClasses.stream() - .filter(e -> !Objects.equals(oldMappings.get(e), mappings.get(e))); - - if (fileNameFormat == MappingFileNameFormat.BY_DEOBF) { - deletedClassStream = deletedClassStream.map(oldMappingTranslator::translate); - } - - Collection deletedClasses = deletedClassStream.collect(Collectors.toList()); - - for (ClassEntry classEntry : deletedClasses) { - try { - Files.deleteIfExists(resolve(root, classEntry)); - } catch (IOException e) { - System.err.println("Failed to delete deleted class '" + classEntry + "'"); - e.printStackTrace(); - } - } - - for (ClassEntry classEntry : deletedClasses) { - String packageName = classEntry.getPackageName(); - if (packageName != null) { - Path packagePath = Paths.get(packageName); - try { - deleteDeadPackages(root, packagePath); - } catch (IOException e) { - System.err.println("Failed to delete dead package '" + packageName + "'"); - e.printStackTrace(); - } - } - } - } - - private void deleteDeadPackages(Path root, Path packagePath) throws IOException { - for (int i = packagePath.getNameCount() - 1; i >= 0; i--) { - Path subPath = packagePath.subpath(0, i + 1); - Path packagePart = root.resolve(subPath); - if (isEmpty(packagePart)) { - Files.deleteIfExists(packagePart); - } - } - } - - private boolean isEmpty(Path path) { - try (DirectoryStream stream = Files.newDirectoryStream(path)) { - return !stream.iterator().hasNext(); - } catch (IOException e) { - return false; - } - } - - private Path resolve(Path root, ClassEntry classEntry) { - return root.resolve(classEntry.getFullName() + ".mapping"); - } - }, - ZIP { - @Override - public void write(EntryTree mappings, MappingDelta delta, Path zip, ProgressListener progress, MappingSaveParameters saveParameters) { - try (FileSystem fs = FileSystems.newFileSystem(new URI("jar:file", null, zip.toUri().getPath(), ""), Collections.singletonMap("create", "true"))) { - DIRECTORY.write(mappings, delta, fs.getPath("/"), progress, saveParameters); - } catch (IOException e) { - e.printStackTrace(); - } catch (URISyntaxException e) { - throw new RuntimeException("Unexpected error creating URI for " + zip, e); - } - } - }; - - protected void writeRoot(PrintWriter writer, EntryTree mappings, ClassEntry classEntry) { - Collection> children = groupChildren(mappings.getChildren(classEntry)); - - EntryMapping classEntryMapping = mappings.get(classEntry); - - writer.println(writeClass(classEntry, classEntryMapping).trim()); - if (classEntryMapping != null && classEntryMapping.getJavadoc() != null) { - writeDocs(writer, classEntryMapping, 0); - } - - for (Entry child : children) { - writeEntry(writer, mappings, child, 1); - } - - } - - private void writeDocs(PrintWriter writer, EntryMapping mapping, int depth) { - String jd = mapping.getJavadoc(); - if (jd != null) { - for (String line : jd.split("\\R")) { - writer.println(indent(EnigmaFormat.COMMENT + " " + MappingHelper.escape(line), depth + 1)); - } - } - } - - protected void writeEntry(PrintWriter writer, EntryTree mappings, Entry entry, int depth) { - EntryTreeNode node = mappings.findNode(entry); - if (node == null) { - return; - } - - EntryMapping mapping = node.getValue(); - - if (entry instanceof ClassEntry) { - String line = writeClass((ClassEntry) entry, mapping); - writer.println(indent(line, depth)); - } else if (entry instanceof MethodEntry) { - String line = writeMethod((MethodEntry) entry, mapping); - writer.println(indent(line, depth)); - } else if (entry instanceof FieldEntry) { - String line = writeField((FieldEntry) entry, mapping); - writer.println(indent(line, depth)); - } else if (entry instanceof LocalVariableEntry && mapping != null) { - String line = writeArgument((LocalVariableEntry) entry, mapping); - writer.println(indent(line, depth)); - } - if (mapping != null && mapping.getJavadoc() != null) { - writeDocs(writer, mapping, depth); - } - - Collection> children = groupChildren(node.getChildren()); - for (Entry child : children) { - writeEntry(writer, mappings, child, depth + 1); - } - } - - private Collection> groupChildren(Collection> children) { - Collection> result = new ArrayList<>(children.size()); - - children.stream().filter(e -> e instanceof FieldEntry) - .map(e -> (FieldEntry) e) - .sorted() - .forEach(result::add); - - children.stream().filter(e -> e instanceof MethodEntry) - .map(e -> (MethodEntry) e) - .sorted() - .forEach(result::add); - - children.stream().filter(e -> e instanceof LocalVariableEntry) - .map(e -> (LocalVariableEntry) e) - .sorted() - .forEach(result::add); - - children.stream().filter(e -> e instanceof ClassEntry) - .map(e -> (ClassEntry) e) - .sorted() - .forEach(result::add); - - return result; - } - - protected String writeClass(ClassEntry entry, EntryMapping mapping) { - StringBuilder builder = new StringBuilder(EnigmaFormat.CLASS +" "); - builder.append(entry.getName()).append(' '); - writeMapping(builder, mapping); - - return builder.toString(); - } - - protected String writeMethod(MethodEntry entry, EntryMapping mapping) { - StringBuilder builder = new StringBuilder(EnigmaFormat.METHOD + " "); - builder.append(entry.getName()).append(' '); - if (mapping != null && !mapping.getTargetName().equals(entry.getName())) { - writeMapping(builder, mapping); - } - - builder.append(entry.getDesc().toString()); - - return builder.toString(); - } - - protected String writeField(FieldEntry entry, EntryMapping mapping) { - StringBuilder builder = new StringBuilder(EnigmaFormat.FIELD + " "); - builder.append(entry.getName()).append(' '); - if (mapping != null && !mapping.getTargetName().equals(entry.getName())) { - writeMapping(builder, mapping); - } - - builder.append(entry.getDesc().toString()); - - return builder.toString(); - } - - protected String writeArgument(LocalVariableEntry entry, EntryMapping mapping) { - return EnigmaFormat.PARAMETER + " " + entry.getIndex() + ' ' + mapping.getTargetName(); - } - - private void writeMapping(StringBuilder builder, EntryMapping mapping) { - if (mapping != null) { - builder.append(mapping.getTargetName()).append(' '); - if (mapping.getAccessModifier() != AccessModifier.UNCHANGED) { - builder.append(mapping.getAccessModifier().getFormattedName()).append(' '); - } - } - } - - private String indent(String line, int depth) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < depth; i++) { - builder.append("\t"); - } - builder.append(line.trim()); - return builder.toString(); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java deleted file mode 100644 index 6c8c343..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ /dev/null @@ -1,59 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.throwables.MappingParseException; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingDelta; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.nio.file.Path; - -public enum MappingFormat { - ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE), - ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY), - ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP), - TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), - TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), - SRG_FILE(SrgMappingsWriter.INSTANCE, null), - PROGUARD(null, ProguardMappingsReader.INSTANCE); - - - private final MappingsWriter writer; - private final MappingsReader reader; - - MappingFormat(MappingsWriter writer, MappingsReader reader) { - this.writer = writer; - this.reader = reader; - } - - public void write(EntryTree mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { - write(mappings, MappingDelta.added(mappings), path, progressListener, saveParameters); - } - - public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { - if (writer == null) { - throw new IllegalStateException(name() + " does not support writing"); - } - writer.write(mappings, delta, path, progressListener, saveParameters); - } - - public EntryTree read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - if (reader == null) { - throw new IllegalStateException(name() + " does not support reading"); - } - return reader.read(path, progressListener, saveParameters); - } - - @Nullable - public MappingsWriter getWriter() { - return writer; - } - - @Nullable - public MappingsReader getReader() { - return reader; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java deleted file mode 100644 index 7c8f6cc..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingHelper.java +++ /dev/null @@ -1,51 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -public final class MappingHelper { - private static final String TO_ESCAPE = "\\\n\r\0\t"; - private static final String ESCAPED = "\\nr0t"; - - public static String escape(String raw) { - StringBuilder builder = new StringBuilder(raw.length() + 1); - for (int i = 0; i < raw.length(); i++) { - final char c = raw.charAt(i); - final int r = TO_ESCAPE.indexOf(c); - if (r < 0) { - builder.append(c); - } else { - builder.append('\\').append(ESCAPED.charAt(r)); - } - } - return builder.toString(); - } - - public static String unescape(String str) { - int pos = str.indexOf('\\'); - if (pos < 0) return str; - - StringBuilder ret = new StringBuilder(str.length() - 1); - int start = 0; - - do { - ret.append(str, start, pos); - pos++; - int type; - - if (pos >= str.length()) { - throw new RuntimeException("incomplete escape sequence at the end"); - } else if ((type = ESCAPED.indexOf(str.charAt(pos))) < 0) { - throw new RuntimeException("invalid escape character: \\" + str.charAt(pos)); - } else { - ret.append(TO_ESCAPE.charAt(type)); - } - - start = pos + 1; - } while ((pos = str.indexOf('\\', start)) >= 0); - - ret.append(str, start, str.length()); - - return ret.toString(); - } - - private MappingHelper() { - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java deleted file mode 100644 index 4c60787..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsReader.java +++ /dev/null @@ -1,14 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.throwables.MappingParseException; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; - -import java.io.IOException; -import java.nio.file.Path; - -public interface MappingsReader { - EntryTree read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException; -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java deleted file mode 100644 index 8815986..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingsWriter.java +++ /dev/null @@ -1,17 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingDelta; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; - -import java.nio.file.Path; - -public interface MappingsWriter { - void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters); - - default void write(EntryTree mappings, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { - write(mappings, MappingDelta.added(mappings), path, progress, saveParameters); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/ProguardMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/ProguardMappingsReader.java deleted file mode 100644 index b5ede39..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/ProguardMappingsReader.java +++ /dev/null @@ -1,134 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.command.MappingCommandsUtil; -import cuchaz.enigma.throwables.MappingParseException; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; -import cuchaz.enigma.translation.representation.MethodDescriptor; -import cuchaz.enigma.translation.representation.TypeDescriptor; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class ProguardMappingsReader implements MappingsReader { - public static final ProguardMappingsReader INSTANCE = new ProguardMappingsReader(); - private static final String NAME = "[a-zA-Z0-9_\\-.$<>]+"; - private static final String TYPE = NAME + "(?:\\[])*"; - private static final String TYPE_LIST = "|(?:(?:" + TYPE + ",)*" + TYPE + ")"; - private static final Pattern CLASS = Pattern.compile("(" + NAME + ") -> (" + NAME + "):"); - private static final Pattern FIELD = Pattern.compile(" {4}(" + TYPE + ") (" + NAME + ") -> (" + NAME + ")"); - private static final Pattern METHOD = Pattern.compile(" {4}(?:[0-9]+:[0-9]+:)?(" + TYPE + ") (" + NAME + ")\\((" + TYPE_LIST + ")\\) -> (" + NAME + ")"); - - public ProguardMappingsReader() {} - - @Override - public EntryTree read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException { - EntryTree mappings = new HashEntryTree<>(); - - int lineNumber = 0; - ClassEntry currentClass = null; - for (String line : Files.readAllLines(path, StandardCharsets.UTF_8)) { - lineNumber++; - - if (line.startsWith("#") || line.isEmpty()) { - continue; - } - - Matcher classMatcher = CLASS.matcher(line); - Matcher fieldMatcher = FIELD.matcher(line); - Matcher methodMatcher = METHOD.matcher(line); - - if (classMatcher.matches()) { - String name = classMatcher.group(1); - String targetName = classMatcher.group(2); - - mappings.insert(currentClass = new ClassEntry(name.replace('.', '/')), new EntryMapping(ClassEntry.getInnerName(targetName.replace('.', '/')))); - } else if (fieldMatcher.matches()) { - String type = fieldMatcher.group(1); - String name = fieldMatcher.group(2); - String targetName = fieldMatcher.group(3); - - if (currentClass == null) { - throw new MappingParseException(path::toString, lineNumber, "field mapping not inside class: " + line); - } - - mappings.insert(new FieldEntry(currentClass, name, new TypeDescriptor(getDescriptor(type))), new EntryMapping(targetName)); - } else if (methodMatcher.matches()) { - String returnType = methodMatcher.group(1); - String name = methodMatcher.group(2); - String[] parameterTypes = methodMatcher.group(3).isEmpty() ? new String[0] : methodMatcher.group(3).split(","); - String targetName = methodMatcher.group(4); - - if (currentClass == null) { - throw new MappingParseException(path::toString, lineNumber, "method mapping not inside class: " + line); - } - - mappings.insert(new MethodEntry(currentClass, name, new MethodDescriptor(getDescriptor(returnType, parameterTypes))), new EntryMapping(targetName)); - } else { - throw new MappingParseException(path::toString, lineNumber, "invalid mapping line: " + line); - } - } - - return MappingCommandsUtil.invert(mappings); - } - - private String getDescriptor(String type) { - StringBuilder descriptor = new StringBuilder(); - - while (type.endsWith("[]")) { - descriptor.append("["); - type = type.substring(0, type.length() - 2); - } - - switch (type) { - case "byte": - return descriptor + "B"; - case "char": - return descriptor + "C"; - case "short": - return descriptor + "S"; - case "int": - return descriptor + "I"; - case "long": - return descriptor + "J"; - case "float": - return descriptor + "F"; - case "double": - return descriptor + "D"; - case "boolean": - return descriptor + "Z"; - case "void": - return descriptor + "V"; - } - - descriptor.append("L"); - descriptor.append(type.replace('.', '/')); - descriptor.append(";"); - - return descriptor.toString(); - } - - private String getDescriptor(String returnType, String[] parameterTypes) { - StringBuilder descriptor = new StringBuilder(); - descriptor.append('('); - - for (String parameterType : parameterTypes) { - descriptor.append(getDescriptor(parameterType)); - } - - descriptor.append(')'); - descriptor.append(getDescriptor(returnType)); - - return descriptor.toString(); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java deleted file mode 100644 index afb40e9..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/RawEntryMapping.java +++ /dev/null @@ -1,30 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import cuchaz.enigma.translation.mapping.AccessModifier; -import cuchaz.enigma.translation.mapping.EntryMapping; - -import java.util.ArrayList; -import java.util.List; - -final class RawEntryMapping { - private final String targetName; - private final AccessModifier access; - private List javadocs = new ArrayList<>(); - - RawEntryMapping(String targetName) { - this(targetName, null); - } - - RawEntryMapping(String targetName, AccessModifier access) { - this.access = access; - this.targetName = targetName; - } - - void addJavadocLine(String line) { - javadocs.add(line); - } - - EntryMapping bake() { - return new EntryMapping(targetName, access, javadocs.isEmpty() ? null : String.join("\n", javadocs)); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java deleted file mode 100644 index f67f8fc..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java +++ /dev/null @@ -1,118 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import com.google.common.collect.Lists; -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.translation.MappingTranslator; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingDelta; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.VoidEntryResolver; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; -import cuchaz.enigma.utils.I18n; -import cuchaz.enigma.utils.LFPrintWriter; - -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -public enum SrgMappingsWriter implements MappingsWriter { - INSTANCE; - - @Override - public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { - try { - Files.deleteIfExists(path); - Files.createFile(path); - } catch (IOException e) { - e.printStackTrace(); - } - - List classLines = new ArrayList<>(); - List fieldLines = new ArrayList<>(); - List methodLines = new ArrayList<>(); - - Collection> rootEntries = Lists.newArrayList(mappings).stream() - .map(EntryTreeNode::getEntry) - .collect(Collectors.toList()); - progress.init(rootEntries.size(), I18n.translate("progress.mappings.srg_file.generating")); - - int steps = 0; - for (Entry entry : sorted(rootEntries)) { - progress.step(steps++, entry.getName()); - writeEntry(classLines, fieldLines, methodLines, mappings, entry); - } - - progress.init(3, I18n.translate("progress.mappings.srg_file.writing")); - try (PrintWriter writer = new LFPrintWriter(Files.newBufferedWriter(path))) { - progress.step(0, I18n.translate("type.classes")); - classLines.forEach(writer::println); - progress.step(1, I18n.translate("type.fields")); - fieldLines.forEach(writer::println); - progress.step(2, I18n.translate("type.methods")); - methodLines.forEach(writer::println); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void writeEntry(List classes, List fields, List methods, EntryTree mappings, Entry entry) { - EntryTreeNode node = mappings.findNode(entry); - if (node == null) { - return; - } - - Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); - if (entry instanceof ClassEntry) { - classes.add(generateClassLine((ClassEntry) entry, translator)); - } else if (entry instanceof FieldEntry) { - fields.add(generateFieldLine((FieldEntry) entry, translator)); - } else if (entry instanceof MethodEntry) { - methods.add(generateMethodLine((MethodEntry) entry, translator)); - } - - for (Entry child : sorted(node.getChildren())) { - writeEntry(classes, fields, methods, mappings, child); - } - } - - private String generateClassLine(ClassEntry sourceEntry, Translator translator) { - ClassEntry targetEntry = translator.translate(sourceEntry); - return "CL: " + sourceEntry.getFullName() + " " + targetEntry.getFullName(); - } - - private String generateMethodLine(MethodEntry sourceEntry, Translator translator) { - MethodEntry targetEntry = translator.translate(sourceEntry); - return "MD: " + describeMethod(sourceEntry) + " " + describeMethod(targetEntry); - } - - private String describeMethod(MethodEntry entry) { - return entry.getParent().getFullName() + "/" + entry.getName() + " " + entry.getDesc(); - } - - private String generateFieldLine(FieldEntry sourceEntry, Translator translator) { - FieldEntry targetEntry = translator.translate(sourceEntry); - return "FD: " + describeField(sourceEntry) + " " + describeField(targetEntry); - } - - private String describeField(FieldEntry entry) { - return entry.getParent().getFullName() + "/" + entry.getName(); - } - - private Collection> sorted(Iterable> iterable) { - ArrayList> sorted = Lists.newArrayList(iterable); - sorted.sort(Comparator.comparing(Entry::getName)); - return sorted; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java deleted file mode 100644 index 773c95e..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java +++ /dev/null @@ -1,115 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import com.google.common.base.Charsets; -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.throwables.MappingParseException; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingPair; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; -import cuchaz.enigma.translation.representation.MethodDescriptor; -import cuchaz.enigma.translation.representation.TypeDescriptor; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; -import cuchaz.enigma.utils.I18n; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -public enum TinyMappingsReader implements MappingsReader { - INSTANCE; - - @Override - public EntryTree read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - return read(path, Files.readAllLines(path, Charsets.UTF_8), progress); - } - - private EntryTree read(Path path, List lines, ProgressListener progress) throws MappingParseException { - EntryTree mappings = new HashEntryTree<>(); - lines.remove(0); - - progress.init(lines.size(), I18n.translate("progress.mappings.tiny_file.loading")); - - for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { - progress.step(lineNumber, ""); - - String line = lines.get(lineNumber); - - if (line.trim().startsWith("#")) { - continue; - } - - try { - MappingPair mapping = parseLine(line); - mappings.insert(mapping.getEntry(), mapping.getMapping()); - } catch (Throwable t) { - t.printStackTrace(); - throw new MappingParseException(path::toString, lineNumber, t.toString()); - } - } - - return mappings; - } - - private MappingPair parseLine(String line) { - String[] tokens = line.split("\t"); - - String key = tokens[0]; - switch (key) { - case "CLASS": - return parseClass(tokens); - case "FIELD": - return parseField(tokens); - case "METHOD": - return parseMethod(tokens); - case "MTH-ARG": - return parseArgument(tokens); - default: - throw new RuntimeException("Unknown token '" + key + "'!"); - } - } - - private MappingPair parseClass(String[] tokens) { - ClassEntry obfuscatedEntry = new ClassEntry(tokens[1]); - String mapping = tokens[2]; - if (mapping.indexOf('$') > 0) { - // inner classes should map to only the final part - mapping = mapping.substring(mapping.lastIndexOf('$') + 1); - } - return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping)); - } - - private MappingPair parseField(String[] tokens) { - ClassEntry ownerClass = new ClassEntry(tokens[1]); - TypeDescriptor descriptor = new TypeDescriptor(tokens[2]); - - FieldEntry obfuscatedEntry = new FieldEntry(ownerClass, tokens[3], descriptor); - String mapping = tokens[4]; - return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping)); - } - - private MappingPair parseMethod(String[] tokens) { - ClassEntry ownerClass = new ClassEntry(tokens[1]); - MethodDescriptor descriptor = new MethodDescriptor(tokens[2]); - - MethodEntry obfuscatedEntry = new MethodEntry(ownerClass, tokens[3], descriptor); - String mapping = tokens[4]; - return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping)); - } - - private MappingPair parseArgument(String[] tokens) { - ClassEntry ownerClass = new ClassEntry(tokens[1]); - MethodDescriptor ownerDescriptor = new MethodDescriptor(tokens[2]); - MethodEntry ownerMethod = new MethodEntry(ownerClass, tokens[3], ownerDescriptor); - int variableIndex = Integer.parseInt(tokens[4]); - - String mapping = tokens[5]; - LocalVariableEntry obfuscatedEntry = new LocalVariableEntry(ownerMethod, variableIndex, "", true, null); - return new MappingPair<>(obfuscatedEntry, new EntryMapping(mapping)); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsWriter.java deleted file mode 100644 index c82f262..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsWriter.java +++ /dev/null @@ -1,148 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import com.google.common.base.Joiner; -import com.google.common.collect.Lists; -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.translation.MappingTranslator; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingDelta; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.VoidEntryResolver; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Set; - -public class TinyMappingsWriter implements MappingsWriter { - private static final String VERSION_CONSTANT = "v1"; - private static final Joiner TAB_JOINER = Joiner.on('\t'); - - //Possibly add a gui or a way to select the namespaces when exporting from the gui - public static final TinyMappingsWriter INSTANCE = new TinyMappingsWriter("intermediary", "named"); - - // HACK: as of enigma 0.13.1, some fields seem to appear duplicated? - private final Set writtenLines = new HashSet<>(); - private final String nameObf; - private final String nameDeobf; - - public TinyMappingsWriter(String nameObf, String nameDeobf) { - this.nameObf = nameObf; - this.nameDeobf = nameDeobf; - } - - @Override - public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { - try { - Files.deleteIfExists(path); - Files.createFile(path); - } catch (IOException e) { - e.printStackTrace(); - } - - try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) { - writeLine(writer, new String[]{VERSION_CONSTANT, nameObf, nameDeobf}); - - Lists.newArrayList(mappings).stream() - .map(EntryTreeNode::getEntry).sorted(Comparator.comparing(Object::toString)) - .forEach(entry -> writeEntry(writer, mappings, entry)); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void writeEntry(Writer writer, EntryTree mappings, Entry entry) { - EntryTreeNode node = mappings.findNode(entry); - if (node == null) { - return; - } - - Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); - - EntryMapping mapping = mappings.get(entry); - if (mapping != null && !entry.getName().equals(mapping.getTargetName())) { - if (entry instanceof ClassEntry) { - writeClass(writer, (ClassEntry) entry, translator); - } else if (entry instanceof FieldEntry) { - writeLine(writer, serializeEntry(entry, mapping.getTargetName())); - } else if (entry instanceof MethodEntry) { - writeLine(writer, serializeEntry(entry, mapping.getTargetName())); - } - } - - writeChildren(writer, mappings, node); - } - - private void writeChildren(Writer writer, EntryTree mappings, EntryTreeNode node) { - node.getChildren().stream() - .filter(e -> e instanceof FieldEntry).sorted() - .forEach(child -> writeEntry(writer, mappings, child)); - - node.getChildren().stream() - .filter(e -> e instanceof MethodEntry).sorted() - .forEach(child -> writeEntry(writer, mappings, child)); - - node.getChildren().stream() - .filter(e -> e instanceof ClassEntry).sorted() - .forEach(child -> writeEntry(writer, mappings, child)); - } - - private void writeClass(Writer writer, ClassEntry entry, Translator translator) { - ClassEntry translatedEntry = translator.translate(entry); - - String obfClassName = entry.getFullName(); - String deobfClassName = translatedEntry.getFullName(); - writeLine(writer, new String[]{"CLASS", obfClassName, deobfClassName}); - } - - private void writeLine(Writer writer, String[] data) { - try { - String line = TAB_JOINER.join(data) + "\n"; - if (writtenLines.add(line)) { - writer.write(line); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private String[] serializeEntry(Entry entry, String... extraFields) { - String[] data = null; - - if (entry instanceof FieldEntry) { - data = new String[4 + extraFields.length]; - data[0] = "FIELD"; - data[1] = entry.getContainingClass().getFullName(); - data[2] = ((FieldEntry) entry).getDesc().toString(); - data[3] = entry.getName(); - } else if (entry instanceof MethodEntry) { - data = new String[4 + extraFields.length]; - data[0] = "METHOD"; - data[1] = entry.getContainingClass().getFullName(); - data[2] = ((MethodEntry) entry).getDesc().toString(); - data[3] = entry.getName(); - } else if (entry instanceof ClassEntry) { - data = new String[2 + extraFields.length]; - data[0] = "CLASS"; - data[1] = ((ClassEntry) entry).getFullName(); - } - - if (data != null) { - System.arraycopy(extraFields, 0, data, data.length - extraFields.length, extraFields.length); - } - - return data; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java deleted file mode 100644 index d81cbdb..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java +++ /dev/null @@ -1,295 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.throwables.MappingParseException; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingPair; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.HashEntryTree; -import cuchaz.enigma.translation.representation.MethodDescriptor; -import cuchaz.enigma.translation.representation.TypeDescriptor; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; -import cuchaz.enigma.utils.I18n; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.BitSet; -import java.util.List; - -final class TinyV2Reader implements MappingsReader { - - private static final String MINOR_VERSION = "0"; - // 0 indent - private static final int IN_HEADER = 0; - private static final int IN_CLASS = IN_HEADER + 1; - // 1 indent - private static final int IN_METHOD = IN_CLASS + 1; - private static final int IN_FIELD = IN_METHOD + 1; - // 2 indent - private static final int IN_PARAMETER = IN_FIELD + 1; - // general properties - private static final int STATE_SIZE = IN_PARAMETER + 1; - private static final int[] INDENT_CLEAR_START = {IN_HEADER, IN_METHOD, IN_PARAMETER, STATE_SIZE}; - - @Override - public EntryTree read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - return read(path, Files.readAllLines(path, StandardCharsets.UTF_8), progress); - } - - private EntryTree read(Path path, List lines, ProgressListener progress) throws MappingParseException { - EntryTree mappings = new HashEntryTree<>(); - - progress.init(lines.size(), I18n.translate("progress.mappings.tiny_v2.loading")); - - BitSet state = new BitSet(STATE_SIZE); - @SuppressWarnings({"unchecked", "rawtypes"}) - MappingPair, RawEntryMapping>[] holds = new MappingPair[STATE_SIZE]; - boolean escapeNames = false; - - for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { - try { - progress.step(lineNumber, ""); - String line = lines.get(lineNumber); - - int indent = 0; - while (line.charAt(indent) == '\t') - indent++; - - String[] parts = line.substring(indent).split("\t", -1); - if (parts.length == 0 || indent >= INDENT_CLEAR_START.length) - throw new IllegalArgumentException("Invalid format"); - - // clean and register stuff in stack - for (int i = INDENT_CLEAR_START[indent]; i < STATE_SIZE; i++) { - state.clear(i); - if (holds[i] != null) { - RawEntryMapping mapping = holds[i].getMapping(); - if (mapping != null) { - EntryMapping baked = mapping.bake(); - if (baked != null) { - mappings.insert(holds[i].getEntry(), baked); - } - } - holds[i] = null; - } - } - - switch (indent) { - case 0: - switch (parts[0]) { - case "tiny": // header - if (lineNumber != 0) { - throw new IllegalArgumentException("Header can only be on the first line"); - } - if (parts.length < 5) { - throw new IllegalArgumentException("Not enough header columns, needs at least 5"); - } - if (!"2".equals(parts[1]) || !MINOR_VERSION.equals(parts[2])) { - throw new IllegalArgumentException("Unsupported TinyV2 version, requires major " + "2" + " and minor " + MINOR_VERSION + ""); - } - state.set(IN_HEADER); - break; - case "c": // class - state.set(IN_CLASS); - holds[IN_CLASS] = parseClass(parts, escapeNames); - break; - default: - unsupportKey(parts); - } - - break; - case 1: - if (state.get(IN_HEADER)) { - if (parts[0].equals("esacpe-names")) { - escapeNames = true; - } - - break; - } - - if (state.get(IN_CLASS)) { - switch (parts[0]) { - case "m": // method - state.set(IN_METHOD); - holds[IN_METHOD] = parseMethod(holds[IN_CLASS], parts, escapeNames); - break; - case "f": // field - state.set(IN_FIELD); - holds[IN_FIELD] = parseField(holds[IN_CLASS], parts, escapeNames); - break; - case "c": // class javadoc - addJavadoc(holds[IN_CLASS], parts); - break; - default: - unsupportKey(parts); - } - break; - } - - unsupportKey(parts); - case 2: - if (state.get(IN_METHOD)) { - switch (parts[0]) { - case "p": // parameter - state.set(IN_PARAMETER); - holds[IN_PARAMETER] = parseArgument(holds[IN_METHOD], parts, escapeNames); - break; - case "v": // local variable - // TODO add local var mapping - break; - case "c": // method javadoc - addJavadoc(holds[IN_METHOD], parts); - break; - default: - unsupportKey(parts); - } - break; - } - - if (state.get(IN_FIELD)) { - switch (parts[0]) { - case "c": // field javadoc - addJavadoc(holds[IN_FIELD], parts); - break; - default: - unsupportKey(parts); - } - break; - } - unsupportKey(parts); - case 3: - if (state.get(IN_PARAMETER)) { - switch (parts[0]) { - case "c": - addJavadoc(holds[IN_PARAMETER], parts); - break; - default: - unsupportKey(parts); - } - break; - } - unsupportKey(parts); - default: - unsupportKey(parts); - } - - } catch (Throwable t) { - t.printStackTrace(); - throw new MappingParseException(path::toString, lineNumber + 1, t.toString()); - } - } - - return mappings; - } - - private void unsupportKey(String[] parts) { - throw new IllegalArgumentException("Unsupported key " + parts[0]); - } - - private void addJavadoc(MappingPair pair, String[] parts) { - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid javadoc declaration"); - } - - addJavadoc(pair, parts[1]); - } - - private MappingPair parseClass(String[] tokens, boolean escapeNames) { - ClassEntry obfuscatedEntry = new ClassEntry(unescapeOpt(tokens[1], escapeNames)); - if (tokens.length <= 2) - return new MappingPair<>(obfuscatedEntry); - String token2 = unescapeOpt(tokens[2], escapeNames); - String mapping = token2.substring(token2.lastIndexOf('$') + 1); - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping)); - } - - private MappingPair parseField(MappingPair parent, String[] tokens, boolean escapeNames) { - ClassEntry ownerClass = (ClassEntry) parent.getEntry(); - TypeDescriptor descriptor = new TypeDescriptor(unescapeOpt(tokens[1], escapeNames)); - - FieldEntry obfuscatedEntry = new FieldEntry(ownerClass, unescapeOpt(tokens[2], escapeNames), descriptor); - if (tokens.length <= 3) - return new MappingPair<>(obfuscatedEntry); - String mapping = unescapeOpt(tokens[3], escapeNames); - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping)); - } - - private MappingPair parseMethod(MappingPair parent, String[] tokens, boolean escapeNames) { - ClassEntry ownerClass = (ClassEntry) parent.getEntry(); - MethodDescriptor descriptor = new MethodDescriptor(unescapeOpt(tokens[1], escapeNames)); - - MethodEntry obfuscatedEntry = new MethodEntry(ownerClass, unescapeOpt(tokens[2], escapeNames), descriptor); - if (tokens.length <= 3) - return new MappingPair<>(obfuscatedEntry); - String mapping = unescapeOpt(tokens[3], escapeNames); - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping)); - } - - - - private void addJavadoc(MappingPair pair, String javadoc) { - RawEntryMapping mapping = pair.getMapping(); - if (mapping == null) { - throw new IllegalArgumentException("Javadoc requires a mapping in enigma!"); - } - mapping.addJavadocLine(unescape(javadoc)); - } - - - - private MappingPair parseArgument(MappingPair parent, String[] tokens, boolean escapeNames) { - MethodEntry ownerMethod = (MethodEntry) parent.getEntry(); - int variableIndex = Integer.parseInt(tokens[1]); - - // tokens[2] is the useless obf name - - LocalVariableEntry obfuscatedEntry = new LocalVariableEntry(ownerMethod, variableIndex, "", true, null); - if (tokens.length <= 3) - return new MappingPair<>(obfuscatedEntry); - String mapping = unescapeOpt(tokens[3], escapeNames); - return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping)); - } - - private static final String TO_ESCAPE = "\\\n\r\0\t"; - private static final String ESCAPED = "\\nr0t"; - - private static String unescapeOpt(String raw, boolean escapedStrings) { - return escapedStrings ? unescape(raw) : raw; - } - - private static String unescape(String str) { - // copied from matcher, lazy! - int pos = str.indexOf('\\'); - if (pos < 0) return str; - - StringBuilder ret = new StringBuilder(str.length() - 1); - int start = 0; - - do { - ret.append(str, start, pos); - pos++; - int type; - - if (pos >= str.length()) { - throw new RuntimeException("incomplete escape sequence at the end"); - } else if ((type = ESCAPED.indexOf(str.charAt(pos))) < 0) { - throw new RuntimeException("invalid escape character: \\" + str.charAt(pos)); - } else { - ret.append(TO_ESCAPE.charAt(type)); - } - - start = pos + 1; - } while ((pos = str.indexOf('\\', start)) >= 0); - - ret.append(str, start, str.length()); - - return ret.toString(); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Writer.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Writer.java deleted file mode 100644 index 95e04c3..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Writer.java +++ /dev/null @@ -1,169 +0,0 @@ -package cuchaz.enigma.translation.mapping.serde; - -import com.google.common.base.Strings; -import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.MappingDelta; -import cuchaz.enigma.translation.mapping.MappingSaveParameters; -import cuchaz.enigma.translation.mapping.tree.EntryTree; -import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.Entry; -import cuchaz.enigma.translation.representation.entry.FieldEntry; -import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; -import cuchaz.enigma.utils.LFPrintWriter; - -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -public final class TinyV2Writer implements MappingsWriter { - - private static final String MINOR_VERSION = "0"; - private final String obfHeader; - private final String deobfHeader; - - public TinyV2Writer(String obfHeader, String deobfHeader) { - this.obfHeader = obfHeader; - this.deobfHeader = deobfHeader; - } - - @Override - public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress, MappingSaveParameters parameters) { - List> classes = StreamSupport.stream(mappings.spliterator(), false).filter(node -> node.getEntry() instanceof ClassEntry).collect(Collectors.toList()); - - try (PrintWriter writer = new LFPrintWriter(Files.newBufferedWriter(path))) { - writer.println("tiny\t2\t" + MINOR_VERSION + "\t" + obfHeader + "\t" + deobfHeader); - - // no escape names - - for (EntryTreeNode node : classes) { - writeClass(writer, node, mappings); - } - } catch (IOException ex) { - ex.printStackTrace(); // TODO add some better logging system - } - } - - private void writeClass(PrintWriter writer, EntryTreeNode node, EntryMap tree) { - writer.print("c\t"); - ClassEntry classEntry = (ClassEntry) node.getEntry(); - String fullName = classEntry.getFullName(); - writer.print(fullName); - Deque parts = new LinkedList<>(); - do { - EntryMapping mapping = tree.get(classEntry); - if (mapping != null) { - parts.addFirst(mapping.getTargetName()); - } else { - parts.addFirst(classEntry.getName()); - } - classEntry = classEntry.getOuterClass(); - } while (classEntry != null); - - String mappedName = String.join("$", parts); - - writer.print("\t"); - - writer.print(mappedName); // todo escaping when we have v2 fixed later - - writer.println(); - - writeComment(writer, node.getValue(), 1); - - for (EntryTreeNode child : node.getChildNodes()) { - Entry entry = child.getEntry(); - if (entry instanceof FieldEntry) { - writeField(writer, child); - } else if (entry instanceof MethodEntry) { - writeMethod(writer, child); - } - } - } - - private void writeMethod(PrintWriter writer, EntryTreeNode node) { - writer.print(indent(1)); - writer.print("m\t"); - writer.print(((MethodEntry) node.getEntry()).getDesc().toString()); - writer.print("\t"); - writer.print(node.getEntry().getName()); - writer.print("\t"); - EntryMapping mapping = node.getValue(); - if (mapping == null) { - writer.println(node.getEntry().getName()); // todo fix v2 name inference - } else { - writer.println(mapping.getTargetName()); - - writeComment(writer, mapping, 2); - } - - for (EntryTreeNode child : node.getChildNodes()) { - Entry entry = child.getEntry(); - if (entry instanceof LocalVariableEntry) { - writeParameter(writer, child); - } - // TODO write actual local variables - } - } - - private void writeField(PrintWriter writer, EntryTreeNode node) { - if (node.getValue() == null) - return; // Shortcut - - writer.print(indent(1)); - writer.print("f\t"); - writer.print(((FieldEntry) node.getEntry()).getDesc().toString()); - writer.print("\t"); - writer.print(node.getEntry().getName()); - writer.print("\t"); - EntryMapping mapping = node.getValue(); - if (mapping == null) { - writer.println(node.getEntry().getName()); // todo fix v2 name inference - } else { - writer.println(mapping.getTargetName()); - - writeComment(writer, mapping, 2); - } - } - - private void writeParameter(PrintWriter writer, EntryTreeNode node) { - if (node.getValue() == null) - return; // Shortcut - - writer.print(indent(2)); - writer.print("p\t"); - writer.print(((LocalVariableEntry) node.getEntry()).getIndex()); - writer.print("\t"); - writer.print(node.getEntry().getName()); - writer.print("\t"); - EntryMapping mapping = node.getValue(); - if (mapping == null) { - writer.println(); // todo ??? - } else { - writer.println(mapping.getTargetName()); - - writeComment(writer, mapping, 3); - } - } - - private void writeComment(PrintWriter writer, EntryMapping mapping, int indent) { - if (mapping != null && mapping.getJavadoc() != null) { - writer.print(indent(indent)); - writer.print("c\t"); - writer.print(MappingHelper.escape(mapping.getJavadoc())); - writer.println(); - } - } - - private String indent(int level) { - return Strings.repeat("\t", level); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java deleted file mode 100644 index 255fa5f..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/DeltaTrackingTree.java +++ /dev/null @@ -1,110 +0,0 @@ -package cuchaz.enigma.translation.mapping.tree; - -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.mapping.MappingDelta; -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nullable; -import java.util.Collection; -import java.util.Iterator; -import java.util.stream.Stream; - -public class DeltaTrackingTree implements EntryTree { - private final EntryTree delegate; - - private EntryTree deltaReference; - private EntryTree changes = new HashEntryTree<>(); - - public DeltaTrackingTree(EntryTree delegate) { - this.delegate = delegate; - this.deltaReference = new HashEntryTree<>(delegate); - } - - public DeltaTrackingTree() { - this(new HashEntryTree<>()); - } - - @Override - public void insert(Entry entry, T value) { - trackChange(entry); - delegate.insert(entry, value); - } - - @Nullable - @Override - public T remove(Entry entry) { - trackChange(entry); - return delegate.remove(entry); - } - - public void trackChange(Entry entry) { - changes.insert(entry, MappingDelta.PLACEHOLDER); - } - - @Nullable - @Override - public T get(Entry entry) { - return delegate.get(entry); - } - - @Override - public Collection> getChildren(Entry entry) { - return delegate.getChildren(entry); - } - - @Override - public Collection> getSiblings(Entry entry) { - return delegate.getSiblings(entry); - } - - @Nullable - @Override - public EntryTreeNode findNode(Entry entry) { - return delegate.findNode(entry); - } - - @Override - public Stream> getRootNodes() { - return delegate.getRootNodes(); - } - - @Override - public DeltaTrackingTree translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - DeltaTrackingTree translatedTree = new DeltaTrackingTree<>(delegate.translate(translator, resolver, mappings)); - translatedTree.changes = changes.translate(translator, resolver, mappings); - return translatedTree; - } - - @Override - public Stream> getAllEntries() { - return delegate.getAllEntries(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public Iterator> iterator() { - return delegate.iterator(); - } - - public MappingDelta takeDelta() { - MappingDelta delta = new MappingDelta<>(deltaReference, changes); - resetDelta(); - return delta; - } - - private void resetDelta() { - deltaReference = new HashEntryTree<>(delegate); - changes = new HashEntryTree<>(); - } - - public boolean isDirty() { - return !changes.isEmpty(); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java deleted file mode 100644 index daaefcc..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTree.java +++ /dev/null @@ -1,26 +0,0 @@ -package cuchaz.enigma.translation.mapping.tree; - -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nullable; -import java.util.Collection; -import java.util.stream.Stream; - -public interface EntryTree extends EntryMap, Iterable>, Translatable { - Collection> getChildren(Entry entry); - - Collection> getSiblings(Entry entry); - - @Nullable - EntryTreeNode findNode(Entry entry); - - Stream> getRootNodes(); - - @Override - EntryTree translate(Translator translator, EntryResolver resolver, EntryMap mappings); -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java deleted file mode 100644 index affcd50..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/EntryTreeNode.java +++ /dev/null @@ -1,40 +0,0 @@ -package cuchaz.enigma.translation.mapping.tree; - -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.stream.Collectors; - -public interface EntryTreeNode { - @Nullable - T getValue(); - - Entry getEntry(); - - boolean isEmpty(); - - Collection> getChildren(); - - Collection> getChildNodes(); - - default Collection> getNodesRecursively() { - Collection> nodes = new ArrayList<>(); - nodes.add(this); - for (EntryTreeNode node : getChildNodes()) { - nodes.addAll(node.getNodesRecursively()); - } - return nodes; - } - - default Collection> getChildrenRecursively() { - return getNodesRecursively().stream() - .map(EntryTreeNode::getEntry) - .collect(Collectors.toList()); - } - - default boolean hasValue() { - return getValue() != null; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java deleted file mode 100644 index 570941c..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/HashEntryTree.java +++ /dev/null @@ -1,188 +0,0 @@ -package cuchaz.enigma.translation.mapping.tree; - -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nullable; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -public class HashEntryTree implements EntryTree { - private final Map, HashTreeNode> root = new HashMap<>(); - - public HashEntryTree() { - } - - public HashEntryTree(EntryTree tree) { - for (EntryTreeNode node : tree) { - insert(node.getEntry(), node.getValue()); - } - } - - @Override - public void insert(Entry entry, T value) { - List> path = computePath(entry, true); - path.get(path.size() - 1).putValue(value); - if (value == null) { - removeDeadAlong(path); - } - } - - @Override - @Nullable - public T remove(Entry entry) { - List> path = computePath(entry, false); - if (path.isEmpty()) { - return null; - } - - T value = path.get(path.size() - 1).removeValue(); - - removeDeadAlong(path); - - return value; - } - - @Override - @Nullable - public T get(Entry entry) { - HashTreeNode node = findNode(entry); - if (node == null) { - return null; - } - return node.getValue(); - } - - @Override - public boolean contains(Entry entry) { - return get(entry) != null; - } - - @Override - public Collection> getChildren(Entry entry) { - HashTreeNode leaf = findNode(entry); - if (leaf == null) { - return Collections.emptyList(); - } - return leaf.getChildren(); - } - - @Override - public Collection> getSiblings(Entry entry) { - Entry parent = entry.getParent(); - if (parent == null) { - return getSiblings(entry, root.keySet()); - } - return getSiblings(entry, getChildren(parent)); - } - - private Collection> getSiblings(Entry entry, Collection> generation) { - Set> siblings = new HashSet<>(generation); - siblings.remove(entry); - return siblings; - } - - @Override - @Nullable - public HashTreeNode findNode(Entry target) { - List> parentChain = target.getAncestry(); - if (parentChain.isEmpty()) { - return null; - } - - HashTreeNode node = root.get(parentChain.get(0)); - for (int i = 1; i < parentChain.size(); i++) { - if (node == null) { - return null; - } - node = node.getChild(parentChain.get(i)); - } - - return node; - } - - private List> computePath(Entry target, boolean make) { - List> ancestry = target.getAncestry(); - if (ancestry.isEmpty()) { - return Collections.emptyList(); - } - - List> path = new ArrayList<>(ancestry.size()); - - Entry rootEntry = ancestry.get(0); - HashTreeNode node = make ? root.computeIfAbsent(rootEntry, HashTreeNode::new) : root.get(rootEntry); - if (node == null) { - return Collections.emptyList(); - } - - path.add(node); - - for (int i = 1; i < ancestry.size(); i++) { - Entry ancestor = ancestry.get(i); - node = make ? node.computeChild(ancestor) : node.getChild(ancestor); - if (node == null) { - return Collections.emptyList(); - } - - path.add(node); - } - - return path; - } - - private void removeDeadAlong(List> path) { - for (int i = path.size() - 1; i >= 0; i--) { - HashTreeNode node = path.get(i); - if (node.isEmpty()) { - if (i > 0) { - HashTreeNode parentNode = path.get(i - 1); - parentNode.remove(node.getEntry()); - } else { - root.remove(node.getEntry()); - } - } else { - break; - } - } - } - - @Override - public Iterator> iterator() { - Collection> nodes = new ArrayList<>(); - for (EntryTreeNode node : root.values()) { - nodes.addAll(node.getNodesRecursively()); - } - return nodes.iterator(); - } - - @Override - public Stream> getAllEntries() { - return StreamSupport.stream(spliterator(), false) - .filter(EntryTreeNode::hasValue) - .map(EntryTreeNode::getEntry); - } - - @Override - public Stream> getRootNodes() { - return root.values().stream().map(Function.identity()); - } - - @Override - public boolean isEmpty() { - return root.isEmpty(); - } - - @Override - public HashEntryTree translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - HashEntryTree translatedTree = new HashEntryTree<>(); - for (EntryTreeNode node : this) { - translatedTree.insert(translator.translate(node.getEntry()), node.getValue()); - } - return translatedTree; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/mapping/tree/HashTreeNode.java b/src/main/java/cuchaz/enigma/translation/mapping/tree/HashTreeNode.java deleted file mode 100644 index 0a990bd..0000000 --- a/src/main/java/cuchaz/enigma/translation/mapping/tree/HashTreeNode.java +++ /dev/null @@ -1,75 +0,0 @@ -package cuchaz.enigma.translation.mapping.tree; - -import cuchaz.enigma.translation.representation.entry.Entry; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -public class HashTreeNode implements EntryTreeNode, Iterable> { - private final Entry entry; - private final Map, HashTreeNode> children = new HashMap<>(); - private T value; - - HashTreeNode(Entry entry) { - this.entry = entry; - } - - void putValue(T value) { - this.value = value; - } - - T removeValue() { - T value = this.value; - this.value = null; - return value; - } - - @Nullable - HashTreeNode getChild(Entry entry) { - return children.get(entry); - } - - @Nonnull - HashTreeNode computeChild(Entry entry) { - return children.computeIfAbsent(entry, HashTreeNode::new); - } - - void remove(Entry entry) { - children.remove(entry); - } - - @Override - @Nullable - public T getValue() { - return value; - } - - @Override - public Entry getEntry() { - return entry; - } - - @Override - public boolean isEmpty() { - return children.isEmpty() && value == null; - } - - @Override - public Collection> getChildren() { - return children.keySet(); - } - - @Override - public Collection> getChildNodes() { - return children.values(); - } - - @Override - public Iterator> iterator() { - return children.values().iterator(); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/AccessFlags.java b/src/main/java/cuchaz/enigma/translation/representation/AccessFlags.java deleted file mode 100644 index b280eef..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/AccessFlags.java +++ /dev/null @@ -1,116 +0,0 @@ -package cuchaz.enigma.translation.representation; - -import cuchaz.enigma.analysis.Access; -import org.objectweb.asm.Opcodes; - -import java.lang.reflect.Modifier; - -public class AccessFlags { - public static final AccessFlags PRIVATE = new AccessFlags(Opcodes.ACC_PRIVATE); - public static final AccessFlags PUBLIC = new AccessFlags(Opcodes.ACC_PUBLIC); - - private int flags; - - public AccessFlags(int flags) { - this.flags = flags; - } - - public boolean isPrivate() { - return Modifier.isPrivate(this.flags); - } - - public boolean isProtected() { - return Modifier.isProtected(this.flags); - } - - public boolean isPublic() { - return Modifier.isPublic(this.flags); - } - - public boolean isSynthetic() { - return (this.flags & Opcodes.ACC_SYNTHETIC) != 0; - } - - public boolean isStatic() { - return Modifier.isStatic(this.flags); - } - - public boolean isEnum() { - return (flags & Opcodes.ACC_ENUM) != 0; - } - - public boolean isBridge() { - return (flags & Opcodes.ACC_BRIDGE) != 0; - } - - public boolean isFinal() { - return (flags & Opcodes.ACC_FINAL) != 0; - } - - public boolean isInterface() { - return (flags & Opcodes.ACC_INTERFACE) != 0; - } - - public AccessFlags setPrivate() { - this.setVisibility(Opcodes.ACC_PRIVATE); - return this; - } - - public AccessFlags setProtected() { - this.setVisibility(Opcodes.ACC_PROTECTED); - return this; - } - - public AccessFlags setPublic() { - this.setVisibility(Opcodes.ACC_PUBLIC); - return this; - } - - public AccessFlags setBridge() { - flags |= Opcodes.ACC_BRIDGE; - return this; - } - - @Deprecated - public AccessFlags setBridged() { - return setBridge(); - } - - public void setVisibility(int visibility) { - this.resetVisibility(); - this.flags |= visibility; - } - - private void resetVisibility() { - this.flags &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC); - } - - public int getFlags() { - return this.flags; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof AccessFlags && ((AccessFlags) obj).flags == flags; - } - - @Override - public int hashCode() { - return flags; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(Access.get(this).toString().toLowerCase()); - if (isStatic()) { - builder.append(" static"); - } - if (isSynthetic()) { - builder.append(" synthetic"); - } - if (isBridge()) { - builder.append(" bridge"); - } - return builder.toString(); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/Lambda.java b/src/main/java/cuchaz/enigma/translation/representation/Lambda.java deleted file mode 100644 index 63eb563..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/Lambda.java +++ /dev/null @@ -1,105 +0,0 @@ -package cuchaz.enigma.translation.representation; - -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.mapping.ResolutionStrategy; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.translation.representation.entry.MethodEntry; -import cuchaz.enigma.translation.representation.entry.ParentedEntry; - -import java.util.Objects; - -public class Lambda implements Translatable { - private final String invokedName; - private final MethodDescriptor invokedType; - private final MethodDescriptor samMethodType; - private final ParentedEntry implMethod; - private final MethodDescriptor instantiatedMethodType; - - public Lambda(String invokedName, MethodDescriptor invokedType, MethodDescriptor samMethodType, ParentedEntry implMethod, MethodDescriptor instantiatedMethodType) { - this.invokedName = invokedName; - this.invokedType = invokedType; - this.samMethodType = samMethodType; - this.implMethod = implMethod; - this.instantiatedMethodType = instantiatedMethodType; - } - - @Override - public Lambda translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - MethodEntry samMethod = new MethodEntry(getInterface(), invokedName, samMethodType); - EntryMapping samMethodMapping = resolveMapping(resolver, mappings, samMethod); - - return new Lambda( - samMethodMapping != null ? samMethodMapping.getTargetName() : invokedName, - invokedType.translate(translator, resolver, mappings), - samMethodType.translate(translator, resolver, mappings), - implMethod.translate(translator, resolver, mappings), - instantiatedMethodType.translate(translator, resolver, mappings) - ); - } - - private EntryMapping resolveMapping(EntryResolver resolver, EntryMap mappings, MethodEntry methodEntry) { - for (MethodEntry entry : resolver.resolveEntry(methodEntry, ResolutionStrategy.RESOLVE_ROOT)) { - EntryMapping mapping = mappings.get(entry); - if (mapping != null) { - return mapping; - } - } - return null; - } - - public ClassEntry getInterface() { - return invokedType.getReturnDesc().getTypeEntry(); - } - - public String getInvokedName() { - return invokedName; - } - - public MethodDescriptor getInvokedType() { - return invokedType; - } - - public MethodDescriptor getSamMethodType() { - return samMethodType; - } - - public ParentedEntry getImplMethod() { - return implMethod; - } - - public MethodDescriptor getInstantiatedMethodType() { - return instantiatedMethodType; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Lambda lambda = (Lambda) o; - return Objects.equals(invokedName, lambda.invokedName) && - Objects.equals(invokedType, lambda.invokedType) && - Objects.equals(samMethodType, lambda.samMethodType) && - Objects.equals(implMethod, lambda.implMethod) && - Objects.equals(instantiatedMethodType, lambda.instantiatedMethodType); - } - - @Override - public int hashCode() { - return Objects.hash(invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType); - } - - @Override - public String toString() { - return "Lambda{" + - "invokedName='" + invokedName + '\'' + - ", invokedType=" + invokedType + - ", samMethodType=" + samMethodType + - ", implMethod=" + implMethod + - ", instantiatedMethodType=" + instantiatedMethodType + - '}'; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/MethodDescriptor.java b/src/main/java/cuchaz/enigma/translation/representation/MethodDescriptor.java deleted file mode 100644 index 37a7014..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/MethodDescriptor.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation; - -import com.google.common.collect.Lists; -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import cuchaz.enigma.utils.Utils; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -public class MethodDescriptor implements Translatable { - - private List argumentDescs; - private TypeDescriptor returnDesc; - - public MethodDescriptor(String desc) { - try { - this.argumentDescs = Lists.newArrayList(); - int i = 0; - while (i < desc.length()) { - char c = desc.charAt(i); - if (c == '(') { - assert (this.argumentDescs.isEmpty()); - assert (this.returnDesc == null); - i++; - } else if (c == ')') { - i++; - break; - } else { - String type = TypeDescriptor.parseFirst(desc.substring(i)); - this.argumentDescs.add(new TypeDescriptor(type)); - i += type.length(); - } - } - this.returnDesc = new TypeDescriptor(TypeDescriptor.parseFirst(desc.substring(i))); - } catch (Exception ex) { - throw new IllegalArgumentException("Unable to parse method descriptor: " + desc, ex); - } - } - - public MethodDescriptor(List argumentDescs, TypeDescriptor returnDesc) { - this.argumentDescs = argumentDescs; - this.returnDesc = returnDesc; - } - - public List getArgumentDescs() { - return this.argumentDescs; - } - - public TypeDescriptor getReturnDesc() { - return this.returnDesc; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("("); - for (TypeDescriptor desc : this.argumentDescs) { - buf.append(desc); - } - buf.append(")"); - buf.append(this.returnDesc); - return buf.toString(); - } - - public Iterable types() { - List descs = Lists.newArrayList(); - descs.addAll(this.argumentDescs); - descs.add(this.returnDesc); - return descs; - } - - @Override - public boolean equals(Object other) { - return other instanceof MethodDescriptor && equals((MethodDescriptor) other); - } - - public boolean equals(MethodDescriptor other) { - return this.argumentDescs.equals(other.argumentDescs) && this.returnDesc.equals(other.returnDesc); - } - - @Override - public int hashCode() { - return Utils.combineHashesOrdered(this.argumentDescs.hashCode(), this.returnDesc.hashCode()); - } - - public boolean hasClass(ClassEntry classEntry) { - for (TypeDescriptor desc : types()) { - if (desc.containsType() && desc.getTypeEntry().equals(classEntry)) { - return true; - } - } - return false; - } - - public MethodDescriptor remap(Function remapper) { - List argumentDescs = new ArrayList<>(this.argumentDescs.size()); - for (TypeDescriptor desc : this.argumentDescs) { - argumentDescs.add(desc.remap(remapper)); - } - return new MethodDescriptor(argumentDescs, returnDesc.remap(remapper)); - } - - @Override - public MethodDescriptor translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - List translatedArguments = new ArrayList<>(argumentDescs.size()); - for (TypeDescriptor argument : argumentDescs) { - translatedArguments.add(translator.translate(argument)); - } - return new MethodDescriptor(translatedArguments, translator.translate(returnDesc)); - } - - public boolean canConflictWith(MethodDescriptor descriptor) { - return descriptor.argumentDescs.equals(argumentDescs); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/Signature.java b/src/main/java/cuchaz/enigma/translation/representation/Signature.java deleted file mode 100644 index 424088a..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/Signature.java +++ /dev/null @@ -1,98 +0,0 @@ -package cuchaz.enigma.translation.representation; - -import cuchaz.enigma.bytecode.translators.TranslationSignatureVisitor; -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.representation.entry.ClassEntry; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; -import org.objectweb.asm.signature.SignatureWriter; - -import java.util.function.Function; -import java.util.regex.Pattern; - -public class Signature implements Translatable { - private static final Pattern OBJECT_PATTERN = Pattern.compile(".*:Ljava/lang/Object;:.*"); - - private final String signature; - private final boolean isType; - - private Signature(String signature, boolean isType) { - if (signature != null && OBJECT_PATTERN.matcher(signature).matches()) { - signature = signature.replaceAll(":Ljava/lang/Object;:", "::"); - } - - this.signature = signature; - this.isType = isType; - } - - public static Signature createTypedSignature(String signature) { - if (signature != null && !signature.isEmpty()) { - return new Signature(signature, true); - } - return new Signature(null, true); - } - - public static Signature createSignature(String signature) { - if (signature != null && !signature.isEmpty()) { - return new Signature(signature, false); - } - return new Signature(null, false); - } - - public String getSignature() { - return signature; - } - - public boolean isType() { - return isType; - } - - public Signature remap(Function remapper) { - if (signature == null) { - return this; - } - SignatureWriter writer = new SignatureWriter(); - SignatureVisitor visitor = new TranslationSignatureVisitor(remapper, writer); - if (isType) { - new SignatureReader(signature).acceptType(visitor); - } else { - new SignatureReader(signature).accept(visitor); - } - return new Signature(writer.toString(), isType); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Signature) { - Signature other = (Signature) obj; - return (other.signature == null && signature == null || other.signature != null - && signature != null && other.signature.equals(signature)) - && other.isType == this.isType; - } - return false; - } - - @Override - public int hashCode() { - int hash = (isType ? 1 : 0) << 16; - if (signature != null) { - hash |= signature.hashCode(); - } - - return hash; - } - - @Override - public String toString() { - return signature; - } - - @Override - public Translatable translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - return remap(name -> translator.translate(new ClassEntry(name)).getFullName()); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java b/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java deleted file mode 100644 index f7ba849..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java +++ /dev/null @@ -1,268 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.representation.entry.ClassEntry; - -import java.util.Map; -import java.util.function.Function; - -public class TypeDescriptor implements Translatable { - - protected final String desc; - - public TypeDescriptor(String desc) { - Preconditions.checkNotNull(desc, "Desc cannot be null"); - - // don't deal with generics - // this is just for raw jvm types - if (desc.charAt(0) == 'T' || desc.indexOf('<') >= 0 || desc.indexOf('>') >= 0) { - throw new IllegalArgumentException("don't use with generic types or templates: " + desc); - } - - this.desc = desc; - } - - public static String parseFirst(String in) { - - if (in == null || in.length() <= 0) { - throw new IllegalArgumentException("No desc to parse, input is empty!"); - } - - // read one desc from the input - - char c = in.charAt(0); - - // first check for void - if (c == 'V') { - return "V"; - } - - // then check for primitives - Primitive primitive = Primitive.get(c); - if (primitive != null) { - return in.substring(0, 1); - } - - // then check for classes - if (c == 'L') { - return readClass(in); - } - - // then check for templates - if (c == 'T') { - return readClass(in); - } - - // then check for arrays - int dim = countArrayDimension(in); - if (dim > 0) { - String arrayType = TypeDescriptor.parseFirst(in.substring(dim)); - return in.substring(0, dim + arrayType.length()); - } - - throw new IllegalArgumentException("don't know how to parse: " + in); - } - - private static int countArrayDimension(String in) { - int i = 0; - while (i < in.length() && in.charAt(i) == '[') - i++; - return i; - } - - private static String readClass(String in) { - // read all the characters in the buffer until we hit a ';' - // include the parameters too - StringBuilder buf = new StringBuilder(); - int depth = 0; - for (int i = 0; i < in.length(); i++) { - char c = in.charAt(i); - buf.append(c); - - if (c == '<') { - depth++; - } else if (c == '>') { - depth--; - } else if (depth == 0 && c == ';') { - return buf.toString(); - } - } - return null; - } - - public static TypeDescriptor of(String name) { - return new TypeDescriptor("L" + name + ";"); - } - - @Override - public String toString() { - return this.desc; - } - - public boolean isVoid() { - return this.desc.length() == 1 && this.desc.charAt(0) == 'V'; - } - - public boolean isPrimitive() { - return this.desc.length() == 1 && Primitive.get(this.desc.charAt(0)) != null; - } - - public Primitive getPrimitive() { - if (!isPrimitive()) { - throw new IllegalStateException("not a primitive"); - } - return Primitive.get(this.desc.charAt(0)); - } - - public boolean isType() { - return this.desc.charAt(0) == 'L' && this.desc.charAt(this.desc.length() - 1) == ';'; - } - - public ClassEntry getTypeEntry() { - if (isType()) { - String name = this.desc.substring(1, this.desc.length() - 1); - - int pos = name.indexOf('<'); - if (pos >= 0) { - // remove the parameters from the class name - name = name.substring(0, pos); - } - - return new ClassEntry(name); - - } else if (isArray() && getArrayType().isType()) { - return getArrayType().getTypeEntry(); - } else { - throw new IllegalStateException("desc doesn't have a class"); - } - } - - public boolean isArray() { - return this.desc.charAt(0) == '['; - } - - public int getArrayDimension() { - if (!isArray()) { - throw new IllegalStateException("not an array"); - } - return countArrayDimension(this.desc); - } - - public TypeDescriptor getArrayType() { - if (!isArray()) { - throw new IllegalStateException("not an array"); - } - return new TypeDescriptor(this.desc.substring(getArrayDimension())); - } - - public boolean containsType() { - return isType() || (isArray() && getArrayType().containsType()); - } - - @Override - public boolean equals(Object other) { - return other instanceof TypeDescriptor && equals((TypeDescriptor) other); - } - - public boolean equals(TypeDescriptor other) { - return this.desc.equals(other.desc); - } - - @Override - public int hashCode() { - return this.desc.hashCode(); - } - - public TypeDescriptor remap(Function remapper) { - String desc = this.desc; - if (isType() || (isArray() && containsType())) { - String replacedName = remapper.apply(this.getTypeEntry().getFullName()); - if (replacedName != null) { - if (this.isType()) { - desc = "L" + replacedName + ";"; - } else { - desc = getArrayPrefix(this.getArrayDimension()) + "L" + replacedName + ";"; - } - } - } - return new TypeDescriptor(desc); - } - - private static String getArrayPrefix(int dimension) { - StringBuilder buf = new StringBuilder(); - for (int i = 0; i < dimension; i++) { - buf.append("["); - } - return buf.toString(); - } - - public int getSize() { - switch (desc.charAt(0)) { - case 'J': - case 'D': - if (desc.length() == 1) { - return 2; - } else { - return 1; - } - default: - return 1; - } - } - - @Override - public Translatable translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - return remap(name -> translator.translate(new ClassEntry(name)).getFullName()); - } - - public enum Primitive { - BYTE('B'), - CHARACTER('C'), - SHORT('S'), - INTEGER('I'), - LONG('J'), - FLOAT('F'), - DOUBLE('D'), - BOOLEAN('Z'); - - private static final Map lookup; - - static { - lookup = Maps.newTreeMap(); - for (Primitive val : values()) { - lookup.put(val.getCode(), val); - } - } - - private char code; - - Primitive(char code) { - this.code = code; - } - - public static Primitive get(char code) { - return lookup.get(code); - } - - public char getCode() { - return this.code; - } - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java deleted file mode 100644 index 6930765..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassDefEntry.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.representation.AccessFlags; -import cuchaz.enigma.translation.representation.Signature; - -import javax.annotation.Nullable; -import java.util.Arrays; - -public class ClassDefEntry extends ClassEntry implements DefEntry { - private final AccessFlags access; - private final Signature signature; - private final ClassEntry superClass; - private final ClassEntry[] interfaces; - - public ClassDefEntry(String className, Signature signature, AccessFlags access, @Nullable ClassEntry superClass, ClassEntry[] interfaces) { - this(getOuterClass(className), getInnerName(className), signature, access, superClass, interfaces, null); - } - - public ClassDefEntry(ClassEntry parent, String className, Signature signature, AccessFlags access, @Nullable ClassEntry superClass, ClassEntry[] interfaces) { - this(parent, className, signature, access, superClass, interfaces, null); - } - - public ClassDefEntry(ClassEntry parent, String className, Signature signature, AccessFlags access, @Nullable ClassEntry superClass, - ClassEntry[] interfaces, String javadocs) { - super(parent, className, javadocs); - Preconditions.checkNotNull(signature, "Class signature cannot be null"); - Preconditions.checkNotNull(access, "Class access cannot be null"); - - this.signature = signature; - this.access = access; - this.superClass = superClass; - this.interfaces = interfaces != null ? interfaces : new ClassEntry[0]; - } - - public static ClassDefEntry parse(int access, String name, String signature, String superName, String[] interfaces) { - ClassEntry superClass = superName != null ? new ClassEntry(superName) : null; - ClassEntry[] interfaceClasses = Arrays.stream(interfaces).map(ClassEntry::new).toArray(ClassEntry[]::new); - return new ClassDefEntry(name, Signature.createSignature(signature), new AccessFlags(access), superClass, interfaceClasses); - } - - public Signature getSignature() { - return signature; - } - - @Override - public AccessFlags getAccess() { - return access; - } - - @Nullable - public ClassEntry getSuperClass() { - return superClass; - } - - public ClassEntry[] getInterfaces() { - return interfaces; - } - - @Override - public ClassDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { - Signature translatedSignature = translator.translate(signature); - String translatedName = mapping != null ? mapping.getTargetName() : name; - AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; - ClassEntry translatedSuper = translator.translate(superClass); - ClassEntry[] translatedInterfaces = Arrays.stream(interfaces).map(translator::translate).toArray(ClassEntry[]::new); - String docs = mapping != null ? mapping.getJavadoc() : null; - return new ClassDefEntry(parent, translatedName, translatedSignature, translatedAccess, translatedSuper, translatedInterfaces, docs); - } - - @Override - public ClassDefEntry withName(String name) { - return new ClassDefEntry(parent, name, signature, access, superClass, interfaces, javadocs); - } - - @Override - public ClassDefEntry withParent(ClassEntry parent) { - return new ClassDefEntry(parent, name, signature, access, superClass, interfaces, javadocs); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java deleted file mode 100644 index d6171f1..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java +++ /dev/null @@ -1,214 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import cuchaz.enigma.throwables.IllegalNameException; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.NameValidator; -import cuchaz.enigma.translation.representation.TypeDescriptor; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.List; -import java.util.Objects; - -public class ClassEntry extends ParentedEntry implements Comparable { - private final String fullName; - - public ClassEntry(String className) { - this(getOuterClass(className), getInnerName(className), null); - } - - public ClassEntry(@Nullable ClassEntry parent, String className) { - this(parent, className, null); - } - - public ClassEntry(@Nullable ClassEntry parent, String className, @Nullable String javadocs) { - super(parent, className, javadocs); - if (parent != null) { - fullName = parent.getFullName() + "$" + name; - } else { - fullName = name; - } - - if (parent == null && className.indexOf('.') >= 0) { - throw new IllegalArgumentException("Class name must be in JVM format. ie, path/to/package/class$inner : " + className); - } - } - - @Override - public Class getParentType() { - return ClassEntry.class; - } - - @Override - public String getName() { - return this.name; - } - - public String getFullName() { - return fullName; - } - - @Override - public ClassEntry translate(Translator translator, @Nullable EntryMapping mapping) { - if (name.charAt(0) == '[') { - String translatedName = translator.translate(new TypeDescriptor(name)).toString(); - return new ClassEntry(parent, translatedName); - } - - String translatedName = mapping != null ? mapping.getTargetName() : name; - String docs = mapping != null ? mapping.getJavadoc() : null; - return new ClassEntry(parent, translatedName, docs); - } - - @Override - public ClassEntry getContainingClass() { - return this; - } - - @Override - public int hashCode() { - return fullName.hashCode(); - } - - @Override - public boolean equals(Object other) { - return other instanceof ClassEntry && equals((ClassEntry) other); - } - - public boolean equals(ClassEntry other) { - return other != null && Objects.equals(parent, other.parent) && this.name.equals(other.name); - } - - @Override - public boolean canConflictWith(Entry entry) { - return true; - } - - @Override - public void validateName(String name) throws IllegalNameException { - NameValidator.validateClassName(name); - } - - @Override - public ClassEntry withName(String name) { - return new ClassEntry(parent, name, javadocs); - } - - @Override - public ClassEntry withParent(ClassEntry parent) { - return new ClassEntry(parent, name, javadocs); - } - - @Override - public String toString() { - return getFullName(); - } - - public String getPackageName() { - return getPackageName(fullName); - } - - public String getSimpleName() { - int packagePos = name.lastIndexOf('/'); - if (packagePos > 0) { - return name.substring(packagePos + 1); - } - return name; - } - - public boolean isInnerClass() { - return parent != null; - } - - @Nullable - public ClassEntry getOuterClass() { - return parent; - } - - @Nonnull - public ClassEntry getOutermostClass() { - if (parent == null) { - return this; - } - return parent.getOutermostClass(); - } - - public ClassEntry buildClassEntry(List classChain) { - assert (classChain.contains(this)); - StringBuilder buf = new StringBuilder(); - for (ClassEntry chainEntry : classChain) { - if (buf.length() == 0) { - buf.append(chainEntry.getFullName()); - } else { - buf.append("$"); - buf.append(chainEntry.getSimpleName()); - } - - if (chainEntry == this) { - break; - } - } - return new ClassEntry(buf.toString()); - } - - public boolean isJre() { - String packageName = getPackageName(); - return packageName != null && (packageName.startsWith("java") || packageName.startsWith("javax")); - } - - public static String getPackageName(String name) { - int pos = name.lastIndexOf('/'); - if (pos > 0) { - return name.substring(0, pos); - } - return null; - } - - @Nullable - public static ClassEntry getOuterClass(String name) { - int index = name.lastIndexOf('$'); - if (index >= 0) { - return new ClassEntry(name.substring(0, index)); - } - return null; - } - - public static String getInnerName(String name) { - int innerClassPos = name.lastIndexOf('$'); - if (innerClassPos > 0) { - return name.substring(innerClassPos + 1); - } - return name; - } - - @Override - public String getSourceRemapName() { - ClassEntry outerClass = getOuterClass(); - if (outerClass != null) { - return outerClass.getSourceRemapName() + "." + name; - } - return getSimpleName(); - } - - @Override - public int compareTo(ClassEntry entry) { - String fullName = getFullName(); - String otherFullName = entry.getFullName(); - if (fullName.length() != otherFullName.length()) { - return fullName.length() - otherFullName.length(); - } - return fullName.compareTo(otherFullName); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/DefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/DefEntry.java deleted file mode 100644 index 82536c7..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/DefEntry.java +++ /dev/null @@ -1,7 +0,0 @@ -package cuchaz.enigma.translation.representation.entry; - -import cuchaz.enigma.translation.representation.AccessFlags; - -public interface DefEntry

> extends Entry

{ - AccessFlags getAccess(); -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java deleted file mode 100644 index 72b0391..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import cuchaz.enigma.throwables.IllegalNameException; -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.mapping.NameValidator; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; - -public interface Entry

> extends Translatable { - String getName(); - - String getJavadocs(); - - default String getSourceRemapName() { - return getName(); - } - - @Nullable - P getParent(); - - Class

getParentType(); - - Entry

withName(String name); - - Entry

withParent(P parent); - - boolean canConflictWith(Entry entry); - - @Nullable - default ClassEntry getContainingClass() { - P parent = getParent(); - if (parent == null) { - return null; - } - if (parent instanceof ClassEntry) { - return (ClassEntry) parent; - } - return parent.getContainingClass(); - } - - default List> getAncestry() { - P parent = getParent(); - List> entries = new ArrayList<>(); - if (parent != null) { - entries.addAll(parent.getAncestry()); - } - entries.add(this); - return entries; - } - - @Nullable - @SuppressWarnings("unchecked") - default > E findAncestor(Class type) { - List> ancestry = getAncestry(); - for (int i = ancestry.size() - 1; i >= 0; i--) { - Entry ancestor = ancestry.get(i); - if (type.isAssignableFrom(ancestor.getClass())) { - return (E) ancestor; - } - } - return null; - } - - @SuppressWarnings("unchecked") - default > Entry

replaceAncestor(E target, E replacement) { - if (replacement.equals(target)) { - return this; - } - - if (equals(target)) { - return (Entry

) replacement; - } - - P parent = getParent(); - if (parent == null) { - return this; - } - - return withParent((P) parent.replaceAncestor(target, replacement)); - } - - default void validateName(String name) throws IllegalNameException { - NameValidator.validateIdentifier(name); - } - - @SuppressWarnings("unchecked") - @Nullable - default > Entry castParent(Class parentType) { - if (parentType.equals(getParentType())) { - return (Entry) this; - } - return null; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java deleted file mode 100644 index f9282b2..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldDefEntry.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.representation.AccessFlags; -import cuchaz.enigma.translation.representation.Signature; -import cuchaz.enigma.translation.representation.TypeDescriptor; - -import javax.annotation.Nullable; - -public class FieldDefEntry extends FieldEntry implements DefEntry { - private final AccessFlags access; - private final Signature signature; - - public FieldDefEntry(ClassEntry owner, String name, TypeDescriptor desc, Signature signature, AccessFlags access) { - this(owner, name, desc, signature, access, null); - } - - public FieldDefEntry(ClassEntry owner, String name, TypeDescriptor desc, Signature signature, AccessFlags access, String javadocs) { - super(owner, name, desc, javadocs); - Preconditions.checkNotNull(access, "Field access cannot be null"); - Preconditions.checkNotNull(signature, "Field signature cannot be null"); - this.access = access; - this.signature = signature; - } - - public static FieldDefEntry parse(ClassEntry owner, int access, String name, String desc, String signature) { - return new FieldDefEntry(owner, name, new TypeDescriptor(desc), Signature.createTypedSignature(signature), new AccessFlags(access), null); - } - - @Override - public AccessFlags getAccess() { - return access; - } - - public Signature getSignature() { - return signature; - } - - @Override - public FieldDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { - TypeDescriptor translatedDesc = translator.translate(desc); - Signature translatedSignature = translator.translate(signature); - String translatedName = mapping != null ? mapping.getTargetName() : name; - AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; - String docs = mapping != null ? mapping.getJavadoc() : null; - return new FieldDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs); - } - - @Override - public FieldDefEntry withName(String name) { - return new FieldDefEntry(parent, name, desc, signature, access, javadocs); - } - - @Override - public FieldDefEntry withParent(ClassEntry owner) { - return new FieldDefEntry(owner, this.name, this.desc, signature, access, javadocs); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java deleted file mode 100644 index bef0edf..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/FieldEntry.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.representation.TypeDescriptor; -import cuchaz.enigma.utils.Utils; - -import javax.annotation.Nullable; - -public class FieldEntry extends ParentedEntry implements Comparable { - protected final TypeDescriptor desc; - - public FieldEntry(ClassEntry parent, String name, TypeDescriptor desc) { - this(parent, name, desc, null); - } - - public FieldEntry(ClassEntry parent, String name, TypeDescriptor desc, String javadocs) { - super(parent, name, javadocs); - - Preconditions.checkNotNull(parent, "Owner cannot be null"); - Preconditions.checkNotNull(desc, "Field descriptor cannot be null"); - - this.desc = desc; - } - - public static FieldEntry parse(String owner, String name, String desc) { - return new FieldEntry(new ClassEntry(owner), name, new TypeDescriptor(desc), null); - } - - @Override - public Class getParentType() { - return ClassEntry.class; - } - - public TypeDescriptor getDesc() { - return this.desc; - } - - @Override - public FieldEntry withName(String name) { - return new FieldEntry(parent, name, desc, null); - } - - @Override - public FieldEntry withParent(ClassEntry parent) { - return new FieldEntry(parent, this.name, this.desc, null); - } - - @Override - protected FieldEntry translate(Translator translator, @Nullable EntryMapping mapping) { - String translatedName = mapping != null ? mapping.getTargetName() : name; - String docs = mapping != null ? mapping.getJavadoc() : null; - return new FieldEntry(parent, translatedName, translator.translate(desc), docs); - } - - @Override - public int hashCode() { - return Utils.combineHashesOrdered(this.parent, this.name, this.desc); - } - - @Override - public boolean equals(Object other) { - return other instanceof FieldEntry && equals((FieldEntry) other); - } - - public boolean equals(FieldEntry other) { - return this.parent.equals(other.parent) && name.equals(other.name) && desc.equals(other.desc); - } - - @Override - public boolean canConflictWith(Entry entry) { - return entry instanceof FieldEntry && ((FieldEntry) entry).parent.equals(parent); - } - - @Override - public String toString() { - return this.parent.getFullName() + "." + this.name + ":" + this.desc; - } - - @Override - public int compareTo(FieldEntry entry) { - return (name + desc.toString()).compareTo(entry.name + entry.desc.toString()); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java deleted file mode 100644 index aad4236..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableDefEntry.java +++ /dev/null @@ -1,51 +0,0 @@ -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.representation.TypeDescriptor; - -import javax.annotation.Nullable; - -/** - * TypeDescriptor... - * Created by Thog - * 19/10/2016 - */ -public class LocalVariableDefEntry extends LocalVariableEntry { - protected final TypeDescriptor desc; - - public LocalVariableDefEntry(MethodEntry ownerEntry, int index, String name, boolean parameter, TypeDescriptor desc, String javadoc) { - super(ownerEntry, index, name, parameter, javadoc); - Preconditions.checkNotNull(desc, "Variable desc cannot be null"); - - this.desc = desc; - } - - public TypeDescriptor getDesc() { - return desc; - } - - @Override - public LocalVariableDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { - TypeDescriptor translatedDesc = translator.translate(desc); - String translatedName = mapping != null ? mapping.getTargetName() : name; - String javadoc = mapping != null ? mapping.getJavadoc() : javadocs; - return new LocalVariableDefEntry(parent, index, translatedName, parameter, translatedDesc, javadoc); - } - - @Override - public LocalVariableDefEntry withName(String name) { - return new LocalVariableDefEntry(parent, index, name, parameter, desc, javadocs); - } - - @Override - public LocalVariableDefEntry withParent(MethodEntry entry) { - return new LocalVariableDefEntry(entry, index, name, parameter, desc, javadocs); - } - - @Override - public String toString() { - return this.parent + "(" + this.index + ":" + this.name + ":" + this.desc + ")"; - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java deleted file mode 100644 index 3ccb1fa..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/LocalVariableEntry.java +++ /dev/null @@ -1,93 +0,0 @@ -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.utils.Utils; - -import javax.annotation.Nullable; - -/** - * TypeDescriptor... - * Created by Thog - * 19/10/2016 - */ -public class LocalVariableEntry extends ParentedEntry implements Comparable { - - protected final int index; - protected final boolean parameter; - - public LocalVariableEntry(MethodEntry parent, int index, String name, boolean parameter, String javadoc) { - super(parent, name, javadoc); - - Preconditions.checkNotNull(parent, "Variable owner cannot be null"); - Preconditions.checkArgument(index >= 0, "Index must be positive"); - - this.index = index; - this.parameter = parameter; - } - - @Override - public Class getParentType() { - return MethodEntry.class; - } - - public boolean isArgument() { - return this.parameter; - } - - public int getIndex() { - return index; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public LocalVariableEntry translate(Translator translator, @Nullable EntryMapping mapping) { - String translatedName = mapping != null ? mapping.getTargetName() : name; - String javadoc = mapping != null ? mapping.getJavadoc() : null; - return new LocalVariableEntry(parent, index, translatedName, parameter, javadoc); - } - - @Override - public LocalVariableEntry withName(String name) { - return new LocalVariableEntry(parent, index, name, parameter, javadocs); - } - - @Override - public LocalVariableEntry withParent(MethodEntry parent) { - return new LocalVariableEntry(parent, index, name, parameter, javadocs); - } - - @Override - public int hashCode() { - return Utils.combineHashesOrdered(this.parent, this.index); - } - - @Override - public boolean equals(Object other) { - return other instanceof LocalVariableEntry && equals((LocalVariableEntry) other); - } - - public boolean equals(LocalVariableEntry other) { - return this.parent.equals(other.parent) && this.index == other.index; - } - - @Override - public boolean canConflictWith(Entry entry) { - return entry instanceof LocalVariableEntry && ((LocalVariableEntry) entry).parent.equals(parent); - } - - @Override - public String toString() { - return this.parent + "(" + this.index + ":" + this.name + ")"; - } - - @Override - public int compareTo(LocalVariableEntry entry) { - return Integer.compare(index, entry.index); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java deleted file mode 100644 index 4e75a5c..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodDefEntry.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.representation.AccessFlags; -import cuchaz.enigma.translation.representation.MethodDescriptor; -import cuchaz.enigma.translation.representation.Signature; - -import javax.annotation.Nullable; - -public class MethodDefEntry extends MethodEntry implements DefEntry { - private final AccessFlags access; - private final Signature signature; - - public MethodDefEntry(ClassEntry owner, String name, MethodDescriptor descriptor, Signature signature, AccessFlags access) { - this(owner, name, descriptor, signature, access, null); - } - - public MethodDefEntry(ClassEntry owner, String name, MethodDescriptor descriptor, Signature signature, AccessFlags access, String docs) { - super(owner, name, descriptor, docs); - Preconditions.checkNotNull(access, "Method access cannot be null"); - Preconditions.checkNotNull(signature, "Method signature cannot be null"); - this.access = access; - this.signature = signature; - } - - public static MethodDefEntry parse(ClassEntry owner, int access, String name, String desc, String signature) { - return new MethodDefEntry(owner, name, new MethodDescriptor(desc), Signature.createSignature(signature), new AccessFlags(access), null); - } - - @Override - public AccessFlags getAccess() { - return access; - } - - public Signature getSignature() { - return signature; - } - - @Override - public MethodDefEntry translate(Translator translator, @Nullable EntryMapping mapping) { - MethodDescriptor translatedDesc = translator.translate(descriptor); - Signature translatedSignature = translator.translate(signature); - String translatedName = mapping != null ? mapping.getTargetName() : name; - AccessFlags translatedAccess = mapping != null ? mapping.getAccessModifier().transform(access) : access; - String docs = mapping != null ? mapping.getJavadoc() : null; - return new MethodDefEntry(parent, translatedName, translatedDesc, translatedSignature, translatedAccess, docs); - } - - @Override - public MethodDefEntry withName(String name) { - return new MethodDefEntry(parent, name, descriptor, signature, access, javadocs); - } - - @Override - public MethodDefEntry withParent(ClassEntry parent) { - return new MethodDefEntry(new ClassEntry(parent.getFullName()), name, descriptor, signature, access, javadocs); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java deleted file mode 100644 index e1ffad3..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/MethodEntry.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.representation.MethodDescriptor; -import cuchaz.enigma.utils.Utils; - -import javax.annotation.Nullable; - -public class MethodEntry extends ParentedEntry implements Comparable { - - protected final MethodDescriptor descriptor; - - public MethodEntry(ClassEntry parent, String name, MethodDescriptor descriptor) { - this(parent, name, descriptor, null); - } - - public MethodEntry(ClassEntry parent, String name, MethodDescriptor descriptor, String javadocs) { - super(parent, name, javadocs); - - Preconditions.checkNotNull(parent, "Parent cannot be null"); - Preconditions.checkNotNull(descriptor, "Method descriptor cannot be null"); - - this.descriptor = descriptor; - } - - public static MethodEntry parse(String owner, String name, String desc) { - return new MethodEntry(new ClassEntry(owner), name, new MethodDescriptor(desc), null); - } - - @Override - public Class getParentType() { - return ClassEntry.class; - } - - public MethodDescriptor getDesc() { - return this.descriptor; - } - - public boolean isConstructor() { - return name.equals("") || name.equals(""); - } - - @Override - public MethodEntry translate(Translator translator, @Nullable EntryMapping mapping) { - String translatedName = mapping != null ? mapping.getTargetName() : name; - String docs = mapping != null ? mapping.getJavadoc() : null; - return new MethodEntry(parent, translatedName, translator.translate(descriptor), docs); - } - - @Override - public MethodEntry withName(String name) { - return new MethodEntry(parent, name, descriptor, javadocs); - } - - @Override - public MethodEntry withParent(ClassEntry parent) { - return new MethodEntry(new ClassEntry(parent.getFullName()), name, descriptor, javadocs); - } - - @Override - public int hashCode() { - return Utils.combineHashesOrdered(this.parent, this.name, this.descriptor); - } - - @Override - public boolean equals(Object other) { - return other instanceof MethodEntry && equals((MethodEntry) other); - } - - public boolean equals(MethodEntry other) { - return this.parent.equals(other.getParent()) && this.name.equals(other.getName()) && this.descriptor.equals(other.getDesc()); - } - - @Override - public boolean canConflictWith(Entry entry) { - if (entry instanceof MethodEntry) { - MethodEntry methodEntry = (MethodEntry) entry; - return methodEntry.parent.equals(parent) && methodEntry.descriptor.canConflictWith(descriptor); - } - return false; - } - - @Override - public String toString() { - return this.parent.getFullName() + "." + this.name + this.descriptor; - } - - @Override - public int compareTo(MethodEntry entry) { - return (name + descriptor.toString()).compareTo(entry.name + entry.descriptor.toString()); - } -} diff --git a/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java b/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java deleted file mode 100644 index cbc5faf..0000000 --- a/src/main/java/cuchaz/enigma/translation/representation/entry/ParentedEntry.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma.translation.representation.entry; - -import com.google.common.base.Preconditions; -import cuchaz.enigma.translation.Translatable; -import cuchaz.enigma.translation.Translator; -import cuchaz.enigma.translation.mapping.EntryMap; -import cuchaz.enigma.translation.mapping.EntryMapping; -import cuchaz.enigma.translation.mapping.EntryResolver; -import cuchaz.enigma.translation.mapping.ResolutionStrategy; - -import javax.annotation.Nullable; - -public abstract class ParentedEntry

> implements Entry

{ - protected final P parent; - protected final String name; - protected final @Nullable String javadocs; - - protected ParentedEntry(P parent, String name, String javadocs) { - this.parent = parent; - this.name = name; - this.javadocs = javadocs; - - Preconditions.checkNotNull(name, "Name cannot be null"); - } - - @Override - public abstract ParentedEntry

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

withName(String name); - - protected abstract ParentedEntry

translate(Translator translator, @Nullable EntryMapping mapping); - - @Override - public String getName() { - return name; - } - - @Override - @Nullable - public P getParent() { - return parent; - } - - @Nullable - @Override - public String getJavadocs() { - return javadocs; - } - - @Override - public ParentedEntry

translate(Translator translator, EntryResolver resolver, EntryMap mappings) { - P parent = getParent(); - EntryMapping mapping = resolveMapping(resolver, mappings); - if (parent == null) { - return translate(translator, mapping); - } - P translatedParent = translator.translate(parent); - return withParent(translatedParent).translate(translator, mapping); - } - - private EntryMapping resolveMapping(EntryResolver resolver, EntryMap mappings) { - for (ParentedEntry

entry : resolver.resolveEntry(this, ResolutionStrategy.RESOLVE_ROOT)) { - EntryMapping mapping = mappings.get(entry); - if (mapping != null) { - return mapping; - } - } - return null; - } -} -- cgit v1.2.3