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.operandstack.JcfaOSLocalVariable;
15 import jp.igapyon.jcfa.vo.operandstack.JcfaOSRef;
17 import org.apache.bcel.Constants;
18 import org.apache.bcel.classfile.JavaClass;
20 public class JcfaWriteUtil {
21 public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
22 final StringBuffer result = new StringBuffer();
24 for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
25 writeClass(jcfaClass, result);
28 final BufferedWriter writer = new BufferedWriter(
29 new OutputStreamWriter(new FileOutputStream(
30 jcfaUnit.getTargetFile())));
31 writer.write(JcfaEclipseUtil.formatSource(result.toString()));
42 public static void writeClass(final JcfaClass jcfaClass,
43 final StringBuffer result) throws IOException {
45 if (jcfaClass.isMainClass()) {
46 if (jcfaClass.getName().contains(".")) {
47 result.append(" package "
48 + jcfaClass.getName().substring(0,
49 jcfaClass.getName().lastIndexOf(".")) + ";");
53 writeComment(jcfaClass.getComment(), result);
55 result.append(jcfaClass.getAccess());
56 result.append(" class " + jcfaClass.getLocalName());
57 if (jcfaClass.getExtendsName() != null
58 && jcfaClass.getExtendsName().length() > 0
59 && jcfaClass.getExtendsName().equals("java.lang.Object") == false) {
60 result.append(" extends " + jcfaClass.getExtendsName());
64 for (JcfaField jcfaField : jcfaClass.getFieldList()) {
65 writeField(jcfaField, result);
68 for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
69 writeMethod(jcfaClass, jcfaMethod, result);
81 public static void writeField(final JcfaField jcfaField,
82 final StringBuffer result) {
83 writeComment(jcfaField.getComment(), result);
85 result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
86 + " " + jcfaField.getName());
87 if (jcfaField.getConstantValue() != null) {
89 result.append(jcfaField.getConstantValue());
100 * @throws IOException
102 public static void writeMethod(final JcfaClass jcfaClass,
103 final JcfaMethod jcfaMethod, final StringBuffer result)
106 writeComment(jcfaMethod.getComment(), result);
108 if (jcfaMethod.getName().equals("<init>")) {
109 result.append("public " + jcfaClass.getLocalName() + "(");
111 result.append("public " + jcfaMethod.getType() + " "
112 + jcfaMethod.getName() + "(");
116 for (String argumentType : jcfaMethod.getArugumentTypeList()) {
120 result.append(argumentType);
121 result.append(" arg" + argNo);
128 writeCodes(jcfaClass, jcfaMethod, result);
133 public static void writeCodes(final JcfaClass jcfaClass,
134 final JcfaMethod jcfaMethod, final StringBuffer result)
136 for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
137 final byte[] codes = jcfaCode.getCodes();
138 final JavaClass jc = jcfaCode.getJavaClass();
140 switch (jcfaCode.getOpcode()) {
141 case Constants.ALOAD_0: {
142 final JcfaOSLocalVariable osLocalVariable = new JcfaOSLocalVariable();
143 jcfaMethod.getFrame().getOperandStack().push(osLocalVariable);
144 osLocalVariable.setLocalVariable(jcfaMethod.getFrame()
145 .getLocalVariableList().get(0));
147 jcfaCode.getComment().getCommentList()
148 .add(osLocalVariable.getLocalVariable().getName());
152 case Constants.RETURN: {
155 case Constants.GETSTATIC: {
156 final JcfaOSRef osRef = new JcfaOSRef();
157 jcfaMethod.getFrame().getOperandStack().push(osRef);
158 osRef.setClassName(JcfaUtil.getConstantFieldrefString(jc,
159 codes[1], codes[2]));
161 jcfaCode.getComment().getCommentList()
162 .add(osRef.getClassName());
165 case Constants.LDC: {
166 jcfaCode.getComment().getCommentList()
167 .add(JcfaUtil.getConstantString(jc, codes[1]));
170 case Constants.INVOKEVIRTUAL:
171 case Constants.INVOKESPECIAL: {
172 final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
174 jcfaCode.getComment().getCommentList()
175 .add(JcfaUtil.getConstantMethodRefString(jc, operand));
178 case Constants.LOOKUPSWITCH:
180 jcfaCode.getComment().getCommentList()
181 .add(" TODO temporary disabled.");
184 int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
187 jcfaCode.getComment().getCommentList()
188 .add(" TODO skipping bytes: " + (skipBytes));
192 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
193 jcfaCode.getComment().getCommentList()
194 .add(" TODO skipping bytes: " + (diff));
196 int loopCount = JcfaUtil
197 .byte2Int(codes[lookupOp++], codes[lookupOp++],
198 codes[lookupOp++], codes[lookupOp++]);
199 for (int index = 0; index < loopCount; index++) {
200 jcfaCode.getComment()
202 .add(JcfaUtil.byte2Int(codes[lookupOp++],
203 codes[lookupOp++], codes[lookupOp++],
206 + (JcfaUtil.byte2Int(codes[lookupOp++],
209 codes[lookupOp++])));
212 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
213 jcfaCode.getComment().getCommentList()
214 .add(" TODO skipping bytes: " + (diff2));
218 jcfaCode.getComment().getCommentList()
219 .add("TODO unsupported opcode");
223 writeComment(jcfaCode.getComment(), result);
235 public static void writeComment(final JcfaComment jcfaComment,
236 final StringBuffer result) {
237 if (jcfaComment.isJavaDoc()) {
238 result.append("\n/** ");
240 result.append("\n/* ");
243 if (jcfaComment.getCommentList().size() > 1) {
247 for (String comment : jcfaComment.getCommentList()) {
248 if (jcfaComment.getCommentList().size() > 1) {
249 result.append(" * " + comment + "\n");
251 result.append(comment);
255 result.append(" */\n");