| 1 11 package org.eclipse.jdt.internal.core.util; 12 13 import java.io.PrintWriter ; 14 import java.io.StringWriter ; 15 16 import org.eclipse.jdt.core.JavaCore; 17 import org.eclipse.jdt.core.Signature; 18 import org.eclipse.jdt.core.compiler.CharOperation; 19 import org.eclipse.jdt.core.util.*; 20 import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants; 21 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 22 23 27 public class Disassembler extends ClassFileBytesDisassembler { 28 29 private static final char[] ANY_EXCEPTION = Messages.classfileformat_anyexceptionhandler.toCharArray(); 30 private static final String VERSION_UNKNOWN = Messages.classfileformat_versionUnknown; 31 32 private boolean appendModifier(StringBuffer buffer, int accessFlags, int modifierConstant, String modifier, boolean firstModifier) { 33 if ((accessFlags & modifierConstant) != 0) { 34 if (!firstModifier) { 35 buffer.append(Messages.disassembler_space); 36 } 37 if (firstModifier) { 38 firstModifier = false; 39 } 40 buffer.append(modifier); 41 } 42 return firstModifier; 43 } 44 45 private void decodeModifiers(StringBuffer buffer, int accessFlags, int[] checkBits) { 46 decodeModifiers(buffer, accessFlags, false, false, checkBits); 47 } 48 49 private void decodeModifiers(StringBuffer buffer, int accessFlags, boolean printDefault, boolean asBridge, int[] checkBits) { 50 if (checkBits == null) return; 51 boolean firstModifier = true; 52 for (int i = 0, max = checkBits.length; i < max; i++) { 53 switch(checkBits[i]) { 54 case IModifierConstants.ACC_PUBLIC : 55 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PUBLIC, "public", firstModifier); break; 57 case IModifierConstants.ACC_PROTECTED : 58 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PROTECTED, "protected", firstModifier); break; 60 case IModifierConstants.ACC_PRIVATE : 61 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PRIVATE, "private", firstModifier); break; 63 case IModifierConstants.ACC_ABSTRACT : 64 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ABSTRACT, "abstract", firstModifier); break; 66 case IModifierConstants.ACC_STATIC : 67 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STATIC, "static", firstModifier); break; 69 case IModifierConstants.ACC_FINAL : 70 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_FINAL, "final", firstModifier); break; 72 case IModifierConstants.ACC_SYNCHRONIZED : 73 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_SYNCHRONIZED, "synchronized", firstModifier); break; 75 case IModifierConstants.ACC_NATIVE : 76 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_NATIVE, "native", firstModifier); break; 78 case IModifierConstants.ACC_STRICT : 79 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STRICT, "strictfp", firstModifier); break; 81 case IModifierConstants.ACC_TRANSIENT : 82 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_TRANSIENT, "transient", firstModifier); break; 84 case IModifierConstants.ACC_VOLATILE : 85 if (asBridge) { 87 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_BRIDGE, "bridge", firstModifier); } else { 89 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_VOLATILE, "volatile", firstModifier); } 91 break; 92 case IModifierConstants.ACC_ENUM : 93 firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ENUM, "enum", firstModifier); break; 95 } 96 } 97 if (!firstModifier) { 98 if (!printDefault) buffer.append(Messages.disassembler_space); 99 } else if (printDefault) { 100 buffer.append("default"); } 103 } 104 105 private void decodeModifiersForField(StringBuffer buffer, int accessFlags) { 106 decodeModifiers(buffer, accessFlags, new int[] { 107 IModifierConstants.ACC_PUBLIC, 108 IModifierConstants.ACC_PROTECTED, 109 IModifierConstants.ACC_PRIVATE, 110 IModifierConstants.ACC_STATIC, 111 IModifierConstants.ACC_FINAL, 112 IModifierConstants.ACC_TRANSIENT, 113 IModifierConstants.ACC_VOLATILE, 114 IModifierConstants.ACC_ENUM 115 }); 116 } 117 118 private void decodeModifiersForFieldForWorkingCopy(StringBuffer buffer, int accessFlags) { 119 decodeModifiers(buffer, accessFlags, new int[] { 120 IModifierConstants.ACC_PUBLIC, 121 IModifierConstants.ACC_PROTECTED, 122 IModifierConstants.ACC_PRIVATE, 123 IModifierConstants.ACC_STATIC, 124 IModifierConstants.ACC_FINAL, 125 IModifierConstants.ACC_TRANSIENT, 126 IModifierConstants.ACC_VOLATILE, 127 }); 128 } 129 130 private final void decodeModifiersForInnerClasses(StringBuffer buffer, int accessFlags, boolean printDefault) { 131 decodeModifiers(buffer, accessFlags, printDefault, false, new int[] { 132 IModifierConstants.ACC_PUBLIC, 133 IModifierConstants.ACC_PROTECTED, 134 IModifierConstants.ACC_PRIVATE, 135 IModifierConstants.ACC_ABSTRACT, 136 IModifierConstants.ACC_STATIC, 137 IModifierConstants.ACC_FINAL, 138 }); 139 } 140 141 private final void decodeModifiersForMethod(StringBuffer buffer, int accessFlags) { 142 decodeModifiers(buffer, accessFlags, false, true, new int[] { 143 IModifierConstants.ACC_PUBLIC, 144 IModifierConstants.ACC_PROTECTED, 145 IModifierConstants.ACC_PRIVATE, 146 IModifierConstants.ACC_ABSTRACT, 147 IModifierConstants.ACC_STATIC, 148 IModifierConstants.ACC_FINAL, 149 IModifierConstants.ACC_SYNCHRONIZED, 150 IModifierConstants.ACC_NATIVE, 151 IModifierConstants.ACC_STRICT, 152 IModifierConstants.ACC_BRIDGE, 153 }); 154 } 155 156 private final void decodeModifiersForType(StringBuffer buffer, int accessFlags) { 157 decodeModifiers(buffer, accessFlags, new int[] { 158 IModifierConstants.ACC_PUBLIC, 159 IModifierConstants.ACC_ABSTRACT, 160 IModifierConstants.ACC_FINAL, 161 }); 162 } 163 public static String escapeString(String s) { 164 StringBuffer buffer = new StringBuffer (); 165 for (int i = 0, max = s.length(); i < max; i++) { 166 char c = s.charAt(i); 167 switch(c) { 168 case '\b' : 169 buffer.append("\\b"); break; 171 case '\t' : 172 buffer.append("\\t"); break; 174 case '\n' : 175 buffer.append("\\n"); break; 177 case '\f' : 178 buffer.append("\\f"); break; 180 case '\r' : 181 buffer.append("\\r"); break; 183 case '\0' : 184 buffer.append("\\0"); break; 186 case '\1' : 187 buffer.append("\\1"); break; 189 case '\2' : 190 buffer.append("\\2"); break; 192 case '\3' : 193 buffer.append("\\3"); break; 195 case '\4' : 196 buffer.append("\\4"); break; 198 case '\5' : 199 buffer.append("\\5"); break; 201 case '\6' : 202 buffer.append("\\6"); break; 204 case '\7' : 205 buffer.append("\\7"); break; 207 default: 208 buffer.append(c); 209 } 210 } 211 return buffer.toString(); 212 } 213 214 static String decodeStringValue(char[] chars) { 215 StringBuffer buffer = new StringBuffer (); 216 for (int i = 0, max = chars.length; i < max; i++) { 217 char c = chars[i]; 218 switch(c) { 219 case '\b' : 220 buffer.append("\\b"); break; 222 case '\t' : 223 buffer.append("\\t"); break; 225 case '\n' : 226 buffer.append("\\n"); break; 228 case '\f' : 229 buffer.append("\\f"); break; 231 case '\r' : 232 buffer.append("\\r"); break; 234 case '\0' : 235 buffer.append("\\0"); break; 237 case '\1' : 238 buffer.append("\\1"); break; 240 case '\2' : 241 buffer.append("\\2"); break; 243 case '\3' : 244 buffer.append("\\3"); break; 246 case '\4' : 247 buffer.append("\\4"); break; 249 case '\5' : 250 buffer.append("\\5"); break; 252 case '\6' : 253 buffer.append("\\6"); break; 255 case '\7' : 256 buffer.append("\\7"); break; 258 default: 259 buffer.append(c); 260 } 261 } 262 return buffer.toString(); 263 } 264 265 static String decodeStringValue(String s) { 266 return decodeStringValue(s.toCharArray()); 267 } 268 269 272 public String disassemble(byte[] classFileBytes, String lineSeparator) throws ClassFormatException { 273 try { 274 return disassemble(new ClassFileReader(classFileBytes, IClassFileReader.ALL), lineSeparator, ClassFileBytesDisassembler.DEFAULT); 275 } catch (ArrayIndexOutOfBoundsException e) { 276 StringWriter stringWriter = new StringWriter (); 277 PrintWriter writer = new PrintWriter (stringWriter); 278 e.printStackTrace(writer); 279 writer.flush(); 280 writer.close(); 281 throw new ClassFormatException(String.valueOf(stringWriter.getBuffer())); 282 } 283 } 284 285 288 public String disassemble(byte[] classFileBytes, String lineSeparator, int mode) throws ClassFormatException { 289 try { 290 return disassemble(new ClassFileReader(classFileBytes, IClassFileReader.ALL), lineSeparator, mode); 291 } catch (ArrayIndexOutOfBoundsException e) { 292 StringWriter stringWriter = new StringWriter (); 293 PrintWriter writer = new PrintWriter (stringWriter); 294 e.printStackTrace(writer); 295 writer.flush(); 296 writer.close(); 297 throw new ClassFormatException(String.valueOf(stringWriter.getBuffer())); 298 } 299 } 300 301 private void disassemble(IAnnotation annotation, StringBuffer buffer, String lineSeparator, int tabNumber) { 302 writeNewLine(buffer, lineSeparator, tabNumber + 1); 303 final int typeIndex = annotation.getTypeIndex(); 304 final char[] typeName = CharOperation.replaceOnCopy(annotation.getTypeName(), '/', '.'); 305 buffer.append( 306 Messages.bind(Messages.disassembler_annotationentrystart, new String [] { 307 Integer.toString(typeIndex), 308 new String (Signature.toCharArray(typeName)) 309 })); 310 final IAnnotationComponent[] components = annotation.getComponents(); 311 for (int i = 0, max = components.length; i < max; i++) { 312 disassemble(components[i], buffer, lineSeparator, tabNumber + 1); 313 } 314 writeNewLine(buffer, lineSeparator, tabNumber + 1); 315 buffer.append(Messages.disassembler_annotationentryend); 316 } 317 318 private void disassemble(IAnnotationComponent annotationComponent, StringBuffer buffer, String lineSeparator, int tabNumber) { 319 writeNewLine(buffer, lineSeparator, tabNumber + 1); 320 buffer.append( 321 Messages.bind(Messages.disassembler_annotationcomponent, 322 new String [] { 323 Integer.toString(annotationComponent.getComponentNameIndex()), 324 new String (annotationComponent.getComponentName()) 325 })); 326 disassemble(annotationComponent.getComponentValue(), buffer, lineSeparator, tabNumber + 1); 327 } 328 329 private void disassemble(IAnnotationComponentValue annotationComponentValue, StringBuffer buffer, String lineSeparator, int tabNumber) { 330 switch(annotationComponentValue.getTag()) { 331 case IAnnotationComponentValue.BYTE_TAG: 332 case IAnnotationComponentValue.CHAR_TAG: 333 case IAnnotationComponentValue.DOUBLE_TAG: 334 case IAnnotationComponentValue.FLOAT_TAG: 335 case IAnnotationComponentValue.INTEGER_TAG: 336 case IAnnotationComponentValue.LONG_TAG: 337 case IAnnotationComponentValue.SHORT_TAG: 338 case IAnnotationComponentValue.BOOLEAN_TAG: 339 case IAnnotationComponentValue.STRING_TAG: 340 IConstantPoolEntry constantPoolEntry = annotationComponentValue.getConstantValue(); 341 String value = null; 342 switch(constantPoolEntry.getKind()) { 343 case IConstantPoolConstant.CONSTANT_Long : 344 value = constantPoolEntry.getLongValue() + "L"; break; 346 case IConstantPoolConstant.CONSTANT_Float : 347 value = constantPoolEntry.getFloatValue() + "f"; break; 349 case IConstantPoolConstant.CONSTANT_Double : 350 value = Double.toString(constantPoolEntry.getDoubleValue()); 351 break; 352 case IConstantPoolConstant.CONSTANT_Integer: 353 switch(annotationComponentValue.getTag()) { 354 case IAnnotationComponentValue.CHAR_TAG : 355 value = "'" + (char) constantPoolEntry.getIntegerValue() + "'"; break; 357 case IAnnotationComponentValue.BOOLEAN_TAG : 358 value = constantPoolEntry.getIntegerValue() == 1 ? "true" : "false"; break; 360 case IAnnotationComponentValue.BYTE_TAG : 361 value = "(byte) " + constantPoolEntry.getIntegerValue(); break; 363 case IAnnotationComponentValue.SHORT_TAG : 364 value = "(short) " + constantPoolEntry.getIntegerValue(); break; 366 case IAnnotationComponentValue.INTEGER_TAG : 367 value = "(int) " + constantPoolEntry.getIntegerValue(); } 369 break; 370 case IConstantPoolConstant.CONSTANT_Utf8: 371 value = "\"" + decodeStringValue(constantPoolEntry.getUtf8Value()) + "\""; } 373 buffer.append(Messages.bind(Messages.disassembler_annotationdefaultvalue, value)); 374 break; 375 case IAnnotationComponentValue.ENUM_TAG: 376 final int enumConstantTypeNameIndex = annotationComponentValue.getEnumConstantTypeNameIndex(); 377 final char[] typeName = CharOperation.replaceOnCopy(annotationComponentValue.getEnumConstantTypeName(), '/', '.'); 378 final int enumConstantNameIndex = annotationComponentValue.getEnumConstantNameIndex(); 379 final char[] constantName = annotationComponentValue.getEnumConstantName(); 380 buffer.append(Messages.bind(Messages.disassembler_annotationenumvalue, 381 new String [] { 382 Integer.toString(enumConstantTypeNameIndex), 383 Integer.toString(enumConstantNameIndex), 384 new String (Signature.toCharArray(typeName)), 385 new String (constantName) 386 })); 387 break; 388 case IAnnotationComponentValue.CLASS_TAG: 389 final int classIndex = annotationComponentValue.getClassInfoIndex(); 390 constantPoolEntry = annotationComponentValue.getClassInfo(); 391 final char[] className = CharOperation.replaceOnCopy(constantPoolEntry.getUtf8Value(), '/', '.'); 392 buffer.append(Messages.bind(Messages.disassembler_annotationclassvalue, 393 new String [] { 394 Integer.toString(classIndex), 395 new String (Signature.toCharArray(className)) 396 })); 397 break; 398 case IAnnotationComponentValue.ANNOTATION_TAG: 399 buffer.append(Messages.disassembler_annotationannotationvalue); 400 IAnnotation annotation = annotationComponentValue.getAnnotationValue(); 401 disassemble(annotation, buffer, lineSeparator, tabNumber + 1); 402 break; 403 case IAnnotationComponentValue.ARRAY_TAG: 404 buffer.append(Messages.disassembler_annotationarrayvaluestart); 405 final IAnnotationComponentValue[] annotationComponentValues = annotationComponentValue.getAnnotationComponentValues(); 406 for (int i = 0, max = annotationComponentValues.length; i < max; i++) { 407 writeNewLine(buffer, lineSeparator, tabNumber + 1); 408 disassemble(annotationComponentValues[i], buffer, lineSeparator, tabNumber + 1); 409 } 410 writeNewLine(buffer, lineSeparator, tabNumber + 1); 411 buffer.append(Messages.disassembler_annotationarrayvalueend); 412 } 413 } 414 415 private void disassemble(IAnnotationDefaultAttribute annotationDefaultAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) { 416 writeNewLine(buffer, lineSeparator, tabNumber + 1); 417 buffer.append(Messages.disassembler_annotationdefaultheader); 418 IAnnotationComponentValue componentValue = annotationDefaultAttribute.getMemberValue(); 419 writeNewLine(buffer, lineSeparator, tabNumber + 2); 420 disassemble(componentValue, buffer, lineSeparator, tabNumber + 1); 421 } 422 423 private void disassemble(IClassFileAttribute classFileAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) { 424 writeNewLine(buffer, lineSeparator, tabNumber + 1); 425 buffer.append(Messages.bind(Messages.disassembler_genericattributeheader, 426 new String [] { 427 new String (classFileAttribute.getAttributeName()), 428 Long.toString(classFileAttribute.getAttributeLength()) 429 })); 430 } 431 432 private void disassembleEnumConstructor(IClassFileReader classFileReader, char[] className, IMethodInfo methodInfo, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) { 433 writeNewLine(buffer, lineSeparator, tabNumber); 434 final ICodeAttribute codeAttribute = methodInfo.getCodeAttribute(); 435 char[] methodDescriptor = methodInfo.getDescriptor(); 436 final IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS); 437 final IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS); 438 if (runtimeInvisibleAnnotationsAttribute != null) { 440 disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber + 1, mode); 441 writeNewLine(buffer, lineSeparator, tabNumber); 442 } 443 if (runtimeVisibleAnnotationsAttribute != null) { 444 disassembleAsModifier((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber + 1, mode); 445 writeNewLine(buffer, lineSeparator, tabNumber); 446 } 447 final int accessFlags = methodInfo.getAccessFlags(); 448 decodeModifiersForMethod(buffer, accessFlags & IModifierConstants.ACC_PRIVATE); 449 CharOperation.replace(methodDescriptor, '/', '.'); 450 final boolean isVarArgs = (accessFlags & IModifierConstants.ACC_VARARGS) != 0; 451 final char[] signature = Signature.toCharArray(methodDescriptor, returnClassName(className, '.', COMPACT), getParameterNames(methodDescriptor, codeAttribute, accessFlags) , !checkMode(mode, COMPACT), false, isVarArgs); 452 int index = CharOperation.indexOf(',', signature); 453 index = CharOperation.indexOf(',', signature, index + 1); 454 buffer.append(signature, 0, CharOperation.indexOf('(', signature) + 1); 455 buffer.append(signature, index + 2, signature.length - index - 2); 456 IExceptionAttribute exceptionAttribute = methodInfo.getExceptionAttribute(); 457 if (exceptionAttribute != null) { 458 buffer.append(" throws "); char[][] exceptionNames = exceptionAttribute.getExceptionNames(); 460 int length = exceptionNames.length; 461 for (int i = 0; i < length; i++) { 462 if (i != 0) { 463 buffer 464 .append(Messages.disassembler_comma) 465 .append(Messages.disassembler_space); 466 } 467 char[] exceptionName = exceptionNames[i]; 468 CharOperation.replace(exceptionName, '/', '.'); 469 buffer.append(returnClassName(exceptionName, '.', mode)); 470 } 471 } 472 if (((accessFlags & IModifierConstants.ACC_NATIVE) == 0) 473 && ((accessFlags & IModifierConstants.ACC_ABSTRACT) == 0)) { 474 buffer.append(" {"); final char[] returnType = Signature.getReturnType(methodDescriptor); 476 if (returnType.length == 1) { 477 switch(returnType[0]) { 478 case 'V' : 479 writeNewLine(buffer, lineSeparator, tabNumber); 480 break; 481 case 'I' : 482 case 'B' : 483 case 'J' : 484 case 'D' : 485 case 'F' : 486 case 'S' : 487 case 'C' : 488 writeNewLine(buffer, lineSeparator, tabNumber + 1); 489 buffer.append("return 0;"); writeNewLine(buffer, lineSeparator, tabNumber); 491 break; 492 default : 493 writeNewLine(buffer, lineSeparator, tabNumber + 1); 495 buffer.append("return false;"); writeNewLine(buffer, lineSeparator, tabNumber); 497 } 498 } else { 499 writeNewLine(buffer, lineSeparator, tabNumber + 1); 501 buffer.append("return null;"); writeNewLine(buffer, lineSeparator, tabNumber); 503 } 504 buffer.append('}'); 505 } else { 506 buffer.append(';'); 507 } 508 } 509 510 513 private void disassemble(IClassFileReader classFileReader, char[] className, IMethodInfo methodInfo, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) { 514 writeNewLine(buffer, lineSeparator, tabNumber); 515 final ICodeAttribute codeAttribute = methodInfo.getCodeAttribute(); 516 final char[] methodDescriptor = methodInfo.getDescriptor(); 517 final ISignatureAttribute signatureAttribute = (ISignatureAttribute) Util.getAttribute(methodInfo, IAttributeNamesConstants.SIGNATURE); 518 final IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS); 519 final IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS); 520 final IClassFileAttribute runtimeVisibleParameterAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS); 521 final IClassFileAttribute runtimeInvisibleParameterAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS); 522 final IClassFileAttribute annotationDefaultAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.ANNOTATION_DEFAULT); 523 if (checkMode(mode, SYSTEM | DETAILED)) { 524 buffer.append(Messages.bind(Messages.classfileformat_methoddescriptor, 525 new String [] { 526 Integer.toString(methodInfo.getDescriptorIndex()), 527 new String (methodDescriptor) 528 })); 529 if (methodInfo.isDeprecated()) { 530 buffer.append(Messages.disassembler_deprecated); 531 } 532 writeNewLine(buffer, lineSeparator, tabNumber); 533 if (signatureAttribute != null) { 534 buffer.append(Messages.bind(Messages.disassembler_signatureattributeheader, new String (signatureAttribute.getSignature()))); 535 writeNewLine(buffer, lineSeparator, tabNumber); 536 } 537 if (codeAttribute != null) { 538 buffer.append(Messages.bind(Messages.classfileformat_stacksAndLocals, 539 new String [] { 540 Integer.toString(codeAttribute.getMaxStack()), 541 Integer.toString(codeAttribute.getMaxLocals()) 542 })); 543 writeNewLine(buffer, lineSeparator, tabNumber); 544 } 545 } 546 if (checkMode(mode, DETAILED)) { 547 if (runtimeInvisibleAnnotationsAttribute != null) { 549 disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber + 1, mode); 550 writeNewLine(buffer, lineSeparator, tabNumber); 551 } 552 if (runtimeVisibleAnnotationsAttribute != null) { 553 disassembleAsModifier((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber + 1, mode); 554 writeNewLine(buffer, lineSeparator, tabNumber); 555 } 556 } 557 final int accessFlags = methodInfo.getAccessFlags(); 558 decodeModifiersForMethod(buffer, accessFlags); 559 if (methodInfo.isSynthetic() && !checkMode(mode, WORKING_COPY)) { 560 buffer.append("synthetic"); buffer.append(Messages.disassembler_space); 562 } 563 CharOperation.replace(methodDescriptor, '/', '.'); 564 final boolean isVarArgs = isVarArgs(methodInfo); 565 if (methodInfo.isConstructor()) { 566 if (checkMode(mode, WORKING_COPY) && signatureAttribute != null) { 567 final char[] signature = signatureAttribute.getSignature(); 568 CharOperation.replace(signature, '/', '.'); 569 disassembleGenericSignature(mode, buffer, signature); 570 buffer.append(' '); 571 buffer.append(Signature.toCharArray(signature, returnClassName(className, '.', COMPACT), getParameterNames(methodDescriptor, codeAttribute, accessFlags) , !checkMode(mode, COMPACT), false, isVarArgs)); 572 } else { 573 buffer.append(Signature.toCharArray(methodDescriptor, returnClassName(className, '.', COMPACT), getParameterNames(methodDescriptor, codeAttribute, accessFlags) , !checkMode(mode, COMPACT), false, isVarArgs)); 574 } 575 } else if (methodInfo.isClinit()) { 576 buffer.append(Messages.bind(Messages.classfileformat_clinitname)); 577 } else { 578 if (checkMode(mode, WORKING_COPY) && signatureAttribute != null) { 579 final char[] signature = signatureAttribute.getSignature(); 580 CharOperation.replace(signature, '/', '.'); 581 disassembleGenericSignature(mode, buffer, signature); 582 buffer.append(' '); 583 buffer.append(Signature.toCharArray(signature, methodInfo.getName(), getParameterNames(methodDescriptor, codeAttribute, accessFlags) , !checkMode(mode, COMPACT), true, isVarArgs)); 584 } else { 585 buffer.append(Signature.toCharArray(methodDescriptor, methodInfo.getName(), getParameterNames(methodDescriptor, codeAttribute, accessFlags) , !checkMode(mode, COMPACT), true, isVarArgs)); 586 } 587 } 588 IExceptionAttribute exceptionAttribute = methodInfo.getExceptionAttribute(); 589 if (exceptionAttribute != null) { 590 buffer.append(" throws "); char[][] exceptionNames = exceptionAttribute.getExceptionNames(); 592 int length = exceptionNames.length; 593 for (int i = 0; i < length; i++) { 594 if (i != 0) { 595 buffer 596 .append(Messages.disassembler_comma) 597 .append(Messages.disassembler_space); 598 } 599 char[] exceptionName = exceptionNames[i]; 600 CharOperation.replace(exceptionName, '/', '.'); 601 buffer.append(returnClassName(exceptionName, '.', mode)); 602 } 603 } 604 if (checkMode(mode, DETAILED)) { 605 if (annotationDefaultAttribute != null) { 606 buffer.append(" default "); disassembleAsModifier((IAnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber, mode); 608 } 609 } 610 if (checkMode(mode, WORKING_COPY)) { 611 if (annotationDefaultAttribute != null) { 613 buffer.append(" default "); disassembleAsModifier((IAnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber, mode); 615 } 616 if (((accessFlags & IModifierConstants.ACC_NATIVE) == 0) 617 && ((accessFlags & IModifierConstants.ACC_ABSTRACT) == 0)) { 618 buffer.append(" {"); final char[] returnType = Signature.getReturnType(methodDescriptor); 620 if (returnType.length == 1) { 621 switch(returnType[0]) { 622 case 'V' : 623 writeNewLine(buffer, lineSeparator, tabNumber); 624
|