diff options
| author | 2019-01-30 21:05:32 +0200 | |
|---|---|---|
| committer | 2019-01-30 21:05:32 +0200 | |
| commit | ba7a354efae7d49833c887cf147ac940c975a1fa (patch) | |
| tree | 02e14fda81dd5984e24f2df392c57c6e829fc875 /src/main/java/cuchaz/enigma/analysis | |
| parent | Rewrite the Jenkinsfile to use the new declarative pipeline syntax, lets hope... (diff) | |
| download | enigma-fork-ba7a354efae7d49833c887cf147ac940c975a1fa.tar.gz enigma-fork-ba7a354efae7d49833c887cf147ac940c975a1fa.tar.xz enigma-fork-ba7a354efae7d49833c887cf147ac940c975a1fa.zip | |
Remap sources (#106)
* Source remapping beginnings
* Fix navigation to remapped classes
* Translate identifier info reference
* Remap local variables with default names in source
* Caching translator
* Fix lack of highlighting for first opened class
* Fix unicode variable names
* Unicode checker shouldn't be checking just alphanumeric
* Fix package tree being built from obf names
* Don't index `this` as method call for method::reference
* Apply proposed names
* Fix source export issues
* Replace unicode var names at bytecode level uniquely
* Drop imports from editor source
* Class selector fixes
* Delta keep track of base mappings to enable lookup of old names
* Optimize source remapping by remapping source with a StringBuffer instead of copying
* Bump version
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis')
12 files changed, 147 insertions, 184 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/DropImportAstTransform.java b/src/main/java/cuchaz/enigma/analysis/DropImportAstTransform.java new file mode 100644 index 0000000..991e91d --- /dev/null +++ b/src/main/java/cuchaz/enigma/analysis/DropImportAstTransform.java | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | package cuchaz.enigma.analysis; | ||
| 2 | |||
| 3 | import com.strobel.decompiler.languages.java.ast.AstNode; | ||
| 4 | import com.strobel.decompiler.languages.java.ast.DepthFirstAstVisitor; | ||
| 5 | import com.strobel.decompiler.languages.java.ast.ImportDeclaration; | ||
| 6 | import com.strobel.decompiler.languages.java.ast.PackageDeclaration; | ||
| 7 | import com.strobel.decompiler.languages.java.ast.transforms.IAstTransform; | ||
| 8 | |||
| 9 | public final class DropImportAstTransform implements IAstTransform { | ||
| 10 | public static final DropImportAstTransform INSTANCE = new DropImportAstTransform(); | ||
| 11 | |||
| 12 | private DropImportAstTransform() { | ||
| 13 | } | ||
| 14 | |||
| 15 | @Override | ||
| 16 | public void run(AstNode compilationUnit) { | ||
| 17 | compilationUnit.acceptVisitor(new Visitor(), null); | ||
| 18 | } | ||
| 19 | |||
| 20 | static class Visitor extends DepthFirstAstVisitor<Void, Void> { | ||
| 21 | @Override | ||
| 22 | public Void visitPackageDeclaration(PackageDeclaration node, Void data) { | ||
| 23 | node.remove(); | ||
| 24 | return null; | ||
| 25 | } | ||
| 26 | |||
| 27 | @Override | ||
| 28 | public Void visitImportDeclaration(ImportDeclaration node, Void data) { | ||
| 29 | node.remove(); | ||
| 30 | return null; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | } | ||
diff --git a/src/main/java/cuchaz/enigma/analysis/ParsedJar.java b/src/main/java/cuchaz/enigma/analysis/ParsedJar.java index ad3aceb..ddcda3e 100644 --- a/src/main/java/cuchaz/enigma/analysis/ParsedJar.java +++ b/src/main/java/cuchaz/enigma/analysis/ParsedJar.java | |||
| @@ -12,9 +12,12 @@ | |||
| 12 | package cuchaz.enigma.analysis; | 12 | package cuchaz.enigma.analysis; |
| 13 | 13 | ||
| 14 | import com.google.common.io.ByteStreams; | 14 | import com.google.common.io.ByteStreams; |
| 15 | import cuchaz.enigma.CompiledSource; | ||
| 16 | import cuchaz.enigma.bytecode.translators.LocalVariableFixVisitor; | ||
| 15 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 17 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 16 | import org.objectweb.asm.ClassReader; | 18 | import org.objectweb.asm.ClassReader; |
| 17 | import org.objectweb.asm.ClassVisitor; | 19 | import org.objectweb.asm.ClassVisitor; |
| 20 | import org.objectweb.asm.Opcodes; | ||
| 18 | import org.objectweb.asm.tree.ClassNode; | 21 | import org.objectweb.asm.tree.ClassNode; |
| 19 | 22 | ||
| 20 | import javax.annotation.Nullable; | 23 | import javax.annotation.Nullable; |
| @@ -28,12 +31,12 @@ import java.util.jar.JarEntry; | |||
| 28 | import java.util.jar.JarFile; | 31 | import java.util.jar.JarFile; |
| 29 | import java.util.jar.JarInputStream; | 32 | import java.util.jar.JarInputStream; |
| 30 | 33 | ||
| 31 | public class ParsedJar { | 34 | public class ParsedJar implements CompiledSource { |
| 32 | private final Map<String, byte[]> classBytes; | 35 | private final Map<String, byte[]> classBytes; |
| 33 | private final Map<String, ClassNode> nodeCache = new HashMap<>(); | 36 | private final Map<String, ClassNode> nodeCache = new HashMap<>(); |
| 34 | 37 | ||
| 35 | public ParsedJar(JarFile jar) throws IOException { | 38 | public ParsedJar(JarFile jar) throws IOException { |
| 36 | Map<String, byte[]> uClassBytes = new LinkedHashMap<>();; | 39 | Map<String, byte[]> uClassBytes = new LinkedHashMap<>(); |
| 37 | try { | 40 | try { |
| 38 | // get the jar entries that correspond to classes | 41 | // get the jar entries that correspond to classes |
| 39 | Enumeration<JarEntry> entries = jar.entries(); | 42 | Enumeration<JarEntry> entries = jar.entries(); |
| @@ -93,29 +96,34 @@ public class ParsedJar { | |||
| 93 | return classBytes.size(); | 96 | return classBytes.size(); |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | public List<ClassEntry> getClassEntries() { | ||
| 97 | List<ClassEntry> entries = new ArrayList<>(classBytes.size()); | ||
| 98 | for (String s : classBytes.keySet()) { | ||
| 99 | entries.add(new ClassEntry(s)); | ||
| 100 | } | ||
| 101 | return entries; | ||
| 102 | } | ||
| 103 | |||
| 104 | @Nullable | 99 | @Nullable |
| 100 | @Override | ||
| 105 | public ClassNode getClassNode(String name) { | 101 | public ClassNode getClassNode(String name) { |
| 106 | return nodeCache.computeIfAbsent(name, (n) -> { | 102 | return nodeCache.computeIfAbsent(name, (n) -> { |
| 107 | byte[] bytes = classBytes.get(name); | 103 | byte[] bytes = classBytes.get(name); |
| 108 | if (bytes == null) { | 104 | if (bytes == null) { |
| 109 | return null; | 105 | return null; |
| 110 | } | 106 | } |
| 107 | |||
| 111 | ClassReader reader = new ClassReader(bytes); | 108 | ClassReader reader = new ClassReader(bytes); |
| 112 | ClassNode node = new ClassNode(); | 109 | ClassNode node = new ClassNode(); |
| 113 | reader.accept(node, 0); | 110 | |
| 111 | LocalVariableFixVisitor visitor = new LocalVariableFixVisitor(Opcodes.ASM5, node); | ||
| 112 | reader.accept(visitor, 0); | ||
| 113 | |||
| 114 | return node; | 114 | return node; |
| 115 | }); | 115 | }); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | public Map<String, byte[]> getClassDataMap() { | 118 | public List<ClassEntry> getClassEntries() { |
| 119 | List<ClassEntry> entries = new ArrayList<>(classBytes.size()); | ||
| 120 | for (String s : classBytes.keySet()) { | ||
| 121 | entries.add(new ClassEntry(s)); | ||
| 122 | } | ||
| 123 | return entries; | ||
| 124 | } | ||
| 125 | |||
| 126 | public Map<String, byte[]> getClassDataMap() { | ||
| 119 | return classBytes; | 127 | return classBytes; |
| 120 | } | 128 | } |
| 121 | } | 129 | } |
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java index abdec92..ed12ce3 100644 --- a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java | |||
| @@ -11,17 +11,24 @@ | |||
| 11 | 11 | ||
| 12 | package cuchaz.enigma.analysis; | 12 | package cuchaz.enigma.analysis; |
| 13 | 13 | ||
| 14 | import com.google.common.collect.*; | 14 | import com.google.common.collect.HashMultimap; |
| 15 | import com.google.common.collect.Lists; | ||
| 16 | import com.google.common.collect.Maps; | ||
| 17 | import com.google.common.collect.Multimap; | ||
| 15 | import com.strobel.decompiler.languages.Region; | 18 | import com.strobel.decompiler.languages.Region; |
| 16 | import com.strobel.decompiler.languages.java.ast.AstNode; | 19 | import com.strobel.decompiler.languages.java.ast.*; |
| 17 | import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration; | 20 | import cuchaz.enigma.gui.SourceRemapper; |
| 18 | import com.strobel.decompiler.languages.java.ast.Identifier; | 21 | import cuchaz.enigma.translation.mapping.EntryResolver; |
| 19 | import com.strobel.decompiler.languages.java.ast.TypeDeclaration; | 22 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; |
| 20 | import cuchaz.enigma.translation.representation.entry.Entry; | 23 | import cuchaz.enigma.translation.representation.entry.Entry; |
| 21 | 24 | ||
| 22 | import javax.annotation.Nullable; | 25 | import javax.annotation.Nullable; |
| 23 | import java.util.*; | 26 | import java.util.Collection; |
| 27 | import java.util.List; | ||
| 28 | import java.util.Map; | ||
| 29 | import java.util.TreeMap; | ||
| 24 | import java.util.regex.Pattern; | 30 | import java.util.regex.Pattern; |
| 31 | import java.util.stream.Collectors; | ||
| 25 | 32 | ||
| 26 | public class SourceIndex { | 33 | public class SourceIndex { |
| 27 | private static Pattern ANONYMOUS_INNER = Pattern.compile("\\$\\d+$"); | 34 | private static Pattern ANONYMOUS_INNER = Pattern.compile("\\$\\d+$"); |
| @@ -46,6 +53,13 @@ public class SourceIndex { | |||
| 46 | calculateLineOffsets(); | 53 | calculateLineOffsets(); |
| 47 | } | 54 | } |
| 48 | 55 | ||
| 56 | public static SourceIndex buildIndex(String sourceString, CompilationUnit sourceTree, boolean ignoreBadTokens) { | ||
| 57 | SourceIndex index = new SourceIndex(sourceString, ignoreBadTokens); | ||
| 58 | sourceTree.acceptVisitor(new SourceIndexVisitor(), index); | ||
| 59 | |||
| 60 | return index; | ||
| 61 | } | ||
| 62 | |||
| 49 | private void calculateLineOffsets() { | 63 | private void calculateLineOffsets() { |
| 50 | // count the lines | 64 | // count the lines |
| 51 | this.lineOffsets = Lists.newArrayList(); | 65 | this.lineOffsets = Lists.newArrayList(); |
| @@ -57,32 +71,29 @@ public class SourceIndex { | |||
| 57 | } | 71 | } |
| 58 | } | 72 | } |
| 59 | 73 | ||
| 60 | public void remap(String source, Map<Token, Token> tokenMap) { | 74 | public SourceIndex remapTo(SourceRemapper.Result result) { |
| 61 | this.source = source; | 75 | SourceIndex remapped = new SourceIndex(result.getSource(), ignoreBadTokens); |
| 62 | calculateLineOffsets(); | ||
| 63 | 76 | ||
| 64 | for (Entry<?> entry : Lists.newArrayList(declarationToToken.keySet())) { | 77 | for (Map.Entry<Entry<?>, Token> entry : declarationToToken.entrySet()) { |
| 65 | Token token = declarationToToken.get(entry); | 78 | remapped.declarationToToken.put(entry.getKey(), result.getRemappedToken(entry.getValue())); |
| 66 | declarationToToken.put(entry, tokenMap.getOrDefault(token, token)); | ||
| 67 | } | 79 | } |
| 68 | 80 | ||
| 69 | for (EntryReference<Entry<?>, Entry<?>> ref : referenceToTokens.keySet()) { | 81 | for (Map.Entry<EntryReference<Entry<?>, Entry<?>>, Collection<Token>> entry : referenceToTokens.asMap().entrySet()) { |
| 70 | Collection<Token> oldTokens = referenceToTokens.get(ref); | 82 | EntryReference<Entry<?>, Entry<?>> reference = entry.getKey(); |
| 71 | List<Token> newTokens = new ArrayList<>(oldTokens.size()); | 83 | Collection<Token> oldTokens = entry.getValue(); |
| 72 | 84 | ||
| 73 | for (Token token : oldTokens) { | 85 | Collection<Token> newTokens = oldTokens.stream() |
| 74 | newTokens.add(tokenMap.getOrDefault(token, token)); | 86 | .map(result::getRemappedToken) |
| 75 | } | 87 | .collect(Collectors.toList()); |
| 76 | 88 | ||
| 77 | referenceToTokens.replaceValues(ref, newTokens); | 89 | remapped.referenceToTokens.putAll(reference, newTokens); |
| 78 | } | 90 | } |
| 79 | 91 | ||
| 80 | TreeMap<Token, EntryReference<Entry<?>, Entry<?>>> tokenToReferenceCopy = new TreeMap<>(tokenToReference); | 92 | for (Map.Entry<Token, EntryReference<Entry<?>, Entry<?>>> entry : tokenToReference.entrySet()) { |
| 81 | 93 | remapped.tokenToReference.put(result.getRemappedToken(entry.getKey()), entry.getValue()); | |
| 82 | tokenToReference.clear(); | ||
| 83 | for (Token token : tokenToReferenceCopy.keySet()) { | ||
| 84 | tokenToReference.put(tokenMap.getOrDefault(token, token), tokenToReferenceCopy.get(token)); | ||
| 85 | } | 94 | } |
| 95 | |||
| 96 | return remapped; | ||
| 86 | } | 97 | } |
| 87 | 98 | ||
| 88 | public String getSource() { | 99 | public String getSource() { |
| @@ -164,20 +175,13 @@ public class SourceIndex { | |||
| 164 | } | 175 | } |
| 165 | 176 | ||
| 166 | @Nullable | 177 | @Nullable |
| 167 | public EntryReference<Entry<?>, Entry<?>> getDeobfReference(Token token) { | 178 | public EntryReference<Entry<?>, Entry<?>> getReference(Token token) { |
| 168 | if (token == null) { | 179 | if (token == null) { |
| 169 | return null; | 180 | return null; |
| 170 | } | 181 | } |
| 171 | return this.tokenToReference.get(token); | 182 | return this.tokenToReference.get(token); |
| 172 | } | 183 | } |
| 173 | 184 | ||
| 174 | public void replaceDeobfReference(Token token, EntryReference<Entry<?>, Entry<?>> newDeobfReference) { | ||
| 175 | EntryReference<Entry<?>, Entry<?>> oldDeobfReferences = this.tokenToReference.replace(token, newDeobfReference); | ||
| 176 | |||
| 177 | Collection<Token> tokens = this.referenceToTokens.removeAll(oldDeobfReferences); | ||
| 178 | this.referenceToTokens.putAll(newDeobfReference, tokens); | ||
| 179 | } | ||
| 180 | |||
| 181 | public Iterable<Token> referenceTokens() { | 185 | public Iterable<Token> referenceTokens() { |
| 182 | return this.tokenToReference.keySet(); | 186 | return this.tokenToReference.keySet(); |
| 183 | } | 187 | } |
| @@ -190,8 +194,8 @@ public class SourceIndex { | |||
| 190 | return this.declarationToToken.keySet(); | 194 | return this.declarationToToken.keySet(); |
| 191 | } | 195 | } |
| 192 | 196 | ||
| 193 | public Token getDeclarationToken(Entry<?> deobfEntry) { | 197 | public Token getDeclarationToken(Entry<?> entry) { |
| 194 | return this.declarationToToken.get(deobfEntry); | 198 | return this.declarationToToken.get(entry); |
| 195 | } | 199 | } |
| 196 | 200 | ||
| 197 | public int getLineNumber(int pos) { | 201 | public int getLineNumber(int pos) { |
| @@ -215,4 +219,18 @@ public class SourceIndex { | |||
| 215 | // line and col are 1-based | 219 | // line and col are 1-based |
| 216 | return this.lineOffsets.get(line - 1) + col - 1; | 220 | return this.lineOffsets.get(line - 1) + col - 1; |
| 217 | } | 221 | } |
| 222 | |||
| 223 | public void resolveReferences(EntryResolver resolver) { | ||
| 224 | // resolve all the classes in the source references | ||
| 225 | for (Token token : Lists.newArrayList(referenceToTokens.values())) { | ||
| 226 | EntryReference<Entry<?>, Entry<?>> reference = tokenToReference.get(token); | ||
| 227 | EntryReference<Entry<?>, Entry<?>> resolvedReference = resolver.resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); | ||
| 228 | |||
| 229 | // replace the reference | ||
| 230 | tokenToReference.replace(token, resolvedReference); | ||
| 231 | |||
| 232 | Collection<Token> tokens = referenceToTokens.removeAll(reference); | ||
| 233 | referenceToTokens.putAll(resolvedReference, tokens); | ||
| 234 | } | ||
| 235 | } | ||
| 218 | } | 236 | } |
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java index 486603c..a4fe9ee 100644 --- a/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java +++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexClassVisitor.java | |||
| @@ -18,21 +18,17 @@ import com.strobel.assembler.metadata.TypeReference; | |||
| 18 | import com.strobel.decompiler.languages.TextLocation; | 18 | import com.strobel.decompiler.languages.TextLocation; |
| 19 | import com.strobel.decompiler.languages.java.ast.*; | 19 | import com.strobel.decompiler.languages.java.ast.*; |
| 20 | import cuchaz.enigma.translation.representation.ProcyonEntryFactory; | 20 | import cuchaz.enigma.translation.representation.ProcyonEntryFactory; |
| 21 | import cuchaz.enigma.translation.representation.ReferencedEntryPool; | ||
| 22 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; | 21 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; |
| 23 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 22 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 24 | import cuchaz.enigma.translation.representation.entry.FieldDefEntry; | 23 | import cuchaz.enigma.translation.representation.entry.FieldDefEntry; |
| 25 | import cuchaz.enigma.translation.representation.entry.MethodDefEntry; | 24 | import cuchaz.enigma.translation.representation.entry.MethodDefEntry; |
| 26 | 25 | ||
| 27 | public class SourceIndexClassVisitor extends SourceIndexVisitor { | 26 | public class SourceIndexClassVisitor extends SourceIndexVisitor { |
| 28 | private final ReferencedEntryPool entryPool; | ||
| 29 | private final ProcyonEntryFactory entryFactory; | 27 | private final ProcyonEntryFactory entryFactory; |
| 30 | private ClassDefEntry classEntry; | 28 | private ClassDefEntry classEntry; |
| 31 | 29 | ||
| 32 | public SourceIndexClassVisitor(ReferencedEntryPool entryPool, ClassDefEntry classEntry) { | 30 | public SourceIndexClassVisitor(ClassDefEntry classEntry) { |
| 33 | super(entryPool); | 31 | this.entryFactory = new ProcyonEntryFactory(); |
| 34 | this.entryPool = entryPool; | ||
| 35 | this.entryFactory = new ProcyonEntryFactory(entryPool); | ||
| 36 | this.classEntry = classEntry; | 32 | this.classEntry = classEntry; |
| 37 | } | 33 | } |
| 38 | 34 | ||
| @@ -44,7 +40,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor { | |||
| 44 | if (!classEntry.equals(this.classEntry)) { | 40 | if (!classEntry.equals(this.classEntry)) { |
| 45 | // it's a subtype, recurse | 41 | // it's a subtype, recurse |
| 46 | index.addDeclaration(node.getNameToken(), classEntry); | 42 | index.addDeclaration(node.getNameToken(), classEntry); |
| 47 | return node.acceptVisitor(new SourceIndexClassVisitor(entryPool, classEntry), index); | 43 | return node.acceptVisitor(new SourceIndexClassVisitor(classEntry), index); |
| 48 | } | 44 | } |
| 49 | 45 | ||
| 50 | return recurse(node, index); | 46 | return recurse(node, index); |
| @@ -71,7 +67,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor { | |||
| 71 | tokenNode = node.getModifiers().firstOrNullObject(); | 67 | tokenNode = node.getModifiers().firstOrNullObject(); |
| 72 | } | 68 | } |
| 73 | index.addDeclaration(tokenNode, methodEntry); | 69 | index.addDeclaration(tokenNode, methodEntry); |
| 74 | return node.acceptVisitor(new SourceIndexMethodVisitor(entryPool, methodEntry), index); | 70 | return node.acceptVisitor(new SourceIndexMethodVisitor(methodEntry), index); |
| 75 | } | 71 | } |
| 76 | 72 | ||
| 77 | @Override | 73 | @Override |
| @@ -79,7 +75,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor { | |||
| 79 | MethodDefinition def = node.getUserData(Keys.METHOD_DEFINITION); | 75 | MethodDefinition def = node.getUserData(Keys.METHOD_DEFINITION); |
| 80 | MethodDefEntry methodEntry = entryFactory.getMethodDefEntry(def); | 76 | MethodDefEntry methodEntry = entryFactory.getMethodDefEntry(def); |
| 81 | index.addDeclaration(node.getNameToken(), methodEntry); | 77 | index.addDeclaration(node.getNameToken(), methodEntry); |
| 82 | return node.acceptVisitor(new SourceIndexMethodVisitor(entryPool, methodEntry), index); | 78 | return node.acceptVisitor(new SourceIndexMethodVisitor(methodEntry), index); |
| 83 | } | 79 | } |
| 84 | 80 | ||
| 85 | @Override | 81 | @Override |
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java index 73db28f..c4785b6 100644 --- a/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java +++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java | |||
| @@ -17,8 +17,8 @@ import com.strobel.assembler.metadata.*; | |||
| 17 | import com.strobel.decompiler.ast.Variable; | 17 | import com.strobel.decompiler.ast.Variable; |
| 18 | import com.strobel.decompiler.languages.TextLocation; | 18 | import com.strobel.decompiler.languages.TextLocation; |
| 19 | import com.strobel.decompiler.languages.java.ast.*; | 19 | import com.strobel.decompiler.languages.java.ast.*; |
| 20 | import cuchaz.enigma.translation.representation.MethodDescriptor; | ||
| 20 | import cuchaz.enigma.translation.representation.TypeDescriptor; | 21 | import cuchaz.enigma.translation.representation.TypeDescriptor; |
| 21 | import cuchaz.enigma.translation.representation.*; | ||
| 22 | import cuchaz.enigma.translation.representation.entry.*; | 22 | import cuchaz.enigma.translation.representation.entry.*; |
| 23 | 23 | ||
| 24 | import java.lang.Error; | 24 | import java.lang.Error; |
| @@ -26,16 +26,12 @@ import java.util.HashMap; | |||
| 26 | import java.util.Map; | 26 | import java.util.Map; |
| 27 | 27 | ||
| 28 | public class SourceIndexMethodVisitor extends SourceIndexVisitor { | 28 | public class SourceIndexMethodVisitor extends SourceIndexVisitor { |
| 29 | private final ReferencedEntryPool entryPool; | ||
| 30 | |||
| 31 | private final MethodDefEntry methodEntry; | 29 | private final MethodDefEntry methodEntry; |
| 32 | 30 | ||
| 33 | private Multimap<String, Identifier> unmatchedIdentifier = HashMultimap.create(); | 31 | private Multimap<String, Identifier> unmatchedIdentifier = HashMultimap.create(); |
| 34 | private Map<String, Entry<?>> identifierEntryCache = new HashMap<>(); | 32 | private Map<String, Entry<?>> identifierEntryCache = new HashMap<>(); |
| 35 | 33 | ||
| 36 | public SourceIndexMethodVisitor(ReferencedEntryPool entryPool, MethodDefEntry methodEntry) { | 34 | public SourceIndexMethodVisitor(MethodDefEntry methodEntry) { |
| 37 | super(entryPool); | ||
| 38 | this.entryPool = entryPool; | ||
| 39 | this.methodEntry = methodEntry; | 35 | this.methodEntry = methodEntry; |
| 40 | } | 36 | } |
| 41 | 37 | ||
| @@ -44,10 +40,10 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 44 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); | 40 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); |
| 45 | 41 | ||
| 46 | // get the behavior entry | 42 | // get the behavior entry |
| 47 | ClassEntry classEntry = entryPool.getClass(ref.getDeclaringType().getInternalName()); | 43 | ClassEntry classEntry = new ClassEntry(ref.getDeclaringType().getInternalName()); |
| 48 | MethodEntry methodEntry = null; | 44 | MethodEntry methodEntry = null; |
| 49 | if (ref instanceof MethodReference) { | 45 | if (ref instanceof MethodReference) { |
| 50 | methodEntry = entryPool.getMethod(classEntry, ref.getName(), ref.getErasedSignature()); | 46 | methodEntry = new MethodEntry(classEntry, ref.getName(), new MethodDescriptor(ref.getErasedSignature())); |
| 51 | } | 47 | } |
| 52 | if (methodEntry != null) { | 48 | if (methodEntry != null) { |
| 53 | // get the node for the token | 49 | // get the node for the token |
| @@ -80,11 +76,8 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 80 | throw new Error("Expected a field here! got " + ref); | 76 | throw new Error("Expected a field here! got " + ref); |
| 81 | } | 77 | } |
| 82 | 78 | ||
| 83 | ClassEntry classEntry = entryPool.getClass(ref.getDeclaringType().getInternalName()); | 79 | ClassEntry classEntry = new ClassEntry(ref.getDeclaringType().getInternalName()); |
| 84 | FieldEntry fieldEntry = entryPool.getField(classEntry, ref.getName(), new TypeDescriptor(erasedSignature)); | 80 | FieldEntry fieldEntry = new FieldEntry(classEntry, ref.getName(), new TypeDescriptor(erasedSignature)); |
| 85 | if (fieldEntry == null) { | ||
| 86 | throw new Error("Failed to find field " + ref.getName() + " on " + classEntry.getFullName()); | ||
| 87 | } | ||
| 88 | index.addReference(node.getMemberNameToken(), fieldEntry, this.methodEntry); | 81 | index.addReference(node.getMemberNameToken(), fieldEntry, this.methodEntry); |
| 89 | } | 82 | } |
| 90 | 83 | ||
| @@ -95,7 +88,7 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 95 | public Void visitSimpleType(SimpleType node, SourceIndex index) { | 88 | public Void visitSimpleType(SimpleType node, SourceIndex index) { |
| 96 | TypeReference ref = node.getUserData(Keys.TYPE_REFERENCE); | 89 | TypeReference ref = node.getUserData(Keys.TYPE_REFERENCE); |
| 97 | if (node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY) { | 90 | if (node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY) { |
| 98 | ClassEntry classEntry = entryPool.getClass(ref.getInternalName()); | 91 | ClassEntry classEntry = new ClassEntry(ref.getInternalName()); |
| 99 | index.addReference(node.getIdentifierToken(), classEntry, this.methodEntry); | 92 | index.addReference(node.getIdentifierToken(), classEntry, this.methodEntry); |
| 100 | } | 93 | } |
| 101 | 94 | ||
| @@ -108,7 +101,8 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 108 | int parameterIndex = def.getSlot(); | 101 | int parameterIndex = def.getSlot(); |
| 109 | 102 | ||
| 110 | if (parameterIndex >= 0) { | 103 | if (parameterIndex >= 0) { |
| 111 | LocalVariableEntry localVariableEntry = new LocalVariableEntry(methodEntry, parameterIndex, node.getName(), true); | 104 | TypeDescriptor parameterType = TypeDescriptor.parse(def.getParameterType()); |
| 105 | LocalVariableDefEntry localVariableEntry = new LocalVariableDefEntry(methodEntry, parameterIndex, node.getName(), true, parameterType); | ||
| 112 | Identifier identifier = node.getNameToken(); | 106 | Identifier identifier = node.getNameToken(); |
| 113 | // cache the argument entry and the identifier | 107 | // cache the argument entry and the identifier |
| 114 | identifierEntryCache.put(identifier.getName(), localVariableEntry); | 108 | identifierEntryCache.put(identifier.getName(), localVariableEntry); |
| @@ -122,11 +116,8 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 122 | public Void visitIdentifierExpression(IdentifierExpression node, SourceIndex index) { | 116 | public Void visitIdentifierExpression(IdentifierExpression node, SourceIndex index) { |
| 123 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); | 117 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); |
| 124 | if (ref != null) { | 118 | if (ref != null) { |
| 125 | ClassEntry classEntry = entryPool.getClass(ref.getDeclaringType().getInternalName()); | 119 | ClassEntry classEntry = new ClassEntry(ref.getDeclaringType().getInternalName()); |
| 126 | FieldEntry fieldEntry = entryPool.getField(classEntry, ref.getName(), new TypeDescriptor(ref.getErasedSignature())); | 120 | FieldEntry fieldEntry = new FieldEntry(classEntry, ref.getName(), new TypeDescriptor(ref.getErasedSignature())); |
| 127 | if (fieldEntry == null) { | ||
| 128 | throw new Error("Failed to find field " + ref.getName() + " on " + classEntry.getFullName()); | ||
| 129 | } | ||
| 130 | index.addReference(node.getIdentifierToken(), fieldEntry, this.methodEntry); | 121 | index.addReference(node.getIdentifierToken(), fieldEntry, this.methodEntry); |
| 131 | } else | 122 | } else |
| 132 | this.checkIdentifier(node, index); | 123 | this.checkIdentifier(node, index); |
| @@ -154,13 +145,11 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 154 | @Override | 145 | @Override |
| 155 | public Void visitObjectCreationExpression(ObjectCreationExpression node, SourceIndex index) { | 146 | public Void visitObjectCreationExpression(ObjectCreationExpression node, SourceIndex index) { |
| 156 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); | 147 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); |
| 157 | if (ref != null) { | 148 | if (ref != null && node.getType() instanceof SimpleType) { |
| 158 | ClassEntry classEntry = entryPool.getClass(ref.getDeclaringType().getInternalName()); | 149 | SimpleType simpleTypeNode = (SimpleType) node.getType(); |
| 159 | MethodEntry constructorEntry = entryPool.getMethod(classEntry, "<init>", ref.getErasedSignature()); | 150 | ClassEntry classEntry = new ClassEntry(ref.getDeclaringType().getInternalName()); |
| 160 | if (node.getType() instanceof SimpleType) { | 151 | MethodEntry constructorEntry = new MethodEntry(classEntry, "<init>", new MethodDescriptor(ref.getErasedSignature())); |
| 161 | SimpleType simpleTypeNode = (SimpleType) node.getType(); | 152 | index.addReference(simpleTypeNode.getIdentifierToken(), constructorEntry, this.methodEntry); |
| 162 | index.addReference(simpleTypeNode.getIdentifierToken(), constructorEntry, this.methodEntry); | ||
| 163 | } | ||
| 164 | } | 153 | } |
| 165 | 154 | ||
| 166 | return recurse(node, index); | 155 | return recurse(node, index); |
| @@ -181,7 +170,8 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 181 | if (originalVariable != null) { | 170 | if (originalVariable != null) { |
| 182 | int variableIndex = originalVariable.getSlot(); | 171 | int variableIndex = originalVariable.getSlot(); |
| 183 | if (variableIndex >= 0) { | 172 | if (variableIndex >= 0) { |
| 184 | LocalVariableEntry localVariableEntry = new LocalVariableEntry(methodEntry, variableIndex, initializer.getName(), false); | 173 | TypeDescriptor variableType = TypeDescriptor.parse(originalVariable.getVariableType()); |
| 174 | LocalVariableDefEntry localVariableEntry = new LocalVariableDefEntry(methodEntry, variableIndex, initializer.getName(), false, variableType); | ||
| 185 | identifierEntryCache.put(identifier.getName(), localVariableEntry); | 175 | identifierEntryCache.put(identifier.getName(), localVariableEntry); |
| 186 | addDeclarationToUnmatched(identifier.getName(), index); | 176 | addDeclarationToUnmatched(identifier.getName(), index); |
| 187 | index.addDeclaration(identifier, localVariableEntry); | 177 | index.addDeclaration(identifier, localVariableEntry); |
| @@ -199,17 +189,19 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 199 | 189 | ||
| 200 | if (ref instanceof MethodReference) { | 190 | if (ref instanceof MethodReference) { |
| 201 | // get the behavior entry | 191 | // get the behavior entry |
| 202 | ClassEntry classEntry = entryPool.getClass(ref.getDeclaringType().getInternalName()); | 192 | ClassEntry classEntry = new ClassEntry(ref.getDeclaringType().getInternalName()); |
| 203 | MethodEntry methodEntry = null; | 193 | MethodEntry methodEntry = new MethodEntry(classEntry, ref.getName(), new MethodDescriptor(ref.getErasedSignature())); |
| 204 | 194 | ||
| 205 | methodEntry = entryPool.getMethod(classEntry, ref.getName(), ref.getErasedSignature()); | ||
| 206 | // get the node for the token | 195 | // get the node for the token |
| 207 | AstNode tokenNode = node.getMethodNameToken(); | 196 | AstNode methodNameToken = node.getMethodNameToken(); |
| 208 | if (tokenNode == null || (tokenNode.getRegion().getBeginLine() == 0 || tokenNode.getRegion().getEndLine() == 0)){ | 197 | AstNode targetToken = node.getTarget(); |
| 209 | tokenNode = node.getTarget(); | 198 | |
| 199 | if (methodNameToken != null) { | ||
| 200 | index.addReference(methodNameToken, methodEntry, this.methodEntry); | ||
| 210 | } | 201 | } |
| 211 | if (tokenNode != null) { | 202 | |
| 212 | index.addReference(tokenNode, methodEntry, this.methodEntry); | 203 | if (targetToken != null && !(targetToken instanceof ThisReferenceExpression)) { |
| 204 | index.addReference(targetToken, methodEntry.getParent(), this.methodEntry); | ||
| 213 | } | 205 | } |
| 214 | } | 206 | } |
| 215 | 207 | ||
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java index 564830c..75a66a2 100644 --- a/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java +++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexVisitor.java | |||
| @@ -14,23 +14,16 @@ package cuchaz.enigma.analysis; | |||
| 14 | import com.strobel.assembler.metadata.TypeDefinition; | 14 | import com.strobel.assembler.metadata.TypeDefinition; |
| 15 | import com.strobel.decompiler.languages.java.ast.*; | 15 | import com.strobel.decompiler.languages.java.ast.*; |
| 16 | import com.strobel.decompiler.patterns.Pattern; | 16 | import com.strobel.decompiler.patterns.Pattern; |
| 17 | import cuchaz.enigma.translation.representation.ReferencedEntryPool; | ||
| 18 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; | 17 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; |
| 19 | 18 | ||
| 20 | public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void> { | 19 | public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void> { |
| 21 | private final ReferencedEntryPool entryPool; | ||
| 22 | |||
| 23 | public SourceIndexVisitor(ReferencedEntryPool entryPool) { | ||
| 24 | this.entryPool = entryPool; | ||
| 25 | } | ||
| 26 | |||
| 27 | @Override | 20 | @Override |
| 28 | public Void visitTypeDeclaration(TypeDeclaration node, SourceIndex index) { | 21 | public Void visitTypeDeclaration(TypeDeclaration node, SourceIndex index) { |
| 29 | TypeDefinition def = node.getUserData(Keys.TYPE_DEFINITION); | 22 | TypeDefinition def = node.getUserData(Keys.TYPE_DEFINITION); |
| 30 | ClassDefEntry classEntry = ClassDefEntry.parse(def); | 23 | ClassDefEntry classEntry = ClassDefEntry.parse(def); |
| 31 | index.addDeclaration(node.getNameToken(), classEntry); | 24 | index.addDeclaration(node.getNameToken(), classEntry); |
| 32 | 25 | ||
| 33 | return node.acceptVisitor(new SourceIndexClassVisitor(entryPool, classEntry), index); | 26 | return node.acceptVisitor(new SourceIndexClassVisitor(classEntry), index); |
| 34 | } | 27 | } |
| 35 | 28 | ||
| 36 | protected Void recurse(AstNode node, SourceIndex index) { | 29 | protected Void recurse(AstNode node, SourceIndex index) { |
diff --git a/src/main/java/cuchaz/enigma/analysis/Token.java b/src/main/java/cuchaz/enigma/analysis/Token.java index 14fa7ca..12e0aa6 100644 --- a/src/main/java/cuchaz/enigma/analysis/Token.java +++ b/src/main/java/cuchaz/enigma/analysis/Token.java | |||
| @@ -30,12 +30,12 @@ public class Token implements Comparable<Token> { | |||
| 30 | return to.length() - length; | 30 | return to.length() - length; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | public String rename(String source, String to) { | 33 | public void rename(StringBuffer source, String to) { |
| 34 | int oldEnd = this.end; | 34 | int oldEnd = this.end; |
| 35 | this.text = to; | 35 | this.text = to; |
| 36 | this.end = this.start + to.length(); | 36 | this.end = this.start + to.length(); |
| 37 | 37 | ||
| 38 | return source.substring(0, this.start) + to + source.substring(oldEnd); | 38 | source.replace(start, oldEnd, to); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | public Token move(int offset) { | 41 | public Token move(int offset) { |
| @@ -64,7 +64,7 @@ public class Token implements Comparable<Token> { | |||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | public boolean equals(Token other) { | 66 | public boolean equals(Token other) { |
| 67 | return start == other.start && end == other.end; | 67 | return start == other.start && end == other.end && text.equals(other.text); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | @Override | 70 | @Override |
diff --git a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java index e1903d9..8f6bd46 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | package cuchaz.enigma.analysis.index; | 1 | package cuchaz.enigma.analysis.index; |
| 2 | 2 | ||
| 3 | import com.google.common.collect.Maps; | 3 | import com.google.common.collect.Maps; |
| 4 | import cuchaz.enigma.translation.Translator; | ||
| 5 | import cuchaz.enigma.translation.mapping.EntryResolver; | 4 | import cuchaz.enigma.translation.mapping.EntryResolver; |
| 6 | import cuchaz.enigma.translation.representation.AccessFlags; | 5 | import cuchaz.enigma.translation.representation.AccessFlags; |
| 7 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | 6 | import cuchaz.enigma.translation.representation.entry.MethodEntry; |
| @@ -10,7 +9,7 @@ import javax.annotation.Nullable; | |||
| 10 | import java.util.Collection; | 9 | import java.util.Collection; |
| 11 | import java.util.Map; | 10 | import java.util.Map; |
| 12 | 11 | ||
| 13 | public class BridgeMethodIndex implements JarIndexer, RemappableIndex { | 12 | public class BridgeMethodIndex implements JarIndexer { |
| 14 | private final EntryIndex entryIndex; | 13 | private final EntryIndex entryIndex; |
| 15 | private final ReferenceIndex referenceIndex; | 14 | private final ReferenceIndex referenceIndex; |
| 16 | 15 | ||
| @@ -22,19 +21,6 @@ public class BridgeMethodIndex implements JarIndexer, RemappableIndex { | |||
| 22 | } | 21 | } |
| 23 | 22 | ||
| 24 | @Override | 23 | @Override |
| 25 | public void remap(Translator translator) { | ||
| 26 | accessedToBridge = translator.translate(accessedToBridge); | ||
| 27 | } | ||
| 28 | |||
| 29 | @Override | ||
| 30 | public BridgeMethodIndex remapped(Translator translator) { | ||
| 31 | BridgeMethodIndex index = new BridgeMethodIndex(entryIndex, referenceIndex); | ||
| 32 | index.accessedToBridge = translator.translate(accessedToBridge); | ||
| 33 | |||
| 34 | return index; | ||
| 35 | } | ||
| 36 | |||
| 37 | @Override | ||
| 38 | public void processIndex(EntryResolver resolver) { | 24 | public void processIndex(EntryResolver resolver) { |
| 39 | // look for access and bridged methods | 25 | // look for access and bridged methods |
| 40 | for (MethodEntry methodEntry : entryIndex.getMethods()) { | 26 | for (MethodEntry methodEntry : entryIndex.getMethods()) { |
diff --git a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java index 55bfbc2..773eaf1 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | package cuchaz.enigma.analysis.index; | 1 | package cuchaz.enigma.analysis.index; |
| 2 | 2 | ||
| 3 | import cuchaz.enigma.translation.Translator; | ||
| 4 | import cuchaz.enigma.translation.representation.AccessFlags; | 3 | import cuchaz.enigma.translation.representation.AccessFlags; |
| 5 | import cuchaz.enigma.translation.representation.entry.*; | 4 | import cuchaz.enigma.translation.representation.entry.*; |
| 6 | 5 | ||
| @@ -9,29 +8,12 @@ import java.util.Collection; | |||
| 9 | import java.util.HashMap; | 8 | import java.util.HashMap; |
| 10 | import java.util.Map; | 9 | import java.util.Map; |
| 11 | 10 | ||
| 12 | public class EntryIndex implements JarIndexer, RemappableIndex { | 11 | public class EntryIndex implements JarIndexer { |
| 13 | private Map<ClassEntry, AccessFlags> classes = new HashMap<>(); | 12 | private Map<ClassEntry, AccessFlags> classes = new HashMap<>(); |
| 14 | private Map<FieldEntry, AccessFlags> fields = new HashMap<>(); | 13 | private Map<FieldEntry, AccessFlags> fields = new HashMap<>(); |
| 15 | private Map<MethodEntry, AccessFlags> methods = new HashMap<>(); | 14 | private Map<MethodEntry, AccessFlags> methods = new HashMap<>(); |
| 16 | 15 | ||
| 17 | @Override | 16 | @Override |
| 18 | public void remap(Translator translator) { | ||
| 19 | classes = translator.translateKeys(classes); | ||
| 20 | fields = translator.translateKeys(fields); | ||
| 21 | methods = translator.translateKeys(methods); | ||
| 22 | } | ||
| 23 | |||
| 24 | @Override | ||
| 25 | public EntryIndex remapped(Translator translator) { | ||
| 26 | EntryIndex index = new EntryIndex(); | ||
| 27 | index.classes = translator.translateKeys(classes); | ||
| 28 | index.fields = translator.translateKeys(fields); | ||
| 29 | index.methods = translator.translateKeys(methods); | ||
| 30 | |||
| 31 | return index; | ||
| 32 | } | ||
| 33 | |||
| 34 | @Override | ||
| 35 | public void indexClass(ClassDefEntry classEntry) { | 17 | public void indexClass(ClassDefEntry classEntry) { |
| 36 | classes.put(classEntry, classEntry.getAccess()); | 18 | classes.put(classEntry, classEntry.getAccess()); |
| 37 | } | 19 | } |
diff --git a/src/main/java/cuchaz/enigma/analysis/index/InheritanceIndex.java b/src/main/java/cuchaz/enigma/analysis/index/InheritanceIndex.java index d165cc8..17bed54 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/InheritanceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/InheritanceIndex.java | |||
| @@ -14,7 +14,6 @@ package cuchaz.enigma.analysis.index; | |||
| 14 | import com.google.common.collect.HashMultimap; | 14 | import com.google.common.collect.HashMultimap; |
| 15 | import com.google.common.collect.Multimap; | 15 | import com.google.common.collect.Multimap; |
| 16 | import com.google.common.collect.Sets; | 16 | import com.google.common.collect.Sets; |
| 17 | import cuchaz.enigma.translation.Translator; | ||
| 18 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; | 17 | import cuchaz.enigma.translation.representation.entry.ClassDefEntry; |
| 19 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 18 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 20 | 19 | ||
| @@ -22,26 +21,11 @@ import java.util.Collection; | |||
| 22 | import java.util.LinkedList; | 21 | import java.util.LinkedList; |
| 23 | import java.util.Set; | 22 | import java.util.Set; |
| 24 | 23 | ||
| 25 | public class InheritanceIndex implements JarIndexer, RemappableIndex { | 24 | public class InheritanceIndex implements JarIndexer { |
| 26 | private Multimap<ClassEntry, ClassEntry> classParents = HashMultimap.create(); | 25 | private Multimap<ClassEntry, ClassEntry> classParents = HashMultimap.create(); |
| 27 | private Multimap<ClassEntry, ClassEntry> classChildren = HashMultimap.create(); | 26 | private Multimap<ClassEntry, ClassEntry> classChildren = HashMultimap.create(); |
| 28 | 27 | ||
| 29 | @Override | 28 | @Override |
| 30 | public void remap(Translator translator) { | ||
| 31 | classChildren = translator.translate(classChildren); | ||
| 32 | classParents = translator.translate(classParents); | ||
| 33 | } | ||
| 34 | |||
| 35 | @Override | ||
| 36 | public InheritanceIndex remapped(Translator translator) { | ||
| 37 | InheritanceIndex index = new InheritanceIndex(); | ||
| 38 | index.classParents = translator.translate(classParents); | ||
| 39 | index.classChildren = translator.translate(classChildren); | ||
| 40 | |||
| 41 | return index; | ||
| 42 | } | ||
| 43 | |||
| 44 | @Override | ||
| 45 | public void indexClass(ClassDefEntry classEntry) { | 29 | public void indexClass(ClassDefEntry classEntry) { |
| 46 | ClassEntry superClass = classEntry.getSuperClass(); | 30 | ClassEntry superClass = classEntry.getSuperClass(); |
| 47 | if (superClass != null) { | 31 | if (superClass != null) { |
diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java index 0880244..9b21cba 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java | |||
| @@ -14,7 +14,6 @@ package cuchaz.enigma.analysis.index; | |||
| 14 | import com.google.common.collect.HashMultimap; | 14 | import com.google.common.collect.HashMultimap; |
| 15 | import com.google.common.collect.Multimap; | 15 | import com.google.common.collect.Multimap; |
| 16 | import cuchaz.enigma.analysis.ParsedJar; | 16 | import cuchaz.enigma.analysis.ParsedJar; |
| 17 | import cuchaz.enigma.translation.Translator; | ||
| 18 | import cuchaz.enigma.translation.mapping.EntryResolver; | 17 | import cuchaz.enigma.translation.mapping.EntryResolver; |
| 19 | import cuchaz.enigma.translation.mapping.IndexEntryResolver; | 18 | import cuchaz.enigma.translation.mapping.IndexEntryResolver; |
| 20 | import cuchaz.enigma.translation.representation.entry.*; | 19 | import cuchaz.enigma.translation.representation.entry.*; |
| @@ -25,7 +24,7 @@ import java.util.Arrays; | |||
| 25 | import java.util.Collection; | 24 | import java.util.Collection; |
| 26 | import java.util.function.Consumer; | 25 | import java.util.function.Consumer; |
| 27 | 26 | ||
| 28 | public class JarIndex implements JarIndexer, RemappableIndex { | 27 | public class JarIndex implements JarIndexer { |
| 29 | private final EntryIndex entryIndex; | 28 | private final EntryIndex entryIndex; |
| 30 | private final InheritanceIndex inheritanceIndex; | 29 | private final InheritanceIndex inheritanceIndex; |
| 31 | private final ReferenceIndex referenceIndex; | 30 | private final ReferenceIndex referenceIndex; |
| @@ -53,25 +52,6 @@ public class JarIndex implements JarIndexer, RemappableIndex { | |||
| 53 | return new JarIndex(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex); | 52 | return new JarIndex(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex); |
| 54 | } | 53 | } |
| 55 | 54 | ||
| 56 | @Override | ||
| 57 | public void remap(Translator translator) { | ||
| 58 | entryIndex.remap(translator); | ||
| 59 | inheritanceIndex.remap(translator); | ||
| 60 | bridgeMethodIndex.remap(translator); | ||
| 61 | } | ||
| 62 | |||
| 63 | @Override | ||
| 64 | public JarIndex remapped(Translator translator) { | ||
| 65 | EntryIndex entryIndex = this.entryIndex.remapped(translator); | ||
| 66 | InheritanceIndex inheritanceIndex = this.inheritanceIndex.remapped(translator); | ||
| 67 | BridgeMethodIndex bridgeMethodIndex = this.bridgeMethodIndex.remapped(translator); | ||
| 68 | |||
| 69 | JarIndex remappedIndex = new JarIndex(entryIndex, inheritanceIndex, this.referenceIndex, bridgeMethodIndex); | ||
| 70 | remappedIndex.methodImplementations.putAll(methodImplementations); | ||
| 71 | |||
| 72 | return remappedIndex; | ||
| 73 | } | ||
| 74 | |||
| 75 | public void indexJar(ParsedJar jar, Consumer<String> progress) { | 55 | public void indexJar(ParsedJar jar, Consumer<String> progress) { |
| 76 | progress.accept("Indexing entries (1/3)"); | 56 | progress.accept("Indexing entries (1/3)"); |
| 77 | jar.visitReader(name -> new IndexClassVisitor(this, Opcodes.ASM5), ClassReader.SKIP_CODE); | 57 | jar.visitReader(name -> new IndexClassVisitor(this, Opcodes.ASM5), ClassReader.SKIP_CODE); |
diff --git a/src/main/java/cuchaz/enigma/analysis/index/RemappableIndex.java b/src/main/java/cuchaz/enigma/analysis/index/RemappableIndex.java deleted file mode 100644 index 537e772..0000000 --- a/src/main/java/cuchaz/enigma/analysis/index/RemappableIndex.java +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | package cuchaz.enigma.analysis.index; | ||
| 2 | |||
| 3 | import cuchaz.enigma.translation.Translator; | ||
| 4 | |||
| 5 | public interface RemappableIndex { | ||
| 6 | void remap(Translator translator); | ||
| 7 | |||
| 8 | RemappableIndex remapped(Translator translator); | ||
| 9 | } | ||