1 package jp.igapyon.jcfa.util;
3 import java.io.BufferedWriter;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStreamWriter;
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;
18 import org.apache.bcel.Constants;
19 import org.apache.bcel.classfile.JavaClass;
21 public class JcfaWriteUtil {
22 public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
23 final StringBuffer result = new StringBuffer();
25 for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
26 writeClass(jcfaClass, result);
29 final BufferedWriter writer = new BufferedWriter(
30 new OutputStreamWriter(new FileOutputStream(
31 jcfaUnit.getTargetFile())));
32 writer.write(JcfaEclipseUtil.formatSource(result.toString()));
43 public static void writeClass(final JcfaClass jcfaClass,
44 final StringBuffer result) throws IOException {
46 if (jcfaClass.isMainClass()) {
47 if (jcfaClass.getName().contains(".")) {
48 result.append(" package "
49 + jcfaClass.getName().substring(0,
50 jcfaClass.getName().lastIndexOf(".")) + ";");
54 writeComment(jcfaClass.getComment(), result);
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());
65 for (JcfaField jcfaField : jcfaClass.getFieldList()) {
66 writeField(jcfaField, result);
69 for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
70 writeMethod(jcfaClass, jcfaMethod, result);
82 public static void writeField(final JcfaField jcfaField,
83 final StringBuffer result) {
84 writeComment(jcfaField.getComment(), result);
86 result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
87 + " " + jcfaField.getName());
88 if (jcfaField.getConstantValue() != null) {
90 result.append(jcfaField.getConstantValue());
101 * @throws IOException
103 public static void writeMethod(final JcfaClass jcfaClass,
104 final JcfaMethod jcfaMethod, final StringBuffer result)
107 writeComment(jcfaMethod.getComment(), result);
109 if (jcfaMethod.getName().equals("<init>")) {
110 result.append("public " + jcfaClass.getLocalName() + "(");
112 result.append("public " + jcfaMethod.getType() + " "
113 + jcfaMethod.getName() + "(");
117 for (String argumentType : jcfaMethod.getArugumentTypeList()) {
121 result.append(argumentType);
122 result.append(" arg" + argNo);
129 writeCodes(jcfaClass, jcfaMethod, result);
134 public static void writeCodes(final JcfaClass jcfaClass,
135 final JcfaMethod jcfaMethod, final StringBuffer result)
137 for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
138 final byte[] codes = jcfaCode.getCodes();
139 final JavaClass jc = jcfaCode.getJavaClass();
141 switch (jcfaCode.getOpcode()) {
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]));
165 jcfaCode.getComment().getCommentList()
166 .add(osString.getObject());
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));
181 jcfaCode.getComment().getCommentList()
182 .add(osLocalVariable.getLocalVariable().getName());
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:
250 case Constants.DUP_X1:
251 case Constants.DUP_X2:
253 case Constants.DUP2_X1:
254 case Constants.DUP2_X2:
284 case Constants.IUSHR:
285 case Constants.LUSHR:
309 case Constants.FCMPL:
310 case Constants.FCMPG:
311 case Constants.DCMPL:
312 case Constants.DCMPG:
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:
330 case Constants.TABLESWITCH:
331 case Constants.LOOKUPSWITCH: {
333 jcfaCode.getComment().getCommentList()
334 .add(" TODO temporary disabled.");
337 int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
340 jcfaCode.getComment().getCommentList()
341 .add(" TODO skipping bytes: " + (skipBytes));
345 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
346 jcfaCode.getComment().getCommentList()
347 .add(" TODO skipping bytes: " + (diff));
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()
355 .add(JcfaUtil.byte2Int(codes[lookupOp++],
356 codes[lookupOp++], codes[lookupOp++],
359 + (JcfaUtil.byte2Int(codes[lookupOp++],
362 codes[lookupOp++])));
365 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
366 jcfaCode.getComment().getCommentList()
367 .add(" TODO skipping bytes: " + (diff2));
371 case Constants.IRETURN:
372 case Constants.LRETURN:
373 case Constants.FRETURN:
374 case Constants.DRETURN:
375 case Constants.ARETURN:
376 case Constants.RETURN: {
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]));
385 jcfaCode.getComment().getCommentList().add(osRef.getObject());
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],
395 jcfaCode.getComment().getCommentList()
396 .add(JcfaUtil.getConstantMethodRefString(jc, operand));
398 jcfaCode.getComment().getCommentList()
399 .add("TODO get args count from signature.");
401 final JcfaItem osNodeArg0 = jcfaMethod.getFrame()
402 .getOperandStack().pop();
404 final JcfaItemReference osRef = (JcfaItemReference) jcfaMethod
405 .getFrame().getOperandStack().pop();
407 jcfaCode.getComment()
409 .add("" + osRef.getObject() + "#"
410 + osNodeArg0.toString());
414 case Constants.INVOKESTATIC:
415 case Constants.INVOKEINTERFACE:
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:
426 case Constants.MULTIANEWARRAY:
427 case Constants.IFNULL:
428 case Constants.IFNONNULL:
429 case Constants.GOTO_W:
430 case Constants.JSR_W:
432 jcfaCode.getComment().getCommentList()
433 .add("TODO unsupported opcode");
437 writeComment(jcfaCode.getComment(), result);
449 public static void writeComment(final JcfaComment jcfaComment,
450 final StringBuffer result) {
451 if (jcfaComment.isJavaDoc()) {
452 result.append("\n/** ");
454 result.append("\n/* ");
457 if (jcfaComment.getCommentList().size() > 1) {
461 for (String comment : jcfaComment.getCommentList()) {
462 if (jcfaComment.getCommentList().size() > 1) {
463 result.append(" * " + comment + "\n");
465 result.append(comment);
469 result.append(" */\n");