< prev index next >

src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java

Print this page

 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package com.sun.tools.javap;
 27 
 28 import java.lang.reflect.AccessFlag;
 29 import java.net.URI;
 30 import java.text.DateFormat;
 31 import java.util.Collection;
 32 import java.util.Date;
 33 import java.util.EnumSet;
 34 import java.util.List;
 35 import java.util.Set;
 36 
 37 import java.lang.constant.ClassDesc;
 38 import java.lang.reflect.Modifier;
 39 import java.util.ArrayList;
 40 import java.util.LinkedHashSet;


 41 import java.lang.classfile.AccessFlags;
 42 import java.lang.classfile.Attributes;
 43 import java.lang.classfile.ClassModel;
 44 import java.lang.classfile.ClassSignature;
 45 import java.lang.classfile.ClassFile;
 46 import static java.lang.classfile.ClassFile.*;
 47 import java.lang.classfile.ClassHierarchyResolver;
 48 import java.lang.classfile.constantpool.*;
 49 import java.lang.classfile.FieldModel;
 50 import java.lang.classfile.MethodModel;
 51 import java.lang.classfile.MethodSignature;
 52 import java.lang.classfile.Signature;
 53 import java.lang.classfile.attribute.CodeAttribute;
 54 import java.lang.classfile.attribute.SignatureAttribute;
 55 
 56 /*
 57  *  The main javap class to write the contents of a class file as text.
 58  *
 59  *  <p><b>This is NOT part of any supported API.
 60  *  If you write code that depends on this, you do so at your own risk.

134                     println("Last modified " + df.format(lm));
135                 }
136             } else if (size > 0) {
137                 println("Size " + size + " bytes");
138             }
139             if (digestName != null && digest != null) {
140                 StringBuilder sb = new StringBuilder();
141                 for (byte b: digest)
142                     sb.append(String.format("%02x", b));
143                 println(digestName + " checksum " + sb);
144             }
145         }
146 
147         cm.findAttribute(Attributes.sourceFile()).ifPresent(sfa ->
148             println("Compiled from \"" + sfa.sourceFile().stringValue() + "\""));
149 
150         if (options.sysInfo || options.verbose) {
151             indent(-1);
152         }
153 
154         writeModifiers(getClassModifiers(cm.flags()));
155 
156         if ((classModel.flags().flagsMask() & ACC_MODULE) != 0) {
157             var attr = classModel.findAttribute(Attributes.module());
158             if (attr.isPresent()) {
159                 var modAttr = attr.get();
160                 if ((modAttr.moduleFlagsMask() & ACC_OPEN) != 0) {
161                     print("open ");
162                 }
163                 print("module ");
164                 print(() -> modAttr.moduleName().name().stringValue());
165                 if (modAttr.moduleVersion().isPresent()) {
166                     print("@");
167                     print(() -> modAttr.moduleVersion().get().stringValue());
168                 }
169             } else {
170                 // fallback for malformed class files
171                 print("class ");
172                 print(() -> getJavaName(classModel.thisClass().asInternalName()));
173             }
174         } else {

431             var a = f.findAttribute(Attributes.constantValue());
432             if (a.isPresent()) {
433                 print(" = ");
434                 var cv = a.get();
435                 print(() -> getConstantValue(f.fieldTypeSymbol(), cv.constant()));
436             }
437         }
438         print(";");
439         println();
440 
441         indent(+1);
442 
443         boolean showBlank = false;
444 
445         if (options.showDescriptors) {
446             print("descriptor: ");println(() -> f.fieldType().stringValue());
447         }
448 
449         if (options.verbose)
450             writeList(String.format("flags: (0x%04x) ", flags.flagsMask()),
451                     flagsReportUnknown(flags).stream().map(fl -> "ACC_" + fl.name()).toList(),
452                     "\n");
453 
454         if (options.showAllAttrs) {
455             attrWriter.write(f.attributes());
456             showBlank = true;
457         }
458 
459         indent(-1);
460 
461         if (showBlank || options.showDisassembled || options.showLineAndLocalVariableTables)
462             println();
463     }
464 
465     protected void writeMethods() {
466         for (MethodModel m: classModel.methods())
467             writeMethod(m);
468         setPendingNewline(false);
469     }
470 
471     private static final int DEFAULT_ALLOWED_MAJOR_VERSION = 52;

791             case '\r': return "\\r";
792             case '\\': return "\\\\";
793             case '\'': return "\\'";
794             case '\"': return "\\\"";
795             default:   return String.format("\\u%04x", (int) c);
796         }
797     }
798 
799     private Set<String> getClassModifiers(AccessFlags flags) {
800         var flagSet = flagsReportUnknown(flags);
801         Set<AccessFlag> set;
802         if (flagSet.contains(AccessFlag.INTERFACE)) {
803             set = EnumSet.copyOf(flagSet);
804             set.remove(AccessFlag.ABSTRACT);
805         } else {
806             set = flagSet;
807         }
808         return getModifiers(set);
809     }
810 














811     private static Set<String> getModifiers(Set<java.lang.reflect.AccessFlag> flags) {
812         Set<String> s = new LinkedHashSet<>();
813         for (var f : flags)
814             if (f.sourceModifier()) s.add(Modifier.toString(f.mask()));
815         return s;
816     }
817 
818     private Set<String> getClassFlags(AccessFlags flags) {
819         return getFlags(flags.flagsMask(), flagsReportUnknown(flags));
820     }
821 
822     private static Set<String> getFlags(int mask, Set<java.lang.reflect.AccessFlag> flags) {
823         Set<String> s = new LinkedHashSet<>();
824         for (var f: flags) {
825             s.add("ACC_" + f.name());
826             mask = mask & ~f.mask();
827         }
828         while (mask != 0) {
829             int bit = Integer.highestOneBit(mask);
830             s.add("0x" + Integer.toHexString(bit));

 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package com.sun.tools.javap;
 27 
 28 import java.lang.reflect.AccessFlag;
 29 import java.net.URI;
 30 import java.text.DateFormat;
 31 import java.util.Collection;
 32 import java.util.Date;
 33 import java.util.EnumSet;
 34 import java.util.List;
 35 import java.util.Set;
 36 
 37 import java.lang.constant.ClassDesc;
 38 import java.lang.reflect.Modifier;
 39 import java.util.ArrayList;
 40 import java.util.LinkedHashSet;
 41 
 42 import com.sun.tools.javac.code.Source;
 43 import java.lang.classfile.AccessFlags;
 44 import java.lang.classfile.Attributes;
 45 import java.lang.classfile.ClassModel;
 46 import java.lang.classfile.ClassSignature;
 47 import java.lang.classfile.ClassFile;
 48 import static java.lang.classfile.ClassFile.*;
 49 import java.lang.classfile.ClassHierarchyResolver;
 50 import java.lang.classfile.constantpool.*;
 51 import java.lang.classfile.FieldModel;
 52 import java.lang.classfile.MethodModel;
 53 import java.lang.classfile.MethodSignature;
 54 import java.lang.classfile.Signature;
 55 import java.lang.classfile.attribute.CodeAttribute;
 56 import java.lang.classfile.attribute.SignatureAttribute;
 57 
 58 /*
 59  *  The main javap class to write the contents of a class file as text.
 60  *
 61  *  <p><b>This is NOT part of any supported API.
 62  *  If you write code that depends on this, you do so at your own risk.

136                     println("Last modified " + df.format(lm));
137                 }
138             } else if (size > 0) {
139                 println("Size " + size + " bytes");
140             }
141             if (digestName != null && digest != null) {
142                 StringBuilder sb = new StringBuilder();
143                 for (byte b: digest)
144                     sb.append(String.format("%02x", b));
145                 println(digestName + " checksum " + sb);
146             }
147         }
148 
149         cm.findAttribute(Attributes.sourceFile()).ifPresent(sfa ->
150             println("Compiled from \"" + sfa.sourceFile().stringValue() + "\""));
151 
152         if (options.sysInfo || options.verbose) {
153             indent(-1);
154         }
155 
156         writeModifiers(getClassModifiers(cm.flags(), classModel.majorVersion(), classModel.minorVersion()));
157 
158         if ((classModel.flags().flagsMask() & ACC_MODULE) != 0) {
159             var attr = classModel.findAttribute(Attributes.module());
160             if (attr.isPresent()) {
161                 var modAttr = attr.get();
162                 if ((modAttr.moduleFlagsMask() & ACC_OPEN) != 0) {
163                     print("open ");
164                 }
165                 print("module ");
166                 print(() -> modAttr.moduleName().name().stringValue());
167                 if (modAttr.moduleVersion().isPresent()) {
168                     print("@");
169                     print(() -> modAttr.moduleVersion().get().stringValue());
170                 }
171             } else {
172                 // fallback for malformed class files
173                 print("class ");
174                 print(() -> getJavaName(classModel.thisClass().asInternalName()));
175             }
176         } else {

433             var a = f.findAttribute(Attributes.constantValue());
434             if (a.isPresent()) {
435                 print(" = ");
436                 var cv = a.get();
437                 print(() -> getConstantValue(f.fieldTypeSymbol(), cv.constant()));
438             }
439         }
440         print(";");
441         println();
442 
443         indent(+1);
444 
445         boolean showBlank = false;
446 
447         if (options.showDescriptors) {
448             print("descriptor: ");println(() -> f.fieldType().stringValue());
449         }
450 
451         if (options.verbose)
452             writeList(String.format("flags: (0x%04x) ", flags.flagsMask()),
453                     flagsReportUnknown(flags).stream().map(fl -> "ACC_" + fl.toString()).toList(),
454                     "\n");
455 
456         if (options.showAllAttrs) {
457             attrWriter.write(f.attributes());
458             showBlank = true;
459         }
460 
461         indent(-1);
462 
463         if (showBlank || options.showDisassembled || options.showLineAndLocalVariableTables)
464             println();
465     }
466 
467     protected void writeMethods() {
468         for (MethodModel m: classModel.methods())
469             writeMethod(m);
470         setPendingNewline(false);
471     }
472 
473     private static final int DEFAULT_ALLOWED_MAJOR_VERSION = 52;

793             case '\r': return "\\r";
794             case '\\': return "\\\\";
795             case '\'': return "\\'";
796             case '\"': return "\\\"";
797             default:   return String.format("\\u%04x", (int) c);
798         }
799     }
800 
801     private Set<String> getClassModifiers(AccessFlags flags) {
802         var flagSet = flagsReportUnknown(flags);
803         Set<AccessFlag> set;
804         if (flagSet.contains(AccessFlag.INTERFACE)) {
805             set = EnumSet.copyOf(flagSet);
806             set.remove(AccessFlag.ABSTRACT);
807         } else {
808             set = flagSet;
809         }
810         return getModifiers(set);
811     }
812 
813     private static Set<String> getClassModifiers(AccessFlags flags, int majorVersion, int minorVersion) {
814         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
815         Set<AccessFlag> flagSet = flags.flags();
816         if (flagSet.contains(AccessFlag.INTERFACE)) {
817             flagSet = EnumSet.copyOf(flagSet);
818             flagSet.remove(AccessFlag.ABSTRACT);
819         } else if (Source.isSupported(Source.Feature.VALUE_CLASSES, majorVersion) && previewClassFile) {
820           Set<String> classModifers = getModifiers(flagSet);
821           classModifers.add("value");
822           return classModifers;
823         }
824         return getModifiers(flagSet);
825     }
826 
827     private static Set<String> getModifiers(Set<java.lang.reflect.AccessFlag> flags) {
828         Set<String> s = new LinkedHashSet<>();
829         for (var f : flags)
830             if (f.sourceModifier()) s.add(Modifier.toString(f.mask()));
831         return s;
832     }
833 
834     private Set<String> getClassFlags(AccessFlags flags) {
835         return getFlags(flags.flagsMask(), flagsReportUnknown(flags));
836     }
837 
838     private static Set<String> getFlags(int mask, Set<java.lang.reflect.AccessFlag> flags) {
839         Set<String> s = new LinkedHashSet<>();
840         for (var f: flags) {
841             s.add("ACC_" + f.name());
842             mask = mask & ~f.mask();
843         }
844         while (mask != 0) {
845             int bit = Integer.highestOneBit(mask);
846             s.add("0x" + Integer.toHexString(bit));
< prev index next >