Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions enigma-swing/src/main/java/org/quiltmc/enigma/gui/Gui.java
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,8 @@ public void showTokens(BaseEditorPanel editor, List<Token> tokens) {
editor.navigateToToken(tokens.get(0));
}

public void showCursorReference(EntryReference<Entry<?>, Entry<?>> reference) {
this.infoPanel.setReference(reference == null ? null : reference.entry);
public void showCursorReference(@Nullable EntryReference<Entry<?>, Entry<?>> reference) {
this.infoPanel.setReference(reference);
}

public void startDocChange(EditorPanel editor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,15 @@ public EditorPopupMenu(EditorPanel editor, Gui gui) {
}

public void updateUiState() {
EntryReference<Entry<?>, Entry<?>> ref = this.editor.getCursorReference();
Entry<?> referenceEntry = ref == null ? null : ref.entry;
EntryReference<Entry<?>, Entry<?>> reference = this.editor.getCursorReference();
Entry<?> referenceEntry = reference == null ? null : reference.entry;
GuiController controller = this.gui.getController();

boolean isClassEntry = referenceEntry instanceof ClassEntry;
boolean isFieldEntry = referenceEntry instanceof FieldEntry;
boolean isMethodEntry = referenceEntry instanceof MethodEntry me && !me.isConstructor();
boolean isConstructorEntry = referenceEntry instanceof MethodEntry me && me.isConstructor();
boolean isRenamable = ref != null && controller.getProject().isRenamable(ref);
boolean isRenamable = reference != null && controller.getProject().isRenamable(reference);

EditableType type = EditableType.fromEntry(referenceEntry);

Expand All @@ -150,11 +150,7 @@ public void updateUiState() {
this.openNextItem.setEnabled(controller.hasNextReference());
this.toggleMappingItem.setEnabled(isRenamable && (type != null && this.gui.isEditable(type)));

if (referenceEntry != null && this.gui.getController().getProject().getRemapper().extendedDeobfuscate(referenceEntry).getType() == TokenType.DEOBFUSCATED) {
this.toggleMappingItem.setText(I18n.translate("popup_menu.reset_obfuscated"));
} else {
this.toggleMappingItem.setText(I18n.translate("popup_menu.mark_deobfuscated"));
}
this.translateToggleMappingItem(reference);
}

public void retranslateUi() {
Expand All @@ -170,10 +166,24 @@ public void retranslateUi() {
this.openEntryItem.setText(I18n.translate("popup_menu.declaration"));
this.openPreviousItem.setText(I18n.translate("popup_menu.back"));
this.openNextItem.setText(I18n.translate("popup_menu.forward"));
this.toggleMappingItem.setText(I18n.translate("popup_menu.mark_deobfuscated"));
this.zoomInItem.setText(I18n.translate("popup_menu.zoom.in"));
this.zoomOutMenu.setText(I18n.translate("popup_menu.zoom.out"));
this.resetZoomItem.setText(I18n.translate("popup_menu.zoom.reset"));

this.translateToggleMappingItem(this.editor.getCursorReference());
}

private void translateToggleMappingItem(EntryReference<Entry<?>, Entry<?>> reference) {
if (
reference != null && this.gui
.getController().getProject().getRemapper()
.extendedDeobfuscate(reference.getNameableEntry())
.getType() == TokenType.DEOBFUSCATED
) {
this.toggleMappingItem.setText(I18n.translate("popup_menu.reset_obfuscated"));
} else {
this.toggleMappingItem.setText(I18n.translate("popup_menu.mark_deobfuscated"));
}
}

public JPopupMenu getUi() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.jspecify.annotations.Nullable;
import org.quiltmc.enigma.api.EnigmaProject;
import org.quiltmc.enigma.api.analysis.EntryReference;
import org.quiltmc.enigma.api.analysis.index.jar.EntryIndex;
import org.quiltmc.enigma.api.translation.mapping.EntryChange;
import org.quiltmc.enigma.api.translation.mapping.EntryMapping;
import org.quiltmc.enigma.api.translation.representation.TypeDescriptor;
import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry;
import org.quiltmc.enigma.api.translation.representation.entry.Entry;
Expand Down Expand Up @@ -36,9 +38,10 @@ public class IdentifierPanel {

private final JPanel ui = new JPanel();

private Entry<?> lastEntry;
private Entry<?> entry;
private Entry<?> deobfEntry;
@Nullable
private EntryReference<Entry<?>, Entry<?>> lastReference;
@Nullable
private EntryReference<Entry<?>, Entry<?>> reference;

private ConvertingTextField nameField;

Expand All @@ -54,8 +57,8 @@ public IdentifierPanel(Gui gui) {
this.ui.setEnabled(false);
}

public void setReference(Entry<?> entry) {
this.entry = entry;
public void setReference(@Nullable EntryReference<Entry<?>, Entry<?>> reference) {
this.reference = reference;
this.refreshReference();
}

Expand All @@ -76,29 +79,32 @@ public boolean startRenaming(String text) {
return true;
}

public void refreshReference() {
private void refreshReference() {
final EnigmaProject project = this.gui.getController().getProject();
this.deobfEntry = this.entry == null ? null : project.getRemapper().deobfuscate(this.entry);
final Entry<?> obfEntry = this.reference == null ? null : this.reference.entry;
final Entry<?> deobfEntry = obfEntry == null ? null : project.getRemapper().deobfuscate(obfEntry);

// Prevent IdentifierPanel from being rebuilt if you didn't click off.
if (this.lastEntry == this.entry && this.nameField != null) {
if (this.lastReference == this.reference && this.nameField != null) {
if (!this.nameField.hasChanges()) {
// nameField != null => lastReference != null => reference != null => obfEntry != null =>
assert deobfEntry != null;

final String name;

// Find what to set the name to.
if (this.deobfEntry instanceof MethodEntry methodEntry && methodEntry.isConstructor()) {
if (deobfEntry instanceof MethodEntry methodEntry && methodEntry.isConstructor()) {
// Get the parent of the method if it is a constructor.
final ClassEntry parent = methodEntry.getParent();

if (parent == null) {
throw new IllegalStateException("constructor method entry to render has no parent!");
}

name = parent.isInnerClass() ? parent.getName() : parent.getFullName();
} else if (this.deobfEntry instanceof ClassEntry classEntry && !classEntry.isInnerClass()) {
name = classEntry.getFullName();
// inner classes return their simple name, outer classes return their full name
name = parent.getName();
} else {
name = this.deobfEntry.getName();
name = deobfEntry.getName();
}

this.nameField.setReferenceText(name);
Expand All @@ -107,45 +113,45 @@ public void refreshReference() {
return;
}

this.lastEntry = this.entry;
this.lastReference = this.reference;

this.nameField = null;

TableHelper th = new TableHelper(this.ui, this.entry, this.gui);
TableHelper th = new TableHelper(this.ui, this.reference, this.gui);
th.begin();
if (this.entry == null) {
if (obfEntry == null) {
this.ui.setEnabled(false);
} else {
this.ui.setEnabled(true);

if (this.deobfEntry instanceof ClassEntry ce) {
String name = ce.isInnerClass() ? ce.getName() : ce.getFullName();
this.nameField = th.addRenameTextField(EditableType.CLASS, name);
th.addCopiableStringRow(I18n.translate("info_panel.identifier.obfuscated"), this.entry.getName());
if (deobfEntry instanceof ClassEntry clazz) {
// inner classes return their simple name, outer classes return their full name
this.nameField = th.addRenameTextField(EditableType.CLASS, clazz.getName());
th.addCopiableStringRow(I18n.translate("info_panel.identifier.obfuscated"), obfEntry.getName());

if (ce.getParent() != null) {
th.addCopiableStringRow(I18n.translate("info_panel.identifier.outer_class"), ce.getParent().getFullName());
if (clazz.getParent() != null) {
th.addCopiableStringRow(I18n.translate("info_panel.identifier.outer_class"), clazz.getParent().getFullName());
}
} else if (this.deobfEntry instanceof FieldEntry fe) {
this.nameField = th.addRenameTextField(EditableType.FIELD, fe.getName());
th.addStringRow(I18n.translate("info_panel.identifier.class"), fe.getParent().getFullName());
th.addCopiableStringRow(I18n.translate("info_panel.identifier.obfuscated"), this.entry.getName());
th.addCopiableStringRow(I18n.translate("info_panel.identifier.type"), toReadableType(fe.getDesc()));
} else if (this.deobfEntry instanceof MethodEntry me) {
if (me.isConstructor()) {
ClassEntry ce = me.getParent();
if (ce != null) {
String name = ce.isInnerClass() ? ce.getName() : ce.getFullName();
this.nameField = th.addRenameTextField(EditableType.CLASS, name);
} else if (deobfEntry instanceof FieldEntry field) {
this.nameField = th.addRenameTextField(EditableType.FIELD, field.getName());
th.addStringRow(I18n.translate("info_panel.identifier.class"), field.getParent().getFullName());
th.addCopiableStringRow(I18n.translate("info_panel.identifier.obfuscated"), obfEntry.getName());
th.addCopiableStringRow(I18n.translate("info_panel.identifier.type"), toReadableType(field.getDesc()));
} else if (deobfEntry instanceof MethodEntry method) {
if (method.isConstructor()) {
final ClassEntry parent = method.getParent();
if (parent != null) {
// inner classes return their simple name, outer classes return their full name
this.nameField = th.addRenameTextField(EditableType.CLASS, parent.getName());
}
} else {
this.nameField = th.addRenameTextField(EditableType.METHOD, me.getName());
th.addStringRow(I18n.translate("info_panel.identifier.class"), me.getParent().getFullName());
this.nameField = th.addRenameTextField(EditableType.METHOD, method.getName());
th.addStringRow(I18n.translate("info_panel.identifier.class"), method.getParent().getFullName());
}

th.addCopiableStringRow(I18n.translate("info_panel.identifier.obfuscated"), this.entry.getName());
th.addCopiableStringRow(I18n.translate("info_panel.identifier.method_descriptor"), me.getDesc().toString());
} else if (this.deobfEntry instanceof LocalVariableEntry local) {
th.addCopiableStringRow(I18n.translate("info_panel.identifier.obfuscated"), obfEntry.getName());
th.addCopiableStringRow(I18n.translate("info_panel.identifier.method_descriptor"), method.getDesc().toString());
} else if (deobfEntry instanceof LocalVariableEntry local) {
EditableType type;

if (local.isArgument()) {
Expand All @@ -160,10 +166,9 @@ public void refreshReference() {
th.addStringRow(I18n.translate("info_panel.identifier.index"), Integer.toString(local.getIndex()));

// type
EntryIndex index = project.getJarIndex().getIndex(EntryIndex.class);
final EntryIndex index = project.getJarIndex().getIndex(EntryIndex.class);
// EntryIndex only contains obf entries, so use the obf entry to look up the local's descriptor
@Nullable
final LocalVariableDefEntry obfLocal = index.getDefinition((LocalVariableEntry) this.entry);
final LocalVariableDefEntry obfLocal = index.getDefinition((LocalVariableEntry) obfEntry);
final String localDesc = obfLocal == null
? I18n.translate("info_panel.identifier.type.unknown")
: toReadableType(project.getRemapper().deobfuscate(obfLocal.getDesc()));
Expand All @@ -173,7 +178,7 @@ public void refreshReference() {
throw new IllegalStateException("unreachable");
}

var mapping = project.getRemapper().getMapping(this.entry);
final EntryMapping mapping = project.getRemapper().getMapping(obfEntry);
if (Config.main().development.showMappingSourcePlugin.value() && mapping.tokenType().isProposed()) {
th.addStringRow(I18n.translate("dev.source_plugin"), mapping.sourcePluginId());
}
Expand Down Expand Up @@ -245,10 +250,7 @@ private void doRename(String newName) {
}

private EntryChange<? extends Entry<?>> getRename(String newName) {
Entry<?> entry = this.entry;
if (entry instanceof MethodEntry method && method.isConstructor()) {
entry = method.getContainingClass();
}
final Entry<?> entry = this.reference == null ? null : this.reference.getNameableEntry();

return EntryChange.modify(entry).withDeobfName(newName);
}
Expand All @@ -263,28 +265,28 @@ public JPanel getUi() {
}

private static final class TableHelper {
private final Container c;
private final Entry<?> e;
private final Container container;
private final EntryReference<Entry<?>, Entry<?>> reference;
private final Gui gui;
private int row;

TableHelper(Container c, Entry<?> e, Gui gui) {
this.c = c;
this.e = e;
TableHelper(Container container, EntryReference<Entry<?>, Entry<?>> reference, Gui gui) {
this.container = container;
this.reference = reference;
this.gui = gui;
}

public void begin() {
this.c.removeAll();
this.c.setLayout(new GridBagLayout());
this.container.removeAll();
this.container.setLayout(new GridBagLayout());
}

public void addRow(Component c1, Component c2) {
GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create()
.insets(2)
.anchor(GridBagConstraints.WEST);
this.c.add(c1, cb.pos(0, this.row).build());
this.c.add(c2, cb.pos(1, this.row).weightX(1.0).fill(GridBagConstraints.HORIZONTAL).build());
this.container.add(c1, cb.pos(0, this.row).build());
this.container.add(c2, cb.pos(1, this.row).weightX(1.0).fill(GridBagConstraints.HORIZONTAL).build());

this.row += 1;
}
Expand Down Expand Up @@ -314,7 +316,7 @@ public ConvertingTextField addRenameTextField(EditableType type, String c2) {
default -> throw new IllegalStateException("Unexpected value: " + type);
};

if (this.gui.getController().getProject().isRenamable(this.e)) {
if (this.reference != null && this.gui.getController().getProject().isRenamable(this.reference)) {
ConvertingTextField field = this.addConvertingTextField(description, c2);
field.setEditable(this.gui.isEditable(type));
return field;
Expand All @@ -334,7 +336,7 @@ public void addCopiableStringRow(String c1, String c2) {

public void end() {
// Add an empty panel with y-weight=1 so that all the other elements get placed at the top edge
this.c.add(new JPanel(), GridBagConstraintsBuilder.create().pos(0, this.row).weight(0.0, 1.0).build());
this.container.add(new JPanel(), GridBagConstraintsBuilder.create().pos(0, this.row).weight(0.0, 1.0).build());
}
}
}