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()) {
142 case Constants.ALOAD_0: {
143 final JcfaItemLocalVariable osLocalVariable = new JcfaItemLocalVariable();
144 jcfaMethod.getFrame().getOperandStack().push(osLocalVariable);
145 osLocalVariable.setLocalVariable(jcfaMethod.getFrame()
146 .getLocalVariableList().get(0));
148 jcfaCode.getComment().getCommentList()
149 .add(osLocalVariable.getLocalVariable().getName());
153 case Constants.RETURN: {
156 case Constants.GETSTATIC: {
157 final JcfaItemReference osRef = new JcfaItemReference();
158 jcfaMethod.getFrame().getOperandStack().push(osRef);
159 osRef.setObject(JcfaUtil.getConstantFieldrefString(jc,
160 codes[1], codes[2]));
162 jcfaCode.getComment().getCommentList().add(osRef.getObject());
165 case Constants.LDC: {
166 final JcfaItemReference osString = new JcfaItemReference();
167 jcfaMethod.getFrame().getOperandStack().push(osString);
168 osString.setObject(JcfaUtil.getConstantString(jc, codes[1]));
170 jcfaCode.getComment().getCommentList()
171 .add(osString.getObject());
174 case Constants.INVOKEVIRTUAL:
175 case Constants.INVOKESPECIAL: {
176 final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
178 jcfaCode.getComment().getCommentList()
179 .add(JcfaUtil.getConstantMethodRefString(jc, operand));
181 jcfaCode.getComment().getCommentList()
182 .add("TODO get args count from signature.");
184 final JcfaItem osNodeArg0 = jcfaMethod.getFrame()
185 .getOperandStack().pop();
187 final JcfaItemReference osRef = (JcfaItemReference) jcfaMethod
188 .getFrame().getOperandStack().pop();
190 jcfaCode.getComment()
192 .add("" + osRef.getObject() + "#"
193 + osNodeArg0.toString());
197 case Constants.LOOKUPSWITCH:
199 jcfaCode.getComment().getCommentList()
200 .add(" TODO temporary disabled.");
203 int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
206 jcfaCode.getComment().getCommentList()
207 .add(" TODO skipping bytes: " + (skipBytes));
211 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
212 jcfaCode.getComment().getCommentList()
213 .add(" TODO skipping bytes: " + (diff));
215 int loopCount = JcfaUtil
216 .byte2Int(codes[lookupOp++], codes[lookupOp++],
217 codes[lookupOp++], codes[lookupOp++]);
218 for (int index = 0; index < loopCount; index++) {
219 jcfaCode.getComment()
221 .add(JcfaUtil.byte2Int(codes[lookupOp++],
222 codes[lookupOp++], codes[lookupOp++],
225 + (JcfaUtil.byte2Int(codes[lookupOp++],
228 codes[lookupOp++])));
231 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
232 jcfaCode.getComment().getCommentList()
233 .add(" TODO skipping bytes: " + (diff2));
237 jcfaCode.getComment().getCommentList()
238 .add("TODO unsupported opcode");
242 writeComment(jcfaCode.getComment(), result);
254 public static void writeComment(final JcfaComment jcfaComment,
255 final StringBuffer result) {
256 if (jcfaComment.isJavaDoc()) {
257 result.append("\n/** ");
259 result.append("\n/* ");
262 if (jcfaComment.getCommentList().size() > 1) {
266 for (String comment : jcfaComment.getCommentList()) {
267 if (jcfaComment.getCommentList().size() > 1) {
268 result.append(" * " + comment + "\n");
270 result.append(comment);
274 result.append(" */\n");