📄 sourcecodebuilder.java
字号:
private String toString(Attribute var) {
switch (var.attribute_tag) {
case Constants.ATTRIBUTE_SourceFile:
return toString((Attribute_SourceFile) var);
case Constants.ATTRIBUTE_ConstantValue:
return toString((Attribute_ConstantValue) var);
case Constants.ATTRIBUTE_Code:
return toString((Attribute_Code) var);
case Constants.ATTRIBUTE_Exceptions:
return toString((Attribute_Exceptions) var);
case Constants.ATTRIBUTE_InnerClasses:
return toString((Attribute_InnerClasses) var);
case Constants.ATTRIBUTE_Synthetic:
return toString((Attribute_Synthetic) var);
case Constants.ATTRIBUTE_LineNumberTable:
return toString((Attribute_LineNumberTable) var);
case Constants.ATTRIBUTE_LocalVariableTable:
return toString((Attribute_LocalVariableTable) var);
case Constants.ATTRIBUTE_Deprecated:
return toString((Attribute_Deprecated) var);
default: {
StringBuffer buf = new StringBuffer();
if (var.attribute_name == null) {
// this is an unknow attribute
buf.append(toString(cpl.getConstant(var.attribute_name_index)));
} else {
buf.append(var.attribute_name);
}
if (var.attrInfo != null) {
buf.append(" = " + new String(var.attrInfo));
}
return buf.toString();
}
}
}
private String toString(Constant_Float var) {
return Float.toString(var.value) + "F";
}
private String toString(Constant_Long var) {
return Long.toString(var.value) + "L";
}
private String toString(Constant_Double var) {
return Double.toString(var.value) + "D";
}
private String toString(Constant_Utf8 var) {
return var.bytes;
}
private String toString(ConstantPoolItem var) {
switch (var.tag) {
case Constants.CONSTANT_Utf8:
return toString((Constant_Utf8) var);
case Constants.CONSTANT_Integer:
return toString((Constant_Integer) var);
case Constants.CONSTANT_Float:
return toString((Constant_Float) var);
case Constants.CONSTANT_Long:
return toString((Constant_Long) var);
case Constants.CONSTANT_Double:
return toString((Constant_Double) var);
case Constants.CONSTANT_Class:
return toString((Constant_Class) var);
case Constants.CONSTANT_Fieldref:
return toString((Constant_Fieldref) var);
case Constants.CONSTANT_String:
return toString((Constant_String) var);
case Constants.CONSTANT_Methodref:
return toString((Constant_Methodref) var);
case Constants.CONSTANT_InterfaceMethodref:
return toString((Constant_InterfaceMethodref) var);
case Constants.CONSTANT_NameAndType:
return toString((Constant_NameAndType) var);
default:
return var.tagName;
}
}
private String toString(Constant_Integer var) {
return Integer.toString(var.value);
}
private String toString(Constant_Class var) {
return Util.constantClassToString(toString((Constant_Utf8) cpl.getConstant(var.name_index)));
}
private String toString(Constant_Fieldref var) {
String name, type, temp = toString(cpl.getConstant(var.name_and_type_index));
int i = temp.indexOf(" ");
name = temp.substring(0, i);
type = temp.substring(i + 1);
type = Util.descriptorToString(type);
return type + " " + toString(cpl.getConstant(var.class_index)) + "." + name;
}
private String toString(Constant_InterfaceMethodref var) {
String name, retType, para, temp = toString(cpl.getConstant(var.name_and_type_index));
int i = temp.indexOf(" ");
name = temp.substring(0, i);
i = temp.indexOf((char) ')');
para = temp.substring(temp.indexOf((char) '(') + 1, i);
retType = temp.substring(i + 1, temp.length());
para = Util.methodParameterToString(para);
retType = Util.descriptorToString(retType);
return retType + " " + toString(cpl.getConstant(var.class_index)) + "." + name + "(" + para + ")";
}
private String toString(Constant_Methodref var) {
String name, retType, para = null, temp = toString(cpl.getConstant(var.name_and_type_index));
int i = temp.indexOf(" ");
name = temp.substring(0, i);
i = temp.indexOf((char) ')');
para = temp.substring(temp.indexOf((char) '(') + 1, i);
retType = temp.substring(i + 1, temp.length());
para = Util.methodParameterToString(para);
retType = Util.descriptorToString(retType);
return retType + " " + toString(cpl.getConstant(var.class_index)) + "." + name + "(" + para + ")";
}
private String toString(Constant_NameAndType var) {
return toString(cpl.getConstant(var.name_index)) + " " + toString(cpl.getConstant(var.descriptor_index));
}
private String toString(Constant_String var) {
return Util.toViewableString(toString(cpl.getConstant(var.string_index)));
}
public String toString(JavaClass clazz) {
StringBuffer buf = new StringBuffer();
this.cpl = clazz.constantPool;
if (config.showVersion == true) {
// Minor and Major version of the class
buf.append("[Major : " + Integer.toString(clazz.major_version) + "]");
buf.append(Constants.LINE_SEPARATER);
buf.append("[Minor : " + Integer.toString(clazz.minor_version) + "]");
buf.append(Constants.LINE_SEPARATER);
}
// class access flag + class name
buf.append(Util.accessFlagToString_Class(clazz.access_flags) + " " + toString(cpl.getConstant(clazz.this_class)));
// super classes
if (clazz.super_class != 0) {
// java.lang.Object dose not hava super class
buf.append(" extends " + toString(cpl.getConstant(clazz.super_class)));
}
// implemented interfaces
if (clazz.interfaces_count != 0) {
buf.append(" implements ");
for (int i = 0; i < clazz.interfaces_count; i++) {
buf.append(toString(cpl.getConstant(clazz.interfaces[i])) + ",");
}
buf.deleteCharAt(buf.length() - 1);
}
buf.append("{");
// fields
if (clazz.fields_count != 0) {
for (int i = 0; i < clazz.fields_count; i++) {
buf.append(Constants.LINE_SEPARATER);
buf.append(toString(clazz.fields[i]));
}
}
// methods
if (clazz.methods_count != 0) {
for (int i = 0; i < clazz.methods_count; i++) {
buf.append(Constants.LINE_SEPARATER);
buf.append(toString(clazz.methods[i]));
}
}
// attributes of this class
if (clazz.attributes_count != 0) {
buf.append(Constants.LINE_SEPARATER);
for (int i = 0; i < clazz.attributes_count; i++) {
buf.append(Constants.LINE_SEPARATER);
String tx = toString(clazz.attributes[i]);
buf.append(tx);
}
}
buf.append(Constants.LINE_SEPARATER);
buf.append("}");
return buf.toString();
}
private String toString(Field field) {
StringBuffer buf = new StringBuffer();
// access flag
buf.append(Util.accessFlagToString_Field((short) field.access_flags) + " ");
// field descriptor
buf.append(Util.descriptorToString(toString(cpl.getConstant(field.descriptor_index))) + " ");
// field name
buf.append(toString(cpl.getConstant(field.name_index)));
// constant value
if (field.attributes_count != 0) {
for (int i = 0; i < field.attributes_count; i++) {
if (field.attributes[i] instanceof Attribute_ConstantValue) {
buf.append(" = ");
buf.append(toString(field.attributes[i]));
}
}
}
// deprecated or synthetic attribute
if (field.attributes_count != 0) {
for (int i = 0; i < field.attributes_count; i++) {
if ((field.attributes[i] instanceof Attribute_ConstantValue) == false) {
buf.append('\t');
buf.append(toString(field.attributes[i]));
}
}
}
return buf.toString().trim();
}
private String toString(Method method) {
StringBuffer buf = new StringBuffer();
// method access flag
buf.append(Util.accessFlagToString_Method((short) method.access_flags) + " ");
// method parameter and return type
String retType, paras, temp = toString(cpl.getConstant(method.descriptor_index));
int ti = temp.indexOf(")");
paras = Util.methodParameterToString(temp.substring(1, ti));
retType = Util.descriptorToString(temp.substring(ti + 1));
// return type
buf.append(retType + " ");
// method name
buf.append(toString(cpl.getConstant(method.name_index)) + " ");
// method para
buf.append("(" + paras + ")");
// exception
if (method.attributes_count != 0) {
for (int i = 0; i < method.attributes_count; i++) {
if (method.attributes[i].attribute_tag == Constants.ATTRIBUTE_Exceptions) {
buf.append(" throws ");
buf.append(toString(method.attributes[i]));
}
}
}
buf.append("{");
// code
if (method.attributes_count != 0) {
for (int i = 0; i < method.attributes_count; i++) {
if (method.attributes[i].attribute_tag == Constants.ATTRIBUTE_Code) {
buf.append(Constants.LINE_SEPARATER);
buf.append(toString((Attribute_Code) method.attributes[i], calculateReferences(method)));
}
}
}
if (method.attributes_count != 0) {
for (int i = 0; i < method.attributes_count; i++) {
if (method.attributes[i].attribute_tag != Constants.ATTRIBUTE_Code
&& method.attributes[i].attribute_tag != Constants.ATTRIBUTE_Exceptions) {
buf.append(Constants.LINE_SEPARATER);
buf.append(toString(method.attributes[i]));
}
}
}
buf.append(Constants.LINE_SEPARATER);
buf.append("}");
return buf.toString();
}
/**
* generate a set containing all the line numbers which are refered inside
* the method.
*
* @param meth
* @return
*/
private HashSet calculateReferences(Method meth) {
HashSet set = new HashSet();
Attribute att;
Attribute_Code.Opcode[] ops = null;
Attribute_Code.Opcode op;
for (int i = 0; i < meth.attributes_count; i++) {
if (meth.attributes[i].attribute_tag == Constants.ATTRIBUTE_Code) {
ops = ((Attribute_Code) meth.attributes[i]).codes;
break;
}
}
if (ops == null) {
return set;
}
for (int i = 0; i < meth.attributes_count; i++) {
att = meth.attributes[i];
if (att.attribute_tag == Constants.ATTRIBUTE_Code) {
Attribute_Code code = (Attribute_Code) att;
for (int j = 0; j < ops.length; j++) {
op = ops[j];
switch (op.opcode) {
case Constants.LOOKUPSWITCH:
set.add(Integer.toString(Util.getSignedNum(op.operands[1]) + op.offset)); //default
for (int t = 4; t < op.operands.length; t++) {
set.add(Integer.toString(Util.getSignedNum(op.operands[t++]) + op.offset));
}
break;
case Constants.TABLESWITCH:
set.add(Integer.toString(Util.getSignedNum(op.operands[1]) + op.offset)); //default
for (int t = 4; t < op.operands.length; t++) {
set.add(Integer.toString(Util.getSignedNum(op.operands[t]) + op.offset));
}
break;
case Constants.GOTO:
case Constants.IFEQ:
case Constants.IFGE:
case Constants.IFGT:
case Constants.IFLE:
case Constants.IFLT:
case Constants.JSR:
case Constants.IFNE:
case Constants.IFNONNULL:
case Constants.IFNULL:
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
case Constants.IF_ICMPEQ:
case Constants.IF_ICMPGE:
case Constants.IF_ICMPGT:
case Constants.IF_ICMPLE:
case Constants.IF_ICMPLT:
case Constants.IF_ICMPNE:
case Constants.GOTO_W:
case Constants.JSR_W:
set.add(Integer.toString(Util.getSignedNum(op.operands[0]) + op.offset));
break;
}
}
if (code.exception_table_length != 0) {
Attribute_Code.ExceptionTableItem[] exceptions = code.exception_table;
Attribute_Code.ExceptionTableItem exc;
for (int j = 0; j < exceptions.length; j++) {
exc = exceptions[j];
set.add(Integer.toString(exc.start_pc));
set.add(Integer.toString(exc.end_pc));
set.add(Integer.toString(exc.handler_pc));
}
}
if (code.attributes_count != 0) {
for (int j = 0; j < code.attributes_count; j++) {
if (code.attributes[j].attribute_tag == Constants.ATTRIBUTE_LineNumberTable && config.showLineNumber == true) {
Attribute_LineNumberTable lineNumberTable = (Attribute_LineNumberTable) code.attributes[j];
Attribute_LineNumberTable.LineNumber[] lines = lineNumberTable.lineNumberTable;
for (int x = 0; x < lineNumberTable.line_number_table_length; x++) {
set.add(Integer.toString(lines[x].start_pc));
}
} else if (code.attributes[j].attribute_tag == Constants.ATTRIBUTE_LocalVariableTable) {
Attribute_LocalVariableTable lvt = (Attribute_LocalVariableTable) code.attributes[j];
if (lvt.local_variable_table_length != 0) {
Attribute_LocalVariableTable.LocalVariable[] lvs = lvt.local_variable_table;
Attribute_LocalVariableTable.LocalVariable lv;
for (int x = 0; x < lvs.length; x++) {
lv = lvs[x];
set.add(Integer.toString(lv.start_pc));
if (lv.length != 1) {
op = findPreviousInstruction(lv.start_pc + lv.length, ops);
if (op != null) {
set.add(Integer.toString(op.offset));
}
}
}
}
}
}
}
break;
}
}
return set;
}
/**
* given an offset, and a series of instructions, find the first instruction
* that is before the given offset
*
* @param offset
* @param ops
* @return
*/
private Attribute_Code.Opcode findPreviousInstruction(int offset, Attribute_Code.Opcode[] ops) {
for (int i = ops.length - 1; i > -1; i--) {
if (ops[i].offset < offset) {
return ops[i];
}
}
return null;
}
public static String toString_Static(JavaClass clazz) {
SourceCodeBuilder builder = new SourceCodeBuilder();
return builder.toString(clazz);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -