From 65235c6b5b2cd96666da8b7cc37f1a65375e2c83 Mon Sep 17 00:00:00 2001 From: SuspiciousActivity <38253929+SuspiciousActivity@users.noreply.github.com> Date: Thu, 26 Nov 2020 15:52:35 +0100 Subject: [PATCH] ToolTips for #... --- src/me/ByteEdit/edit/Assembler.java | 6 +- src/me/ByteEdit/edit/Disassembler.java | 10 +++- src/me/ByteEdit/main/Main.java | 83 ++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/me/ByteEdit/edit/Assembler.java b/src/me/ByteEdit/edit/Assembler.java index 8ac43d9..d306af8 100644 --- a/src/me/ByteEdit/edit/Assembler.java +++ b/src/me/ByteEdit/edit/Assembler.java @@ -53,7 +53,7 @@ import me.ByteEdit.utils.UnicodeUtils; public class Assembler { - private static final Pattern SPACE = Pattern.compile(" "); + public static final Pattern SPACE = Pattern.compile(" "); public static ClassNode assemble(String input) { Main.txtByteEditView.removeAllLineHighlights(); @@ -841,7 +841,9 @@ public class Assembler { UnicodeUtils.unescape(hsr, split2[3].substring(6, split2[3].length() - 1)), Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5))); } else if (str.startsWith("\"") && str.endsWith("\"")) { - val = UnicodeUtils.unescape(hsr, str.substring(1, str.length() - 1)); + val = UnicodeUtils.unescape(hsr, str.substring(1, str.length() - 1), true); + } else if (str.startsWith("#")) { + val = UnicodeUtils.unescape(hsr, str); } else if (str.endsWith("l")) { val = Long.parseLong(str.substring(0, str.length() - 1)); } else if (str.endsWith("f")) { diff --git a/src/me/ByteEdit/edit/Disassembler.java b/src/me/ByteEdit/edit/Disassembler.java index 1f8ebc3..681550b 100644 --- a/src/me/ByteEdit/edit/Disassembler.java +++ b/src/me/ByteEdit/edit/Disassembler.java @@ -619,8 +619,14 @@ public class Disassembler { s += "\n\t\t]\n"; return s; } else { - return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " - + ClassUtil.getDecompiledValue(node.cst, "", hs) + "\n"; + String decomp = ClassUtil.getDecompiledValue(node.cst, "", hs); + if (node.cst instanceof String) { + if (decomp.startsWith("\"#") && decomp.endsWith("\"")) + decomp = decomp.substring(1, decomp.length() - 1); + else if (decomp.startsWith("\"\\u0023")) + decomp = "\"#" + decomp.substring(7); + } + return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + decomp + "\n"; } }); iiMap.put(VarInsnNode.class, (n, labels, hs) -> { diff --git a/src/me/ByteEdit/main/Main.java b/src/me/ByteEdit/main/Main.java index 76f7d85..172fbfb 100644 --- a/src/me/ByteEdit/main/Main.java +++ b/src/me/ByteEdit/main/Main.java @@ -17,11 +17,14 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; 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; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -75,7 +78,9 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.folding.CurlyFoldParser; import org.fife.ui.rsyntaxtextarea.folding.FoldParserManager; +import org.fife.ui.rtextarea.RTextArea; import org.fife.ui.rtextarea.RTextScrollPane; +import org.fife.ui.rtextarea.ToolTipSupplier; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.tree.ClassNode; @@ -594,6 +599,84 @@ public class Main extends JFrame { txtByteEditView = new RSyntaxTextArea(); ac.install(txtByteEditView); txtByteEditView.setCodeFoldingEnabled(true); + // ToolTips for HugeStrings + txtByteEditView.setToolTipSupplier(new ToolTipSupplier() { + + @Override + public String getToolTipText(RTextArea textArea, MouseEvent e) { + int idx = textArea.viewToModel(e.getPoint()); + if (idx < 0) + return null; + int subIdx = Math.max(idx - 15, 0); + int subLen = Math.min(30, textArea.getDocument().getLength() - subIdx); + if (subLen <= 0) + return null; + try { + String cut = textArea.getText(subIdx, subLen); + int hashIdx = -1; + for (int off = idx - subIdx; off >= 0; off--) { + if (cut.charAt(off) == '#') { + hashIdx = off; + break; + } + } + if (hashIdx < 0) { + for (int off = idx - subIdx; off < cut.length(); off++) { + if (cut.charAt(off) == '#') { + hashIdx = off; + break; + } + } + } + if (hashIdx < 0) + return null; + if (hashIdx >= 5 && cut.substring(hashIdx - 5, hashIdx).equals("ldc \"")) // ldc "#..." + return null; + int numLen = 1; + for (int i = hashIdx + 1; i < cut.length(); i++) { + if (!(cut.charAt(i) - '0' >= 0 && cut.charAt(i) - '0' <= 9)) { + break; + } + numLen++; + } + if (numLen < 2 || hashIdx > idx - subIdx || idx - subIdx - numLen >= hashIdx) + return null; + String hashNum = cut.substring(hashIdx, hashIdx + numLen); + + String txt = txtByteEditView.getText(); + int len = 0; + for (String asm : txt.split("\\/\\/ #Annotations:\n")) { + len += 19; // "\\/\\/ #Annotations:\n".length() + if (asm.isEmpty()) + continue; + if (idx >= len && idx < len + asm.length()) { + try (BufferedReader reader = new BufferedReader(new StringReader(asm))) { + String s; + while (!(s = reader.readLine()).startsWith("// #SourceFile: ")) { + } + while (!(s = reader.readLine()).equals("// #Fields")) { + if (s.startsWith("#")) { + String[] split = Assembler.SPACE.split(s, 2); + if (hashNum.equals(split[0].substring(0, split[0].length() - 1))) { + String toolTip = split[1]; + if (toolTip.length() > 500) + toolTip = toolTip.substring(0, 500) + "..."; + return toolTip; + } + } + } + } catch (IOException e1) { + } + break; + } else { + len += asm.length(); + } + } + } catch (BadLocationException e1) { + } + return null; + } + }); txtByteEditView.addKeyListener(new KeyAdapter() { @Override