diff options
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java')
| -rw-r--r-- | src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java | 159 |
1 files changed, 0 insertions, 159 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java b/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java deleted file mode 100644 index 08df3e7..0000000 --- a/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java +++ /dev/null | |||
| @@ -1,159 +0,0 @@ | |||
| 1 | package cuchaz.enigma.gui; | ||
| 2 | |||
| 3 | import cuchaz.enigma.EnigmaProject; | ||
| 4 | import cuchaz.enigma.EnigmaServices; | ||
| 5 | import cuchaz.enigma.analysis.EntryReference; | ||
| 6 | import cuchaz.enigma.analysis.Token; | ||
| 7 | import cuchaz.enigma.api.service.NameProposalService; | ||
| 8 | import cuchaz.enigma.gui.highlight.TokenHighlightType; | ||
| 9 | import cuchaz.enigma.source.SourceIndex; | ||
| 10 | import cuchaz.enigma.translation.LocalNameGenerator; | ||
| 11 | import cuchaz.enigma.translation.Translator; | ||
| 12 | import cuchaz.enigma.translation.mapping.EntryRemapper; | ||
| 13 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; | ||
| 14 | import cuchaz.enigma.translation.representation.TypeDescriptor; | ||
| 15 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 16 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 17 | import cuchaz.enigma.translation.representation.entry.LocalVariableDefEntry; | ||
| 18 | |||
| 19 | import javax.annotation.Nullable; | ||
| 20 | import java.util.*; | ||
| 21 | |||
| 22 | public class DecompiledClassSource { | ||
| 23 | private final ClassEntry classEntry; | ||
| 24 | |||
| 25 | private final SourceIndex obfuscatedIndex; | ||
| 26 | private SourceIndex remappedIndex; | ||
| 27 | |||
| 28 | private final Map<TokenHighlightType, Collection<Token>> highlightedTokens = new EnumMap<>(TokenHighlightType.class); | ||
| 29 | |||
| 30 | public DecompiledClassSource(ClassEntry classEntry, SourceIndex index) { | ||
| 31 | this.classEntry = classEntry; | ||
| 32 | this.obfuscatedIndex = index; | ||
| 33 | this.remappedIndex = index; | ||
| 34 | } | ||
| 35 | |||
| 36 | public static DecompiledClassSource text(ClassEntry classEntry, String text) { | ||
| 37 | return new DecompiledClassSource(classEntry, new SourceIndex(text)); | ||
| 38 | } | ||
| 39 | |||
| 40 | public void remapSource(EnigmaProject project, Translator translator) { | ||
| 41 | highlightedTokens.clear(); | ||
| 42 | |||
| 43 | SourceRemapper remapper = new SourceRemapper(obfuscatedIndex.getSource(), obfuscatedIndex.referenceTokens()); | ||
| 44 | |||
| 45 | SourceRemapper.Result remapResult = remapper.remap((token, movedToken) -> remapToken(project, token, movedToken, translator)); | ||
| 46 | remappedIndex = obfuscatedIndex.remapTo(remapResult); | ||
| 47 | } | ||
| 48 | |||
| 49 | private String remapToken(EnigmaProject project, Token token, Token movedToken, Translator translator) { | ||
| 50 | EntryReference<Entry<?>, Entry<?>> reference = obfuscatedIndex.getReference(token); | ||
| 51 | |||
| 52 | Entry<?> entry = reference.getNameableEntry(); | ||
| 53 | Entry<?> translatedEntry = translator.translate(entry); | ||
| 54 | |||
| 55 | if (project.isRenamable(reference)) { | ||
| 56 | if (isDeobfuscated(entry, translatedEntry)) { | ||
| 57 | highlightToken(movedToken, TokenHighlightType.DEOBFUSCATED); | ||
| 58 | return translatedEntry.getSourceRemapName(); | ||
| 59 | } else { | ||
| 60 | Optional<String> proposedName = proposeName(project, entry); | ||
| 61 | if (proposedName.isPresent()) { | ||
| 62 | highlightToken(movedToken, TokenHighlightType.PROPOSED); | ||
| 63 | return proposedName.get(); | ||
| 64 | } | ||
| 65 | |||
| 66 | highlightToken(movedToken, TokenHighlightType.OBFUSCATED); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | String defaultName = generateDefaultName(translatedEntry); | ||
| 71 | if (defaultName != null) { | ||
| 72 | return defaultName; | ||
| 73 | } | ||
| 74 | |||
| 75 | return null; | ||
| 76 | } | ||
| 77 | |||
| 78 | private Optional<String> proposeName(EnigmaProject project, Entry<?> entry) { | ||
| 79 | EnigmaServices services = project.getEnigma().getServices(); | ||
| 80 | |||
| 81 | return services.get(NameProposalService.TYPE).stream().flatMap(nameProposalService -> { | ||
| 82 | EntryRemapper mapper = project.getMapper(); | ||
| 83 | Collection<Entry<?>> resolved = mapper.getObfResolver().resolveEntry(entry, ResolutionStrategy.RESOLVE_ROOT); | ||
| 84 | |||
| 85 | return resolved.stream() | ||
| 86 | .map(e -> nameProposalService.proposeName(e, mapper)) | ||
| 87 | .filter(Optional::isPresent) | ||
| 88 | .map(Optional::get); | ||
| 89 | }).findFirst(); | ||
| 90 | } | ||
| 91 | |||
| 92 | @Nullable | ||
| 93 | private String generateDefaultName(Entry<?> entry) { | ||
| 94 | if (entry instanceof LocalVariableDefEntry) { | ||
| 95 | LocalVariableDefEntry localVariable = (LocalVariableDefEntry) entry; | ||
| 96 | |||
| 97 | int index = localVariable.getIndex(); | ||
| 98 | if (localVariable.isArgument()) { | ||
| 99 | List<TypeDescriptor> arguments = localVariable.getParent().getDesc().getArgumentDescs(); | ||
| 100 | return LocalNameGenerator.generateArgumentName(index, localVariable.getDesc(), arguments); | ||
| 101 | } else { | ||
| 102 | return LocalNameGenerator.generateLocalVariableName(index, localVariable.getDesc()); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | return null; | ||
| 107 | } | ||
| 108 | |||
| 109 | private boolean isDeobfuscated(Entry<?> entry, Entry<?> translatedEntry) { | ||
| 110 | return !entry.getName().equals(translatedEntry.getName()); | ||
| 111 | } | ||
| 112 | |||
| 113 | public ClassEntry getEntry() { | ||
| 114 | return classEntry; | ||
| 115 | } | ||
| 116 | |||
| 117 | public SourceIndex getIndex() { | ||
| 118 | return remappedIndex; | ||
| 119 | } | ||
| 120 | |||
| 121 | public Map<TokenHighlightType, Collection<Token>> getHighlightedTokens() { | ||
| 122 | return highlightedTokens; | ||
| 123 | } | ||
| 124 | |||
| 125 | private void highlightToken(Token token, TokenHighlightType highlightType) { | ||
| 126 | highlightedTokens.computeIfAbsent(highlightType, t -> new ArrayList<>()).add(token); | ||
| 127 | } | ||
| 128 | |||
| 129 | public int getObfuscatedOffset(int deobfOffset) { | ||
| 130 | return getOffset(remappedIndex, obfuscatedIndex, deobfOffset); | ||
| 131 | } | ||
| 132 | |||
| 133 | public int getDeobfuscatedOffset(int obfOffset) { | ||
| 134 | return getOffset(obfuscatedIndex, remappedIndex, obfOffset); | ||
| 135 | } | ||
| 136 | |||
| 137 | private static int getOffset(SourceIndex fromIndex, SourceIndex toIndex, int fromOffset) { | ||
| 138 | int relativeOffset = 0; | ||
| 139 | |||
| 140 | Iterator<Token> fromTokenItr = fromIndex.referenceTokens().iterator(); | ||
| 141 | Iterator<Token> toTokenItr = toIndex.referenceTokens().iterator(); | ||
| 142 | while (fromTokenItr.hasNext() && toTokenItr.hasNext()) { | ||
| 143 | Token fromToken = fromTokenItr.next(); | ||
| 144 | Token toToken = toTokenItr.next(); | ||
| 145 | if (fromToken.end > fromOffset) { | ||
| 146 | break; | ||
| 147 | } | ||
| 148 | |||
| 149 | relativeOffset = toToken.end - fromToken.end; | ||
| 150 | } | ||
| 151 | |||
| 152 | return fromOffset + relativeOffset; | ||
| 153 | } | ||
| 154 | |||
| 155 | @Override | ||
| 156 | public String toString() { | ||
| 157 | return remappedIndex.getSource(); | ||
| 158 | } | ||
| 159 | } | ||