package org.apache.bcel.util;
import org.apache.bcel.classfile.LocalVariable;
import org.apache.bcel.classfile.InnerClass;
import org.apache.bcel.classfile.LineNumber;
import org.apache.bcel.classfile.CodeException;
import org.apache.bcel.classfile.InnerClasses;
import org.apache.bcel.classfile.Utility;
import org.apache.bcel.classfile.LocalVariableTable;
import org.apache.bcel.classfile.LineNumberTable;
import org.apache.bcel.classfile.ExceptionTable;
import org.apache.bcel.classfile.SourceFile;
import org.apache.bcel.classfile.ConstantValue;
import org.apache.bcel.classfile.Code;
import org.apache.bcel.Const;
import org.apache.bcel.classfile.Attribute;
import java.io.UnsupportedEncodingException;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import org.apache.bcel.classfile.ConstantPool;
import java.io.PrintWriter;
import java.io.Closeable;
final class AttributeHTML implements Closeable
{
private final String className;
private final PrintWriter printWriter;
private int attrCount;
private final ConstantHTML constantHtml;
private final ConstantPool constantPool;
AttributeHTML(final String dir, final String className, final ConstantPool constantPool, final ConstantHTML constantHtml, final Charset charset) throws FileNotFoundException, UnsupportedEncodingException {
this.className = className;
this.constantPool = constantPool;
this.constantHtml = constantHtml;
(this.printWriter = new PrintWriter(dir + className + "_attributes.html", charset.name())).print("
");
this.printWriter.println("");
}
@Override
public void close() {
this.printWriter.println("
");
this.printWriter.close();
}
private String codeLink(final int link, final int methodNumber) {
return "" + link + "";
}
void writeAttribute(final Attribute attribute, final String anchor) {
this.writeAttribute(attribute, anchor, 0);
}
void writeAttribute(final Attribute attribute, final String anchor, final int methodNumber) {
final byte tag = attribute.getTag();
if (tag == -1) {
return;
}
++this.attrCount;
if (this.attrCount % 2 == 0) {
this.printWriter.print("");
}
else {
this.printWriter.print(" |
");
}
this.printWriter.println("");
switch (tag) {
case 2: {
final Code c = (Code)attribute;
this.printWriter.print("- Maximum stack size = " + c.getMaxStack() + "
\n- Number of local variables = " + c.getMaxLocals() + "
\n- Byte code
\n");
final CodeException[] ce = c.getExceptionTable();
final int len = ce.length;
if (len > 0) {
this.printWriter.print("Exceptions handled ");
for (final CodeException cex : ce) {
final int catchType = cex.getCatchType();
this.printWriter.print("- ");
if (catchType != 0) {
this.printWriter.print(this.constantHtml.referenceConstant(catchType));
}
else {
this.printWriter.print("Any Exception");
}
this.printWriter.print("
(Ranging from lines " + this.codeLink(cex.getStartPC(), methodNumber) + " to " + this.codeLink(cex.getEndPC(), methodNumber) + ", handled at line " + this.codeLink(cex.getHandlerPC(), methodNumber) + ") ");
}
this.printWriter.print(" ");
break;
}
break;
}
case 1: {
final int index = ((ConstantValue)attribute).getConstantValueIndex();
this.printWriter.print("\n");
break;
}
case 0: {
final int index = ((SourceFile)attribute).getSourceFileIndex();
this.printWriter.print("\n");
break;
}
case 3: {
final int[] indices = ((ExceptionTable)attribute).getExceptionIndexTable();
this.printWriter.print("\n");
break;
}
case 4: {
final LineNumber[] lineNumbers = ((LineNumberTable)attribute).getLineNumberTable();
this.printWriter.print("");
for (int i = 0; i < lineNumbers.length; ++i) {
this.printWriter.print("(" + lineNumbers[i].getStartPC() + ", " + lineNumbers[i].getLineNumber() + ")");
if (i < lineNumbers.length - 1) {
this.printWriter.print(", ");
}
}
break;
}
case 5: {
this.printWriter.print(" ");
((LocalVariableTable)attribute).forEach(var -> {
final int sigIdx = var.getSignatureIndex();
final String signature = this.constantPool.getConstantUtf8(sigIdx).getBytes();
final String signature2 = Utility.signatureToString(signature, false);
final int start = var.getStartPC();
final int end = start + var.getLength();
this.printWriter.println("- " + Class2HTML.referenceType(signature2) + " " + var.getName() + " in slot %" + var.getIndex() + "
Valid from lines " + start + " to " + end + " ");
return;
});
this.printWriter.print(" \n");
break;
}
case 6: {
this.printWriter.print("");
for (final InnerClass clazz : ((InnerClasses)attribute).getInnerClasses()) {
final int index = clazz.getInnerNameIndex();
String name;
if (index > 0) {
name = this.constantPool.getConstantUtf8(index).getBytes();
}
else {
name = "<anonymous>";
}
final String access = Utility.accessToString(clazz.getInnerAccessFlags());
this.printWriter.print("- " + access + " " + this.constantHtml.referenceConstant(clazz.getInnerClassIndex()) + " in class " + this.constantHtml.referenceConstant(clazz.getOuterClassIndex()) + " named " + name + "
\n");
}
this.printWriter.print(" \n");
break;
}
default: {
this.printWriter.print("" + attribute);
break;
}
}
this.printWriter.println(" |
");
this.printWriter.flush();
}
}