1 package de.loskutov.bco.asm; 2 3 import java.util.ArrayList ; 4 import java.util.HashMap ; 5 import java.util.List ; 6 import java.util.Map ; 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 18 19 public class DecompiledClass { 20 21 public static final String ATTR_CLAS_SIZE = "class.size"; 22 public static final String ATTR_JAVA_VERSION = "java.version"; 23 public static final String ATTR_ACCESS_FLAGS = "access"; 24 25 26 private Map methodToJavaElt; 27 private List text; 28 31 private Map classAttributesMap = new HashMap (); 32 private String value; 33 private ClassNode classNode; 34 35 public DecompiledClass(final List text) { 36 this.text = text; 37 methodToJavaElt = new HashMap (); 38 } 39 40 public void setAttribute(String key, String value){ 41 classAttributesMap.put(key, value); 42 } 43 44 48 public int getAccessFlags(){ 49 int result = 0; 50 String flags = (String ) classAttributesMap.get(ATTR_ACCESS_FLAGS); 51 if(flags == null){ 52 return result; 53 } 54 try { 55 Integer intFlags = Integer.valueOf(flags); 56 result = intFlags.intValue(); 57 } catch (NumberFormatException e) { 58 } 60 return result; 61 } 62 63 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 getAttribute(String key){ 73 return (String )classAttributesMap.get(key); 74 } 75 76 public String getText() { 77 if (value == null) { 78 StringBuffer buf = new StringBuffer (); 79 for (int i = 0; i < text.size(); ++i) { 80 Object 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 [][] getTextTable() { 93 List lines = new ArrayList (); 94 for (int i = 0; i < text.size(); ++i) { 95 Object o = text.get(i); 96 if (o instanceof DecompiledMethod) { 97 String [][] 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 []{"", "", o.toString(), ""}); 103 } 104 } 105 return (String [][]) lines.toArray(new String [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 o = text.get(i); 112 if (o instanceof DecompiledMethod) { 113 DecompiledMethod m = (DecompiledMethod) o; 114 Integer 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 o = text.get(i); 130 if (o instanceof DecompiledMethod) { 131 DecompiledMethod m = (DecompiledMethod) o; 132 Integer 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 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 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 signature) { 181 for (int i = 0; i < text.size(); ++i) { 182 Object 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 methSignature){ 211 int currentDecompiledLine = 0; 212 for (int i = 0; i < text.size(); ++i) { 213 Object 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 233 public String [] getFrame(final int decompiledLine, final boolean showQualifiedNames) { 234 int currentDecompiledLine = 0; 235 for (int i = 0; i < text.size(); ++i) { 236 Object o = text.get(i); 237 if (o instanceof DecompiledMethod) { 238 DecompiledMethod m = (DecompiledMethod) o; 239 String [] 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 [][][] getFrameTables(final int decompiledLine, boolean useQualifiedNames) { 253 int currentDecompiledLine = 0; 254 for (int i = 0; i < text.size(); ++i) { 255 Object o = text.get(i); 256 if (o instanceof DecompiledMethod) { 257 DecompiledMethod m = (DecompiledMethod) o; 258 String [][][] 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 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 getErrorLines() { 289 List errors = new ArrayList (); 290 int currentDecompiledLine = 0; 291 for (int i = 0; i < text.size(); ++i) { 292 Object 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 (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 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 |