OSDN Git Service

save
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / util / JcfaWriteUtil.java
1 package jp.igapyon.jcfa.util;
2
3 import java.io.BufferedWriter;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStreamWriter;
7
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
15 import org.apache.bcel.Constants;
16 import org.apache.bcel.classfile.JavaClass;
17
18 public class JcfaWriteUtil {
19         public static void writeToFile(final JcfaUnit jcfaUnit) throws IOException {
20                 final StringBuffer result = new StringBuffer();
21
22                 for (JcfaClass jcfaClass : jcfaUnit.getClassList()) {
23                         writeClass(jcfaClass, result);
24                 }
25
26                 final BufferedWriter writer = new BufferedWriter(
27                                 new OutputStreamWriter(new FileOutputStream(
28                                                 jcfaUnit.getTargetFile())));
29                 writer.write(JcfaEclipseUtil.formatSource(result.toString()));
30                 writer.close();
31         }
32
33         /**
34          * Write class
35          * 
36          * @param jcfaClass
37          * @param result
38          * @throws IOException
39          */
40         public static void writeClass(final JcfaClass jcfaClass,
41                         final StringBuffer result) throws IOException {
42
43                 if (jcfaClass.isMainClass()) {
44                         if (jcfaClass.getName().contains(".")) {
45                                 result.append(" package "
46                                                 + jcfaClass.getName().substring(0,
47                                                                 jcfaClass.getName().lastIndexOf(".")) + ";");
48                         }
49                 }
50
51                 writeComment(jcfaClass.getComment(), result);
52
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());
59                 }
60                 result.append("{");
61
62                 for (JcfaField jcfaField : jcfaClass.getFieldList()) {
63                         writeField(jcfaField, result);
64                 }
65
66                 for (JcfaMethod jcfaMethod : jcfaClass.getMethodList()) {
67                         writeMethod(jcfaClass, jcfaMethod, result);
68                 }
69
70                 result.append("}");
71         }
72
73         /**
74          * Write field.
75          * 
76          * @param jcfaField
77          * @param result
78          */
79         public static void writeField(final JcfaField jcfaField,
80                         final StringBuffer result) {
81                 writeComment(jcfaField.getComment(), result);
82
83                 result.append(" " + jcfaField.getAccess() + " " + jcfaField.getType()
84                                 + " " + jcfaField.getName());
85                 if (jcfaField.getConstantValue() != null) {
86                         result.append(" = ");
87                         result.append(jcfaField.getConstantValue());
88                 }
89                 result.append(";");
90         }
91
92         /**
93          * Write method.
94          * 
95          * @param jcfaClass
96          * @param jcfaMethod
97          * @param result
98          * @throws IOException
99          */
100         public static void writeMethod(final JcfaClass jcfaClass,
101                         final JcfaMethod jcfaMethod, final StringBuffer result)
102                         throws IOException {
103
104                 writeComment(jcfaMethod.getComment(), result);
105
106                 if (jcfaMethod.getName().equals("<init>")) {
107                         result.append("public " + jcfaClass.getLocalName() + "(");
108                 } else {
109                         result.append("public " + jcfaMethod.getType() + " "
110                                         + jcfaMethod.getName() + "(");
111                 }
112
113                 int argNo = 0;
114                 for (String argumentType : jcfaMethod.getArugumentTypeList()) {
115                         if (argNo != 0) {
116                                 result.append(", ");
117                         }
118                         result.append(argumentType);
119                         result.append(" arg" + argNo);
120                 }
121
122                 result.append(")");
123
124                 result.append("{");
125
126                 writeCodes(jcfaClass, jcfaMethod, result);
127
128                 result.append("}");
129         }
130
131         public static void writeCodes(final JcfaClass jcfaClass,
132                         final JcfaMethod jcfaMethod, final StringBuffer result)
133                         throws IOException {
134                 for (JcfaCode jcfaCode : jcfaMethod.getCodeList()) {
135                         final byte[] codes = jcfaCode.getCodes();
136                         final JavaClass jc = jcfaCode.getJavaClass();
137
138                         switch (jcfaCode.getOpcode()) {
139                         case Constants.RETURN: {
140                                 break;
141                         }
142                         case Constants.GETSTATIC: {
143                                 jcfaCode.getComment()
144                                                 .getCommentList()
145                                                 .add(JcfaUtil.getConstantFieldrefString(jc, codes[1],
146                                                                 codes[2]));
147                                 break;
148                         }
149                         case Constants.LDC: {
150                                 jcfaCode.getComment().getCommentList()
151                                                 .add(JcfaUtil.getConstantString(jc, codes[1]));
152                         }
153                                 break;
154                         case Constants.INVOKEVIRTUAL:
155                         case Constants.INVOKESPECIAL: {
156                                 final int operand = JcfaUtil.byte2UnsignedShort(codes[1],
157                                                 codes[2]);
158                                 jcfaCode.getComment().getCommentList()
159                                                 .add(JcfaUtil.getConstantMethodRefString(jc, operand));
160                         }
161                                 break;
162                         case Constants.LOOKUPSWITCH:
163                                 if (true) {
164                                         jcfaCode.getComment().getCommentList()
165                                                         .add("  TODO temporary disabled.");
166                                         break;
167                                 }
168                                 int skipBytes = JcfaUtil.byte2Int(codes[1], codes[2], codes[3],
169                                                 codes[4]);
170
171                                 jcfaCode.getComment().getCommentList()
172                                                 .add("  TODO skipping bytes: " + (skipBytes));
173
174                                 int lookupOp = 5;
175
176                                 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
177                                 jcfaCode.getComment().getCommentList()
178                                                 .add("  TODO skipping bytes: " + (diff));
179
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()
185                                                         .getCommentList()
186                                                         .add(JcfaUtil.byte2Int(codes[lookupOp++],
187                                                                         codes[lookupOp++], codes[lookupOp++],
188                                                                         codes[lookupOp++])
189                                                                         + ":"
190                                                                         + (JcfaUtil.byte2Int(codes[lookupOp++],
191                                                                                         codes[lookupOp++],
192                                                                                         codes[lookupOp++],
193                                                                                         codes[lookupOp++])));
194                                 }
195
196                                 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
197                                 jcfaCode.getComment().getCommentList()
198                                                 .add("  TODO skipping bytes: " + (diff2));
199
200                                 break;
201                         default:
202                                 jcfaCode.getComment().getCommentList()
203                                                 .add("TODO unsupported opcode");
204                                 break;
205                         }
206
207                         writeComment(jcfaCode.getComment(), result);
208
209                         // TODO and code...
210                 }
211         }
212
213         /**
214          * Write comment.
215          * 
216          * @param jcfaComment
217          * @param result
218          */
219         public static void writeComment(final JcfaComment jcfaComment,
220                         final StringBuffer result) {
221                 if (jcfaComment.isJavaDoc()) {
222                         result.append("\n/** ");
223                 } else {
224                         result.append("\n/* ");
225                 }
226
227                 if (jcfaComment.getCommentList().size() > 1) {
228                         result.append("\n");
229                 }
230
231                 for (String comment : jcfaComment.getCommentList()) {
232                         if (jcfaComment.getCommentList().size() > 1) {
233                                 result.append(" * " + comment + "\n");
234                         } else {
235                                 result.append(comment);
236                         }
237                 }
238
239                 result.append(" */\n");
240         }
241 }