diff options
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis/SourceIndex.java')
| -rw-r--r-- | src/main/java/cuchaz/enigma/analysis/SourceIndex.java | 86 |
1 files changed, 52 insertions, 34 deletions
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 | } |