OSDN Git Service

save
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / JavaClassFileAnalyzer.java
index 1ae2884..d5c9c11 100644 (file)
@@ -1,11 +1,13 @@
 package jp.igapyon.jcfa;\r
 \r
+import java.io.ByteArrayOutputStream;\r
 import java.io.File;\r
 import java.io.IOException;\r
 \r
 import jp.igapyon.jcfa.util.JcfaUtil;\r
 import jp.igapyon.jcfa.util.JcfaWriteUtil;\r
 import jp.igapyon.jcfa.vo.JcfaClass;\r
+import jp.igapyon.jcfa.vo.JcfaCode;\r
 import jp.igapyon.jcfa.vo.JcfaField;\r
 import jp.igapyon.jcfa.vo.JcfaMethod;\r
 import jp.igapyon.jcfa.vo.JcfaUnit;\r
@@ -25,6 +27,8 @@ public class JavaClassFileAnalyzer {
 \r
        public static final void main(final String[] args) {\r
                new JavaClassFileAnalyzer().parseDir(new File("./bin/test"));\r
+               new JavaClassFileAnalyzer().parseDir(new File(\r
+                               "./bin/jp/igapyon/jcfa/vo"));\r
        }\r
 \r
        private void parseDir(final File dir) {\r
@@ -46,6 +50,10 @@ public class JavaClassFileAnalyzer {
        }\r
 \r
        private final void process(final File inputFile, final File outputDir) {\r
+               parseUnit(inputFile, outputDir);\r
+       }\r
+\r
+       private void parseUnit(final File inputFile, final File outputDir) {\r
                try {\r
                        final JavaClass jc = new ClassParser(inputFile.getCanonicalPath())\r
                                        .parse();\r
@@ -63,13 +71,13 @@ public class JavaClassFileAnalyzer {
                        File actualyTargetDir = outputDir;\r
                        if (split.length > 1) {\r
                                for (int index = 0; index < split.length - 1; index++) {\r
-                                       actualyTargetDir = new File(outputDir, split[index]);\r
+                                       actualyTargetDir = new File(actualyTargetDir, split[index]);\r
                                        actualyTargetDir.mkdirs();\r
                                }\r
                        }\r
 \r
-                       analyzeFields(jc, jcfaClass);\r
-                       analyzeMethods(jc, jcfaClass);\r
+                       parseFields(jc, jcfaClass);\r
+                       parseMethods(jc, jcfaClass);\r
 \r
                        jcfaUnit.setTargetFile(new File(actualyTargetDir,\r
                                        split[split.length - 1] + ".jcfa"));\r
@@ -82,15 +90,15 @@ public class JavaClassFileAnalyzer {
                }\r
        }\r
 \r
-       private void analyzeFields(final JavaClass jc, final JcfaClass jcfaClass) {\r
+       private void parseFields(final JavaClass jc, final JcfaClass jcfaClass) {\r
                final org.apache.bcel.classfile.Field[] fields = jc.getFields();\r
                for (int indexField = 0; indexField < fields.length; indexField++) {\r
                        final Field field = fields[indexField];\r
-                       analyzeField(jc, field, jcfaClass);\r
+                       parseField(jc, field, jcfaClass);\r
                }\r
        }\r
 \r
-       private void analyzeField(final JavaClass jc, final Field field,\r
+       private void parseField(final JavaClass jc, final Field field,\r
                        final JcfaClass jcfaClass) {\r
                final JcfaField jcfaField = new JcfaField();\r
                jcfaField.setName(field.getName());\r
@@ -125,12 +133,12 @@ public class JavaClassFileAnalyzer {
                }\r
        }\r
 \r
-       private void analyzeMethods(final JavaClass jc, final JcfaClass jcfaClass)\r
+       private void parseMethods(final JavaClass jc, final JcfaClass jcfaClass)\r
                        throws IOException {\r
                final org.apache.bcel.classfile.Method[] methods = jc.getMethods();\r
                for (int indexMethod = 0; indexMethod < methods.length; indexMethod++) {\r
                        final Method method = methods[indexMethod];\r
-                       analyzeMethod(jc, method, jcfaClass);\r
+                       parseMethod(jc, method, jcfaClass);\r
 \r
                }\r
        }\r
@@ -143,7 +151,7 @@ public class JavaClassFileAnalyzer {
         * @param jcfaClass\r
         * @throws IOException\r
         */\r
-       private void analyzeMethod(final JavaClass jc, final Method method,\r
+       private void parseMethod(final JavaClass jc, final Method method,\r
                        final JcfaClass jcfaClass) throws IOException {\r
                final JcfaMethod jcfaMethod = new JcfaMethod();\r
                jcfaClass.getMethodList().add(jcfaMethod);\r
@@ -159,8 +167,9 @@ public class JavaClassFileAnalyzer {
 \r
                for (Type type : method.getArgumentTypes()) {\r
                        jcfaMethod.getComment().getCommentList().add(type.toString());\r
+                       jcfaMethod.getArugumentTypeList().add(type.toString());\r
                }\r
-               jcfaMethod.setType(method.getReturnType().getSignature());\r
+               jcfaMethod.setType(method.getReturnType().toString());\r
 \r
                final Code code = method.getCode();\r
                if (code == null) {\r
@@ -169,83 +178,79 @@ public class JavaClassFileAnalyzer {
 \r
                final byte[] codes = code.getCode();\r
                for (int pc = 0; pc < codes.length; pc++) {\r
-                       final short opcode = JcfaUtil.byte2UnsignedByte(codes[pc]);\r
-                       short operands = Constants.NO_OF_OPERANDS[opcode];\r
+                       final int operands = parseCodes(jc, method, jcfaClass, jcfaMethod,\r
+                                       pc, codes);\r
                        if (operands < 0) {\r
-                               System.err.println("  TODO negative value:"\r
-                                               + Constants.OPCODE_NAMES[opcode] + ": " + operands);\r
-                               // break;\r
-                       }\r
-\r
-                       switch (opcode) {\r
-                       case Constants.RETURN: {\r
-                               System.out.println("    " + pc + ": "\r
-                                               + Constants.OPCODE_NAMES[opcode]);\r
-                               break;\r
-                       }\r
-                       case Constants.GETSTATIC: {\r
-                               System.out.println("    "\r
-                                               + pc\r
-                                               + ": "\r
-                                               + Constants.OPCODE_NAMES[opcode]\r
-                                               + ": "\r
-                                               + JcfaUtil.getConstantFieldrefString(jc, codes[pc + 1],\r
-                                                               codes[pc + 2]));\r
                                break;\r
                        }\r
-                       case Constants.LDC: {\r
-                               System.out.println("    " + pc + ": "\r
-                                               + Constants.OPCODE_NAMES[opcode] + ": "\r
-                                               + JcfaUtil.getConstantString(jc, codes[pc + 1]));\r
-                       }\r
-                               break;\r
-                       case Constants.INVOKEVIRTUAL:\r
-                       case Constants.INVOKESPECIAL: {\r
-                               final int operand = JcfaUtil.byte2UnsignedShort(codes[pc + 1],\r
-                                               codes[pc + 2]);\r
-                               System.out.println("    " + pc + ": "\r
-                                               + Constants.OPCODE_NAMES[opcode] + ": "\r
-                                               + JcfaUtil.getConstantMethodRefString(jc, operand));\r
-                       }\r
-                               break;\r
-                       case Constants.LOOKUPSWITCH:\r
-                               int result = JcfaUtil.byte2Int(codes[pc + 1], codes[pc + 2],\r
-                                               codes[pc + 3], codes[pc + 4]);\r
-                               System.out.println("  TODO skipping bytes: " + (result));\r
-\r
-                               int lookupOp = pc + 5;\r
-\r
-                               short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
-                               System.out.println("  TODO skipping bytes: " + (diff));\r
-\r
-                               int loopCount = JcfaUtil\r
-                                               .byte2Int(codes[lookupOp++], codes[lookupOp++],\r
-                                                               codes[lookupOp++], codes[lookupOp++]);\r
-                               for (int index = 0; index < loopCount; index++) {\r
-                                       System.out.println("      "\r
-                                                       + JcfaUtil.byte2Int(codes[lookupOp++],\r
-                                                                       codes[lookupOp++], codes[lookupOp++],\r
-                                                                       codes[lookupOp++])\r
-                                                       + ":"\r
-                                                       + (JcfaUtil.byte2Int(codes[lookupOp++],\r
-                                                                       codes[lookupOp++], codes[lookupOp++],\r
-                                                                       codes[lookupOp++]) + pc));\r
-                               }\r
 \r
-                               short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
-                               System.out.println("  TODO skipping bytes: " + (diff2));\r
+                       pc += operands;\r
+               }\r
+       }\r
+\r
+       private int parseCodes(final JavaClass jc, final Method method,\r
+                       final JcfaClass jcfaClass, final JcfaMethod jcfaMethod,\r
+                       final int pc, final byte[] codes) throws IOException {\r
+               final JcfaCode jcfaCode = new JcfaCode();\r
+               jcfaMethod.getCodeList().add(jcfaCode);\r
+               jcfaCode.setJavaClass(jc);\r
+\r
+               jcfaCode.setOpcode(JcfaUtil.byte2UnsignedByte(codes[pc]));\r
+               jcfaCode.getComment()\r
+                               .getCommentList()\r
+                               .add("" + pc + ": "\r
+                                               + Constants.OPCODE_NAMES[jcfaCode.getOpcode()]);\r
+\r
+               short operands = Constants.NO_OF_OPERANDS[jcfaCode.getOpcode()];\r
+               if (operands < 0) {\r
+                       jcfaCode.getComment()\r
+                                       .getCommentList()\r
+                                       .add("FIXME NO_OF_OPERANDS has negative value:"\r
+                                                       + Constants.OPCODE_NAMES[jcfaCode.getOpcode()]\r
+                                                       + ": " + operands);\r
+                       return operands;\r
+               }\r
 \r
-                               operands += (lookupOp - pc);\r
+               switch (jcfaCode.getOpcode()) {\r
+               case Constants.RETURN:\r
+                       break;\r
+               case Constants.GETSTATIC:\r
+                       break;\r
+               case Constants.LDC:\r
+                       break;\r
+               case Constants.INVOKEVIRTUAL:\r
+               case Constants.INVOKESPECIAL:\r
+                       break;\r
+               case Constants.LOOKUPSWITCH: {\r
+                       int result = JcfaUtil.byte2Int(codes[pc + 1], codes[pc + 2],\r
+                                       codes[pc + 3], codes[pc + 4]);\r
+                       System.out.println("  TODO skipping bytes: " + (result));\r
+\r
+                       int lookupOp = pc + 5;\r
+\r
+                       short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
+                       System.out.println("  TODO skipping bytes: " + (diff));\r
+\r
+                       int loopCount = JcfaUtil.byte2Int(codes[lookupOp++],\r
+                                       codes[lookupOp++], codes[lookupOp++], codes[lookupOp++]);\r
+\r
+                       short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
+                       jcfaCode.getComment().getCommentList()\r
+                                       .add("  TODO skipping bytes: " + (diff2));\r
+\r
+                       operands += (lookupOp - pc);\r
+               }\r
+                       break;\r
+               default:\r
+                       break;\r
+               }\r
 \r
-                               break;\r
-                       default: {\r
-                               System.out.println("    " + pc + ": "\r
-                                               + Constants.OPCODE_NAMES[opcode] + " (" + operands\r
-                                               + ")");\r
-                       }\r
-                               break;\r
-                       }\r
-                       pc += operands;\r
+               {\r
+                       final ByteArrayOutputStream outStream = new ByteArrayOutputStream();\r
+                       outStream.write(codes, pc, operands + 1);\r
+                       outStream.flush();\r
+                       jcfaCode.setCodes(outStream.toByteArray());\r
                }\r
+               return operands;\r
        }\r
 }
\ No newline at end of file