From bc0ec7307120412ce69bb1bbc427b1cfdb8bad9c Mon Sep 17 00:00:00 2001 From: SuspiciousActivity <38253929+SuspiciousActivity@users.noreply.github.com> Date: Tue, 9 Mar 2021 18:24:07 +0100 Subject: [PATCH] Cleanup --- src/me/ByteEdit/boxes/CompilationBox.java | 17 +- .../ByteEdit/boxes/GlobalSearchOpenBox.java | 18 +- src/me/ByteEdit/boxes/RenameBox.java | 27 +- src/me/ByteEdit/boxes/TypeOpenBox.java | 3 +- src/me/ByteEdit/decompiler/CFRDecompiler.java | 28 +- .../ByteEdit/decompiler/EnumDecompiler.java | 48 ++- .../decompiler/FernflowerDecompiler.java | 14 +- src/me/ByteEdit/decompiler/IDecompiler.java | 16 + src/me/ByteEdit/decompiler/JDDecompiler.java | 20 +- .../decompiler/ProcyonDecompiler.java | 9 +- .../decompiler/SingleThreadedExecutor.java | 33 +- src/me/ByteEdit/edit/Disassembler.java | 96 ++---- src/me/ByteEdit/edit/OptionBox.java | 8 +- src/me/ByteEdit/edit/SearchBox.java | 28 +- src/me/ByteEdit/edit/TypeOpenBox.java | 29 +- src/me/ByteEdit/main/Main.java | 309 ++++++------------ src/org/fife/eclipse_dark.xml | 2 +- .../rsyntaxtextarea/DefaultTokenFactory.java | 3 +- .../ui/rsyntaxtextarea/TokenMakerBase.java | 3 +- .../rsyntaxtextarea/modes/JavaTokenMaker.java | 3 +- 20 files changed, 277 insertions(+), 437 deletions(-) create mode 100644 src/me/ByteEdit/decompiler/IDecompiler.java diff --git a/src/me/ByteEdit/boxes/CompilationBox.java b/src/me/ByteEdit/boxes/CompilationBox.java index c943f57..1359890 100644 --- a/src/me/ByteEdit/boxes/CompilationBox.java +++ b/src/me/ByteEdit/boxes/CompilationBox.java @@ -15,7 +15,6 @@ import java.io.StringWriter; import java.net.URI; import java.nio.file.Files; import java.util.Arrays; -import java.util.concurrent.TimeUnit; import javax.swing.JComponent; import javax.swing.JFrame; @@ -27,14 +26,14 @@ import javax.tools.JavaCompiler; import javax.tools.SimpleJavaFileObject; import javax.tools.ToolProvider; -import me.ByteEdit.decompiler.SingleThreadedExecutor; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rtextarea.RTextScrollPane; import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.ClassNode; -import me.ByteEdit.edit.Disassembler; +import me.ByteEdit.decompiler.EnumDecompiler; +import me.ByteEdit.decompiler.SingleThreadedExecutor; import me.ByteEdit.main.Main; import me.ByteEdit.main.ThemeManager; @@ -107,9 +106,7 @@ public class CompilationBox extends JFrame { null, Arrays.asList(new JavaSourceFromString("Compiled", source))).call(); String res = out.toString(); if (res.isEmpty()) { - - - SingleThreadedExecutor.execute( () -> { + SingleThreadedExecutor.execute(() -> { try { File clazz = new File(tmpFolder, "Compiled.class"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -121,11 +118,11 @@ public class CompilationBox extends JFrame { } is.close(); - ClassReader read = new ClassReader(baos.toByteArray()); ClassNode node = new ClassNode(); read.accept(node, 0); - String dis = Disassembler.disassemble(node); + EnumDecompiler decompiler = EnumDecompiler.BYTEEDIT; + String dis = decompiler.getDecompiler().decompile(node); File[] files = tmpFolder.listFiles(); if (files != null) for (File f : files) { @@ -140,11 +137,11 @@ public class CompilationBox extends JFrame { read = new ClassReader(baos.toByteArray()); node = new ClassNode(); read.accept(node, 0); - dis += "\n" + Disassembler.disassemble(node); + dis += "\n" + decompiler.getDecompiler().decompile(node); } compSuccess.textArea.setText(dis); compSuccess.setVisible(true); - }catch (IOException e2){ + } catch (IOException e2) { e2.printStackTrace(); } }); diff --git a/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java b/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java index e7dc129..5616412 100644 --- a/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java +++ b/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java @@ -1,7 +1,6 @@ package me.ByteEdit.boxes; import java.awt.Toolkit; -import java.util.concurrent.TimeUnit; import javax.swing.DefaultListModel; import javax.swing.JFrame; @@ -12,11 +11,10 @@ import javax.swing.ListSelectionModel; import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import javax.swing.text.BadLocationException; -import me.ByteEdit.decompiler.SingleThreadedExecutor; import org.objectweb.asm.tree.MethodNode; +import me.ByteEdit.decompiler.SingleThreadedExecutor; import me.ByteEdit.main.Main; public class GlobalSearchOpenBox extends JFrame { @@ -38,23 +36,13 @@ public class GlobalSearchOpenBox extends JFrame { model = new DefaultListModel<>(); JList list = new JList(model); list.addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - - SingleThreadedExecutor.execute( () -> { + SingleThreadedExecutor.execute(() -> { Info val = list.getSelectedValue(); if (val != null && !val.owner.equals(Main.currentNodeName)) { - int lineFound = Main.selectFileWithSearch(val.nodePath, val.mn); - if (lineFound != -1) { - try { - Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound)); - } catch (BadLocationException e1) { - //e1.printStackTrace(); - } - } + Main.selectFile(val.nodePath); } }); - } }); diff --git a/src/me/ByteEdit/boxes/RenameBox.java b/src/me/ByteEdit/boxes/RenameBox.java index b8e4e18..cae21d6 100644 --- a/src/me/ByteEdit/boxes/RenameBox.java +++ b/src/me/ByteEdit/boxes/RenameBox.java @@ -4,7 +4,6 @@ import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.LinkedList; -import java.util.concurrent.TimeUnit; import javax.swing.JButton; import javax.swing.JFrame; @@ -14,7 +13,6 @@ import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; -import me.ByteEdit.decompiler.SingleThreadedExecutor; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldInsnNode; @@ -22,7 +20,7 @@ import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; -import me.ByteEdit.edit.Disassembler; +import me.ByteEdit.decompiler.SingleThreadedExecutor; import me.ByteEdit.main.Main; import me.ByteEdit.utils.ClassUtil; import me.ByteEdit.utils.UnicodeUtils; @@ -213,30 +211,13 @@ public class RenameBox extends JFrame { } } - SingleThreadedExecutor.execute( () -> { - try { // refresh - ClassNode classNode = Main.classNodes.get(Main.currentNodeName); - int prev = Main.txtByteEditView.getCaretPosition(); - String dis = Disassembler.disassemble(classNode); - String substr = Main.currentNodeName.substring(0, Main.currentNodeName.length() - 6); - for (String key : Main.classNodes.keySet()) { - if (key.contains("$")) { - String[] split = key.split("\\$"); - if (split[0].equals(substr)) { - dis += "\n" + Disassembler.disassemble(Main.classNodes.get(key)); - } - } - } - Main.txtByteEditView.setText(dis); - Main.txtByteEditView.setCaretPosition(prev); - } catch (Exception e2) { - e2.printStackTrace(); - } + SingleThreadedExecutor.execute(() -> { + // refresh + Main.decompileCurrentNode(); name = newName; desc = newDesc; RenameBox.this.setVisible(false); }); - } }); btnRename.setBounds(345, 237, 89, 23); diff --git a/src/me/ByteEdit/boxes/TypeOpenBox.java b/src/me/ByteEdit/boxes/TypeOpenBox.java index 2506786..26e9b73 100644 --- a/src/me/ByteEdit/boxes/TypeOpenBox.java +++ b/src/me/ByteEdit/boxes/TypeOpenBox.java @@ -3,7 +3,6 @@ package me.ByteEdit.boxes; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.concurrent.TimeUnit; import javax.swing.DefaultListModel; import javax.swing.JFrame; @@ -46,7 +45,7 @@ public class TypeOpenBox extends JFrame { String val = list.getSelectedValue(); if (val != null && !val.equals(Main.currentNodeName)) { - SingleThreadedExecutor.execute( () -> Main.selectFile(val)); + SingleThreadedExecutor.execute(() -> Main.selectFile(val)); } } }); diff --git a/src/me/ByteEdit/decompiler/CFRDecompiler.java b/src/me/ByteEdit/decompiler/CFRDecompiler.java index f8e54bb..e6e0280 100644 --- a/src/me/ByteEdit/decompiler/CFRDecompiler.java +++ b/src/me/ByteEdit/decompiler/CFRDecompiler.java @@ -1,8 +1,6 @@ package me.ByteEdit.decompiler; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Field; @@ -24,8 +22,7 @@ import org.benf.cfr.reader.util.output.ToStringDumper; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; -@SuppressWarnings("deprecation") -public class CFRDecompiler { +public class CFRDecompiler implements IDecompiler { public static final HashMap options = new HashMap<>(); @@ -84,7 +81,12 @@ public class CFRDecompiler { options.put("usenametable", "true"); } - public static String decompile(ClassNode cn, byte[] b, MethodNode mn) { + @Override + public String decompile(ClassNode cn) { + return doDecompilation(cn, getBytes(cn), null); + } + + private static String doDecompilation(ClassNode cn, byte[] b, MethodNode mn) { try { HashMap ops = options; ClassFileSource cfs = new ClassFileSource() { @@ -131,7 +133,7 @@ public class CFRDecompiler { } String decompilation = runner.getDecompilationFor(cn.name); System.gc(); // cfr has a performance bug - return decompilation.substring(37); // small hack to remove watermark + return decompilation; } catch (Exception e) { e.printStackTrace(); StringWriter sw = new StringWriter(); @@ -148,18 +150,4 @@ public class CFRDecompiler { DCCommonState dcCommonState = new DCCommonState(options, classFileSource); return dcCommonState; } - - protected Pair getSystemClass(String name, String path) throws IOException { - InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(path); - if (is != null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[4096]; - int n; - while ((n = is.read(buffer)) > 0) { - baos.write(buffer, 0, n); - } - return Pair.make(baos.toByteArray(), name); - } - return null; - } } diff --git a/src/me/ByteEdit/decompiler/EnumDecompiler.java b/src/me/ByteEdit/decompiler/EnumDecompiler.java index 359d9c9..1419be9 100644 --- a/src/me/ByteEdit/decompiler/EnumDecompiler.java +++ b/src/me/ByteEdit/decompiler/EnumDecompiler.java @@ -1,15 +1,45 @@ package me.ByteEdit.decompiler; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; + +import me.ByteEdit.edit.Disassembler; + public enum EnumDecompiler { - BYTEEDIT("ByteEdit"), PROCYON("Procyon"), FERNFLOWER("FernFlower"), JD_GUI("JD-GUI"), CFR("CFR"); + BYTEEDIT("ByteEdit", new Disassembler(), false), PROCYON("Procyon", new ProcyonDecompiler()), + FERNFLOWER("FernFlower", new FernflowerDecompiler()), JD_GUI("JD-GUI", new JDDecompiler()), + CFR("CFR", new CFRDecompiler()); - final String name; + private final String name; + private final IDecompiler decompiler; + private final String syntaxStyle; + private final boolean isEditable; - EnumDecompiler(String name){ - this.name = name; - } - @Override - public String toString() { - return name; - } + private EnumDecompiler(String name, IDecompiler decompiler) { + this(name, decompiler, true); + } + + private EnumDecompiler(String name, IDecompiler decompiler, boolean isDecompiler) { + this.name = name; + this.decompiler = decompiler; + this.syntaxStyle = isDecompiler ? SyntaxConstants.SYNTAX_STYLE_JAVA + : SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE; + this.isEditable = !isDecompiler; + } + + public IDecompiler getDecompiler() { + return decompiler; + } + + public String getSyntaxStyle() { + return syntaxStyle; + } + + public boolean isEditable() { + return isEditable; + } + + @Override + public String toString() { + return name; + } } diff --git a/src/me/ByteEdit/decompiler/FernflowerDecompiler.java b/src/me/ByteEdit/decompiler/FernflowerDecompiler.java index ec04525..00bc7c1 100644 --- a/src/me/ByteEdit/decompiler/FernflowerDecompiler.java +++ b/src/me/ByteEdit/decompiler/FernflowerDecompiler.java @@ -18,7 +18,7 @@ import org.jetbrains.java.decompiler.struct.lazy.LazyLoader; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; -public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver { +public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver, IDecompiler { private byte[] bytes; private String returned; @@ -50,7 +50,12 @@ public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver { options.put("lac", false); } - public String decompile(ClassNode cn, byte[] b, MethodNode mn) { + @Override + public String decompile(ClassNode cn) { + return doDecompilation(cn, getBytes(cn), null); + } + + public String doDecompilation(ClassNode cn, byte[] b, MethodNode mn) { try { // TODO decompile method only this.bytes = b; @@ -66,6 +71,11 @@ public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver { @Override public void writeMessage(String message, Severity severity) { } + + @Override + public boolean accepts(Severity severity) { + return false; + } }); StructContext sc = f.getStructContext(); StructClass cl = new StructClass(b, true, sc.getLoader()); diff --git a/src/me/ByteEdit/decompiler/IDecompiler.java b/src/me/ByteEdit/decompiler/IDecompiler.java new file mode 100644 index 0000000..b292593 --- /dev/null +++ b/src/me/ByteEdit/decompiler/IDecompiler.java @@ -0,0 +1,16 @@ +package me.ByteEdit.decompiler; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; + +public interface IDecompiler { + + String decompile(ClassNode cn); + + default byte[] getBytes(ClassNode cn) { + ClassWriter classWriter = new ClassWriter(0); + cn.accept(classWriter); + return classWriter.toByteArray(); + } + +} diff --git a/src/me/ByteEdit/decompiler/JDDecompiler.java b/src/me/ByteEdit/decompiler/JDDecompiler.java index 51fe4df..cee2e60 100644 --- a/src/me/ByteEdit/decompiler/JDDecompiler.java +++ b/src/me/ByteEdit/decompiler/JDDecompiler.java @@ -1,6 +1,5 @@ package me.ByteEdit.decompiler; -import me.ByteEdit.main.Main; import org.jd.core.v1.ClassFileToJavaSourceDecompiler; import org.jd.core.v1.api.loader.Loader; import org.jd.core.v1.api.loader.LoaderException; @@ -8,24 +7,29 @@ import org.jd.core.v1.api.printer.Printer; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.tree.ClassNode; +import me.ByteEdit.main.Main; -public class JDDecompiler implements Loader, Printer { - - public String decompile(ClassNode cl) { +public class JDDecompiler implements Loader, Printer, IDecompiler { + + @Override + public String decompile(ClassNode cn) { ClassFileToJavaSourceDecompiler decompiler = new ClassFileToJavaSourceDecompiler(); try { - decompiler.decompile(this, this, cl.name); + decompiler.decompile(this, this, cn.name); } catch (Throwable e) { e.printStackTrace(); String str = e.getClass().getName() + " - " + e.getMessage() + System.lineSeparator(); - for(int i = 0; i < e.getStackTrace().length; i++) { + for (int i = 0; i < e.getStackTrace().length; i++) { str += e.getStackTrace()[i].toString() + System.lineSeparator(); } return str; } - return toString(); + String decomp = toString(); + indentationCount = 0; + sb = new StringBuilder(); + return decomp; } - + @Override public boolean canLoad(String internalName) { return Main.classNodes.containsKey(internalName + ".class"); diff --git a/src/me/ByteEdit/decompiler/ProcyonDecompiler.java b/src/me/ByteEdit/decompiler/ProcyonDecompiler.java index a2bd8b1..7feb7f2 100644 --- a/src/me/ByteEdit/decompiler/ProcyonDecompiler.java +++ b/src/me/ByteEdit/decompiler/ProcyonDecompiler.java @@ -17,9 +17,14 @@ import com.strobel.decompiler.DecompilationOptions; import com.strobel.decompiler.DecompilerSettings; import com.strobel.decompiler.PlainTextOutput; -public class ProcyonDecompiler { +public class ProcyonDecompiler implements IDecompiler { - public static String decompile(ClassNode cn, byte[] b, MethodNode mn) { + @Override + public String decompile(ClassNode cn) { + return doDecompilation(cn, getBytes(cn), null); + } + + private static String doDecompilation(ClassNode cn, byte[] b, MethodNode mn) { try { // TODO decompile method only DecompilerSettings settings = new DecompilerSettings(); diff --git a/src/me/ByteEdit/decompiler/SingleThreadedExecutor.java b/src/me/ByteEdit/decompiler/SingleThreadedExecutor.java index 6c34383..42577e2 100644 --- a/src/me/ByteEdit/decompiler/SingleThreadedExecutor.java +++ b/src/me/ByteEdit/decompiler/SingleThreadedExecutor.java @@ -4,24 +4,23 @@ import java.util.concurrent.LinkedBlockingQueue; public class SingleThreadedExecutor { + private static final LinkedBlockingQueue queue = new LinkedBlockingQueue<>(); - private static LinkedBlockingQueue queue = new LinkedBlockingQueue<>(); + private static final Thread thread = new Thread(() -> { + while (true) { + try { + queue.take().run(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + }, "SingleThreadedExecutor"); - private static final Thread thread = new Thread(() -> { - while(true){ - try { - queue.take().run(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - }, "Single"); - static { - thread.start(); - } + static { + thread.start(); + } - - public static void execute(Runnable r){ - queue.add(r); - } + public static void execute(Runnable r) { + queue.add(r); + } } diff --git a/src/me/ByteEdit/edit/Disassembler.java b/src/me/ByteEdit/edit/Disassembler.java index 249f638..b103f32 100644 --- a/src/me/ByteEdit/edit/Disassembler.java +++ b/src/me/ByteEdit/edit/Disassembler.java @@ -27,14 +27,11 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; -import java.util.concurrent.atomic.AtomicInteger; -import com.strobel.decompiler.Decompiler; -import me.ByteEdit.decompiler.CFRDecompiler; -import me.ByteEdit.decompiler.FernflowerDecompiler; -import me.ByteEdit.decompiler.JDDecompiler; -import me.ByteEdit.decompiler.ProcyonDecompiler; -import org.objectweb.asm.*; +import org.objectweb.asm.Handle; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; @@ -60,76 +57,29 @@ import org.objectweb.asm.tree.TryCatchBlockNode; import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.VarInsnNode; +import me.ByteEdit.decompiler.IDecompiler; import me.ByteEdit.main.Main; import me.ByteEdit.utils.ClassUtil; import me.ByteEdit.utils.OpcodesReverse; import me.ByteEdit.utils.UnicodeUtils; -public class Disassembler { +public class Disassembler implements IDecompiler { private static final ExecutorService exec = Executors .newFixedThreadPool((Runtime.getRuntime().availableProcessors() + 1) / 2); - public static String disassemble(ClassNode classNode) { - return disassemble(classNode, null).getDisassembly(); + @Override + public String decompile(ClassNode cn) { + return disassemble(cn); } - public static class DisassembleTuple { - - private final String dis; - private final int line; - - public DisassembleTuple(String dis) { - this.dis = dis; - this.line = -1; - } - - public DisassembleTuple(String dis, int line) { - this.dis = dis; - this.line = line; - } - - public String getDisassembly() { - return dis; - } - - public int getLine() { - return line; - } - - } - - public static DisassembleTuple disassemble(ClassNode classNode, Object nodeToFind) { - + private static String disassemble(ClassNode classNode) { if (classNode == null) { - return new DisassembleTuple("ClassNode is null! This is not a valid java class file!"); + return "ClassNode is null! This is not a valid java class file!"; } - - - try { - System.out.println(Main.decompiler); - ClassWriter classWriter = new ClassWriter(0); - switch (Main.decompiler){ - case PROCYON: - classNode.accept(classWriter); - return new DisassembleTuple(ProcyonDecompiler.decompile(classNode, classWriter.toByteArray(), null)); - case FERNFLOWER: - classNode.accept(classWriter); - return new DisassembleTuple(new FernflowerDecompiler().decompile(classNode, classWriter.toByteArray(), null)); - case JD_GUI: - classNode.accept(classWriter); - return new DisassembleTuple(new JDDecompiler().decompile(classNode)); - case CFR: - classNode.accept(classWriter); - return new DisassembleTuple(CFRDecompiler.decompile(classNode, classWriter.toByteArray(), null)); - default: - break; - } - HugeStrings hs = new HugeStrings(); - AtomicInteger lineFound = new AtomicInteger(-1); StringContext ctx = new StringContext(18); ctx.next("// #Annotations:\n"); ctx.next(doAnnotations(classNode.visibleAnnotations, hs, "")); @@ -175,19 +125,18 @@ public class Disassembler { + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(hs, classNode.sourceFile)) + "\n"); int hugeIdx = ctx.next(""); ctx.next("\n// #Fields\n"); - ctx.next(doFields(classNode.fields, nodeToFind, lineFound, hs)); + ctx.next(doFields(classNode.fields, hs)); ctx.next("\n// #Methods\n"); - ctx.next(doMethods(classNode.methods, classNode.name, nodeToFind, lineFound, hs)); + ctx.next(doMethods(classNode.methods, classNode.name, hs)); ctx.next("}\n"); if (!hs.isEmpty()) ctx.set(hugeIdx, hs.makeStringsList()); - return new DisassembleTuple(ctx.finish(), lineFound.get()); + return ctx.finish(); } catch (Throwable e) { - return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": " - + e.getMessage() + "\n" + return "Class couldn't be decompiled:\n" + e.getClass().getName() + ": " + e.getMessage() + "\n" + Arrays.toString(e.getStackTrace()).replace(", ", "\n\tat ").replace("[", "\tat ").replace("]", "") - + "\n"); + + "\n"; } } @@ -258,8 +207,8 @@ public class Disassembler { return ctx.finish(); } - private static String doMethods(List methods, String className, Object nodeToFind, - AtomicInteger lineFound, HugeStrings hs) throws InterruptedException, ExecutionException { + private static String doMethods(List methods, String className, HugeStrings hs) + throws InterruptedException, ExecutionException { boolean multithreaded = Main.INSTANCE.mntmMultithreaded.isSelected(); Future[] futures = new Future[methods.size()]; for (int i = 0; i < futures.length; i++) { @@ -277,9 +226,6 @@ public class Disassembler { ms += dis[1]; if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) ms += doAnnotations(mn.visibleAnnotations, hs, "\t"); - if (mn.equals(nodeToFind)) { - lineFound.set(ms.split("\\n").length); - } ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escapeWithSpaces(hs, mn.name) + " " + UnicodeUtils.escapeWithSpaces(hs, mn.desc) + " "; @@ -321,7 +267,7 @@ public class Disassembler { return s; } - private static String doFields(List fields, Object nodeToFind, AtomicInteger lineFound, HugeStrings hs) { + private static String doFields(List fields, HugeStrings hs) { StringContext ctx = new StringContext(fields.size()); for (FieldNode fn : fields) { String s = ""; @@ -329,9 +275,6 @@ public class Disassembler { s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, fn.signature) + "\n"; if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) s += doAnnotations(fn.visibleAnnotations, hs, "\t"); - if (fn.equals(nodeToFind)) { - lineFound.set(s.split("\\n").length); - } s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + UnicodeUtils.escapeWithSpaces(hs, fn.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, fn.name); if (fn.value != null) { @@ -604,5 +547,4 @@ public class Disassembler { } return "null"; } - } diff --git a/src/me/ByteEdit/edit/OptionBox.java b/src/me/ByteEdit/edit/OptionBox.java index 2448b9f..2f4a362 100644 --- a/src/me/ByteEdit/edit/OptionBox.java +++ b/src/me/ByteEdit/edit/OptionBox.java @@ -10,17 +10,17 @@ import javax.swing.UIManager; import javax.swing.border.EmptyBorder; public class OptionBox extends JFrame { - + private JPanel contentPane; public JCheckBox chckbxComputeFrames; public JCheckBox chckbxComputeMax; - + /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { - + public void run() { try { OptionBox frame = new OptionBox(); @@ -31,7 +31,7 @@ public class OptionBox extends JFrame { } }); } - + /** * Create the frame. */ diff --git a/src/me/ByteEdit/edit/SearchBox.java b/src/me/ByteEdit/edit/SearchBox.java index 5974128..809fc7e 100644 --- a/src/me/ByteEdit/edit/SearchBox.java +++ b/src/me/ByteEdit/edit/SearchBox.java @@ -20,12 +20,12 @@ import javax.swing.border.EmptyBorder; import me.ByteEdit.main.Main; public class SearchBox extends JFrame { - + public JPanel contentPane; public JTextField txtFind; public JTextField txtReplace; public JCheckBox chckbxCaseSensitive; - + /** * Create the frame. */ @@ -50,7 +50,7 @@ public class SearchBox extends JFrame { txtFind = new JTextField(); KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); txtFind.registerKeyboardAction(new ActionListener() { - + @Override public void actionPerformed(ActionEvent e) { find(); @@ -71,7 +71,7 @@ public class SearchBox extends JFrame { contentPane.add(chckbxCaseSensitive); JButton btnFind = new JButton("Find"); btnFind.addActionListener(new ActionListener() { - + public void actionPerformed(ActionEvent e) { find(); } @@ -80,7 +80,7 @@ public class SearchBox extends JFrame { contentPane.add(btnFind); JButton btnReplacefind = new JButton("Replace/Find"); btnReplacefind.addActionListener(new ActionListener() { - + public void actionPerformed(ActionEvent e) { replaceFind(); } @@ -89,7 +89,7 @@ public class SearchBox extends JFrame { contentPane.add(btnReplacefind); JButton btnReplace = new JButton("Replace"); btnReplace.addActionListener(new ActionListener() { - + public void actionPerformed(ActionEvent e) { replace(); } @@ -98,7 +98,7 @@ public class SearchBox extends JFrame { contentPane.add(btnReplace); JButton btnReplaceAll = new JButton("Replace All"); btnReplaceAll.addActionListener(new ActionListener() { - + public void actionPerformed(ActionEvent e) { replaceAll(); } @@ -106,7 +106,7 @@ public class SearchBox extends JFrame { btnReplaceAll.setBounds(130, 184, 110, 23); contentPane.add(btnReplaceAll); } - + public void find() { int startPos = Main.txtByteEditView.getCaretPosition(); String toFind = txtFind.getText(); @@ -114,7 +114,8 @@ public class SearchBox extends JFrame { : Main.txtByteEditView.getText().substring(startPos).toLowerCase(); int index = txt.indexOf(chckbxCaseSensitive.isSelected() ? toFind : toFind.toLowerCase()); if (index == -1) { - txt = chckbxCaseSensitive.isSelected() ? Main.txtByteEditView.getText() : Main.txtByteEditView.getText().toLowerCase(); + txt = chckbxCaseSensitive.isSelected() ? Main.txtByteEditView.getText() + : Main.txtByteEditView.getText().toLowerCase(); index = txt.indexOf(chckbxCaseSensitive.isSelected() ? toFind : toFind.toLowerCase()); startPos = 0; if (index == -1) { @@ -123,19 +124,19 @@ public class SearchBox extends JFrame { } Main.txtByteEditView.select(startPos + index, startPos + index + toFind.length()); } - + public void replaceFind() { replace(); find(); } - + public void replace() { String txt = Main.txtByteEditView.getText(); int startPos = Main.txtByteEditView.getSelectionStart(); Main.txtByteEditView.replaceSelection(txtReplace.getText()); Main.txtByteEditView.select(startPos, startPos + txtReplace.getText().length()); } - + public void replaceAll() { String toFind = txtFind.getText(); String toReplace = txtReplace.getText(); @@ -144,7 +145,8 @@ public class SearchBox extends JFrame { if (chckbxCaseSensitive.isSelected()) { Main.txtByteEditView.replaceRange(txt.replace(toFind, toReplace), 0, txt.length()); } else { - Main.txtByteEditView.replaceRange(txt.replaceAll("(?i)" + Pattern.quote(toFind), toReplace), 0, txt.length()); + Main.txtByteEditView.replaceRange(txt.replaceAll("(?i)" + Pattern.quote(toFind), toReplace), 0, + txt.length()); } Main.txtByteEditView.setCaretPosition(prev); } diff --git a/src/me/ByteEdit/edit/TypeOpenBox.java b/src/me/ByteEdit/edit/TypeOpenBox.java index 83c735d..5690785 100644 --- a/src/me/ByteEdit/edit/TypeOpenBox.java +++ b/src/me/ByteEdit/edit/TypeOpenBox.java @@ -3,7 +3,6 @@ package me.ByteEdit.edit; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.concurrent.TimeUnit; import javax.swing.DefaultListModel; import javax.swing.JFrame; @@ -23,10 +22,10 @@ import me.ByteEdit.decompiler.SingleThreadedExecutor; import me.ByteEdit.main.Main; public class TypeOpenBox extends JFrame { - + public JPanel contentPane; public JTextField txtSearch; - + /** * Create the frame. */ @@ -45,23 +44,23 @@ public class TypeOpenBox extends JFrame { contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); - + DefaultListModel model = new DefaultListModel<>(); JList list = new JList(model); list.addListSelectionListener(new ListSelectionListener() { - + public void valueChanged(ListSelectionEvent e) { String val = list.getSelectedValue(); if (val != null && !val.equals(Main.currentNodeName)) { - SingleThreadedExecutor.execute( () -> Main.selectFile(val)); + SingleThreadedExecutor.execute(() -> Main.selectFile(val)); } } }); - + txtSearch = new JTextField(); txtSearch.addActionListener(new ActionListener() { - + public void actionPerformed(ActionEvent e) { if (model.size() == 1) { list.setSelectedIndex(0); @@ -69,19 +68,19 @@ public class TypeOpenBox extends JFrame { } }); txtSearch.getDocument().addDocumentListener(new DocumentListener() { - + public void changedUpdate(DocumentEvent e) { updateList(); } - + public void removeUpdate(DocumentEvent e) { updateList(); } - + public void insertUpdate(DocumentEvent e) { updateList(); } - + public void updateList() { model.clear(); if (txtSearch.getText().isEmpty()) { @@ -110,13 +109,13 @@ public class TypeOpenBox extends JFrame { txtSearch.setBounds(10, 11, 374, 20); contentPane.add(txtSearch); txtSearch.setColumns(10); - + JScrollPane scrollPane = new JScrollPane(); scrollPane.setBounds(10, 46, 374, 194); contentPane.add(scrollPane); - + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); scrollPane.setViewportView(list); } - + } diff --git a/src/me/ByteEdit/main/Main.java b/src/me/ByteEdit/main/Main.java index f03c95a..2a4b384 100644 --- a/src/me/ByteEdit/main/Main.java +++ b/src/me/ByteEdit/main/Main.java @@ -1,6 +1,12 @@ package me.ByteEdit.main; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.HeadlessException; +import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DropTarget; @@ -8,7 +14,13 @@ import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; @@ -16,13 +28,15 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashMap; import java.util.List; import java.util.Map.Entry; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -30,7 +44,24 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -import javax.swing.*; +import javax.swing.ButtonGroup; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTree; +import javax.swing.KeyStroke; import javax.swing.border.EmptyBorder; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; @@ -44,8 +75,6 @@ import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; -import me.ByteEdit.decompiler.EnumDecompiler; -import me.ByteEdit.decompiler.SingleThreadedExecutor; import org.fife.ui.autocomplete.AutoCompletion; import org.fife.ui.autocomplete.BasicCompletion; import org.fife.ui.autocomplete.CompletionProvider; @@ -61,7 +90,6 @@ import org.fife.ui.rtextarea.ToolTipSupplier; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodNode; import me.ByteEdit.boxes.CompilationBox; @@ -71,9 +99,9 @@ import me.ByteEdit.boxes.SearchBox; import me.ByteEdit.boxes.ThemeBox; import me.ByteEdit.boxes.TypeOpenBox; import me.ByteEdit.boxes.UnicodeBox; +import me.ByteEdit.decompiler.EnumDecompiler; +import me.ByteEdit.decompiler.SingleThreadedExecutor; import me.ByteEdit.edit.Assembler; -import me.ByteEdit.edit.Disassembler; -import me.ByteEdit.edit.Disassembler.DisassembleTuple; import me.ByteEdit.edit.HugeStrings; import me.ByteEdit.utils.ClassUtil; import me.ByteEdit.utils.OpcodesReverse; @@ -81,8 +109,6 @@ import me.ByteEdit.utils.UnicodeUtils; public class Main extends JFrame { - - public static Main INSTANCE; private JPanel contentPane; private volatile boolean isChangingFile; @@ -136,19 +162,15 @@ public class Main extends JFrame { * Launch the application. */ public static void main(String[] args) { - EventQueue.invokeLater(new Runnable() { - - public void run() { - try { - Main frame = new Main(); - frame.setVisible(true); - ThemeManager.applyRSTATheme(); - } catch (Exception e) { - e.printStackTrace(); - } + EventQueue.invokeLater(() -> { + try { + Main frame = new Main(); + frame.setVisible(true); + ThemeManager.applyRSTATheme(); + } catch (Exception e) { + e.printStackTrace(); } }); - } /** @@ -431,7 +453,6 @@ public class Main extends JFrame { tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeExpansionListener(new FurtherExpandingTreeExpansionListener()); tree.addKeyListener(new KeyAdapter() { - @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == 116 && jarFile != null) { // F5 @@ -505,8 +526,8 @@ public class Main extends JFrame { public void valueChanged(TreeSelectionEvent e) { synchronized (treeLock) { if (!isChangingFile) { - - SingleThreadedExecutor.execute( () -> selectFile(((ByteEditTreeNode) e.getPath().getLastPathComponent()).path)); + SingleThreadedExecutor.execute( + () -> selectFile(((ByteEditTreeNode) e.getPath().getLastPathComponent()).path)); } } } @@ -526,7 +547,7 @@ public class Main extends JFrame { for (int i = 0; i < flavors.length; i++) { if (flavors[i].isFlavorJavaFileListType()) { dtde.acceptDrop(dtde.getDropAction()); - java.util.List files = (java.util.List) tr.getTransferData(flavors[i]); + List files = (List) tr.getTransferData(flavors[i]); final File file = files.get(0); if (file.getName().endsWith(".jar")) { jarFile = file; @@ -676,34 +697,10 @@ public class Main extends JFrame { } }); txtByteEditView.addKeyListener(new KeyAdapter() { - @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == 116 && currentNodeName != null) { // F5 - - SingleThreadedExecutor.execute( () -> { - try { - ClassNode classNode = classNodes.get(currentNodeName); - int prev = txtByteEditView.getCaretPosition(); - String dis = Disassembler.disassemble(classNode); - String substr = currentNodeName.substring(0, currentNodeName.length() - 6); - synchronized (Main.classNodes){ - for (String key : Main.classNodes.keySet()) { - if (key.contains("$")) { - String[] split = key.split("\\$"); - if (split[0].equals(substr)) { - dis += "\n" + Disassembler.disassemble(classNodes.get(key)); - } - } - } - } - txtByteEditView.setText(dis); - if (dis.length() > prev) - txtByteEditView.setCaretPosition(prev); - } catch (Exception e2) { - e2.printStackTrace(); - } - }); + SingleThreadedExecutor.execute(Main::decompileCurrentNode); } } }); @@ -740,13 +737,6 @@ public class Main extends JFrame { // specific tree.registerKeyboardAction(e -> save(), ctrlS, JComponent.WHEN_FOCUSED); txtByteEditView.registerKeyboardAction(e -> saveCurrentClassNode(), ctrlS, JComponent.WHEN_FOCUSED); - txtByteEditView.registerKeyboardAction(e -> { - try { - goToSelected(); - } catch (BadLocationException e1) { - e1.printStackTrace(); - } - }, ctrlG, JComponent.WHEN_FOCUSED); txtByteEditView.registerKeyboardAction(e -> { try { renameSelected(); @@ -769,147 +759,39 @@ public class Main extends JFrame { decompilerMode.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { - - SingleThreadedExecutor.execute( () -> { - decompiler = (EnumDecompiler) e.getItem(); - try { - txtByteEditView.setSyntaxEditingStyle(decompiler == EnumDecompiler.BYTEEDIT ? SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE : SyntaxConstants.SYNTAX_STYLE_JAVA); - } catch (Throwable t){} - txtByteEditView.setEditable(decompiler == EnumDecompiler.BYTEEDIT); - if (currentNodeName != null) { - - - try { - ClassNode classNode = classNodes.get(currentNodeName); - int prev = txtByteEditView.getCaretPosition(); - String dis = Disassembler.disassemble(classNode); - String substr = currentNodeName.substring(0, currentNodeName.length() - 6); - for (String key : Main.classNodes.keySet()) { - if (key.contains("$")) { - String[] split = key.split("\\$"); - if (split[0].equals(substr)) { - dis += "\n" + Disassembler.disassemble(classNodes.get(key)); + if (e.getStateChange() == ItemEvent.SELECTED) { + EnumDecompiler selected = (EnumDecompiler) e.getItem(); + SingleThreadedExecutor.execute(() -> { + decompiler = selected; + if (currentNodeName != null) { + decompileCurrentNode(); + try { + EventQueue.invokeAndWait(() -> { + txtByteEditView.setCaretPosition(0); + try { + txtByteEditView.setSyntaxEditingStyle(decompiler.getSyntaxStyle()); + } catch (Throwable t) { } - } + txtByteEditView.setEditable(decompiler.isEditable()); + }); + } catch (Exception e1) { + e1.printStackTrace(); } - txtByteEditView.setText(dis); - if (dis.length() > prev) - txtByteEditView.setCaretPosition(prev); - } catch (Exception e2) { - e2.printStackTrace(); } - - - } - - }); + }); + } } }); panel.add(decompilerMode, BorderLayout.NORTH); - - splitPane.setRightComponent(panel); scrollPane_ByteEdit.setViewportView(txtByteEditView); scrollPane_ByteEdit.setLineNumbersEnabled(true); scrollPane_ByteEdit.setFoldIndicatorEnabled(true); } - - public static EnumDecompiler decompiler = EnumDecompiler.BYTEEDIT; - private final Pattern jumpableInstructionPattern = Pattern.compile("^\t\t(?!//|\t+).+ .+"); - - public void goToSelected() throws BadLocationException { - int lineStart = txtByteEditView.getLineStartOffsetOfCurrentLine(); - int lineEnd = txtByteEditView.getLineEndOffsetOfCurrentLine() - 1; - if (lineEnd < lineStart) - return; - String line = txtByteEditView.getText(lineStart, lineEnd - lineStart); - if (!jumpableInstructionPattern.matcher(line).matches()) { - return; - } - line = line.substring(2); - if (line.startsWith("invoke")) { - String[] split = line.split(" "); - String desc = UnicodeUtils.unescape(null, split[1], true); - String target = split[2]; - int index = target.lastIndexOf("/"); - String className = UnicodeUtils.unescape(null, target.substring(0, index), true); - String methodName = UnicodeUtils.unescape(null, target.substring(index + 1), true); - ClassNode classNode = classNodes.get(getFullName(className)); - if (classNode == null) { - return; - } - for (MethodNode mn : classNode.methods) { - if (mn.name.equals(methodName) && mn.desc.equals(desc)) { - while (classNode.outerClass != null) { - classNode = classNodes.get(getFullName(classNode.outerClass)); - } - - - ClassNode finalClassNode = classNode; - SingleThreadedExecutor.execute( () -> { - int lineFound = selectFileWithSearch(getFullName(finalClassNode.name), mn); - if (lineFound != -1) { - try { - Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound)); - } catch (BadLocationException e) { - e.printStackTrace(); - } - } - }); - - break; - } - } - } else if (line.startsWith("new ")) { - String[] split = line.split(" "); - String className = UnicodeUtils.unescape(null, split[1], true); - ClassNode classNode = classNodes.get(getFullName(className)); - if (classNode == null) { - return; - } - - SingleThreadedExecutor.execute( () -> selectFile(getFullName(className))); - } else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ") - || line.startsWith("putfield ")) { - String[] split = line.split(" "); - String desc = UnicodeUtils.unescape(null, split[1], true); - String target = split[2]; - int index = target.lastIndexOf("/"); - String className = UnicodeUtils.unescape(null, target.substring(0, index), true); - String fieldName = UnicodeUtils.unescape(null, target.substring(index + 1), true); - ClassNode classNode = classNodes.get(getFullName(className)); - if (classNode == null) { - return; - } - for (FieldNode fn : classNode.fields) { - if (fn.name.equals(fieldName) && fn.desc.equals(desc)) { - while (classNode.outerClass != null) { - classNode = classNodes.get(getFullName(classNode.outerClass)); - } - - ClassNode finalClassNode = classNode; - ClassNode finalClassNode1 = classNode; - SingleThreadedExecutor.execute( () -> { - int lineFound = selectFileWithSearch(getFullName(finalClassNode1.name), fn); - if (lineFound != -1) { - try { - Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound)); - } catch (BadLocationException e) { - e.printStackTrace(); - } - } - }); - - break; - } - } - } - } - private final Pattern renameableFieldPattern = Pattern .compile("^\t(?:[a-z]+ |0x[0-9a-fA-F]+ )*?(\\[*(?:V|Z|C|B|S|I|F|J|D|L.+?;)) ([^ ]+) ?.*"); private final Pattern renameableMethodPattern = Pattern @@ -999,41 +881,38 @@ public class Main extends JFrame { } } - public static int selectFileWithSearch(String s, Object nodeToFind) { - if (s != null && s.endsWith(".class")) { - currentNodeName = s; - int lineFound = -1; - ClassNode classNode = classNodes.get(s); - if (classNode == null) - return -1; - String dis = ""; - DisassembleTuple tuple = Disassembler.disassemble(classNode, nodeToFind); - if (tuple.getLine() != -1) { - lineFound = dis.split("\\n").length + tuple.getLine() - 1; - } - dis += tuple.getDisassembly(); - String substr = s.substring(0, s.length() - 6); - for (String key : Main.classNodes.keySet()) { - if (key.contains("$")) { - String[] split = key.split("\\$"); - if (split[0].equals(substr)) { - tuple = Disassembler.disassemble(classNodes.get(key), nodeToFind); - if (tuple.getLine() != -1) { - lineFound = dis.split("\\n").length + tuple.getLine() + 1; + public static void decompileCurrentNode() { + try { + EnumDecompiler decompiler = Main.decompiler; + String current = currentNodeName; + ClassNode classNode = classNodes.get(current); + int prev = txtByteEditView.getCaretPosition(); + String dis = decompiler.getDecompiler().decompile(classNode); + String substr = current.substring(0, current.length() - 6); + synchronized (Main.classNodes) { + for (String key : Main.classNodes.keySet()) { + if (key.contains("$")) { + String[] split = key.split("\\$"); + if (split[0].equals(substr)) { + dis += "\n" + decompiler.getDecompiler().decompile(classNodes.get(key)); } - dis += "\n" + tuple.getDisassembly(); } } } txtByteEditView.setText(dis); - txtByteEditView.setCaretPosition(0); - return lineFound; + if (dis.length() > prev) + txtByteEditView.setCaretPosition(prev); + } catch (Exception e2) { + e2.printStackTrace(); } - return -1; } - public static int selectFile(String s) { - return selectFileWithSearch(s, null); + public static void selectFile(String s) { + if (s != null && s.endsWith(".class")) { + currentNodeName = s; + decompileCurrentNode(); + txtByteEditView.setCaretPosition(0); + } } public void save() { diff --git a/src/org/fife/eclipse_dark.xml b/src/org/fife/eclipse_dark.xml index 6009675..5790c21 100644 --- a/src/org/fife/eclipse_dark.xml +++ b/src/org/fife/eclipse_dark.xml @@ -14,7 +14,7 @@ - + diff --git a/src/org/fife/ui/rsyntaxtextarea/DefaultTokenFactory.java b/src/org/fife/ui/rsyntaxtextarea/DefaultTokenFactory.java index c8fa4e4..8f74a3d 100644 --- a/src/org/fife/ui/rsyntaxtextarea/DefaultTokenFactory.java +++ b/src/org/fife/ui/rsyntaxtextarea/DefaultTokenFactory.java @@ -102,7 +102,8 @@ class DefaultTokenFactory implements TokenFactory { @Override public TokenImpl createToken(final char[] line, final int beg, final int end, final int startOffset, final int type) { - // if(tokenList.length - 1 > currentFreeToken) return null; +// if (tokenList.length - 1 > currentFreeToken) +// return null; TokenImpl token = tokenList[currentFreeToken]; token.set(line, beg, end, startOffset, type); currentFreeToken++; diff --git a/src/org/fife/ui/rsyntaxtextarea/TokenMakerBase.java b/src/org/fife/ui/rsyntaxtextarea/TokenMakerBase.java index 398d798..f4f468b 100644 --- a/src/org/fife/ui/rsyntaxtextarea/TokenMakerBase.java +++ b/src/org/fife/ui/rsyntaxtextarea/TokenMakerBase.java @@ -108,7 +108,8 @@ public abstract class TokenMakerBase implements TokenMaker { currentToken = firstToken; // previous token is still null. } else { TokenImpl next = tokenFactory.createToken(array, start, end, startOffset, tokenType); - if(currentToken == null || next == null ) return; + if (currentToken == null || next == null) + return; currentToken.setNextToken(next); previousToken = currentToken; currentToken = next; diff --git a/src/org/fife/ui/rsyntaxtextarea/modes/JavaTokenMaker.java b/src/org/fife/ui/rsyntaxtextarea/modes/JavaTokenMaker.java index 35e0fdb..21bfc7d 100644 --- a/src/org/fife/ui/rsyntaxtextarea/modes/JavaTokenMaker.java +++ b/src/org/fife/ui/rsyntaxtextarea/modes/JavaTokenMaker.java @@ -3184,9 +3184,8 @@ public class JavaTokenMaker extends AbstractJFlexCTokenMaker { return null; } } else { - //zzScanError(ZZ_NO_MATCH); + // zzScanError(ZZ_NO_MATCH); return null; - } } }