summaryrefslogtreecommitdiff
path: root/enigma
diff options
context:
space:
mode:
authorGravatar Yanis482020-12-14 21:15:53 +0100
committerGravatar Yanis482020-12-14 21:15:53 +0100
commite16f81dba9edadb3fc02492bfeff06266890e754 (patch)
treefbc2389fbea75c110712c9ae982cfa5d5b957fee /enigma
parentBump version (diff)
downloadenigma-fork-e16f81dba9edadb3fc02492bfeff06266890e754.tar.gz
enigma-fork-e16f81dba9edadb3fc02492bfeff06266890e754.tar.xz
enigma-fork-e16f81dba9edadb3fc02492bfeff06266890e754.zip
Structure panel!
Diffstat (limited to 'enigma')
-rw-r--r--enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java109
-rw-r--r--enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java24
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java27
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java7
-rw-r--r--enigma/src/main/resources/lang/en_us.json2
-rw-r--r--enigma/src/main/resources/lang/fr_fr.json2
7 files changed, 161 insertions, 13 deletions
diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java
new file mode 100644
index 0000000..13f277c
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java
@@ -0,0 +1,109 @@
1package cuchaz.enigma.analysis;
2
3import cuchaz.enigma.analysis.index.JarIndex;
4import cuchaz.enigma.translation.Translator;
5import cuchaz.enigma.translation.representation.TypeDescriptor;
6import cuchaz.enigma.translation.representation.entry.*;
7
8import javax.swing.tree.DefaultMutableTreeNode;
9import java.util.List;
10
11public class StructureTreeNode extends DefaultMutableTreeNode {
12 private final Translator translator;
13 private final ClassEntry parentEntry;
14 private final ParentedEntry entry;
15
16 public StructureTreeNode(Translator translator, ClassEntry parentEntry, ParentedEntry entry) {
17 this.translator = translator;
18 this.parentEntry = parentEntry;
19 this.entry = entry;
20 }
21
22 /**
23 * Returns the parented entry corresponding to this tree node.
24 */
25 public ParentedEntry getEntry() {
26 return this.entry;
27 }
28
29 public void load(JarIndex jarIndex, boolean hideDeobfuscated) {
30 List<ParentedEntry> children = jarIndex.getChildrenByClass().get(this.parentEntry);
31
32 for (ParentedEntry child : children) {
33 StructureTreeNode childNode = new StructureTreeNode(this.translator, this.parentEntry, child);
34
35 if (child instanceof ClassEntry) {
36 childNode = new StructureTreeNode(this.translator, (ClassEntry) child, child);
37 childNode.load(jarIndex, hideDeobfuscated);
38 }
39
40 // don't add deobfuscated members if hideDeobfuscated is true, unless it's an inner class
41 if (hideDeobfuscated && this.translator.extendedTranslate(child).isDeobfuscated() && !(child instanceof ClassEntry)) {
42 continue;
43 }
44
45 // don't add constructor methods if hideDeobfuscated is true
46 if (hideDeobfuscated && (child instanceof MethodEntry) && ((MethodEntry) child).isConstructor()) {
47 continue;
48 }
49
50 this.add(childNode);
51 }
52 }
53
54 @Override
55 public String toString() {
56 ParentedEntry translatedEntry = this.translator.extendedTranslate(this.entry).getValue();
57 String result = translatedEntry.getName();
58
59 if (this.entry instanceof FieldDefEntry) {
60 FieldDefEntry field = (FieldDefEntry) translatedEntry;
61 String returnType = this.parseDesc(field.getDesc());
62
63 result = result + ": " + returnType;
64 } else if (this.entry instanceof MethodDefEntry) {
65 MethodDefEntry method = (MethodDefEntry) translatedEntry;
66 String args = this.parseArgs(method.getDesc().getArgumentDescs());
67 String returnType = this.parseDesc(method.getDesc().getReturnDesc());
68
69 if (method.isConstructor()) {
70 result = method.getParent().getSimpleName() + args;
71 } else {
72 result = result + args + ": " + returnType;
73 }
74 }
75
76 return result;
77 }
78
79 private String parseArgs(List<TypeDescriptor> args) {
80 if (args.size() > 0) {
81 String result = "(";
82
83 for (int i = 0; i < args.size(); i++) {
84 if (i > 0) {
85 result += ", ";
86 }
87
88 result += this.parseDesc(args.get(i));
89 }
90
91 return result + ")";
92 }
93
94 return "()";
95 }
96
97 private String parseDesc(TypeDescriptor desc) {
98 if (desc.isVoid()) return "void";
99 if (desc.isPrimitive()) return desc.getPrimitive().getKeyword();
100 if (desc.isType()) return desc.getTypeEntry().getSimpleName();
101
102 if (desc.isArray()) {
103 if (desc.getArrayType().isPrimitive()) return desc.getArrayType().getPrimitive().getKeyword() + "[]";
104 if (desc.getArrayType().isType()) return desc.getArrayType().getTypeEntry().getSimpleName() + "[]";
105 }
106
107 return null;
108 }
109}
diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
index b5ad91a..d41731f 100644
--- a/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
+++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
@@ -23,10 +23,7 @@ import cuchaz.enigma.translation.representation.Lambda;
23import cuchaz.enigma.translation.representation.entry.*; 23import cuchaz.enigma.translation.representation.entry.*;
24import cuchaz.enigma.utils.I18n; 24import cuchaz.enigma.utils.I18n;
25 25
26import java.util.Arrays; 26import java.util.*;
27import java.util.Collection;
28import java.util.HashSet;
29import java.util.Set;
30 27
31public class JarIndex implements JarIndexer { 28public class JarIndex implements JarIndexer {
32 private final Set<String> indexedClasses = new HashSet<>(); 29 private final Set<String> indexedClasses = new HashSet<>();
@@ -40,6 +37,7 @@ public class JarIndex implements JarIndexer {
40 private final Collection<JarIndexer> indexers; 37 private final Collection<JarIndexer> indexers;
41 38
42 private final Multimap<String, MethodDefEntry> methodImplementations = HashMultimap.create(); 39 private final Multimap<String, MethodDefEntry> methodImplementations = HashMultimap.create();
40 private final Map<ClassEntry, List<ParentedEntry>> childrenByClass;
43 41
44 public JarIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex, BridgeMethodIndex bridgeMethodIndex, PackageVisibilityIndex packageVisibilityIndex) { 42 public JarIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex, BridgeMethodIndex bridgeMethodIndex, PackageVisibilityIndex packageVisibilityIndex) {
45 this.entryIndex = entryIndex; 43 this.entryIndex = entryIndex;
@@ -49,6 +47,7 @@ public class JarIndex implements JarIndexer {
49 this.packageVisibilityIndex = packageVisibilityIndex; 47 this.packageVisibilityIndex = packageVisibilityIndex;
50 this.indexers = Arrays.asList(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex); 48 this.indexers = Arrays.asList(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex);
51 this.entryResolver = new IndexEntryResolver(this); 49 this.entryResolver = new IndexEntryResolver(this);
50 this.childrenByClass = new HashMap<>();
52 } 51 }
53 52
54 public static JarIndex empty() { 53 public static JarIndex empty() {
@@ -101,6 +100,11 @@ public class JarIndex implements JarIndexer {
101 } 100 }
102 101
103 indexers.forEach(indexer -> indexer.indexClass(classEntry)); 102 indexers.forEach(indexer -> indexer.indexClass(classEntry));
103 childrenByClass.putIfAbsent(classEntry, new ArrayList<>());
104 if (classEntry.isInnerClass() && !classEntry.getAccess().isSynthetic()) {
105 childrenByClass.putIfAbsent(classEntry.getParent(), new ArrayList<>());
106 childrenByClass.get(classEntry.getParent()).add(classEntry);
107 }
104 } 108 }
105 109
106 @Override 110 @Override
@@ -110,6 +114,10 @@ public class JarIndex implements JarIndexer {
110 } 114 }
111 115
112 indexers.forEach(indexer -> indexer.indexField(fieldEntry)); 116 indexers.forEach(indexer -> indexer.indexField(fieldEntry));
117 if (!fieldEntry.getAccess().isSynthetic()) {
118 childrenByClass.putIfAbsent(fieldEntry.getParent(), new ArrayList<>());
119 childrenByClass.get(fieldEntry.getParent()).add(fieldEntry);
120 }
113 } 121 }
114 122
115 @Override 123 @Override
@@ -119,6 +127,10 @@ public class JarIndex implements JarIndexer {
119 } 127 }
120 128
121 indexers.forEach(indexer -> indexer.indexMethod(methodEntry)); 129 indexers.forEach(indexer -> indexer.indexMethod(methodEntry));
130 if (!methodEntry.getAccess().isSynthetic() && !methodEntry.getName().equals("<clinit>")) {
131 childrenByClass.putIfAbsent(methodEntry.getParent(), new ArrayList<>());
132 childrenByClass.get(methodEntry.getParent()).add(methodEntry);
133 }
122 134
123 if (!methodEntry.isConstructor()) { 135 if (!methodEntry.isConstructor()) {
124 methodImplementations.put(methodEntry.getParent().getFullName(), methodEntry); 136 methodImplementations.put(methodEntry.getParent().getFullName(), methodEntry);
@@ -176,6 +188,10 @@ public class JarIndex implements JarIndexer {
176 return entryResolver; 188 return entryResolver;
177 } 189 }
178 190
191 public Map<ClassEntry, List<ParentedEntry>> getChildrenByClass() {
192 return this.childrenByClass;
193 }
194
179 public boolean isIndexed(String internalName) { 195 public boolean isIndexed(String internalName) {
180 return indexedClasses.contains(internalName); 196 return indexedClasses.contains(internalName);
181 } 197 }
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java
index a7dccfc..6a1b82f 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/TypeDescriptor.java
@@ -235,14 +235,14 @@ public class TypeDescriptor implements Translatable {
235 } 235 }
236 236
237 public enum Primitive { 237 public enum Primitive {
238 BYTE('B'), 238 BYTE('B', "byte"),
239 CHARACTER('C'), 239 CHARACTER('C', "char"),
240 SHORT('S'), 240 SHORT('S', "short"),
241 INTEGER('I'), 241 INTEGER('I', "int"),
242 LONG('J'), 242 LONG('J', "long"),
243 FLOAT('F'), 243 FLOAT('F', "float"),
244 DOUBLE('D'), 244 DOUBLE('D', "double"),
245 BOOLEAN('Z'); 245 BOOLEAN('Z', "boolean");
246 246
247 private static final Map<Character, Primitive> lookup; 247 private static final Map<Character, Primitive> lookup;
248 248
@@ -254,9 +254,11 @@ public class TypeDescriptor implements Translatable {
254 } 254 }
255 255
256 private char code; 256 private char code;
257 private String keyword;
257 258
258 Primitive(char code) { 259 Primitive(char code, String keyword) {
259 this.code = code; 260 this.code = code;
261 this.keyword = keyword;
260 } 262 }
261 263
262 public static Primitive get(char code) { 264 public static Primitive get(char code) {
@@ -266,5 +268,12 @@ public class TypeDescriptor implements Translatable {
266 public char getCode() { 268 public char getCode() {
267 return this.code; 269 return this.code;
268 } 270 }
271
272 /**
273 * Returns the Java keyword corresponding to this primitive.
274 */
275 public String getKeyword() {
276 return this.keyword;
277 }
269 } 278 }
270} 279}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
index 4a50021..b4a22f1 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/ClassEntry.java
@@ -134,6 +134,9 @@ public class ClassEntry extends ParentedEntry<ClassEntry> implements Comparable<
134 return name; 134 return name;
135 } 135 }
136 136
137 /**
138 * Returns whether this class entry has a parent, and therefore is an inner class.
139 */
137 public boolean isInnerClass() { 140 public boolean isInnerClass() {
138 return parent != null; 141 return parent != null;
139 } 142 }
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java
index ff392fe..6fd412a 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/representation/entry/Entry.java
@@ -29,6 +29,13 @@ public interface Entry<P extends Entry<?>> extends Translatable {
29 return getName(); 29 return getName();
30 } 30 }
31 31
32 /**
33 * Returns the parent entry of this entry.
34 *
35 * <p>The parent entry should be a {@linkplain MethodEntry method} for local variables,
36 * a {@linkplain ClassEntry class} for methods, fields and inner classes, and {@code null}
37 * for other classes.</p>
38 */
32 @Nullable 39 @Nullable
33 P getParent(); 40 P getParent();
34 41
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json
index 9db4e1f..8195bb1 100644
--- a/enigma/src/main/resources/lang/en_us.json
+++ b/enigma/src/main/resources/lang/en_us.json
@@ -101,6 +101,8 @@
101 "info_panel.identifier.index": "Index", 101 "info_panel.identifier.index": "Index",
102 "info_panel.editor.class.decompiling": "(decompiling...)", 102 "info_panel.editor.class.decompiling": "(decompiling...)",
103 "info_panel.editor.class.not_found": "Unable to find class:", 103 "info_panel.editor.class.not_found": "Unable to find class:",
104 "info_panel.tree.structure": "Structure",
105 "info_panel.tree.structure.hide_deobfuscated": "Hide deobfuscated members",
104 "info_panel.tree.inheritance": "Inheritance", 106 "info_panel.tree.inheritance": "Inheritance",
105 "info_panel.tree.implementations": "Implementations", 107 "info_panel.tree.implementations": "Implementations",
106 "info_panel.tree.calls": "Call Graph", 108 "info_panel.tree.calls": "Call Graph",
diff --git a/enigma/src/main/resources/lang/fr_fr.json b/enigma/src/main/resources/lang/fr_fr.json
index 127b9c8..43bea4d 100644
--- a/enigma/src/main/resources/lang/fr_fr.json
+++ b/enigma/src/main/resources/lang/fr_fr.json
@@ -101,6 +101,8 @@
101 "info_panel.identifier.index": "Index", 101 "info_panel.identifier.index": "Index",
102 "info_panel.editor.class.decompiling": "(décompilation...)", 102 "info_panel.editor.class.decompiling": "(décompilation...)",
103 "info_panel.editor.class.not_found": "Impossible de trouver la classe :", 103 "info_panel.editor.class.not_found": "Impossible de trouver la classe :",
104 "info_panel.tree.structure": "Structure",
105 "info_panel.tree.structure.hide_deobfuscated": "Masquer les membres déobfusqués",
104 "info_panel.tree.inheritance": "Héritage", 106 "info_panel.tree.inheritance": "Héritage",
105 "info_panel.tree.implementations": "Implémentations", 107 "info_panel.tree.implementations": "Implémentations",
106 "info_panel.tree.calls": "Graphique des appels", 108 "info_panel.tree.calls": "Graphique des appels",