OSDN Git Service

save
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / util / JcfaWriteUtil.java
index b1dc0cf..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,44 +61,193 @@ public class JcfaWriteUtil {
                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");
        }
 }