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;
15 import org.apache.bcel.Constants;
16 import org.apache.bcel.classfile.JavaClass;
18 public class JcfaWriteUtil {
19 public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
20 final StringBuffer result = new StringBuffer();
22 for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
23 writeClass(jcfaClass, result);
26 final BufferedWriter writer = new BufferedWriter(
27 new OutputStreamWriter(new FileOutputStream(
28 jcfaUnit.getTargetFile())));
29 writer.write(JcfaEclipseUtil.formatSource(result.toString()));
40 public static void writeClass(final JcfaClass jcfaClass,
41 final StringBuffer result) throws IOException {
43 if (jcfaClass.isMainClass()) {
44 if (jcfaClass.getName().contains(".")) {
45 result.append(" package "
46 + jcfaClass.getName().substring(0,
47 jcfaClass.getName().lastIndexOf(".")) + ";");
51 writeComment(jcfaClass.getComment(), result);
53 result.append(jcfaClass.getAccess());
54 result.append(" class " + jcfaClass.getLocalName());
55 if (jcfaClass.getExtendsName() != null
56 && jcfaClass.getExtendsName().length() > 0
57 && jcfaClass.getExtendsName().equals("java.lang.Object") == false) {
58 result.append(" extends " + jcfaClass.getExtendsName());
62 for (JcfaField jcfaField : jcfaClass.getFieldList()) {
63 writeField(jcfaField, result);
66 for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
67 writeMethod(jcfaClass, jcfaMethod, result);
79 public static void writeField(final JcfaField jcfaField,
80 final StringBuffer result) {
81 writeComment(jcfaField.getComment(), result);
83 result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
84 + " " + jcfaField.getName());
85 if (jcfaField.getConstantValue() != null) {
87 result.append(jcfaField.getConstantValue());
100 public static void writeMethod(final JcfaClass jcfaClass,
101 final JcfaMethod jcfaMethod, final StringBuffer result)
104 writeComment(jcfaMethod.getComment(), result);
106 if (jcfaMethod.getName().equals("<init>")) {
107 result.append("public " + jcfaClass.getLocalName() + "(");
109 result.append("public " + jcfaMethod.getType() + " "
110 + jcfaMethod.getName() + "(");
114 for (String argumentType : jcfaMethod.getArugumentTypeList()) {
118 result.append(argumentType);
119 result.append(" arg" + argNo);
126 writeCodes(jcfaClass, jcfaMethod, result);
131 public static void writeCodes(final JcfaClass jcfaClass,
132 final JcfaMethod jcfaMethod, final StringBuffer result)
134 for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
135 final byte[] codes = jcfaCode.getCodes();
136 final JavaClass jc = jcfaCode.getJavaClass();
138 switch (jcfaCode.getOpcode()) {
139 case Constants.RETURN: {
142 case Constants.GETSTATIC: {
143 jcfaCode.getComment()
145 .add(JcfaUtil.getConstantFieldrefString(jc, codes[1],
149 case Constants.LDC: {
150 jcfaCode.getComment().getCommentList()
151 .add(JcfaUtil.getConstantString(jc, codes[1]));
154 case Constants.INVOKEVIRTUAL:
155 case Constants.INVOKESPECIAL: {
156 final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
158 jcfaCode.getComment().getCommentList()
159 .add(JcfaUtil.getConstantMethodRefString(jc, operand));
162 case Constants.LOOKUPSWITCH:
164 jcfaCode.getComment().getCommentList()
165 .add(" TODO temporary disabled.");
168 int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
171 jcfaCode.getComment().getCommentList()
172 .add(" TODO skipping bytes: " + (skipBytes));
176 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
177 jcfaCode.getComment().getCommentList()
178 .add(" TODO skipping bytes: " + (diff));
180 int loopCount = JcfaUtil
181 .byte2Int(codes[lookupOp++], codes[lookupOp++],
182 codes[lookupOp++], codes[lookupOp++]);
183 for (int index = 0; index < loopCount; index++) {
184 jcfaCode.getComment()
186 .add(JcfaUtil.byte2Int(codes[lookupOp++],
187 codes[lookupOp++], codes[lookupOp++],
190 + (JcfaUtil.byte2Int(codes[lookupOp++],
193 codes[lookupOp++])));
196 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
197 jcfaCode.getComment().getCommentList()
198 .add(" TODO skipping bytes: " + (diff2));
202 jcfaCode.getComment().getCommentList()
203 .add("TODO unsupported opcode");
207 writeComment(jcfaCode.getComment(), result);
219 public static void writeComment(final JcfaComment jcfaComment,
220 final StringBuffer result) {
221 if (jcfaComment.isJavaDoc()) {
222 result.append("\n/** ");
224 result.append("\n/* ");
227 if (jcfaComment.getCommentList().size() > 1) {
231 for (String comment : jcfaComment.getCommentList()) {
232 if (jcfaComment.getCommentList().size() > 1) {
233 result.append(" * " + comment + "\n");
235 result.append(comment);
239 result.append(" */\n");