KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > loskutov > bco > asm > DecompiledClass


1 package de.loskutov.bco.asm;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.HashMap JavaDoc;
5 import java.util.List JavaDoc;
6 import java.util.Map JavaDoc;
7
8 import org.eclipse.jdt.core.IClassFile;
9 import org.eclipse.jdt.core.IJavaElement;
10 import org.objectweb.asm.Opcodes;
11 import org.objectweb.asm.tree.ClassNode;
12
13 import de.loskutov.bco.ui.JdtUtils;
14
15 /**
16  * @author Eric Bruneton
17  */

18
19 public class DecompiledClass {
20
21     public static final String JavaDoc ATTR_CLAS_SIZE = "class.size";
22     public static final String JavaDoc ATTR_JAVA_VERSION = "java.version";
23     public static final String JavaDoc ATTR_ACCESS_FLAGS = "access";
24
25     /** key is DecompiledMethod, value is IJavaElement (Member)*/
26     private Map JavaDoc methodToJavaElt;
27     private List JavaDoc text;
28     /**
29      * key is string, value is string
30      */

31     private Map JavaDoc classAttributesMap = new HashMap JavaDoc();
32     private String JavaDoc value;
33     private ClassNode classNode;
34
35     public DecompiledClass(final List JavaDoc text) {
36         this.text = text;
37         methodToJavaElt = new HashMap JavaDoc();
38     }
39
40     public void setAttribute(String JavaDoc key, String JavaDoc value){
41         classAttributesMap.put(key, value);
42     }
43
44     /**
45      * @return the class's access flags (see {@link Opcodes}). This
46      * parameter also indicates if the class is deprecated.
47      */

48     public int getAccessFlags(){
49         int result = 0;
50         String JavaDoc flags = (String JavaDoc) classAttributesMap.get(ATTR_ACCESS_FLAGS);
51         if(flags == null){
52             return result;
53         }
54         try {
55             Integer JavaDoc intFlags = Integer.valueOf(flags);
56             result = intFlags.intValue();
57         } catch (NumberFormatException JavaDoc e) {
58             // ignore, should not happen
59
}
60         return result;
61     }
62
63     /**
64      * @return true if the class is either abstract or interface
65      */

66     public boolean isAbstractOrInterface(){
67         int accessFlags = getAccessFlags();
68         return ((accessFlags & Opcodes.ACC_ABSTRACT) != 0) ||
69             ((accessFlags & Opcodes.ACC_INTERFACE) != 0);
70     }
71
72     public String JavaDoc getAttribute(String JavaDoc key){
73         return (String JavaDoc)classAttributesMap.get(key);
74     }
75
76     public String JavaDoc getText() {
77         if (value == null) {
78             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
79             for (int i = 0; i < text.size(); ++i) {
80                 Object JavaDoc o = text.get(i);
81                 if (o instanceof DecompiledMethod) {
82                     buf.append(((DecompiledMethod) o).getText());
83                 } else {
84                     buf.append(o);
85                 }
86             }
87             value = buf.toString();
88         }
89         return value;
90     }
91
92     public String JavaDoc[][] getTextTable() {
93         List JavaDoc lines = new ArrayList JavaDoc();
94         for (int i = 0; i < text.size(); ++i) {
95             Object JavaDoc o = text.get(i);
96             if (o instanceof DecompiledMethod) {
97                 String JavaDoc[][] mlines = ((DecompiledMethod) o).getTextTable();
98                 for (int j = 0; j < mlines.length; ++j) {
99                     lines.add(mlines[j]);
100                 }
101             } else {
102                 lines.add(new String JavaDoc[]{"", "", o.toString(), ""});
103             }
104         }
105         return (String JavaDoc[][]) lines.toArray(new String JavaDoc[lines.size()][]);
106     }
107
108     public int getBytecodeOffest(final int decompiledLine) {
109         int currentDecompiledLine = 0;
110         for (int i = 0; i < text.size(); ++i) {
111             Object JavaDoc o = text.get(i);
112             if (o instanceof DecompiledMethod) {
113                 DecompiledMethod m = (DecompiledMethod) o;
114                 Integer JavaDoc offset = m.getBytecodeOffset(decompiledLine - currentDecompiledLine);
115                 if(offset != null){
116                     return offset.intValue();
117                 }
118                 currentDecompiledLine += m.getLineCount();
119             } else {
120                 currentDecompiledLine++;
121             }
122         }
123         return -1;
124     }
125
126     public int getBytecodeInsn(final int decompiledLine) {
127       int currentDecompiledLine = 0;
128       for (int i = 0; i < text.size(); ++i) {
129           Object JavaDoc o = text.get(i);
130           if (o instanceof DecompiledMethod) {
131               DecompiledMethod m = (DecompiledMethod) o;
132               Integer JavaDoc opcode = m.getBytecodeInsn(decompiledLine - currentDecompiledLine);
133               if(opcode != null){
134                   return opcode.intValue();
135               }
136               currentDecompiledLine += m.getLineCount();
137           } else {
138               currentDecompiledLine++;
139           }
140       }
141       return -1;
142   }
143
144     public int getSourceLine(final int decompiledLine) {
145         int currentDecompiledLine = 0;
146         for (int i = 0; i < text.size(); ++i) {
147             Object JavaDoc o = text.get(i);
148             if (o instanceof DecompiledMethod) {
149                 DecompiledMethod m = (DecompiledMethod) o;
150                 int l = m.getSourceLine(decompiledLine - currentDecompiledLine);
151                 if (l != -1) {
152                     return l;
153                 }
154                 currentDecompiledLine += m.getLineCount();
155             } else {
156                 currentDecompiledLine++;
157             }
158         }
159         return -1;
160     }
161
162     public DecompiledMethod getMethod(final int decompiledLine) {
163         int currentDecompiledLine = 0;
164         for (int i = 0; i < text.size(); ++i) {
165             Object JavaDoc o = text.get(i);
166             if (o instanceof DecompiledMethod) {
167                 DecompiledMethod m = (DecompiledMethod) o;
168                 int l = m.getSourceLine(decompiledLine - currentDecompiledLine);
169                 if (l != -1) {
170                     return m;
171                 }
172                 currentDecompiledLine += m.getLineCount();
173             } else {
174                 currentDecompiledLine++;
175             }
176         }
177         return null;
178     }
179
180     public DecompiledMethod getMethod(final String JavaDoc signature) {
181         for (int i = 0; i < text.size(); ++i) {
182             Object JavaDoc o = text.get(i);
183             if (o instanceof DecompiledMethod) {
184                 DecompiledMethod m = (DecompiledMethod) o;
185                 if(signature.equals(m.getSignature())){
186                     return m;
187                 }
188             }
189         }
190         return null;
191     }
192
193     public IJavaElement getJavaElement(int decompiledLine, IClassFile clazz){
194         DecompiledMethod method = getMethod(decompiledLine);
195         if(method != null){
196             IJavaElement javaElement = (IJavaElement) methodToJavaElt.get(method);
197             if(javaElement == null) {
198                 javaElement = JdtUtils.getMethod(clazz, method.getSignature());
199                 if(javaElement != null) {
200                     methodToJavaElt.put(method, javaElement);
201                 } else {
202                     javaElement = clazz;
203                 }
204             }
205             return javaElement;
206         }
207         return clazz;
208     }
209
210     public int getDecompiledLine(String JavaDoc methSignature){
211         int currentDecompiledLine = 0;
212         for (int i = 0; i < text.size(); ++i) {
213             Object JavaDoc o = text.get(i);
214             if (o instanceof DecompiledMethod) {
215                 DecompiledMethod m = (DecompiledMethod) o;
216                 if(methSignature.equals(m.getSignature())){
217                     return currentDecompiledLine;
218                 }
219                 currentDecompiledLine += m.getLineCount();
220             } else {
221                 currentDecompiledLine++;
222             }
223         }
224         return 0;
225     }
226
227     /**
228      *
229      * @param decompiledLine
230      * @return array with two elements, first is the local variables table,
231      * second is the operands stack content. "null" value could be returned too.
232      */

233     public String JavaDoc [] getFrame(final int decompiledLine, final boolean showQualifiedNames) {
234       int currentDecompiledLine = 0;
235       for (int i = 0; i < text.size(); ++i) {
236           Object JavaDoc o = text.get(i);
237           if (o instanceof DecompiledMethod) {
238               DecompiledMethod m = (DecompiledMethod) o;
239               String JavaDoc [] frame = m.getFrame(decompiledLine
240                   - currentDecompiledLine, showQualifiedNames);
241               if (frame != null) {
242                   return frame;
243               }
244               currentDecompiledLine += m.getLineCount();
245           } else {
246               currentDecompiledLine++;
247           }
248       }
249       return null;
250     }
251
252     public String JavaDoc[][][] getFrameTables(final int decompiledLine, boolean useQualifiedNames) {
253       int currentDecompiledLine = 0;
254       for (int i = 0; i < text.size(); ++i) {
255           Object JavaDoc o = text.get(i);
256           if (o instanceof DecompiledMethod) {
257               DecompiledMethod m = (DecompiledMethod) o;
258               String JavaDoc[][][] frame = m.getFrameTables(decompiledLine - currentDecompiledLine, useQualifiedNames);
259               if (frame != null) {
260                    return frame;
261               }
262               currentDecompiledLine += m.getLineCount();
263           } else {
264               currentDecompiledLine++;
265           }
266       }
267       return null;
268     }
269
270     public int getDecompiledLine(final int sourceLine) {
271         int currentDecompiledLine = 0;
272         for (int i = 0; i < text.size(); ++i) {
273             Object JavaDoc o = text.get(i);
274             if (o instanceof DecompiledMethod) {
275                 DecompiledMethod m = (DecompiledMethod) o;
276                 int l = m.getDecompiledLine(sourceLine);
277                 if (l != -1) {
278                     return l + currentDecompiledLine;
279                 }
280                 currentDecompiledLine += m.getLineCount();
281             } else {
282                 currentDecompiledLine++;
283             }
284         }
285         return -1;
286     }
287
288     public List JavaDoc getErrorLines() {
289         List JavaDoc errors = new ArrayList JavaDoc();
290         int currentDecompiledLine = 0;
291         for (int i = 0; i < text.size(); ++i) {
292             Object JavaDoc o = text.get(i);
293             if (o instanceof DecompiledMethod) {
294                 DecompiledMethod m = (DecompiledMethod) o;
295                 int l = m.getErrorLine();
296                 if (l != -1) {
297                     errors.add(new Integer JavaDoc(l + currentDecompiledLine));
298                 }
299                 currentDecompiledLine += m.getLineCount();
300             } else {
301                 currentDecompiledLine++;
302             }
303         }
304         return errors;
305     }
306
307     public int getBestDecompiledMatch(int sourceLine) {
308         int bestMatch = -1;
309
310         for (int i = 0; i < text.size(); ++i) {
311             Object JavaDoc o = text.get(i);
312             if (o instanceof DecompiledMethod) {
313                 DecompiledMethod m = (DecompiledMethod) o;
314                 int line = m.getFirstSourceLine();
315                 if(line >= sourceLine){
316                     if(bestMatch == -1 || line < bestMatch){
317                         bestMatch = line;
318                     }
319                 }
320             }
321         }
322         return bestMatch;
323     }
324
325     public void setClassNode(ClassNode classNode) {
326         this.classNode = classNode;
327     }
328
329     public ClassNode getClassNode(){
330         return classNode;
331     }
332 }
333
Popular Tags