OSDN Git Service

73c6e25ff7e2b56b244a30345cf8c61711293ee4
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / util / JcfaWriteUtil.java
1 package jp.igapyon.jcfa.util;
2
3 import java.io.BufferedWriter;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStreamWriter;
7
8 import jp.igapyon.jcfa.vo.JcfaClass;
9 import jp.igapyon.jcfa.vo.JcfaCode;
10 import jp.igapyon.jcfa.vo.JcfaComment;
11 import jp.igapyon.jcfa.vo.JcfaField;
12 import jp.igapyon.jcfa.vo.JcfaMethod;
13 import jp.igapyon.jcfa.vo.JcfaUnit;
14 import jp.igapyon.jcfa.vo.item.JcfaItem;
15 import jp.igapyon.jcfa.vo.item.JcfaItemLocalVariable;
16 import jp.igapyon.jcfa.vo.item.JcfaItemReference;
17
18 import org.apache.bcel.Constants;
19 import org.apache.bcel.classfile.JavaClass;
20
21 public class JcfaWriteUtil {
22         public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
23                 final StringBuffer result = new StringBuffer();
24
25                 for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
26                         writeClass(jcfaClass, result);
27                 }
28
29                 final BufferedWriter writer = new BufferedWriter(
30                                 new OutputStreamWriter(new FileOutputStream(
31                                                 jcfaUnit.getTargetFile())));
32                 writer.write(JcfaEclipseUtil.formatSource(result.toString()));
33                 writer.close();
34         }
35
36         /**
37          * Write class
38          * 
39          * @param jcfaClass
40          * @param result
41          * @throws IOException
42          */
43         public static void writeClass(final JcfaClass jcfaClass,
44                         final StringBuffer result) throws IOException {
45
46                 if (jcfaClass.isMainClass()) {
47                         if (jcfaClass.getName().contains(".")) {
48                                 result.append(" package "
49                                                 + jcfaClass.getName().substring(0,
50                                                                 jcfaClass.getName().lastIndexOf(".")) + ";");
51                         }
52                 }
53
54                 writeComment(jcfaClass.getComment(), result);
55
56                 result.append(jcfaClass.getAccess());
57                 result.append(" class " + jcfaClass.getLocalName());
58                 if (jcfaClass.getExtendsName() != null
59                                 && jcfaClass.getExtendsName().length() > 0
60                                 && jcfaClass.getExtendsName().equals("java.lang.Object") == false) {
61                         result.append(" extends " + jcfaClass.getExtendsName());
62                 }
63                 result.append("{");
64
65                 for (JcfaField jcfaField : jcfaClass.getFieldList()) {
66                         writeField(jcfaField, result);
67                 }
68
69                 for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
70                         writeMethod(jcfaClass, jcfaMethod, result);
71                 }
72
73                 result.append("}");
74         }
75
76         /**
77          * Write field.
78          * 
79          * @param jcfaField
80          * @param result
81          */
82         public static void writeField(final JcfaField jcfaField,
83                         final StringBuffer result) {
84                 writeComment(jcfaField.getComment(), result);
85
86                 result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
87                                 + " " + jcfaField.getName());
88                 if (jcfaField.getConstantValue() != null) {
89                         result.append(" = ");
90                         result.append(jcfaField.getConstantValue());
91                 }
92                 result.append(";");
93         }
94
95         /**
96          * Write method.
97          * 
98          * @param jcfaClass
99          * @param jcfaMethod
100          * @param result
101          * @throws IOException
102          */
103         public static void writeMethod(final JcfaClass jcfaClass,
104                         final JcfaMethod jcfaMethod, final StringBuffer result)
105                         throws IOException {
106
107                 writeComment(jcfaMethod.getComment(), result);
108
109                 if (jcfaMethod.getName().equals("<init>")) {
110                         result.append("public " + jcfaClass.getLocalName() + "(");
111                 } else {
112                         result.append("public " + jcfaMethod.getType() + " "
113                                         + jcfaMethod.getName() + "(");
114                 }
115
116                 int argNo = 0;
117                 for (String argumentType : jcfaMethod.getArugumentTypeList()) {
118                         if (argNo != 0) {
119                                 result.append(", ");
120                         }
121                         result.append(argumentType);
122                         result.append(" arg" + argNo);
123                 }
124
125                 result.append(")");
126
127                 result.append("{");
128
129                 writeCodes(jcfaClass, jcfaMethod, result);
130
131                 result.append("}");
132         }
133
134         public static void writeCodes(final JcfaClass jcfaClass,
135                         final JcfaMethod jcfaMethod, final StringBuffer result)
136                         throws IOException {
137                 for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
138                         final byte[] codes = jcfaCode.getCodes();
139                         final JavaClass jc = jcfaCode.getJavaClass();
140
141                         switch (jcfaCode.getOpcode()) {
142                         case Constants.NOP:
143                         case Constants.ACONST_NULL:
144                         case Constants.ICONST_M1:
145                         case Constants.ICONST_0:
146                         case Constants.ICONST_1:
147                         case Constants.ICONST_2:
148                         case Constants.ICONST_3:
149                         case Constants.ICONST_4:
150                         case Constants.ICONST_5:
151                         case Constants.LCONST_0:
152                         case Constants.LCONST_1:
153                         case Constants.FCONST_0:
154                         case Constants.FCONST_1:
155                         case Constants.FCONST_2:
156                         case Constants.DCONST_0:
157                         case Constants.DCONST_1:
158                         case Constants.BIPUSH:
159                         case Constants.SIPUSH:
160                         case Constants.LDC: {
161                                 final JcfaItemReference osString = new JcfaItemReference();
162                                 jcfaMethod.getFrame().getOperandStack().push(osString);
163                                 osString.setObject(JcfaUtil.getConstantString(jc, codes[1]));
164
165                                 jcfaCode.getComment().getCommentList()
166                                                 .add(osString.getObject());
167                                 break;
168                         }
169                         case Constants.LDC_W:
170                         case Constants.LDC2_W:
171                         case Constants.ILOAD:
172                         case Constants.LLOAD:
173                         case Constants.FLOAD:
174                         case Constants.DLOAD:
175                         case Constants.ALOAD: {
176                                 final JcfaItemLocalVariable osLocalVariable = new JcfaItemLocalVariable();
177                                 jcfaMethod.getFrame().getOperandStack().push(osLocalVariable);
178                                 osLocalVariable.setLocalVariable(jcfaMethod.getFrame()
179                                                 .getLocalVariableList().get(0));
180
181                                 jcfaCode.getComment().getCommentList()
182                                                 .add(osLocalVariable.getLocalVariable().getName());
183
184                                 break;
185                         }
186                         case Constants.ILOAD_0:
187                         case Constants.ILOAD_1:
188                         case Constants.ILOAD_2:
189                         case Constants.ILOAD_3:
190                         case Constants.LLOAD_0:
191                         case Constants.LLOAD_1:
192                         case Constants.LLOAD_2:
193                         case Constants.LLOAD_3:
194                         case Constants.FLOAD_0:
195                         case Constants.FLOAD_1:
196                         case Constants.FLOAD_2:
197                         case Constants.FLOAD_3:
198                         case Constants.DLOAD_0:
199                         case Constants.DLOAD_1:
200                         case Constants.DLOAD_2:
201                         case Constants.DLOAD_3:
202                         case Constants.ALOAD_0:
203                         case Constants.ALOAD_1:
204                         case Constants.ALOAD_2:
205                         case Constants.ALOAD_3:
206                         case Constants.IALOAD:
207                         case Constants.LALOAD:
208                         case Constants.FALOAD:
209                         case Constants.DALOAD:
210                         case Constants.AALOAD:
211                         case Constants.BALOAD:
212                         case Constants.CALOAD:
213                         case Constants.SALOAD:
214                         case Constants.ISTORE:
215                         case Constants.LSTORE:
216                         case Constants.FSTORE:
217                         case Constants.DSTORE:
218                         case Constants.ASTORE:
219                         case Constants.ISTORE_0:
220                         case Constants.ISTORE_1:
221                         case Constants.ISTORE_2:
222                         case Constants.ISTORE_3:
223                         case Constants.LSTORE_0:
224                         case Constants.LSTORE_1:
225                         case Constants.LSTORE_2:
226                         case Constants.LSTORE_3:
227                         case Constants.FSTORE_0:
228                         case Constants.FSTORE_1:
229                         case Constants.FSTORE_2:
230                         case Constants.FSTORE_3:
231                         case Constants.DSTORE_0:
232                         case Constants.DSTORE_1:
233                         case Constants.DSTORE_2:
234                         case Constants.DSTORE_3:
235                         case Constants.ASTORE_0:
236                         case Constants.ASTORE_1:
237                         case Constants.ASTORE_2:
238                         case Constants.ASTORE_3:
239                         case Constants.IASTORE:
240                         case Constants.LASTORE:
241                         case Constants.FASTORE:
242                         case Constants.DASTORE:
243                         case Constants.AASTORE:
244                         case Constants.BASTORE:
245                         case Constants.CASTORE:
246                         case Constants.SASTORE:
247                         case Constants.POP:
248                         case Constants.POP2:
249                         case Constants.DUP:
250                         case Constants.DUP_X1:
251                         case Constants.DUP_X2:
252                         case Constants.DUP2:
253                         case Constants.DUP2_X1:
254                         case Constants.DUP2_X2:
255                         case Constants.SWAP:
256                         case Constants.IADD:
257                         case Constants.LADD:
258                         case Constants.FADD:
259                         case Constants.DADD:
260                         case Constants.ISUB:
261                         case Constants.LSUB:
262                         case Constants.FSUB:
263                         case Constants.DSUB:
264                         case Constants.IMUL:
265                         case Constants.LMUL:
266                         case Constants.FMUL:
267                         case Constants.DMUL:
268                         case Constants.IDIV:
269                         case Constants.LDIV:
270                         case Constants.FDIV:
271                         case Constants.DDIV:
272                         case Constants.IREM:
273                         case Constants.LREM:
274                         case Constants.FREM:
275                         case Constants.DREM:
276                         case Constants.INEG:
277                         case Constants.LNEG:
278                         case Constants.FNEG:
279                         case Constants.DNEG:
280                         case Constants.ISHL:
281                         case Constants.LSHL:
282                         case Constants.ISHR:
283                         case Constants.LSHR:
284                         case Constants.IUSHR:
285                         case Constants.LUSHR:
286                         case Constants.IAND:
287                         case Constants.LAND:
288                         case Constants.IOR:
289                         case Constants.LOR:
290                         case Constants.IXOR:
291                         case Constants.LXOR:
292                         case Constants.IINC:
293                         case Constants.I2L:
294                         case Constants.I2F:
295                         case Constants.I2D:
296                         case Constants.L2I:
297                         case Constants.L2F:
298                         case Constants.L2D:
299                         case Constants.F2I:
300                         case Constants.F2L:
301                         case Constants.F2D:
302                         case Constants.D2I:
303                         case Constants.D2L:
304                         case Constants.D2F:
305                         case Constants.I2B:
306                         case Constants.I2C:
307                         case Constants.I2S:
308                         case Constants.LCMP:
309                         case Constants.FCMPL:
310                         case Constants.FCMPG:
311                         case Constants.DCMPL:
312                         case Constants.DCMPG:
313                         case Constants.IFEQ:
314                         case Constants.IFNE:
315                         case Constants.IFLT:
316                         case Constants.IFGE:
317                         case Constants.IFGT:
318                         case Constants.IFLE:
319                         case Constants.IF_ICMPEQ:
320                         case Constants.IF_ICMPNE:
321                         case Constants.IF_ICMPLT:
322                         case Constants.IF_ICMPGE:
323                         case Constants.IF_ICMPGT:
324                         case Constants.IF_ICMPLE:
325                         case Constants.IF_ACMPEQ:
326                         case Constants.IF_ACMPNE:
327                         case Constants.GOTO:
328                         case Constants.JSR:
329                         case Constants.RET:
330                         case Constants.TABLESWITCH:
331                         case Constants.LOOKUPSWITCH: {
332                                 if (true) {
333                                         jcfaCode.getComment().getCommentList()
334                                                         .add("  TODO temporary disabled.");
335                                         break;
336                                 }
337                                 int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
338                                                 codes[4]);
339
340                                 jcfaCode.getComment().getCommentList()
341                                                 .add("  TODO skipping bytes: " + (skipBytes));
342
343                                 int lookupOp = 5;
344
345                                 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
346                                 jcfaCode.getComment().getCommentList()
347                                                 .add("  TODO skipping bytes: " + (diff));
348
349                                 int loopCount = JcfaUtil
350                                                 .byte2Int(codes[lookupOp++], codes[lookupOp++],
351                                                                 codes[lookupOp++], codes[lookupOp++]);
352                                 for (int index = 0; index < loopCount; index++) {
353                                         jcfaCode.getComment()
354                                                         .getCommentList()
355                                                         .add(JcfaUtil.byte2Int(codes[lookupOp++],
356                                                                         codes[lookupOp++], codes[lookupOp++],
357                                                                         codes[lookupOp++])
358                                                                         + ":"
359                                                                         + (JcfaUtil.byte2Int(codes[lookupOp++],
360                                                                                         codes[lookupOp++],
361                                                                                         codes[lookupOp++],
362                                                                                         codes[lookupOp++])));
363                                 }
364
365                                 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
366                                 jcfaCode.getComment().getCommentList()
367                                                 .add("  TODO skipping bytes: " + (diff2));
368
369                                 break;
370                         }
371                         case Constants.IRETURN:
372                         case Constants.LRETURN:
373                         case Constants.FRETURN:
374                         case Constants.DRETURN:
375                         case Constants.ARETURN:
376                         case Constants.RETURN: {
377                                 break;
378                         }
379                         case Constants.GETSTATIC: {
380                                 final JcfaItemReference osRef = new JcfaItemReference();
381                                 jcfaMethod.getFrame().getOperandStack().push(osRef);
382                                 osRef.setObject(JcfaUtil.getConstantFieldrefString(jc,
383                                                 codes[1], codes[2]));
384
385                                 jcfaCode.getComment().getCommentList().add(osRef.getObject());
386                                 break;
387                         }
388                         case Constants.PUTSTATIC:
389                         case Constants.GETFIELD:
390                         case Constants.PUTFIELD:
391                         case Constants.INVOKEVIRTUAL:
392                         case Constants.INVOKESPECIAL: {
393                                 final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
394                                                 codes[2]);
395                                 jcfaCode.getComment().getCommentList()
396                                                 .add(JcfaUtil.getConstantMethodRefString(jc, operand));
397
398                                 jcfaCode.getComment().getCommentList()
399                                                 .add("TODO get args count from signature.");
400                                 // get n args.
401                                 final JcfaItem osNodeArg0 = jcfaMethod.getFrame()
402                                                 .getOperandStack().pop();
403
404                                 final JcfaItemReference osRef = (JcfaItemReference) jcfaMethod
405                                                 .getFrame().getOperandStack().pop();
406
407                                 jcfaCode.getComment()
408                                                 .getCommentList()
409                                                 .add("" + osRef.getObject() + "#"
410                                                                 + osNodeArg0.toString());
411
412                                 break;
413                         }
414                         case Constants.INVOKESTATIC:
415                         case Constants.INVOKEINTERFACE:
416                         case Constants.NEW:
417                         case Constants.NEWARRAY:
418                         case Constants.ANEWARRAY:
419                         case Constants.ARRAYLENGTH:
420                         case Constants.ATHROW:
421                         case Constants.CHECKCAST:
422                         case Constants.INSTANCEOF:
423                         case Constants.MONITORENTER:
424                         case Constants.MONITOREXIT:
425                         case Constants.WIDE:
426                         case Constants.MULTIANEWARRAY:
427                         case Constants.IFNULL:
428                         case Constants.IFNONNULL:
429                         case Constants.GOTO_W:
430                         case Constants.JSR_W:
431                         default:
432                                 jcfaCode.getComment().getCommentList()
433                                                 .add("TODO unsupported opcode");
434                                 break;
435                         }
436
437                         writeComment(jcfaCode.getComment(), result);
438
439                         // TODO and code...
440                 }
441         }
442
443         /**
444          * Write comment.
445          * 
446          * @param jcfaComment
447          * @param result
448          */
449         public static void writeComment(final JcfaComment jcfaComment,
450                         final StringBuffer result) {
451                 if (jcfaComment.isJavaDoc()) {
452                         result.append("\n/** ");
453                 } else {
454                         result.append("\n/* ");
455                 }
456
457                 if (jcfaComment.getCommentList().size() > 1) {
458                         result.append("\n");
459                 }
460
461                 for (String comment : jcfaComment.getCommentList()) {
462                         if (jcfaComment.getCommentList().size() > 1) {
463                                 result.append(" * " + comment + "\n");
464                         } else {
465                                 result.append(comment);
466                         }
467                 }
468
469                 result.append(" */\n");
470         }
471 }