From ba7a354efae7d49833c887cf147ac940c975a1fa Mon Sep 17 00:00:00 2001 From: Gegy Date: Wed, 30 Jan 2019 21:05:32 +0200 Subject: 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 --- .../java/cuchaz/enigma/gui/SourceRemapper.java | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/main/java/cuchaz/enigma/gui/SourceRemapper.java (limited to 'src/main/java/cuchaz/enigma/gui/SourceRemapper.java') diff --git a/src/main/java/cuchaz/enigma/gui/SourceRemapper.java b/src/main/java/cuchaz/enigma/gui/SourceRemapper.java new file mode 100644 index 0000000..f38f44e --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/SourceRemapper.java @@ -0,0 +1,64 @@ +package cuchaz.enigma.gui; + +import cuchaz.enigma.analysis.Token; + +import java.util.HashMap; +import java.util.Map; + +public class SourceRemapper { + private final String source; + private final Iterable tokens; + + public SourceRemapper(String source, Iterable tokens) { + this.source = source; + this.tokens = tokens; + } + + public Result remap(Remapper remapper) { + StringBuffer remappedSource = new StringBuffer(source); + Map remappedTokens = new HashMap<>(); + + int accumulatedOffset = 0; + for (Token token : tokens) { + Token movedToken = token.move(accumulatedOffset); + + String remappedName = remapper.remap(token, movedToken); + if (remappedName != null) { + accumulatedOffset += movedToken.getRenameOffset(remappedName); + movedToken.rename(remappedSource, remappedName); + } + + if (!token.equals(movedToken)) { + remappedTokens.put(token, movedToken); + } + } + + return new Result(remappedSource.toString(), remappedTokens); + } + + public static class Result { + private final String remappedSource; + private final Map remappedTokens; + + Result(String remappedSource, Map remappedTokens) { + this.remappedSource = remappedSource; + this.remappedTokens = remappedTokens; + } + + public String getSource() { + return remappedSource; + } + + public Token getRemappedToken(Token token) { + return remappedTokens.getOrDefault(token, token); + } + + public boolean isEmpty() { + return remappedTokens.isEmpty(); + } + } + + public interface Remapper { + String remap(Token token, Token movedToken); + } +} -- cgit v1.2.3