import java.io.OutputStreamWriter;
import jp.igapyon.jcfa.vo.JcfaClass;
+import jp.igapyon.jcfa.vo.JcfaCode;
import jp.igapyon.jcfa.vo.JcfaComment;
import jp.igapyon.jcfa.vo.JcfaField;
import jp.igapyon.jcfa.vo.JcfaMethod;
+import jp.igapyon.jcfa.vo.JcfaOperandStackNode;
import jp.igapyon.jcfa.vo.JcfaUnit;
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.JavaClass;
+
public class JcfaWriteUtil {
public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
final StringBuffer result = new StringBuffer();
for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
- writeToBuffer(jcfaClass, result);
+ writeClass(jcfaClass, result);
}
final BufferedWriter writer = new BufferedWriter(
*
* @param jcfaClass
* @param result
+ * @throws IOException
*/
- public static void writeToBuffer(final JcfaClass jcfaClass,
- final StringBuffer result) {
+ public static void writeClass(final JcfaClass jcfaClass,
+ final StringBuffer result) throws IOException {
if (jcfaClass.isMainClass()) {
if (jcfaClass.getName().contains(".")) {
}
}
- writeToBuffer(jcfaClass.getComment(), result);
+ writeComment(jcfaClass.getComment(), result);
result.append(jcfaClass.getAccess());
result.append(" class " + jcfaClass.getLocalName());
result.append("{");
for (JcfaField jcfaField : jcfaClass.getFieldList()) {
- writeToBuffer(jcfaField, result);
+ writeField(jcfaField, result);
}
for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
- writeToBuffer(jcfaMethod, result);
+ writeMethod(jcfaClass, jcfaMethod, result);
}
result.append("}");
}
- public static void writeToBuffer(final JcfaField jcfaField,
+ /**
+ * Write field.
+ *
+ * @param jcfaField
+ * @param result
+ */
+ public static void writeField(final JcfaField jcfaField,
final StringBuffer result) {
- writeToBuffer(jcfaField.getComment(), result);
+ writeComment(jcfaField.getComment(), result);
- result.append(" " + jcfaField.getAccess() + " " + "String" + " "
- + jcfaField.getName());
+ result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
+ + " " + jcfaField.getName());
+ if (jcfaField.getConstantValue() != null) {
+ result.append(" = ");
+ result.append(jcfaField.getConstantValue());
+ }
result.append(";");
}
- public static void writeToBuffer(final JcfaMethod jcfaMethod,
- final StringBuffer result) {
+ /**
+ * Write method.
+ *
+ * @param jcfaClass
+ * @param jcfaMethod
+ * @param result
+ * @throws IOException
+ */
+ public static void writeMethod(final JcfaClass jcfaClass,
+ final JcfaMethod jcfaMethod, final StringBuffer result)
+ throws IOException {
+
+ writeComment(jcfaMethod.getComment(), result);
+
+ if (jcfaMethod.getName().equals("<init>")) {
+ result.append("public " + jcfaClass.getLocalName() + "(");
+ } else {
+ result.append("public " + jcfaMethod.getType() + " "
+ + jcfaMethod.getName() + "(");
+ }
+
+ int argNo = 0;
+ for (String argumentType : jcfaMethod.getArugumentTypeList()) {
+ if (argNo != 0) {
+ result.append(", ");
+ }
+ result.append(argumentType);
+ result.append(" arg" + argNo);
+ }
+
+ result.append(")");
- writeToBuffer(jcfaMethod.getComment(), result);
+ result.append("{");
+
+ writeCodes(jcfaClass, jcfaMethod, result);
+ result.append("}");
}
- public static void writeToBuffer(final JcfaComment jcfaComment,
+ public static void writeCodes(final JcfaClass jcfaClass,
+ final JcfaMethod jcfaMethod, final StringBuffer result)
+ throws IOException {
+ for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
+ final byte[] codes = jcfaCode.getCodes();
+ final JavaClass jc = jcfaCode.getJavaClass();
+
+ switch (jcfaCode.getOpcode()) {
+ case Constants.ALOAD_0: {
+ jcfaCode.getComment()
+ .getCommentList()
+ .add(jcfaMethod.getFrame().getLocalVariableList()
+ .get(0).getName());
+ final JcfaOperandStackNode operandStackNode = new JcfaOperandStackNode();
+ jcfaMethod.getFrame().getOperandStack().push(operandStackNode);
+ operandStackNode.setName(jcfaMethod.getFrame()
+ .getLocalVariableList().get(0).getName());
+ break;
+ }
+ case Constants.RETURN: {
+ break;
+ }
+ case Constants.GETSTATIC: {
+ jcfaCode.getComment()
+ .getCommentList()
+ .add(JcfaUtil.getConstantFieldrefString(jc, codes[1],
+ codes[2]));
+ break;
+ }
+ case Constants.LDC: {
+ jcfaCode.getComment().getCommentList()
+ .add(JcfaUtil.getConstantString(jc, codes[1]));
+ }
+ break;
+ case Constants.INVOKEVIRTUAL:
+ case Constants.INVOKESPECIAL: {
+ final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
+ codes[2]);
+ jcfaCode.getComment().getCommentList()
+ .add(JcfaUtil.getConstantMethodRefString(jc, operand));
+ }
+ break;
+ case Constants.LOOKUPSWITCH:
+ if (true) {
+ jcfaCode.getComment().getCommentList()
+ .add(" TODO temporary disabled.");
+ break;
+ }
+ int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
+ codes[4]);
+
+ jcfaCode.getComment().getCommentList()
+ .add(" TODO skipping bytes: " + (skipBytes));
+
+ int lookupOp = 5;
+
+ short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
+ jcfaCode.getComment().getCommentList()
+ .add(" TODO skipping bytes: " + (diff));
+
+ int loopCount = JcfaUtil
+ .byte2Int(codes[lookupOp++], codes[lookupOp++],
+ codes[lookupOp++], codes[lookupOp++]);
+ for (int index = 0; index < loopCount; index++) {
+ jcfaCode.getComment()
+ .getCommentList()
+ .add(JcfaUtil.byte2Int(codes[lookupOp++],
+ codes[lookupOp++], codes[lookupOp++],
+ codes[lookupOp++])
+ + ":"
+ + (JcfaUtil.byte2Int(codes[lookupOp++],
+ codes[lookupOp++],
+ codes[lookupOp++],
+ codes[lookupOp++])));
+ }
+
+ short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
+ jcfaCode.getComment().getCommentList()
+ .add(" TODO skipping bytes: " + (diff2));
+
+ break;
+ default:
+ jcfaCode.getComment().getCommentList()
+ .add("TODO unsupported opcode");
+ break;
+ }
+
+ writeComment(jcfaCode.getComment(), result);
+
+ // TODO and code...
+ }
+ }
+
+ /**
+ * Write comment.
+ *
+ * @param jcfaComment
+ * @param result
+ */
+ public static void writeComment(final JcfaComment jcfaComment,
final StringBuffer result) {
if (jcfaComment.isJavaDoc()) {
- result.append("/** ");
+ result.append("\n/** ");
} else {
- result.append("/* ");
+ result.append("\n/* ");
+ }
+
+ if (jcfaComment.getCommentList().size() > 1) {
+ result.append("\n");
}
for (String comment : jcfaComment.getCommentList()) {
- result.append(" " + comment + " ");
+ if (jcfaComment.getCommentList().size() > 1) {
+ result.append(" * " + comment + "\n");
+ } else {
+ result.append(comment);
+ }
}
- result.append(" */");
+ result.append(" */\n");
}
}