diff options
| author | 2025-10-18 16:38:40 +0100 | |
|---|---|---|
| committer | 2025-10-18 16:38:40 +0100 | |
| commit | 87581ffe8d23aaf8ad677ffbb9de1ecfec3cfe80 (patch) | |
| tree | f3191c08ee6be85c11d8f109e6923c320e74368e /enigma | |
| parent | Fix class version check in AddFramesIfNecessaryClassProvider (#575) (diff) | |
| download | enigma-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')
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 | ||
| 11 | import org.jetbrains.annotations.Nullable; | 11 | import org.jetbrains.annotations.Nullable; |
| 12 | 12 | ||
| 13 | import cuchaz.enigma.api.view.entry.MethodEntryView; | ||
| 14 | import cuchaz.enigma.api.view.index.BridgeMethodIndexView; | ||
| 13 | import cuchaz.enigma.translation.representation.AccessFlags; | 15 | import cuchaz.enigma.translation.representation.AccessFlags; |
| 14 | import cuchaz.enigma.translation.representation.MethodDescriptor; | 16 | import cuchaz.enigma.translation.representation.MethodDescriptor; |
| 15 | import cuchaz.enigma.translation.representation.TypeDescriptor; | 17 | import cuchaz.enigma.translation.representation.TypeDescriptor; |
| @@ -17,7 +19,7 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry; | |||
| 17 | import cuchaz.enigma.translation.representation.entry.MethodDefEntry; | 19 | import cuchaz.enigma.translation.representation.entry.MethodDefEntry; |
| 18 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | 20 | import cuchaz.enigma.translation.representation.entry.MethodEntry; |
| 19 | 21 | ||
| 20 | public class BridgeMethodIndex implements JarIndexer { | 22 | public 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 | ||
| 3 | import java.util.Collection; | 3 | import java.util.Collection; |
| 4 | 4 | ||
| 5 | import org.jetbrains.annotations.ApiStatus; | ||
| 5 | import org.jetbrains.annotations.Nullable; | 6 | import org.jetbrains.annotations.Nullable; |
| 6 | 7 | ||
| 8 | @ApiStatus.NonExtendable | ||
| 7 | public interface DataInvalidationEvent { | 9 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api; | ||
| 2 | |||
| 3 | import java.io.IOException; | ||
| 4 | import java.io.InputStream; | ||
| 5 | |||
| 6 | import org.jetbrains.annotations.ApiStatus; | ||
| 7 | |||
| 8 | import cuchaz.enigma.utils.IconLoadingService; | ||
| 9 | |||
| 10 | @ApiStatus.NonExtendable | ||
| 11 | public 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 | ||
| 6 | import javax.swing.KeyStroke; | 6 | import javax.swing.KeyStroke; |
| 7 | 7 | ||
| 8 | import cuchaz.enigma.api.EnigmaIcon; | ||
| 8 | import cuchaz.enigma.api.view.GuiView; | 9 | import cuchaz.enigma.api.view.GuiView; |
| 10 | import cuchaz.enigma.api.view.entry.EntryView; | ||
| 9 | 11 | ||
| 10 | public interface GuiService extends EnigmaService { | 12 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view; | 1 | package cuchaz.enigma.api.view; |
| 2 | 2 | ||
| 3 | import javax.swing.JEditorPane; | ||
| 3 | import javax.swing.JFrame; | 4 | import javax.swing.JFrame; |
| 4 | 5 | ||
| 6 | import org.jetbrains.annotations.ApiStatus; | ||
| 5 | import org.jetbrains.annotations.Nullable; | 7 | import org.jetbrains.annotations.Nullable; |
| 6 | 8 | ||
| 7 | import cuchaz.enigma.api.view.entry.EntryReferenceView; | 9 | import cuchaz.enigma.api.view.entry.EntryReferenceView; |
| 10 | import cuchaz.enigma.api.view.entry.EntryView; | ||
| 8 | 11 | ||
| 12 | @ApiStatus.NonExtendable | ||
| 9 | public interface GuiView { | 13 | public 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; | |||
| 3 | import java.util.Collection; | 3 | import java.util.Collection; |
| 4 | import java.util.List; | 4 | import java.util.List; |
| 5 | 5 | ||
| 6 | import org.jetbrains.annotations.ApiStatus; | ||
| 6 | import org.jetbrains.annotations.Nullable; | 7 | import org.jetbrains.annotations.Nullable; |
| 7 | import org.objectweb.asm.tree.ClassNode; | 8 | import org.objectweb.asm.tree.ClassNode; |
| 8 | 9 | ||
| @@ -11,6 +12,7 @@ import cuchaz.enigma.api.DataInvalidationListener; | |||
| 11 | import cuchaz.enigma.api.view.entry.EntryView; | 12 | import cuchaz.enigma.api.view.entry.EntryView; |
| 12 | import cuchaz.enigma.api.view.index.JarIndexView; | 13 | import cuchaz.enigma.api.view.index.JarIndexView; |
| 13 | 14 | ||
| 15 | @ApiStatus.NonExtendable | ||
| 14 | public interface ProjectView { | 16 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 3 | import org.jetbrains.annotations.Nullable; | 4 | import org.jetbrains.annotations.Nullable; |
| 4 | 5 | ||
| 6 | @ApiStatus.NonExtendable | ||
| 5 | public interface ClassDefEntryView extends ClassEntryView, DefEntryView { | 7 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 3 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 5 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 4 | 6 | ||
| 7 | @ApiStatus.NonExtendable | ||
| 5 | public interface ClassEntryView extends EntryView { | 8 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 5 | @ApiStatus.NonExtendable | ||
| 3 | public interface DefEntryView { | 6 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 5 | @ApiStatus.NonExtendable | ||
| 3 | public interface EntryReferenceView { | 6 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 3 | import org.jetbrains.annotations.Nullable; | 4 | import org.jetbrains.annotations.Nullable; |
| 4 | 5 | ||
| 6 | @ApiStatus.NonExtendable | ||
| 5 | public interface EntryView { | 7 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 3 | import cuchaz.enigma.translation.representation.TypeDescriptor; | 5 | import cuchaz.enigma.translation.representation.TypeDescriptor; |
| 4 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 6 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 5 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | 7 | import cuchaz.enigma.translation.representation.entry.FieldEntry; |
| 6 | 8 | ||
| 9 | @ApiStatus.NonExtendable | ||
| 7 | public interface FieldEntryView extends EntryView { | 10 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 5 | @ApiStatus.NonExtendable | ||
| 3 | public interface LocalVariableDefEntryView extends LocalVariableEntryView { | 6 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 5 | import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; | ||
| 6 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 7 | |||
| 8 | @ApiStatus.NonExtendable | ||
| 3 | public interface LocalVariableEntryView extends EntryView { | 9 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.entry; | 1 | package cuchaz.enigma.api.view.entry; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 3 | import cuchaz.enigma.translation.representation.MethodDescriptor; | 5 | import cuchaz.enigma.translation.representation.MethodDescriptor; |
| 4 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 6 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 5 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | 7 | import cuchaz.enigma.translation.representation.entry.MethodEntry; |
| 6 | 8 | ||
| 9 | @ApiStatus.NonExtendable | ||
| 7 | public interface MethodEntryView extends EntryView { | 10 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.index; | ||
| 2 | |||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | import org.jetbrains.annotations.Nullable; | ||
| 5 | |||
| 6 | import cuchaz.enigma.api.view.entry.MethodEntryView; | ||
| 7 | |||
| 8 | @ApiStatus.NonExtendable | ||
| 9 | public 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 | ||
| 3 | import java.util.Collection; | 3 | import java.util.Collection; |
| 4 | 4 | ||
| 5 | import org.jetbrains.annotations.ApiStatus; | ||
| 6 | |||
| 5 | import cuchaz.enigma.api.view.entry.ClassDefEntryView; | 7 | import cuchaz.enigma.api.view.entry.ClassDefEntryView; |
| 6 | import cuchaz.enigma.api.view.entry.ClassEntryView; | 8 | import cuchaz.enigma.api.view.entry.ClassEntryView; |
| 7 | import cuchaz.enigma.api.view.entry.EntryView; | 9 | import cuchaz.enigma.api.view.entry.EntryView; |
| 8 | 10 | ||
| 11 | @ApiStatus.NonExtendable | ||
| 9 | public interface EntryIndexView { | 12 | public 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 | ||
| 3 | import java.util.Collection; | 3 | import java.util.Collection; |
| 4 | 4 | ||
| 5 | import org.jetbrains.annotations.ApiStatus; | ||
| 6 | |||
| 5 | import cuchaz.enigma.api.view.entry.ClassEntryView; | 7 | import cuchaz.enigma.api.view.entry.ClassEntryView; |
| 6 | 8 | ||
| 9 | @ApiStatus.NonExtendable | ||
| 7 | public interface InheritanceIndexView { | 10 | public 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 @@ | |||
| 1 | package cuchaz.enigma.api.view.index; | 1 | package cuchaz.enigma.api.view.index; |
| 2 | 2 | ||
| 3 | import org.jetbrains.annotations.ApiStatus; | ||
| 4 | |||
| 5 | @ApiStatus.NonExtendable | ||
| 3 | public interface JarIndexView { | 6 | public 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 | ||
| 3 | import java.util.Collection; | 3 | import java.util.Collection; |
| 4 | 4 | ||
| 5 | import org.jetbrains.annotations.ApiStatus; | ||
| 6 | |||
| 5 | import cuchaz.enigma.api.view.entry.ClassEntryView; | 7 | import cuchaz.enigma.api.view.entry.ClassEntryView; |
| 6 | import cuchaz.enigma.api.view.entry.EntryReferenceView; | 8 | import cuchaz.enigma.api.view.entry.EntryReferenceView; |
| 7 | import cuchaz.enigma.api.view.entry.FieldEntryView; | 9 | import cuchaz.enigma.api.view.entry.FieldEntryView; |
| 8 | import cuchaz.enigma.api.view.entry.MethodEntryView; | 10 | import cuchaz.enigma.api.view.entry.MethodEntryView; |
| 9 | 11 | ||
| 12 | @ApiStatus.NonExtendable | ||
| 10 | public interface ReferenceIndexView { | 13 | public 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; | |||
| 7 | import java.util.Map; | 7 | import java.util.Map; |
| 8 | import java.util.TreeMap; | 8 | import java.util.TreeMap; |
| 9 | 9 | ||
| 10 | import org.jetbrains.annotations.Nullable; | ||
| 11 | |||
| 10 | import cuchaz.enigma.analysis.EntryReference; | 12 | import cuchaz.enigma.analysis.EntryReference; |
| 11 | import cuchaz.enigma.translation.mapping.EntryResolver; | 13 | import cuchaz.enigma.translation.mapping.EntryResolver; |
| 12 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; | 14 | import 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 @@ | |||
| 1 | package cuchaz.enigma.utils; | ||
| 2 | |||
| 3 | import java.io.IOException; | ||
| 4 | import java.io.InputStream; | ||
| 5 | import java.util.ServiceLoader; | ||
| 6 | |||
| 7 | import cuchaz.enigma.api.EnigmaIcon; | ||
| 8 | |||
| 9 | public 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 | } | ||