41 import com.sun.tools.classfile.ConstantValue_attribute; 42 import com.sun.tools.classfile.Descriptor; 43 import com.sun.tools.classfile.Descriptor.InvalidDescriptor; 44 import com.sun.tools.classfile.Exceptions_attribute; 45 import com.sun.tools.classfile.Field; 46 import com.sun.tools.classfile.Method; 47 import com.sun.tools.classfile.Module_attribute; 48 import com.sun.tools.classfile.Signature; 49 import com.sun.tools.classfile.Signature_attribute; 50 import com.sun.tools.classfile.SourceFile_attribute; 51 import com.sun.tools.classfile.Type; 52 import com.sun.tools.classfile.Type.ArrayType; 53 import com.sun.tools.classfile.Type.ClassSigType; 54 import com.sun.tools.classfile.Type.ClassType; 55 import com.sun.tools.classfile.Type.MethodType; 56 import com.sun.tools.classfile.Type.SimpleType; 57 import com.sun.tools.classfile.Type.TypeParamType; 58 import com.sun.tools.classfile.Type.WildcardType; 59 60 import static com.sun.tools.classfile.AccessFlags.*; 61 62 /* 63 * The main javap class to write the contents of a class file as text. 64 * 65 * <p><b>This is NOT part of any supported API. 66 * If you write code that depends on this, you do so at your own risk. 67 * This code and its internal interfaces are subject to change or 68 * deletion without notice.</b> 69 */ 70 public class ClassWriter extends BasicWriter { 71 static ClassWriter instance(Context context) { 72 ClassWriter instance = context.get(ClassWriter.class); 73 if (instance == null) 74 instance = new ClassWriter(context); 75 return instance; 76 } 77 78 protected ClassWriter(Context context) { 79 super(context); 80 context.put(ClassWriter.class, this); 149 } 150 151 Attribute sfa = cf.getAttribute(Attribute.SourceFile); 152 if (sfa instanceof SourceFile_attribute) { 153 println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\""); 154 } 155 156 if (options.sysInfo || options.verbose) { 157 indent(-1); 158 } 159 160 AccessFlags flags = cf.access_flags; 161 writeModifiers(flags.getClassModifiers()); 162 163 if (classFile.access_flags.is(AccessFlags.ACC_MODULE)) { 164 Attribute attr = classFile.attributes.get(Attribute.Module); 165 if (attr instanceof Module_attribute) { 166 Module_attribute modAttr = (Module_attribute) attr; 167 String name; 168 try { 169 name = getJavaName(constant_pool.getUTF8Value(modAttr.module_name)); 170 } catch (ConstantPoolException e) { 171 name = report(e); 172 } 173 if ((modAttr.module_flags & Module_attribute.ACC_OPEN) != 0) { 174 print("open "); 175 } 176 print("module "); 177 print(name); 178 } else { 179 // fallback for malformed class files 180 print("class "); 181 print(getJavaName(classFile)); 182 } 183 } else { 184 if (classFile.isClass()) 185 print("class "); 186 else if (classFile.isInterface()) 187 print("interface "); 188 189 print(getJavaName(classFile)); 190 } 191 192 Signature_attribute sigAttr = getSignature(cf.attributes); 193 if (sigAttr == null) { 194 // use info from class file header 195 if (classFile.isClass() && classFile.super_class != 0 ) { 196 String sn = getJavaSuperclassName(cf); 197 if (!sn.equals("java.lang.Object")) { 585 void writeModifiers(Collection<String> items) { 586 for (Object item: items) { 587 print(item); 588 print(" "); 589 } 590 } 591 592 void writeDirectives() { 593 Attribute attr = classFile.attributes.get(Attribute.Module); 594 if (!(attr instanceof Module_attribute)) 595 return; 596 597 Module_attribute m = (Module_attribute) attr; 598 for (Module_attribute.RequiresEntry entry: m.requires) { 599 print("requires"); 600 if ((entry.requires_flags & Module_attribute.ACC_STATIC_PHASE) != 0) 601 print(" static"); 602 if ((entry.requires_flags & Module_attribute.ACC_TRANSITIVE) != 0) 603 print(" transitive"); 604 print(" "); 605 print(getUTF8Value(entry.requires_index).replace('/', '.')); 606 println(";"); 607 } 608 609 for (Module_attribute.ExportsEntry entry: m.exports) { 610 print("exports"); 611 print(" "); 612 print(getUTF8Value(entry.exports_index).replace('/', '.')); 613 boolean first = true; 614 for (int i: entry.exports_to_index) { 615 String mname; 616 try { 617 mname = classFile.constant_pool.getUTF8Value(i).replace('/', '.'); 618 } catch (ConstantPoolException e) { 619 mname = report(e); 620 } 621 if (first) { 622 println(" to"); 623 indent(+1); 624 first = false; 625 } else { 626 println(","); 627 } 628 print(mname); 629 } 630 println(";"); 631 if (!first) 632 indent(-1); 633 } 634 635 for (Module_attribute.OpensEntry entry: m.opens) { 636 print("opens"); 637 print(" "); 638 print(getUTF8Value(entry.opens_index).replace('/', '.')); 639 boolean first = true; 640 for (int i: entry.opens_to_index) { 641 String mname; 642 try { 643 mname = classFile.constant_pool.getUTF8Value(i).replace('/', '.'); 644 } catch (ConstantPoolException e) { 645 mname = report(e); 646 } 647 if (first) { 648 println(" to"); 649 indent(+1); 650 first = false; 651 } else { 652 println(","); 653 } 654 print(mname); 655 } 656 println(";"); 657 if (!first) 658 indent(-1); 659 } 660 661 for (int entry: m.uses_index) { 662 print("uses "); 663 print(getClassName(entry).replace('/', '.')); 667 for (Module_attribute.ProvidesEntry entry: m.provides) { 668 print("provides "); 669 print(getClassName(entry.provides_index).replace('/', '.')); 670 boolean first = true; 671 for (int i: entry.with_index) { 672 if (first) { 673 println(" with"); 674 indent(+1); 675 first = false; 676 } else { 677 println(","); 678 } 679 print(getClassName(i).replace('/', '.')); 680 } 681 println(";"); 682 if (!first) 683 indent(-1); 684 } 685 } 686 687 String getUTF8Value(int index) { 688 try { 689 return classFile.constant_pool.getUTF8Value(index); 690 } catch (ConstantPoolException e) { 691 return report(e); 692 } 693 } 694 695 String getClassName(int index) { 696 try { 697 return classFile.constant_pool.getClassInfo(index).getName(); 698 } catch (ConstantPoolException e) { 699 return report(e); 700 } 701 } 702 703 void writeList(String prefix, Collection<?> items, String suffix) { 704 print(prefix); 705 String sep = ""; 706 for (Object item: items) { | 41 import com.sun.tools.classfile.ConstantValue_attribute; 42 import com.sun.tools.classfile.Descriptor; 43 import com.sun.tools.classfile.Descriptor.InvalidDescriptor; 44 import com.sun.tools.classfile.Exceptions_attribute; 45 import com.sun.tools.classfile.Field; 46 import com.sun.tools.classfile.Method; 47 import com.sun.tools.classfile.Module_attribute; 48 import com.sun.tools.classfile.Signature; 49 import com.sun.tools.classfile.Signature_attribute; 50 import com.sun.tools.classfile.SourceFile_attribute; 51 import com.sun.tools.classfile.Type; 52 import com.sun.tools.classfile.Type.ArrayType; 53 import com.sun.tools.classfile.Type.ClassSigType; 54 import com.sun.tools.classfile.Type.ClassType; 55 import com.sun.tools.classfile.Type.MethodType; 56 import com.sun.tools.classfile.Type.SimpleType; 57 import com.sun.tools.classfile.Type.TypeParamType; 58 import com.sun.tools.classfile.Type.WildcardType; 59 60 import static com.sun.tools.classfile.AccessFlags.*; 61 import static com.sun.tools.classfile.ConstantPool.CONSTANT_Module; 62 import static com.sun.tools.classfile.ConstantPool.CONSTANT_Package; 63 64 /* 65 * The main javap class to write the contents of a class file as text. 66 * 67 * <p><b>This is NOT part of any supported API. 68 * If you write code that depends on this, you do so at your own risk. 69 * This code and its internal interfaces are subject to change or 70 * deletion without notice.</b> 71 */ 72 public class ClassWriter extends BasicWriter { 73 static ClassWriter instance(Context context) { 74 ClassWriter instance = context.get(ClassWriter.class); 75 if (instance == null) 76 instance = new ClassWriter(context); 77 return instance; 78 } 79 80 protected ClassWriter(Context context) { 81 super(context); 82 context.put(ClassWriter.class, this); 151 } 152 153 Attribute sfa = cf.getAttribute(Attribute.SourceFile); 154 if (sfa instanceof SourceFile_attribute) { 155 println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\""); 156 } 157 158 if (options.sysInfo || options.verbose) { 159 indent(-1); 160 } 161 162 AccessFlags flags = cf.access_flags; 163 writeModifiers(flags.getClassModifiers()); 164 165 if (classFile.access_flags.is(AccessFlags.ACC_MODULE)) { 166 Attribute attr = classFile.attributes.get(Attribute.Module); 167 if (attr instanceof Module_attribute) { 168 Module_attribute modAttr = (Module_attribute) attr; 169 String name; 170 try { 171 // FIXME: compatibility code 172 if (constant_pool.get(modAttr.module_name).getTag() == CONSTANT_Module) { 173 name = getJavaName(constant_pool.getModuleInfo(modAttr.module_name).getName()); 174 } else { 175 name = getJavaName(constant_pool.getUTF8Value(modAttr.module_name)); 176 } 177 } catch (ConstantPoolException e) { 178 name = report(e); 179 } 180 if ((modAttr.module_flags & Module_attribute.ACC_OPEN) != 0) { 181 print("open "); 182 } 183 print("module "); 184 print(name); 185 if (modAttr.module_version_index != 0) { 186 print("@"); 187 print(getUTF8Value(modAttr.module_version_index)); 188 } 189 } else { 190 // fallback for malformed class files 191 print("class "); 192 print(getJavaName(classFile)); 193 } 194 } else { 195 if (classFile.isClass()) 196 print("class "); 197 else if (classFile.isInterface()) 198 print("interface "); 199 200 print(getJavaName(classFile)); 201 } 202 203 Signature_attribute sigAttr = getSignature(cf.attributes); 204 if (sigAttr == null) { 205 // use info from class file header 206 if (classFile.isClass() && classFile.super_class != 0 ) { 207 String sn = getJavaSuperclassName(cf); 208 if (!sn.equals("java.lang.Object")) { 596 void writeModifiers(Collection<String> items) { 597 for (Object item: items) { 598 print(item); 599 print(" "); 600 } 601 } 602 603 void writeDirectives() { 604 Attribute attr = classFile.attributes.get(Attribute.Module); 605 if (!(attr instanceof Module_attribute)) 606 return; 607 608 Module_attribute m = (Module_attribute) attr; 609 for (Module_attribute.RequiresEntry entry: m.requires) { 610 print("requires"); 611 if ((entry.requires_flags & Module_attribute.ACC_STATIC_PHASE) != 0) 612 print(" static"); 613 if ((entry.requires_flags & Module_attribute.ACC_TRANSITIVE) != 0) 614 print(" transitive"); 615 print(" "); 616 String mname; 617 try { 618 mname = getModuleName(entry.requires_index); 619 } catch (ConstantPoolException e) { 620 mname = report(e); 621 } 622 print(mname); 623 println(";"); 624 } 625 626 for (Module_attribute.ExportsEntry entry: m.exports) { 627 print("exports"); 628 print(" "); 629 String pname; 630 try { 631 pname = getPackageName(entry.exports_index).replace('/', '.'); 632 } catch (ConstantPoolException e) { 633 pname = report(e); 634 } 635 print(pname); 636 boolean first = true; 637 for (int i: entry.exports_to_index) { 638 String mname; 639 try { 640 mname = getModuleName(i); 641 } catch (ConstantPoolException e) { 642 mname = report(e); 643 } 644 if (first) { 645 println(" to"); 646 indent(+1); 647 first = false; 648 } else { 649 println(","); 650 } 651 print(mname); 652 } 653 println(";"); 654 if (!first) 655 indent(-1); 656 } 657 658 for (Module_attribute.OpensEntry entry: m.opens) { 659 print("opens"); 660 print(" "); 661 String pname; 662 try { 663 pname = getPackageName(entry.opens_index).replace('/', '.'); 664 } catch (ConstantPoolException e) { 665 pname = report(e); 666 } 667 print(pname); 668 boolean first = true; 669 for (int i: entry.opens_to_index) { 670 String mname; 671 try { 672 mname = getModuleName(i); 673 } catch (ConstantPoolException e) { 674 mname = report(e); 675 } 676 if (first) { 677 println(" to"); 678 indent(+1); 679 first = false; 680 } else { 681 println(","); 682 } 683 print(mname); 684 } 685 println(";"); 686 if (!first) 687 indent(-1); 688 } 689 690 for (int entry: m.uses_index) { 691 print("uses "); 692 print(getClassName(entry).replace('/', '.')); 696 for (Module_attribute.ProvidesEntry entry: m.provides) { 697 print("provides "); 698 print(getClassName(entry.provides_index).replace('/', '.')); 699 boolean first = true; 700 for (int i: entry.with_index) { 701 if (first) { 702 println(" with"); 703 indent(+1); 704 first = false; 705 } else { 706 println(","); 707 } 708 print(getClassName(i).replace('/', '.')); 709 } 710 println(";"); 711 if (!first) 712 indent(-1); 713 } 714 } 715 716 String getModuleName(int index) throws ConstantPoolException { 717 if (constant_pool.get(index).getTag() == CONSTANT_Module) { 718 return constant_pool.getModuleInfo(index).getName(); 719 } else { 720 return constant_pool.getUTF8Value(index); 721 } 722 } 723 724 String getPackageName(int index) throws ConstantPoolException { 725 if (constant_pool.get(index).getTag() == CONSTANT_Package) { 726 return constant_pool.getPackageInfo(index).getName(); 727 } else { 728 return constant_pool.getUTF8Value(index); 729 } 730 } 731 732 String getUTF8Value(int index) { 733 try { 734 return classFile.constant_pool.getUTF8Value(index); 735 } catch (ConstantPoolException e) { 736 return report(e); 737 } 738 } 739 740 String getClassName(int index) { 741 try { 742 return classFile.constant_pool.getClassInfo(index).getName(); 743 } catch (ConstantPoolException e) { 744 return report(e); 745 } 746 } 747 748 void writeList(String prefix, Collection<?> items, String suffix) { 749 print(prefix); 750 String sep = ""; 751 for (Object item: items) { |