From a9e03fa0e75b5b338021de982acbbb8277e08706 Mon Sep 17 00:00:00 2001 From: Fudge Date: Mon, 2 Dec 2019 15:43:23 +0200 Subject: Allow attaching class, method, field, and parameter javadocs (#185) * bring liach pr to modern enigma * bump version * fuck off vscode * switch to COMMENT and write comments before * it was already after, what do you want * oops * put inner classes at the end * remove indents and use all caps * add refreshmappings command * Update src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java * Delete RefreshEnigmaMappingsCommand.java * Update CommandMain.java * ok --- src/main/java/cuchaz/enigma/gui/Gui.java | 45 +++++++++++ src/main/java/cuchaz/enigma/gui/GuiController.java | 35 ++++++++- .../cuchaz/enigma/gui/dialog/JavadocDialog.java | 88 ++++++++++++++++++++++ .../cuchaz/enigma/gui/elements/PopupMenuBar.java | 9 +++ .../java/cuchaz/enigma/gui/panels/PanelEditor.java | 4 + .../cuchaz/enigma/gui/stats/StatsGenerator.java | 2 +- 6 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java (limited to 'src/main/java/cuchaz/enigma/gui') diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java index 3ab1cee..1ea3e44 100644 --- a/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/src/main/java/cuchaz/enigma/gui/Gui.java @@ -11,6 +11,7 @@ package cuchaz.enigma.gui; +import com.google.common.base.Strings; import com.google.common.collect.Lists; import cuchaz.enigma.Constants; import cuchaz.enigma.EnigmaProfile; @@ -19,6 +20,7 @@ import cuchaz.enigma.analysis.*; import cuchaz.enigma.config.Config; import cuchaz.enigma.config.Themes; import cuchaz.enigma.gui.dialog.CrashDialog; +import cuchaz.enigma.gui.dialog.JavadocDialog; import cuchaz.enigma.gui.elements.MenuBar; import cuchaz.enigma.gui.elements.PopupMenuBar; import cuchaz.enigma.gui.filechooser.FileChooserAny; @@ -82,6 +84,7 @@ public class Gui { private JTabbedPane tabs; public JTextField renameTextField; + public JTextArea javadocTextArea; public void setEditorTheme(Config.LookAndFeel feel) { if (editor != null && (editorFeel == null || editorFeel != feel)) { @@ -559,6 +562,7 @@ public class Gui { } this.popupMenu.renameMenu.setEnabled(isRenamable); + this.popupMenu.editJavadocMenu.setEnabled(isRenamable); this.popupMenu.showInheritanceMenu.setEnabled(isClassEntry || isMethodEntry || isConstructorEntry); this.popupMenu.showImplementationsMenu.setEnabled(isClassEntry || isMethodEntry); this.popupMenu.showCallsMenu.setEnabled(isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry); @@ -575,6 +579,47 @@ public class Gui { } } + public void startDocChange() { + + // init the text box + javadocTextArea = new JTextArea(10, 40); + + EntryReference, Entry> translatedReference = controller.project.getMapper().deobfuscate(cursorReference); + javadocTextArea.setText(Strings.nullToEmpty(translatedReference.entry.getJavadocs())); + + JavadocDialog.init(frame, javadocTextArea, this::finishDocChange); + javadocTextArea.grabFocus(); + + redraw(); + } + + private void finishDocChange(JFrame ui, boolean saveName) { + String newName = javadocTextArea.getText(); + if (saveName) { + try { + this.controller.changeDocs(cursorReference, newName); + } catch (IllegalNameException ex) { + javadocTextArea.setBorder(BorderFactory.createLineBorder(Color.red, 1)); + javadocTextArea.setToolTipText(ex.getReason()); + Utils.showToolTipNow(javadocTextArea); + return; + } + + ui.setVisible(false); + showCursorReference(cursorReference); + return; + } + + // abort the jd change + javadocTextArea = null; + ui.setVisible(false); + showCursorReference(cursorReference); + + this.editor.grabFocus(); + + redraw(); + } + public void startRename() { // init the text box diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index 69f12e2..0b2fe27 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -368,20 +368,29 @@ public class GuiController { } private void refreshCurrentClass(EntryReference, Entry> reference) { + refreshCurrentClass(reference, false); + } + + private void refreshCurrentClass(EntryReference, Entry> reference, boolean forceDecomp) { if (currentSource != null) { loadClass(currentSource.getEntry(), () -> { if (reference != null) { showReference(reference); } - }); + }, forceDecomp); } } private void loadClass(ClassEntry classEntry, Runnable callback) { + loadClass(classEntry, callback, false); + } + + private void loadClass(ClassEntry classEntry, Runnable callback, boolean forceDecomp) { ClassEntry targetClass = classEntry.getOutermostClass(); - boolean requiresDecompile = currentSource == null || !currentSource.getEntry().equals(targetClass); + boolean requiresDecompile = forceDecomp || currentSource == null || !currentSource.getEntry().equals(targetClass); if (requiresDecompile) { + currentSource = null; // Or the GUI may try to find a nonexistent token gui.setEditorText("(decompiling...)"); } @@ -402,7 +411,7 @@ public class GuiController { private DecompiledClassSource decompileSource(ClassEntry targetClass) { try { - CompilationUnit sourceTree = sourceProvider.getSources(targetClass.getFullName()); + CompilationUnit sourceTree = (CompilationUnit) sourceProvider.getSources(targetClass.getFullName()).clone(); if (sourceTree == null) { gui.setEditorText("Unable to find class: " + targetClass); return DecompiledClassSource.text(targetClass, "Unable to find class"); @@ -410,6 +419,7 @@ public class GuiController { DropImportAstTransform.INSTANCE.run(sourceTree); DropVarModifiersAstTransform.INSTANCE.run(sourceTree); + new AddJavadocsAstTransform(project.getMapper()).run(sourceTree); String sourceString = sourceProvider.writeSourceToString(sourceTree); @@ -521,6 +531,25 @@ public class GuiController { refreshCurrentClass(reference); } + public void changeDocs(EntryReference, Entry> reference, String updatedDocs) { + changeDoc(reference.getNameableEntry(), updatedDocs); + + refreshCurrentClass(reference, true); + } + + public void changeDoc(Entry obfEntry, String newDoc) { + EntryRemapper mapper = project.getMapper(); + if (mapper.getDeobfMapping(obfEntry) == null) { + markAsDeobfuscated(obfEntry,false); // NPE + } + mapper.mapFromObf(obfEntry, mapper.getDeobfMapping(obfEntry).withDocs(newDoc), false); + } + + public void markAsDeobfuscated(Entry obfEntry, boolean renaming) { + EntryRemapper mapper = project.getMapper(); + mapper.mapFromObf(obfEntry, new EntryMapping(mapper.deobfuscate(obfEntry).getName()), renaming); + } + public void markAsDeobfuscated(EntryReference, Entry> reference) { EntryRemapper mapper = project.getMapper(); Entry entry = reference.getNameableEntry(); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java new file mode 100644 index 0000000..84e4d8f --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma.gui.dialog; + +import cuchaz.enigma.utils.Utils; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class JavadocDialog { + + private static JavadocDialog instance = null; + + private JFrame frame; + + private JavadocDialog(JFrame parent, JTextArea text, Callback callback) { + // init frame + frame = new JFrame("Edit Javadocs"); + final Container pane = frame.getContentPane(); + pane.setLayout(new BorderLayout()); + + // editor panel + text.setTabSize(2); + pane.add(new JScrollPane(text), BorderLayout.CENTER); + text.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent event) { + switch (event.getKeyCode()) { + case KeyEvent.VK_ENTER: + if (event.isControlDown()) + callback.closeUi(frame, true); + break; + case KeyEvent.VK_ESCAPE: + callback.closeUi(frame, false); + break; + default: + break; + } + } + }); + + // buttons panel + JPanel buttonsPanel = new JPanel(); + FlowLayout buttonsLayout = new FlowLayout(); + buttonsLayout.setAlignment(FlowLayout.RIGHT); + buttonsPanel.setLayout(buttonsLayout); + buttonsPanel.add(Utils.unboldLabel(new JLabel("Edit javadocs here."))); + JButton cancelButton = new JButton("Cancel"); + cancelButton.addActionListener(event -> { + // close (hide) the dialog + callback.closeUi(frame, false); + }); + buttonsPanel.add(cancelButton); + JButton saveButton = new JButton("Save"); + saveButton.addActionListener(event -> { + // exit enigma + callback.closeUi(frame, true); + }); + buttonsPanel.add(saveButton); + pane.add(buttonsPanel, BorderLayout.SOUTH); + + // show the frame + frame.setSize(600, 400); + frame.setLocationRelativeTo(parent); + frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + } + + public static void init(JFrame parent, JTextArea area, Callback callback) { + instance = new JavadocDialog(parent, area, callback); + instance.frame.doLayout(); + instance.frame.setVisible(true); + } + + public interface Callback { + void closeUi(JFrame frame, boolean save); + } +} diff --git a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java index fbf39ac..b9d459f 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java @@ -9,6 +9,7 @@ import java.awt.event.KeyEvent; public class PopupMenuBar extends JPopupMenu { public final JMenuItem renameMenu; + public final JMenuItem editJavadocMenu; public final JMenuItem showInheritanceMenu; public final JMenuItem showImplementationsMenu; public final JMenuItem showCallsMenu; @@ -27,6 +28,14 @@ public class PopupMenuBar extends JPopupMenu { this.add(menu); this.renameMenu = menu; } + { + JMenuItem menu = new JMenuItem("Edit Javadoc"); + menu.addActionListener(event -> gui.startDocChange()); + menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0)); + menu.setEnabled(false); + this.add(menu); + this.editJavadocMenu = menu; + } { JMenuItem menu = new JMenuItem("Show Inheritance"); menu.addActionListener(event -> gui.showInheritance()); diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java index 9e29699..71ee34c 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java @@ -87,6 +87,10 @@ public class PanelEditor extends JEditorPane { gui.popupMenu.renameMenu.doClick(); break; + case KeyEvent.VK_D: + gui.popupMenu.editJavadocMenu.doClick(); + break; + case KeyEvent.VK_F5: gui.getController().refreshCurrentClass(); break; diff --git a/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java b/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java index 88ed96f..a6e465d 100644 --- a/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java +++ b/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java @@ -67,7 +67,7 @@ public class StatsGenerator { if (includedMembers.contains(StatsMember.PARAMETERS)) { int index = ((MethodDefEntry) method).getAccess().isStatic() ? 0 : 1; for (TypeDescriptor argument : method.getDesc().getArgumentDescs()) { - update(counts, new LocalVariableEntry(method, index, "", true)); + update(counts, new LocalVariableEntry(method, index, "", true,null)); index += argument.getSize(); } } -- cgit v1.2.3