summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java')
-rw-r--r--src/main/java/cuchaz/enigma/gui/DecompiledClassSource.java159
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 @@
1package cuchaz.enigma.gui;
2
3import cuchaz.enigma.EnigmaProject;
4import cuchaz.enigma.EnigmaServices;
5import cuchaz.enigma.analysis.EntryReference;
6import cuchaz.enigma.analysis.Token;
7import cuchaz.enigma.api.service.NameProposalService;
8import cuchaz.enigma.gui.highlight.TokenHighlightType;
9import cuchaz.enigma.source.SourceIndex;
10import cuchaz.enigma.translation.LocalNameGenerator;
11import cuchaz.enigma.translation.Translator;
12import cuchaz.enigma.translation.mapping.EntryRemapper;
13import cuchaz.enigma.translation.mapping.ResolutionStrategy;
14import cuchaz.enigma.translation.representation.TypeDescriptor;
15import cuchaz.enigma.translation.representation.entry.ClassEntry;
16import cuchaz.enigma.translation.representation.entry.Entry;
17import cuchaz.enigma.translation.representation.entry.LocalVariableDefEntry;
18
19import javax.annotation.Nullable;
20import java.util.*;
21
22public 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}