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.JcfaOSNode;
16 import jp.igapyon.jcfa.vo.operandstack.JcfaOSRef;
17 import jp.igapyon.jcfa.vo.operandstack.JcfaOSString;
19 import org.apache.bcel.Constants;
20 import org.apache.bcel.classfile.JavaClass;
22 public class JcfaWriteUtil {
23 public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
24 final StringBuffer result = new StringBuffer();
26 for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
27 writeClass(jcfaClass, result);
30 final BufferedWriter writer = new BufferedWriter(
31 new OutputStreamWriter(new FileOutputStream(
32 jcfaUnit.getTargetFile())));
33 writer.write(JcfaEclipseUtil.formatSource(result.toString()));
44 public static void writeClass(final JcfaClass jcfaClass,
45 final StringBuffer result) throws IOException {
47 if (jcfaClass.isMainClass()) {
48 if (jcfaClass.getName().contains(".")) {
49 result.append(" package "
50 + jcfaClass.getName().substring(0,
51 jcfaClass.getName().lastIndexOf(".")) + ";");
55 writeComment(jcfaClass.getComment(), result);
57 result.append(jcfaClass.getAccess());
58 result.append(" class " + jcfaClass.getLocalName());
59 if (jcfaClass.getExtendsName() != null
60 && jcfaClass.getExtendsName().length() > 0
61 && jcfaClass.getExtendsName().equals("java.lang.Object") == false) {
62 result.append(" extends " + jcfaClass.getExtendsName());
66 for (JcfaField jcfaField : jcfaClass.getFieldList()) {
67 writeField(jcfaField, result);
70 for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
71 writeMethod(jcfaClass, jcfaMethod, result);
83 public static void writeField(final JcfaField jcfaField,
84 final StringBuffer result) {
85 writeComment(jcfaField.getComment(), result);
87 result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
88 + " " + jcfaField.getName());
89 if (jcfaField.getConstantValue() != null) {
91 result.append(jcfaField.getConstantValue());
102 * @throws IOException
104 public static void writeMethod(final JcfaClass jcfaClass,
105 final JcfaMethod jcfaMethod, final StringBuffer result)
108 writeComment(jcfaMethod.getComment(), result);
110 if (jcfaMethod.getName().equals("<init>")) {
111 result.append("public " + jcfaClass.getLocalName() + "(");
113 result.append("public " + jcfaMethod.getType() + " "
114 + jcfaMethod.getName() + "(");
118 for (String argumentType : jcfaMethod.getArugumentTypeList()) {
122 result.append(argumentType);
123 result.append(" arg" + argNo);
130 writeCodes(jcfaClass, jcfaMethod, result);
135 public static void writeCodes(final JcfaClass jcfaClass,
136 final JcfaMethod jcfaMethod, final StringBuffer result)
138 for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
139 final byte[] codes = jcfaCode.getCodes();
140 final JavaClass jc = jcfaCode.getJavaClass();
142 switch (jcfaCode.getOpcode()) {
143 case Constants.ALOAD_0: {
144 final JcfaOSLocalVariable osLocalVariable = new JcfaOSLocalVariable();
145 jcfaMethod.getFrame().getOperandStack().push(osLocalVariable);
146 osLocalVariable.setLocalVariable(jcfaMethod.getFrame()
147 .getLocalVariableList().get(0));
149 jcfaCode.getComment().getCommentList()
150 .add(osLocalVariable.getLocalVariable().getName());
154 case Constants.RETURN: {
157 case Constants.GETSTATIC: {
158 final JcfaOSRef osRef = new JcfaOSRef();
159 jcfaMethod.getFrame().getOperandStack().push(osRef);
160 osRef.setClassName(JcfaUtil.getConstantFieldrefString(jc,
161 codes[1], codes[2]));
163 jcfaCode.getComment().getCommentList()
164 .add(osRef.getClassName());
167 case Constants.LDC: {
168 final JcfaOSString osString = new JcfaOSString();
169 jcfaMethod.getFrame().getOperandStack().push(osString);
170 osString.setString(JcfaUtil.getConstantString(jc, codes[1]));
172 jcfaCode.getComment().getCommentList()
173 .add(osString.getString());
176 case Constants.INVOKEVIRTUAL:
177 case Constants.INVOKESPECIAL: {
178 final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
180 jcfaCode.getComment().getCommentList()
181 .add(JcfaUtil.getConstantMethodRefString(jc, operand));
183 jcfaCode.getComment().getCommentList()
184 .add("TODO get args count from signature.");
186 final JcfaOSNode osNodeArg0 = jcfaMethod.getFrame()
187 .getOperandStack().pop();
189 final JcfaOSRef osRef = (JcfaOSRef) jcfaMethod.getFrame()
190 .getOperandStack().pop();
192 jcfaCode.getComment()
194 .add("" + osRef.getClassName() + "#"
195 + osNodeArg0.toString());
199 case Constants.LOOKUPSWITCH:
201 jcfaCode.getComment().getCommentList()
202 .add(" TODO temporary disabled.");
205 int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
208 jcfaCode.getComment().getCommentList()
209 .add(" TODO skipping bytes: " + (skipBytes));
213 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
214 jcfaCode.getComment().getCommentList()
215 .add(" TODO skipping bytes: " + (diff));
217 int loopCount = JcfaUtil
218 .byte2Int(codes[lookupOp++], codes[lookupOp++],
219 codes[lookupOp++], codes[lookupOp++]);
220 for (int index = 0; index < loopCount; index++) {
221 jcfaCode.getComment()
223 .add(JcfaUtil.byte2Int(codes[lookupOp++],
224 codes[lookupOp++], codes[lookupOp++],
227 + (JcfaUtil.byte2Int(codes[lookupOp++],
230 codes[lookupOp++])));
233 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
234 jcfaCode.getComment().getCommentList()
235 .add(" TODO skipping bytes: " + (diff2));
239 jcfaCode.getComment().getCommentList()
240 .add("TODO unsupported opcode");
244 writeComment(jcfaCode.getComment(), result);
256 public static void writeComment(final JcfaComment jcfaComment,
257 final StringBuffer result) {
258 if (jcfaComment.isJavaDoc()) {
259 result.append("\n/** ");
261 result.append("\n/* ");
264 if (jcfaComment.getCommentList().size() > 1) {
268 for (String comment : jcfaComment.getCommentList()) {
269 if (jcfaComment.getCommentList().size() > 1) {
270 result.append(" * " + comment + "\n");
272 result.append(comment);
276 result.append(" */\n");