OSDN Git Service

save
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / util / JcfaWriteUtil.java
index 0917c22..ae20921 100644 (file)
@@ -6,17 +6,22 @@ import java.io.IOException;
 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(
@@ -31,9 +36,10 @@ public class JcfaWriteUtil {
         * 
         * @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(".")) {
@@ -43,7 +49,7 @@ public class JcfaWriteUtil {
                        }
                }
 
-               writeToBuffer(jcfaClass.getComment(), result);
+               writeComment(jcfaClass.getComment(), result);
 
                result.append(jcfaClass.getAccess());
                result.append(" class " + jcfaClass.getLocalName());
@@ -55,11 +61,11 @@ public class JcfaWriteUtil {
                result.append("{");
 
                for (JcfaField jcfaField : jcfaClass.getFieldList()) {
-                       writeToBuffer(jcfaField, result);
+                       writeField(jcfaField, result);
                }
 
                for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
-                       writeToBuffer(jcfaClass, jcfaMethod, result);
+                       writeMethod(jcfaClass, jcfaMethod, result);
                }
 
                result.append("}");
@@ -71,9 +77,9 @@ public class JcfaWriteUtil {
         * @param jcfaField
         * @param result
         */
-       public static void writeToBuffer(final JcfaField jcfaField,
+       public static void writeField(final JcfaField jcfaField,
                        final StringBuffer result) {
-               writeToBuffer(jcfaField.getComment(), result);
+               writeComment(jcfaField.getComment(), result);
 
                result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
                                + " " + jcfaField.getName());
@@ -90,29 +96,139 @@ public class JcfaWriteUtil {
         * @param jcfaClass
         * @param jcfaMethod
         * @param result
+        * @throws IOException
         */
-       public static void writeToBuffer(final JcfaClass jcfaClass,
-                       final JcfaMethod jcfaMethod, final StringBuffer result) {
+       public static void writeMethod(final JcfaClass jcfaClass,
+                       final JcfaMethod jcfaMethod, final StringBuffer result)
+                       throws IOException {
 
-               writeToBuffer(jcfaMethod.getComment(), result);
+               writeComment(jcfaMethod.getComment(), result);
 
                if (jcfaMethod.getName().equals("<init>")) {
-                       result.append("public " + jcfaClass.getLocalName() + "() {");
+                       result.append("public " + jcfaClass.getLocalName() + "(");
                } else {
                        result.append("public " + jcfaMethod.getType() + " "
-                                       + jcfaMethod.getName() + "() {");
+                                       + jcfaMethod.getName() + "(");
+               }
+
+               int argNo = 0;
+               for (String argumentType : jcfaMethod.getArugumentTypeList()) {
+                       if (argNo != 0) {
+                               result.append(", ");
+                       }
+                       result.append(argumentType);
+                       result.append(" arg" + argNo);
                }
 
+               result.append(")");
+
+               result.append("{");
+
+               writeCodes(jcfaClass, jcfaMethod, result);
+
                result.append("}");
        }
 
+       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 writeToBuffer(final JcfaComment jcfaComment,
+       public static void writeComment(final JcfaComment jcfaComment,
                        final StringBuffer result) {
                if (jcfaComment.isJavaDoc()) {
                        result.append("\n/** ");