summaryrefslogtreecommitdiff
path: root/enigma
diff options
context:
space:
mode:
authorGravatar Joseph Burton2025-10-18 16:38:40 +0100
committerGravatar GitHub2025-10-18 16:38:40 +0100
commit87581ffe8d23aaf8ad677ffbb9de1ecfec3cfe80 (patch)
treef3191c08ee6be85c11d8f109e6923c320e74368e /enigma
parentFix class version check in AddFramesIfNecessaryClassProvider (#575) (diff)
downloadenigma-fork-87581ffe8d23aaf8ad677ffbb9de1ecfec3cfe80.tar.gz
enigma-fork-87581ffe8d23aaf8ad677ffbb9de1ecfec3cfe80.tar.xz
enigma-fork-87581ffe8d23aaf8ad677ffbb9de1ecfec3cfe80.zip
Annotation editor support (#568)
* Add gutter markers * Add more GUI APIs * Use SVG icons for gutter markers * Add a little more padding between the line numbers and the gutter markers * Add API for creating an Enigma JEditorPane * Add API to list all classes including library classes * Add API to create a LocalVariableEntryView * Expose BrdigeMethodIndex to API * Require name to be passed to LocalVariableEntryView * Make implementation of isCursorOnDeclaration more robust * Checkstyle * Replace isCursorOnDeclaration with getCursorDeclaration * Checkstyle again * Refactor EnigmaIcon as per Juuz's suggestions * Add more @NonExtendable and add EnigmaIcon docs
Diffstat (limited to 'enigma')
-rw-r--r--enigma/src/main/java/cuchaz/enigma/EnigmaProject.java5
-rw-r--r--enigma/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java16
-rw-r--r--enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java1
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/DataInvalidationEvent.java2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/EnigmaIcon.java39
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/service/GuiService.java18
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/GuiView.java13
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/ProjectView.java4
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassDefEntryView.java2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassEntryView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/DefEntryView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryReferenceView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryView.java2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/FieldEntryView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableDefEntryView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableEntryView.java10
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/entry/MethodEntryView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/index/BridgeMethodIndexView.java15
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/index/EntryIndexView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/index/InheritanceIndexView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/index/JarIndexView.java4
-rw-r--r--enigma/src/main/java/cuchaz/enigma/api/view/index/ReferenceIndexView.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/source/SourceIndex.java15
-rw-r--r--enigma/src/main/java/cuchaz/enigma/utils/IconLoadingService.java14
24 files changed, 185 insertions, 2 deletions
diff --git a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java
index 348e640..5242385 100644
--- a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java
+++ b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java
@@ -410,6 +410,11 @@ public class EnigmaProject implements ProjectView {
410 } 410 }
411 411
412 @Override 412 @Override
413 public Collection<String> getProjectAndLibraryClasses() {
414 return classProvider.getClassNames();
415 }
416
417 @Override
413 @Nullable 418 @Nullable
414 public ClassNode getBytecode(String className) { 419 public ClassNode getBytecode(String className) {
415 return classProvider.get(className); 420 return classProvider.get(className);
diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java b/enigma/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java
index adb48ba..b852b5f 100644
--- a/enigma/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java
+++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java
@@ -10,6 +10,8 @@ import java.util.concurrent.ConcurrentMap;
10 10
11import org.jetbrains.annotations.Nullable; 11import org.jetbrains.annotations.Nullable;
12 12
13import cuchaz.enigma.api.view.entry.MethodEntryView;
14import cuchaz.enigma.api.view.index.BridgeMethodIndexView;
13import cuchaz.enigma.translation.representation.AccessFlags; 15import cuchaz.enigma.translation.representation.AccessFlags;
14import cuchaz.enigma.translation.representation.MethodDescriptor; 16import cuchaz.enigma.translation.representation.MethodDescriptor;
15import cuchaz.enigma.translation.representation.TypeDescriptor; 17import cuchaz.enigma.translation.representation.TypeDescriptor;
@@ -17,7 +19,7 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry;
17import cuchaz.enigma.translation.representation.entry.MethodDefEntry; 19import cuchaz.enigma.translation.representation.entry.MethodDefEntry;
18import cuchaz.enigma.translation.representation.entry.MethodEntry; 20import cuchaz.enigma.translation.representation.entry.MethodEntry;
19 21
20public class BridgeMethodIndex implements JarIndexer { 22public class BridgeMethodIndex implements JarIndexer, BridgeMethodIndexView {
21 private final EntryIndex entryIndex; 23 private final EntryIndex entryIndex;
22 private final InheritanceIndex inheritanceIndex; 24 private final InheritanceIndex inheritanceIndex;
23 private final ReferenceIndex referenceIndex; 25 private final ReferenceIndex referenceIndex;
@@ -154,6 +156,18 @@ public class BridgeMethodIndex implements JarIndexer {
154 return bridgeToSpecialized.get(bridge); 156 return bridgeToSpecialized.get(bridge);
155 } 157 }
156 158
159 @Override
160 @Nullable
161 public MethodEntryView getBridgeFromSpecialized(MethodEntryView specialized) {
162 return getBridgeFromSpecialized((MethodEntry) specialized);
163 }
164
165 @Override
166 @Nullable
167 public MethodEntryView getSpecializedFromBridge(MethodEntryView bridge) {
168 return getSpecializedFromBridge((MethodEntry) bridge);
169 }
170
157 /** Includes "renamed specialized -> bridge" entries. */ 171 /** Includes "renamed specialized -> bridge" entries. */
158 public Map<MethodEntry, MethodEntry> getSpecializedToBridge() { 172 public Map<MethodEntry, MethodEntry> getSpecializedToBridge() {
159 return Collections.unmodifiableMap(specializedToBridge); 173 return Collections.unmodifiableMap(specializedToBridge);
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 5c5e2c3..242d750 100644
--- a/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
+++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
@@ -204,6 +204,7 @@ public class JarIndex implements JarIndexer, JarIndexView {
204 return referenceIndex; 204 return referenceIndex;
205 } 205 }
206 206
207 @Override
207 public BridgeMethodIndex getBridgeMethodIndex() { 208 public BridgeMethodIndex getBridgeMethodIndex() {
208 return bridgeMethodIndex; 209 return bridgeMethodIndex;
209 } 210 }
diff --git a/enigma/src/main/java/cuchaz/enigma/api/DataInvalidationEvent.java b/enigma/src/main/java/cuchaz/enigma/api/DataInvalidationEvent.java
index 812ad39..9396eff 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/DataInvalidationEvent.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/DataInvalidationEvent.java
@@ -2,8 +2,10 @@ package cuchaz.enigma.api;
2 2
3import java.util.Collection; 3import java.util.Collection;
4 4
5import org.jetbrains.annotations.ApiStatus;
5import org.jetbrains.annotations.Nullable; 6import org.jetbrains.annotations.Nullable;
6 7
8@ApiStatus.NonExtendable
7public interface DataInvalidationEvent { 9public interface DataInvalidationEvent {
8 /** 10 /**
9 * The classes for which the invalidation applies, or {@code null} if the invalidation applies to all classes. 11 * The classes for which the invalidation applies, or {@code null} if the invalidation applies to all classes.
diff --git a/enigma/src/main/java/cuchaz/enigma/api/EnigmaIcon.java b/enigma/src/main/java/cuchaz/enigma/api/EnigmaIcon.java
new file mode 100644
index 0000000..4a4bd0e
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/api/EnigmaIcon.java
@@ -0,0 +1,39 @@
1package cuchaz.enigma.api;
2
3import java.io.IOException;
4import java.io.InputStream;
5
6import org.jetbrains.annotations.ApiStatus;
7
8import cuchaz.enigma.utils.IconLoadingService;
9
10@ApiStatus.NonExtendable
11public interface EnigmaIcon {
12 /**
13 * Loads an icon resource from the given SVG resource path.
14 *
15 * @param resource the path to the resource to be loaded
16 * @return The loaded icon
17 * @throws IOException if the resource could not be found or an error occurred while reading it
18 */
19 static EnigmaIcon loadResource(String resource) throws IOException {
20 try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource)) {
21 if (in == null) {
22 throw new IOException("Could not find resource: " + resource);
23 }
24
25 return load(in);
26 }
27 }
28
29 /**
30 * Loads an icon in SVG format from the given input stream.
31 *
32 * @param in the input stream to load from
33 * @return The loaded icon
34 * @throws IOException if the stream throws an error
35 */
36 static EnigmaIcon load(InputStream in) throws IOException {
37 return IconLoadingService.INSTANCE.loadIcon(in);
38 }
39}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/service/GuiService.java b/enigma/src/main/java/cuchaz/enigma/api/service/GuiService.java
index b00b94d..53b566f 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/service/GuiService.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/service/GuiService.java
@@ -5,7 +5,9 @@ import java.util.function.Supplier;
5 5
6import javax.swing.KeyStroke; 6import javax.swing.KeyStroke;
7 7
8import cuchaz.enigma.api.EnigmaIcon;
8import cuchaz.enigma.api.view.GuiView; 9import cuchaz.enigma.api.view.GuiView;
10import cuchaz.enigma.api.view.entry.EntryView;
9 11
10public interface GuiService extends EnigmaService { 12public interface GuiService extends EnigmaService {
11 EnigmaServiceType<GuiService> TYPE = EnigmaServiceType.create("gui"); 13 EnigmaServiceType<GuiService> TYPE = EnigmaServiceType.create("gui");
@@ -16,6 +18,9 @@ public interface GuiService extends EnigmaService {
16 default void addToEditorContextMenu(GuiView gui, MenuRegistrar registrar) { 18 default void addToEditorContextMenu(GuiView gui, MenuRegistrar registrar) {
17 } 19 }
18 20
21 default void addGutterMarkers(GuiView gui, EntryView entry, GutterMarkerAdder gutter) {
22 }
23
19 interface MenuRegistrar { 24 interface MenuRegistrar {
20 void addSeparator(); 25 void addSeparator();
21 26
@@ -31,4 +36,17 @@ public interface GuiService extends EnigmaService {
31 MenuItemBuilder setEnabledWhen(BooleanSupplier condition); 36 MenuItemBuilder setEnabledWhen(BooleanSupplier condition);
32 MenuItemBuilder setAction(Runnable action); 37 MenuItemBuilder setAction(Runnable action);
33 } 38 }
39
40 interface GutterMarkerAdder {
41 GutterMarkerBuilder addMarker(EnigmaIcon icon, GutterMarkerAlignment alignment);
42 }
43
44 interface GutterMarkerBuilder {
45 GutterMarkerBuilder setClickAction(Runnable action);
46 GutterMarkerBuilder setTooltip(String tooltip);
47 }
48
49 enum GutterMarkerAlignment {
50 LEFT, RIGHT
51 }
34} 52}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/GuiView.java b/enigma/src/main/java/cuchaz/enigma/api/view/GuiView.java
index 519a8ce..1d91573 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/GuiView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/GuiView.java
@@ -1,11 +1,15 @@
1package cuchaz.enigma.api.view; 1package cuchaz.enigma.api.view;
2 2
3import javax.swing.JEditorPane;
3import javax.swing.JFrame; 4import javax.swing.JFrame;
4 5
6import org.jetbrains.annotations.ApiStatus;
5import org.jetbrains.annotations.Nullable; 7import org.jetbrains.annotations.Nullable;
6 8
7import cuchaz.enigma.api.view.entry.EntryReferenceView; 9import cuchaz.enigma.api.view.entry.EntryReferenceView;
10import cuchaz.enigma.api.view.entry.EntryView;
8 11
12@ApiStatus.NonExtendable
9public interface GuiView { 13public interface GuiView {
10 @Nullable 14 @Nullable
11 ProjectView getProject(); 15 ProjectView getProject();
@@ -13,5 +17,14 @@ public interface GuiView {
13 @Nullable 17 @Nullable
14 EntryReferenceView getCursorReference(); 18 EntryReferenceView getCursorReference();
15 19
20 @Nullable
21 EntryView getCursorDeclaration();
22
16 JFrame getFrame(); 23 JFrame getFrame();
24
25 float getScale();
26
27 boolean isDarkTheme();
28
29 JEditorPane createEditorPane();
17} 30}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/ProjectView.java b/enigma/src/main/java/cuchaz/enigma/api/view/ProjectView.java
index b72e1c3..c8cb384 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/ProjectView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/ProjectView.java
@@ -3,6 +3,7 @@ package cuchaz.enigma.api.view;
3import java.util.Collection; 3import java.util.Collection;
4import java.util.List; 4import java.util.List;
5 5
6import org.jetbrains.annotations.ApiStatus;
6import org.jetbrains.annotations.Nullable; 7import org.jetbrains.annotations.Nullable;
7import org.objectweb.asm.tree.ClassNode; 8import org.objectweb.asm.tree.ClassNode;
8 9
@@ -11,6 +12,7 @@ import cuchaz.enigma.api.DataInvalidationListener;
11import cuchaz.enigma.api.view.entry.EntryView; 12import cuchaz.enigma.api.view.entry.EntryView;
12import cuchaz.enigma.api.view.index.JarIndexView; 13import cuchaz.enigma.api.view.index.JarIndexView;
13 14
15@ApiStatus.NonExtendable
14public interface ProjectView { 16public interface ProjectView {
15 <T extends EntryView> T deobfuscate(T entry); 17 <T extends EntryView> T deobfuscate(T entry);
16 18
@@ -25,6 +27,8 @@ public interface ProjectView {
25 27
26 Collection<String> getProjectClasses(); 28 Collection<String> getProjectClasses();
27 29
30 Collection<String> getProjectAndLibraryClasses();
31
28 @Nullable 32 @Nullable
29 ClassNode getBytecode(String className); 33 ClassNode getBytecode(String className);
30 34
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassDefEntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassDefEntryView.java
index 7cb1829..1fb6a7f 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassDefEntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassDefEntryView.java
@@ -1,7 +1,9 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
3import org.jetbrains.annotations.Nullable; 4import org.jetbrains.annotations.Nullable;
4 5
6@ApiStatus.NonExtendable
5public interface ClassDefEntryView extends ClassEntryView, DefEntryView { 7public interface ClassDefEntryView extends ClassEntryView, DefEntryView {
6 @Nullable 8 @Nullable
7 ClassEntryView getSuperClass(); 9 ClassEntryView getSuperClass();
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassEntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassEntryView.java
index 085188b..330920b 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassEntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/ClassEntryView.java
@@ -1,7 +1,10 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
3import cuchaz.enigma.translation.representation.entry.ClassEntry; 5import cuchaz.enigma.translation.representation.entry.ClassEntry;
4 6
7@ApiStatus.NonExtendable
5public interface ClassEntryView extends EntryView { 8public interface ClassEntryView extends EntryView {
6 ClassEntryView getParent(); 9 ClassEntryView getParent();
7 10
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/DefEntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/DefEntryView.java
index bf246fb..a52e685 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/DefEntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/DefEntryView.java
@@ -1,5 +1,8 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
5@ApiStatus.NonExtendable
3public interface DefEntryView { 6public interface DefEntryView {
4 int getAccessFlags(); 7 int getAccessFlags();
5} 8}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryReferenceView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryReferenceView.java
index d49aa1e..6ca87ab 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryReferenceView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryReferenceView.java
@@ -1,5 +1,8 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
5@ApiStatus.NonExtendable
3public interface EntryReferenceView { 6public interface EntryReferenceView {
4 EntryView getEntry(); 7 EntryView getEntry();
5} 8}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryView.java
index 2dad562..963c1e7 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/EntryView.java
@@ -1,7 +1,9 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
3import org.jetbrains.annotations.Nullable; 4import org.jetbrains.annotations.Nullable;
4 5
6@ApiStatus.NonExtendable
5public interface EntryView { 7public interface EntryView {
6 /** 8 /**
7 * Returns the default name of this entry. 9 * Returns the default name of this entry.
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/FieldEntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/FieldEntryView.java
index ae44458..bf22814 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/FieldEntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/FieldEntryView.java
@@ -1,9 +1,12 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
3import cuchaz.enigma.translation.representation.TypeDescriptor; 5import cuchaz.enigma.translation.representation.TypeDescriptor;
4import cuchaz.enigma.translation.representation.entry.ClassEntry; 6import cuchaz.enigma.translation.representation.entry.ClassEntry;
5import cuchaz.enigma.translation.representation.entry.FieldEntry; 7import cuchaz.enigma.translation.representation.entry.FieldEntry;
6 8
9@ApiStatus.NonExtendable
7public interface FieldEntryView extends EntryView { 10public interface FieldEntryView extends EntryView {
8 String getDescriptor(); 11 String getDescriptor();
9 12
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableDefEntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableDefEntryView.java
index d091560..32e0af3 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableDefEntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableDefEntryView.java
@@ -1,5 +1,8 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
5@ApiStatus.NonExtendable
3public interface LocalVariableDefEntryView extends LocalVariableEntryView { 6public interface LocalVariableDefEntryView extends LocalVariableEntryView {
4 String getDescriptor(); 7 String getDescriptor();
5} 8}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableEntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableEntryView.java
index 391bc0f..b4728b5 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableEntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/LocalVariableEntryView.java
@@ -1,9 +1,19 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
5import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
6import cuchaz.enigma.translation.representation.entry.MethodEntry;
7
8@ApiStatus.NonExtendable
3public interface LocalVariableEntryView extends EntryView { 9public interface LocalVariableEntryView extends EntryView {
4 int getIndex(); 10 int getIndex();
5 11
6 boolean isArgument(); 12 boolean isArgument();
7 13
8 MethodEntryView getParent(); 14 MethodEntryView getParent();
15
16 static LocalVariableEntryView create(MethodEntryView parent, int index, String name, boolean argument) {
17 return new LocalVariableEntry((MethodEntry) parent, index, name, argument, null);
18 }
9} 19}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/entry/MethodEntryView.java b/enigma/src/main/java/cuchaz/enigma/api/view/entry/MethodEntryView.java
index 7d7fcd2..3020afa 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/entry/MethodEntryView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/entry/MethodEntryView.java
@@ -1,9 +1,12 @@
1package cuchaz.enigma.api.view.entry; 1package cuchaz.enigma.api.view.entry;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
3import cuchaz.enigma.translation.representation.MethodDescriptor; 5import cuchaz.enigma.translation.representation.MethodDescriptor;
4import cuchaz.enigma.translation.representation.entry.ClassEntry; 6import cuchaz.enigma.translation.representation.entry.ClassEntry;
5import cuchaz.enigma.translation.representation.entry.MethodEntry; 7import cuchaz.enigma.translation.representation.entry.MethodEntry;
6 8
9@ApiStatus.NonExtendable
7public interface MethodEntryView extends EntryView { 10public interface MethodEntryView extends EntryView {
8 String getDescriptor(); 11 String getDescriptor();
9 12
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/index/BridgeMethodIndexView.java b/enigma/src/main/java/cuchaz/enigma/api/view/index/BridgeMethodIndexView.java
new file mode 100644
index 0000000..c07be88
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/index/BridgeMethodIndexView.java
@@ -0,0 +1,15 @@
1package cuchaz.enigma.api.view.index;
2
3import org.jetbrains.annotations.ApiStatus;
4import org.jetbrains.annotations.Nullable;
5
6import cuchaz.enigma.api.view.entry.MethodEntryView;
7
8@ApiStatus.NonExtendable
9public interface BridgeMethodIndexView {
10 @Nullable
11 MethodEntryView getBridgeFromSpecialized(MethodEntryView specialized);
12
13 @Nullable
14 MethodEntryView getSpecializedFromBridge(MethodEntryView bridge);
15}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/index/EntryIndexView.java b/enigma/src/main/java/cuchaz/enigma/api/view/index/EntryIndexView.java
index 56bf70e..9b4fbaf 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/index/EntryIndexView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/index/EntryIndexView.java
@@ -2,10 +2,13 @@ package cuchaz.enigma.api.view.index;
2 2
3import java.util.Collection; 3import java.util.Collection;
4 4
5import org.jetbrains.annotations.ApiStatus;
6
5import cuchaz.enigma.api.view.entry.ClassDefEntryView; 7import cuchaz.enigma.api.view.entry.ClassDefEntryView;
6import cuchaz.enigma.api.view.entry.ClassEntryView; 8import cuchaz.enigma.api.view.entry.ClassEntryView;
7import cuchaz.enigma.api.view.entry.EntryView; 9import cuchaz.enigma.api.view.entry.EntryView;
8 10
11@ApiStatus.NonExtendable
9public interface EntryIndexView { 12public interface EntryIndexView {
10 boolean hasEntry(EntryView entry); 13 boolean hasEntry(EntryView entry);
11 int getAccess(EntryView entry); 14 int getAccess(EntryView entry);
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/index/InheritanceIndexView.java b/enigma/src/main/java/cuchaz/enigma/api/view/index/InheritanceIndexView.java
index a016d11..a156155 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/index/InheritanceIndexView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/index/InheritanceIndexView.java
@@ -2,8 +2,11 @@ package cuchaz.enigma.api.view.index;
2 2
3import java.util.Collection; 3import java.util.Collection;
4 4
5import org.jetbrains.annotations.ApiStatus;
6
5import cuchaz.enigma.api.view.entry.ClassEntryView; 7import cuchaz.enigma.api.view.entry.ClassEntryView;
6 8
9@ApiStatus.NonExtendable
7public interface InheritanceIndexView { 10public interface InheritanceIndexView {
8 Collection<? extends ClassEntryView> getParents(ClassEntryView entry); 11 Collection<? extends ClassEntryView> getParents(ClassEntryView entry);
9 Collection<? extends ClassEntryView> getChildren(ClassEntryView entry); 12 Collection<? extends ClassEntryView> getChildren(ClassEntryView entry);
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/index/JarIndexView.java b/enigma/src/main/java/cuchaz/enigma/api/view/index/JarIndexView.java
index 069b115..b723267 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/index/JarIndexView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/index/JarIndexView.java
@@ -1,7 +1,11 @@
1package cuchaz.enigma.api.view.index; 1package cuchaz.enigma.api.view.index;
2 2
3import org.jetbrains.annotations.ApiStatus;
4
5@ApiStatus.NonExtendable
3public interface JarIndexView { 6public interface JarIndexView {
4 EntryIndexView getEntryIndex(); 7 EntryIndexView getEntryIndex();
5 InheritanceIndexView getInheritanceIndex(); 8 InheritanceIndexView getInheritanceIndex();
6 ReferenceIndexView getReferenceIndex(); 9 ReferenceIndexView getReferenceIndex();
10 BridgeMethodIndexView getBridgeMethodIndex();
7} 11}
diff --git a/enigma/src/main/java/cuchaz/enigma/api/view/index/ReferenceIndexView.java b/enigma/src/main/java/cuchaz/enigma/api/view/index/ReferenceIndexView.java
index 00ab84e..7c0653f 100644
--- a/enigma/src/main/java/cuchaz/enigma/api/view/index/ReferenceIndexView.java
+++ b/enigma/src/main/java/cuchaz/enigma/api/view/index/ReferenceIndexView.java
@@ -2,11 +2,14 @@ package cuchaz.enigma.api.view.index;
2 2
3import java.util.Collection; 3import java.util.Collection;
4 4
5import org.jetbrains.annotations.ApiStatus;
6
5import cuchaz.enigma.api.view.entry.ClassEntryView; 7import cuchaz.enigma.api.view.entry.ClassEntryView;
6import cuchaz.enigma.api.view.entry.EntryReferenceView; 8import cuchaz.enigma.api.view.entry.EntryReferenceView;
7import cuchaz.enigma.api.view.entry.FieldEntryView; 9import cuchaz.enigma.api.view.entry.FieldEntryView;
8import cuchaz.enigma.api.view.entry.MethodEntryView; 10import cuchaz.enigma.api.view.entry.MethodEntryView;
9 11
12@ApiStatus.NonExtendable
10public interface ReferenceIndexView { 13public interface ReferenceIndexView {
11 Collection<? extends MethodEntryView> getMethodsReferencedBy(MethodEntryView entry); 14 Collection<? extends MethodEntryView> getMethodsReferencedBy(MethodEntryView entry);
12 Collection<? extends EntryReferenceView> getReferencesToClass(ClassEntryView entry); 15 Collection<? extends EntryReferenceView> getReferencesToClass(ClassEntryView entry);
diff --git a/enigma/src/main/java/cuchaz/enigma/source/SourceIndex.java b/enigma/src/main/java/cuchaz/enigma/source/SourceIndex.java
index fec20e2..51636e3 100644
--- a/enigma/src/main/java/cuchaz/enigma/source/SourceIndex.java
+++ b/enigma/src/main/java/cuchaz/enigma/source/SourceIndex.java
@@ -7,6 +7,8 @@ import java.util.List;
7import java.util.Map; 7import java.util.Map;
8import java.util.TreeMap; 8import java.util.TreeMap;
9 9
10import org.jetbrains.annotations.Nullable;
11
10import cuchaz.enigma.analysis.EntryReference; 12import cuchaz.enigma.analysis.EntryReference;
11import cuchaz.enigma.translation.mapping.EntryResolver; 13import cuchaz.enigma.translation.mapping.EntryResolver;
12import cuchaz.enigma.translation.mapping.ResolutionStrategy; 14import cuchaz.enigma.translation.mapping.ResolutionStrategy;
@@ -17,11 +19,13 @@ public class SourceIndex {
17 private List<Integer> lineOffsets; 19 private List<Integer> lineOffsets;
18 private final TreeMap<Token, EntryReference<Entry<?>, Entry<?>>> tokenToReference; 20 private final TreeMap<Token, EntryReference<Entry<?>, Entry<?>>> tokenToReference;
19 private final Map<EntryReference<Entry<?>, Entry<?>>, Collection<Token>> referenceToTokens; 21 private final Map<EntryReference<Entry<?>, Entry<?>>, Collection<Token>> referenceToTokens;
22 private final TreeMap<Token, Entry<?>> tokenToDeclaration;
20 private final Map<Entry<?>, Token> declarationToToken; 23 private final Map<Entry<?>, Token> declarationToToken;
21 24
22 public SourceIndex() { 25 public SourceIndex() {
23 tokenToReference = new TreeMap<>(); 26 tokenToReference = new TreeMap<>();
24 referenceToTokens = new HashMap<>(); 27 referenceToTokens = new HashMap<>();
28 tokenToDeclaration = new TreeMap<>();
25 declarationToToken = new HashMap<>(); 29 declarationToToken = new HashMap<>();
26 } 30 }
27 31
@@ -80,6 +84,11 @@ public class SourceIndex {
80 return declarationToToken.get(entry); 84 return declarationToToken.get(entry);
81 } 85 }
82 86
87 @Nullable
88 public Entry<?> getDeclaration(Token token) {
89 return tokenToDeclaration.get(token);
90 }
91
83 public void addDeclaration(Token token, Entry<?> deobfEntry) { 92 public void addDeclaration(Token token, Entry<?> deobfEntry) {
84 if (token != null) { 93 if (token != null) {
85 EntryReference<Entry<?>, Entry<?>> reference = new EntryReference<>(deobfEntry, token.text); 94 EntryReference<Entry<?>, Entry<?>> reference = new EntryReference<>(deobfEntry, token.text);
@@ -88,6 +97,7 @@ public class SourceIndex {
88 .add(token); 97 .add(token);
89 referenceToTokens.computeIfAbsent(EntryReference.declaration(deobfEntry, token.text), key -> new ArrayList<>()) 98 referenceToTokens.computeIfAbsent(EntryReference.declaration(deobfEntry, token.text), key -> new ArrayList<>())
90 .add(token); 99 .add(token);
100 tokenToDeclaration.put(token, deobfEntry);
91 declarationToToken.put(deobfEntry, token); 101 declarationToToken.put(deobfEntry, token);
92 } 102 }
93 } 103 }
@@ -108,6 +118,7 @@ public class SourceIndex {
108 return tokenToReference.keySet(); 118 return tokenToReference.keySet();
109 } 119 }
110 120
121 @Nullable
111 public Token getReferenceToken(int pos) { 122 public Token getReferenceToken(int pos) {
112 Token token = tokenToReference.floorKey(new Token(pos, pos, null)); 123 Token token = tokenToReference.floorKey(new Token(pos, pos, null));
113 124
@@ -153,7 +164,9 @@ public class SourceIndex {
153 SourceIndex remapped = new SourceIndex(result.getSource()); 164 SourceIndex remapped = new SourceIndex(result.getSource());
154 165
155 for (Map.Entry<Entry<?>, Token> entry : declarationToToken.entrySet()) { 166 for (Map.Entry<Entry<?>, Token> entry : declarationToToken.entrySet()) {
156 remapped.declarationToToken.put(entry.getKey(), result.getRemappedToken(entry.getValue())); 167 Token remappedToken = result.getRemappedToken(entry.getValue());
168 remapped.declarationToToken.put(entry.getKey(), remappedToken);
169 remapped.tokenToDeclaration.put(remappedToken, entry.getKey());
157 } 170 }
158 171
159 for (Map.Entry<EntryReference<Entry<?>, Entry<?>>, Collection<Token>> entry : referenceToTokens.entrySet()) { 172 for (Map.Entry<EntryReference<Entry<?>, Entry<?>>, Collection<Token>> entry : referenceToTokens.entrySet()) {
diff --git a/enigma/src/main/java/cuchaz/enigma/utils/IconLoadingService.java b/enigma/src/main/java/cuchaz/enigma/utils/IconLoadingService.java
new file mode 100644
index 0000000..0e66fba
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/utils/IconLoadingService.java
@@ -0,0 +1,14 @@
1package cuchaz.enigma.utils;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.util.ServiceLoader;
6
7import cuchaz.enigma.api.EnigmaIcon;
8
9public interface IconLoadingService {
10 IconLoadingService INSTANCE = ServiceLoader.load(IconLoadingService.class).findFirst()
11 .orElseThrow(() -> new IllegalStateException("Trying to load icon on headless Enigma"));
12
13 EnigmaIcon loadIcon(InputStream in) throws IOException;
14}