Added renaming (CTRL + R) and field goto (CTRL + G)

This commit is contained in:
SuspiciousActivity committed 2018-11-24 14:08:54 +01:00
1 parent 30c6a7a69d
commit 1c887abb73
9 files changed
+383 -38

No files matched your search

+3 -1
View File
@@ -12,6 +12,8 @@ To open a class, press CTRL + T.
To change settings like auto-computation of stack frames and max locals/stack press CTRL + O. To change settings like auto-computation of stack frames and max locals/stack press CTRL + O.
To go to the method definition of the selected line's invoke-method press CTRL + G. To go to the field/method definition in the selected line press CTRL + G.
To (un-)escape unicode characters, press CTRL + U. To (un-)escape unicode characters, press CTRL + U.
To rename a field/method with attention to references in the selected line, press CTRL + R.
-21
View File
@@ -1,6 +1,5 @@
package me.ByteEdit.boxes; package me.ByteEdit.boxes;
import java.awt.EventQueue;
import java.awt.Toolkit; import java.awt.Toolkit;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
@@ -15,26 +14,6 @@ public class OptionBox extends JFrame {
public JCheckBox chckbxComputeFrames; public JCheckBox chckbxComputeFrames;
public JCheckBox chckbxComputeMax; public JCheckBox chckbxComputeMax;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
OptionBox frame = new OptionBox();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public OptionBox() { public OptionBox() {
try { try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+232
View File
@@ -0,0 +1,232 @@
package me.ByteEdit.boxes;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
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.main.Main;
import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.UnicodeUtils;
public class RenameBox extends JFrame {
private JPanel contentPane;
public JTextField txtName;
public JTextField txtDesc;
public String className;
public String name;
public String desc;
public RenameBox() {
setResizable(false);
setTitle("Rename");
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 225),
(int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 150), 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblName = new JLabel("Name");
lblName.setBounds(10, 11, 33, 14);
contentPane.add(lblName);
JLabel lblDesc = new JLabel("Desc");
lblDesc.setBounds(10, 36, 33, 14);
contentPane.add(lblDesc);
txtName = new JTextField();
txtName.setBounds(53, 8, 381, 20);
contentPane.add(txtName);
txtName.setColumns(10);
txtDesc = new JTextField();
txtDesc.setColumns(10);
txtDesc.setBounds(53, 36, 381, 20);
contentPane.add(txtDesc);
JButton btnRename = new JButton("Rename");
btnRename.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (className == null) {
JOptionPane.showMessageDialog(null, "ClassName not set!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
if (name == null) {
JOptionPane.showMessageDialog(null, "Name not set!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
if (desc == null) {
JOptionPane.showMessageDialog(null, "Desc not set!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
ClassNode clazz = Main.classNodes.get(className.replace("/", ".") + ".class");
if (clazz == null) {
JOptionPane.showMessageDialog(null, "ClassNode not found!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
String newName = UnicodeUtils.unescape(txtName.getText());
String newDesc = UnicodeUtils.unescape(txtDesc.getText());
if (ClassUtil.isObjectClassMethod(newName, newDesc, true)) {
JOptionPane.showMessageDialog(null, "Invalid name!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
if (desc.startsWith("(")) {
if (newDesc.startsWith("(")) { // method
ClassNode lastHit = clazz;
while (clazz != null && clazz.superName != null) {
ClassNode tmp = Main.classNodes.get(clazz.superName.replace("/", ".") + ".class");
if (tmp != null) {
boolean found = false;
for (MethodNode mn : clazz.methods) {
if (mn.name.equals(name) && mn.desc.equals(desc)) {
lastHit = clazz;
clazz = tmp;
found = true;
break;
}
}
if (!found) {
clazz = tmp;
lastHit = null;
}
} else {
break;
}
}
if (lastHit != null) {
clazz = lastHit;
}
LinkedList<MethodNode> methodsToRename = new LinkedList<>();
LinkedList<MethodInsnNode> minsToRename = new LinkedList<>();
for (ClassNode cn : Main.classNodes.values()) {
boolean extendsMyClass = cn == clazz;
if (!extendsMyClass) {
ClassNode checkCN = cn;
while (checkCN != null && checkCN.superName != null) {
if (clazz.name.equals(checkCN.superName)) {
extendsMyClass = true;
break;
}
ClassNode tmp = Main.classNodes.get(checkCN.superName.replace("/", ".") + ".class");
if (tmp != null) {
checkCN = tmp;
} else {
break;
}
}
}
for (MethodNode mn : cn.methods) {
if (extendsMyClass) {
if (mn.name.equals(newName) && mn.desc.equals(newDesc)) {
JOptionPane.showMessageDialog(null, "Method already exists in " + cn.name + "!", "Error!",
JOptionPane.ERROR_MESSAGE);
return;
}
if (mn.name.equals(name) && mn.desc.equals(desc)) {
methodsToRename.add(mn);
}
}
for (AbstractInsnNode ain : mn.instructions.toArray()) {
if (ain instanceof MethodInsnNode) {
MethodInsnNode min = (MethodInsnNode) ain;
if (min.name.equals(name) && min.desc.equals(desc) && min.owner.equals(clazz.name)) {
minsToRename.add(min);
}
}
}
}
}
for (MethodNode mn : methodsToRename) {
mn.name = newName;
mn.desc = newDesc;
}
for (MethodInsnNode min : minsToRename) {
min.name = newName;
min.desc = newDesc;
}
} else {
JOptionPane.showMessageDialog(null, "New Desc is not a method desc!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
} else {
if (!newDesc.startsWith("(")) { // field
FieldNode currentFN = null;
for (FieldNode fn : clazz.fields) {
if (fn.name.equals(newName) && fn.desc.equals(newDesc)) {
JOptionPane.showMessageDialog(null, "Field already exists!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
if (fn.name.equals(name) && fn.desc.equals(desc)) {
currentFN = fn;
}
}
if (currentFN == null) {
JOptionPane.showMessageDialog(null, "Field not found?!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
currentFN.name = newName;
currentFN.desc = newDesc;
for (ClassNode cn : Main.classNodes.values()) {
for (MethodNode mn : cn.methods) {
for (AbstractInsnNode ain : mn.instructions.toArray()) {
if (ain instanceof FieldInsnNode) {
FieldInsnNode fin = (FieldInsnNode) ain;
if (fin.name.equals(name) && fin.desc.equals(desc) && fin.owner.equals(className)) {
fin.name = newName;
fin.desc = newDesc;
}
}
}
}
}
} else {
JOptionPane.showMessageDialog(null, "New Desc is not a field desc!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
}
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();
}
name = newName;
desc = newDesc;
}
});
btnRename.setBounds(345, 237, 89, 23);
contentPane.add(btnRename);
}
}
-3
View File
@@ -26,9 +26,6 @@ public class SearchBox extends JFrame {
public JTextField txtReplace; public JTextField txtReplace;
public JCheckBox chckbxCaseSensitive; public JCheckBox chckbxCaseSensitive;
/**
* Create the frame.
*/
public SearchBox() { public SearchBox() {
try { try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-3
View File
@@ -25,9 +25,6 @@ public class TypeOpenBox extends JFrame {
public JPanel contentPane; public JPanel contentPane;
public JTextField txtSearch; public JTextField txtSearch;
/**
* Create the frame.
*/
public TypeOpenBox() { public TypeOpenBox() {
try { try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-3
View File
@@ -19,9 +19,6 @@ public class UnicodeBox extends JFrame {
private JPanel contentPane; private JPanel contentPane;
/**
* Create the frame.
*/
public UnicodeBox() { public UnicodeBox() {
try { try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+5 -2
View File
@@ -70,7 +70,7 @@ public class Disassembler {
} }
public static DisassembleTuple disassemble(ClassNode classNode, MethodNode methodToFind) { public static DisassembleTuple disassemble(ClassNode classNode, Object nodeToFind) {
if (classNode == null) { if (classNode == null) {
return new DisassembleTuple("ClassNode is null! This is not a valid java class file!"); return new DisassembleTuple("ClassNode is null! This is not a valid java class file!");
} }
@@ -228,6 +228,9 @@ public class Disassembler {
s += "\n"; s += "\n";
} }
} }
if (fn.equals(nodeToFind)) {
lineFound = s.split("\\n").length;
}
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + UnicodeUtils.escapeWithSpaces(fn.desc) + " " s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + UnicodeUtils.escapeWithSpaces(fn.desc) + " "
+ UnicodeUtils.escapeWithSpaces(fn.name); + UnicodeUtils.escapeWithSpaces(fn.name);
if (fn.value != null) { if (fn.value != null) {
@@ -303,7 +306,7 @@ public class Disassembler {
s += "\n"; s += "\n";
} }
} }
if (mn.equals(methodToFind)) { if (mn.equals(nodeToFind)) {
lineFound = s.split("\\n").length; lineFound = s.split("\\n").length;
} }
s += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escapeWithSpaces(mn.name) + " " s += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escapeWithSpaces(mn.name) + " "
+109 -5
View File
@@ -30,6 +30,7 @@ import java.util.Map.Entry;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -67,9 +68,11 @@ import org.fife.ui.rtextarea.RTextScrollPane;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import me.ByteEdit.boxes.OptionBox; import me.ByteEdit.boxes.OptionBox;
import me.ByteEdit.boxes.RenameBox;
import me.ByteEdit.boxes.SearchBox; import me.ByteEdit.boxes.SearchBox;
import me.ByteEdit.boxes.TypeOpenBox; import me.ByteEdit.boxes.TypeOpenBox;
import me.ByteEdit.boxes.UnicodeBox; import me.ByteEdit.boxes.UnicodeBox;
@@ -94,6 +97,7 @@ public class Main extends JFrame {
public static TypeOpenBox typeOpenBox; public static TypeOpenBox typeOpenBox;
public static OptionBox optionBox; public static OptionBox optionBox;
public static UnicodeBox unicodeBox; public static UnicodeBox unicodeBox;
public static RenameBox renameBox;
public static JTree tree; public static JTree tree;
public static RTextScrollPane scrollPane_ByteEdit; public static RTextScrollPane scrollPane_ByteEdit;
public static Theme theme; public static Theme theme;
@@ -169,6 +173,7 @@ public class Main extends JFrame {
typeOpenBox = new TypeOpenBox(); typeOpenBox = new TypeOpenBox();
optionBox = new OptionBox(); optionBox = new OptionBox();
unicodeBox = new UnicodeBox(); unicodeBox = new UnicodeBox();
renameBox = new RenameBox();
setTitle("ByteEdit"); setTitle("ByteEdit");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 407), setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 407),
@@ -267,6 +272,13 @@ public class Main extends JFrame {
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); e1.printStackTrace();
} }
txtByteEditView.setText("");
currentNodeName = null;
searchBox.setVisible(false);
typeOpenBox.setVisible(false);
optionBox.setVisible(false);
unicodeBox.setVisible(false);
renameBox.setVisible(false);
isChangingFile = false; isChangingFile = false;
} }
dtde.dropComplete(true); dtde.dropComplete(true);
@@ -300,7 +312,7 @@ public class Main extends JFrame {
@Override @Override
public void keyReleased(KeyEvent e) { public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 116 && currentNodeName != null) { if (e.getKeyCode() == 116 && currentNodeName != null) { // F5
try { try {
ClassNode classNode = classNodes.get(currentNodeName); ClassNode classNode = classNodes.get(currentNodeName);
int prev = txtByteEditView.getCaretPosition(); int prev = txtByteEditView.getCaretPosition();
@@ -316,7 +328,9 @@ public class Main extends JFrame {
} }
txtByteEditView.setText(dis); txtByteEditView.setText(dis);
txtByteEditView.setCaretPosition(prev); txtByteEditView.setCaretPosition(prev);
} catch (Exception e2) {} } catch (Exception e2) {
e2.printStackTrace();
}
} }
} }
}); });
@@ -326,6 +340,7 @@ public class Main extends JFrame {
KeyStroke ctrlG = KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK); KeyStroke ctrlG = KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlO = KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK); KeyStroke ctrlO = KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlU = KeyStroke.getKeyStroke(KeyEvent.VK_U, KeyEvent.CTRL_DOWN_MASK); KeyStroke ctrlU = KeyStroke.getKeyStroke(KeyEvent.VK_U, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlR = KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
// global // global
txtByteEditView.registerKeyboardAction(new ActionListener() { txtByteEditView.registerKeyboardAction(new ActionListener() {
@@ -385,6 +400,17 @@ public class Main extends JFrame {
} }
} }
}, ctrlG, JComponent.WHEN_FOCUSED); }, ctrlG, JComponent.WHEN_FOCUSED);
txtByteEditView.registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
renameSelected();
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}, ctrlR, JComponent.WHEN_FOCUSED);
txtByteEditView.setEditable(true); txtByteEditView.setEditable(true);
txtByteEditView.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE); txtByteEditView.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE);
txtByteEditView.setCodeFoldingEnabled(true); txtByteEditView.setCodeFoldingEnabled(true);
@@ -445,6 +471,84 @@ public class Main extends JFrame {
return; return;
} }
selectFile(className + ".class"); selectFile(className + ".class");
} else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ") || line.startsWith("putfield ")) {
String[] split = line.split(" ");
String desc = UnicodeUtils.unescape(split[1]);
String className = UnicodeUtils.unescape(split[2]);
String[] nameSplit = className.split("/");
String fieldName = nameSplit[nameSplit.length - 1];
className = className.substring(0, className.length() - fieldName.length() - 1);
ClassNode classNode = classNodes.get(className + ".class");
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(classNode.outerClass + ".class");
}
int lineFound = selectFileWithSearch(classNode.name + ".class", fn);
if (lineFound != -1) {
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
}
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
.compile("^\t(?:[a-z]+ |0x[0-9a-fA-F]+ )*?([^ ]+) (\\((?:\\[*(?:V|Z|C|B|S|I|F|J|D|L.+?;))*\\)[^ ]+) .*\\{");
public void renameSelected() throws BadLocationException {
int lineStart = txtByteEditView.getLineStartOffsetOfCurrentLine();
int lineEnd = txtByteEditView.getLineEndOffsetOfCurrentLine() - 1;
String line = txtByteEditView.getText(lineStart, lineEnd - lineStart);
Matcher m = renameableFieldPattern.matcher(line);
if (m.find()) {
setRenameInfo(m, lineEnd);
} else {
m = renameableMethodPattern.matcher(line);
if (m.find()) {
if (ClassUtil.isObjectClassMethod(m.group(1), m.group(2), false)) {
JOptionPane.showMessageDialog(null, "This method can not be renamed!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
setRenameInfo(m, lineEnd);
}
}
}
public void setRenameInfo(Matcher m, int lineEnd) throws BadLocationException {
String[] arr = txtByteEditView.getText(0, lineEnd).split("\n");
int lastClassLine = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i].startsWith("// #Class")) {
lastClassLine = i;
}
}
while (lastClassLine < arr.length && arr[lastClassLine].startsWith("// ")) {
lastClassLine++;
}
if (lastClassLine < arr.length) {
String s = arr[lastClassLine];
s = s.substring(0, s.length() - 2);
if (s.contains(" implements "))
s = s.substring(0, s.lastIndexOf(" implements "));
if (s.contains(" extends "))
s = s.substring(0, s.lastIndexOf(" extends "));
String[] split = s.split(" ");
String className = UnicodeUtils.unescape(split[split.length - 1]);
renameBox.className = className;
String name = m.pattern() == renameableFieldPattern ? m.group(2) : m.group(1);
String desc = m.pattern() == renameableFieldPattern ? m.group(1) : m.group(2);
renameBox.name = name;
renameBox.desc = desc;
renameBox.txtName.setText(name);
renameBox.txtDesc.setText(desc);
renameBox.setVisible(true);
renameBox.txtName.requestFocusInWindow();
} }
} }
@@ -463,13 +567,13 @@ public class Main extends JFrame {
} }
} }
public static int selectFileWithSearch(String s, MethodNode methodToFind) { public static int selectFileWithSearch(String s, Object nodeToFind) {
if (s.endsWith(".class")) { if (s.endsWith(".class")) {
currentNodeName = s; currentNodeName = s;
int lineFound = -1; int lineFound = -1;
ClassNode classNode = classNodes.get(s); ClassNode classNode = classNodes.get(s);
String dis = ""; String dis = "";
DisassembleTuple tuple = Disassembler.disassemble(classNode, methodToFind); DisassembleTuple tuple = Disassembler.disassemble(classNode, nodeToFind);
if (tuple.getLine() != -1) { if (tuple.getLine() != -1) {
lineFound = dis.split("\\n").length + tuple.getLine() - 1; lineFound = dis.split("\\n").length + tuple.getLine() - 1;
} }
@@ -479,7 +583,7 @@ public class Main extends JFrame {
if (key.contains("$")) { if (key.contains("$")) {
String[] split = key.split("\\$"); String[] split = key.split("\\$");
if (split[0].equals(substr)) { if (split[0].equals(substr)) {
tuple = Disassembler.disassemble(classNodes.get(key), methodToFind); tuple = Disassembler.disassemble(classNodes.get(key), nodeToFind);
if (tuple.getLine() != -1) { if (tuple.getLine() != -1) {
lineFound = dis.split("\\n").length + tuple.getLine() + 1; lineFound = dis.split("\\n").length + tuple.getLine() + 1;
} }
+34
View File
@@ -26,6 +26,40 @@ public class ClassUtil {
public static final int ACC_ENUM = 0x4000; public static final int ACC_ENUM = 0x4000;
public static final int ACC_MANDATED = 0x8000; public static final int ACC_MANDATED = 0x8000;
public static boolean isObjectClassMethod(String name, String desc, boolean forbidInits) {
switch (name) {
case "<init>":
case "<clinit>":
if (forbidInits) {
return true;
}
case "notifyAll":
case "notify":
if (desc.equals("()V")) {
return true;
}
break;
case "wait":
if (desc.equals("()V") || desc.equals("(J)V") || desc.equals("(JI)V")) {
return true;
}
break;
case "equals":
if (desc.equals("(Ljava/lang/Object;)Z")) {
return true;
}
break;
case "hashCode":
if (desc.equals("()I")) {
return true;
}
break;
default:
break;
}
return false;
}
public static int getIDFromClassNameForType(String s) { public static int getIDFromClassNameForType(String s) {
s = s.toUpperCase(); s = s.toUpperCase();
switch (s) { switch (s) {