45 import javax.tools.JavaFileManager;
46 import javax.tools.JavaFileObject;
47
48 import com.sun.tools.javac.code.Source;
49 import com.sun.tools.javac.code.Source.Feature;
50 import com.sun.tools.javac.comp.Annotate;
51 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
52 import com.sun.tools.javac.code.*;
53 import com.sun.tools.javac.code.Directive.*;
54 import com.sun.tools.javac.code.Lint.LintCategory;
55 import com.sun.tools.javac.code.Scope.WriteableScope;
56 import com.sun.tools.javac.code.Symbol.*;
57 import com.sun.tools.javac.code.Symtab;
58 import com.sun.tools.javac.code.Type.*;
59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
60 import com.sun.tools.javac.file.BaseFileManager;
61 import com.sun.tools.javac.file.PathFileObject;
62 import com.sun.tools.javac.jvm.ClassFile.Version;
63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
64 import com.sun.tools.javac.main.Option;
65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
66 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
67 import com.sun.tools.javac.util.*;
68 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
69 import com.sun.tools.javac.util.DefinedBy.Api;
70 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
71 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
72
73 import static com.sun.tools.javac.code.Flags.*;
74 import static com.sun.tools.javac.code.Kinds.Kind.*;
75
76 import com.sun.tools.javac.code.Scope.LookupKind;
77
78 import static com.sun.tools.javac.code.TypeTag.ARRAY;
79 import static com.sun.tools.javac.code.TypeTag.CLASS;
80 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
81 import static com.sun.tools.javac.jvm.ClassFile.*;
82 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
83
84 import static com.sun.tools.javac.main.Option.PARAMETERS;
85
86 /** This class provides operations to read a classfile into an internal
87 * representation. The internal representation is anchored in a
88 * ClassSymbol which contains in its scope symbol representations
89 * for all other definitions in the classfile. Top-level Classes themselves
90 * appear as members of the scopes of PackageSymbols.
91 *
92 * <p><b>This is NOT part of any supported API.
93 * If you write code that depends on this, you do so at your own risk.
94 * This code and its internal interfaces are subject to change or
95 * deletion without notice.</b>
96 */
97 public class ClassReader {
98 /** The context key for the class reader. */
99 protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
100
101 public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
102
103 private final Annotate annotate;
104
105 /** Switch: verbose output.
106 */
107 boolean verbose;
108
109 /** Switch: allow modules.
110 */
111 boolean allowModules;
112
113 /** Switch: allow sealed
114 */
115 boolean allowSealedTypes;
116
117 /** Switch: allow records
118 */
119 boolean allowRecords;
120
121 /** Lint option: warn about classfile issues
122 */
123 boolean lintClassfile;
124
125 /** Switch: warn (instead of error) on illegal UTF-8
126 */
127 boolean warnOnIllegalUtf8;
128
129 /** Switch: preserve parameter names from the variable table.
130 */
131 public boolean saveParameterNames;
132
267 protected ClassReader(Context context) {
268 context.put(classReaderKey, this);
269 annotate = Annotate.instance(context);
270 names = Names.instance(context);
271 syms = Symtab.instance(context);
272 types = Types.instance(context);
273 fileManager = context.get(JavaFileManager.class);
274 if (fileManager == null)
275 throw new AssertionError("FileManager initialization error");
276 diagFactory = JCDiagnostic.Factory.instance(context);
277 dcfh = DeferredCompletionFailureHandler.instance(context);
278
279 log = Log.instance(context);
280
281 Options options = Options.instance(context);
282 verbose = options.isSet(Option.VERBOSE);
283
284 Source source = Source.instance(context);
285 preview = Preview.instance(context);
286 allowModules = Feature.MODULES.allowedInSource(source);
287 allowRecords = Feature.RECORDS.allowedInSource(source);
288 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
289 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
290
291 saveParameterNames = options.isSet(PARAMETERS);
292
293 profile = Profile.instance(context);
294
295 typevars = WriteableScope.create(syms.noSymbol);
296
297 lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
298
299 initAttributeReaders();
300 }
301
302 /** Add member to class unless it is synthetic.
303 */
304 private void enterMember(ClassSymbol c, Symbol sym) {
305 // Synthetic members are not entered -- reason lost to history (optimization?).
306 // Lambda methods must be entered because they may have inner classes (which reference them)
561 int sbp = 0;
562 /** Convert class signature to type, where signature is implicit.
563 */
564 Type classSigToType() {
565 if (signature[sigp] != 'L')
566 throw badClassFile("bad.class.signature", quoteBadSignature());
567 sigp++;
568 Type outer = Type.noType;
569 int startSbp = sbp;
570
571 while (true) {
572 final byte c = signature[sigp++];
573 switch (c) {
574
575 case ';': { // end
576 ClassSymbol t = enterClass(readName(signatureBuffer,
577 startSbp,
578 sbp - startSbp));
579
580 try {
581 return (outer == Type.noType) ?
582 t.erasure(types) :
583 new ClassType(outer, List.nil(), t);
584 } finally {
585 sbp = startSbp;
586 }
587 }
588
589 case '<': // generic arguments
590 ClassSymbol t = enterClass(readName(signatureBuffer,
591 startSbp,
592 sbp - startSbp));
593 outer = new ClassType(outer, sigToTypes('>'), t) {
594 boolean completed = false;
595 @Override @DefinedBy(Api.LANGUAGE_MODEL)
596 public Type getEnclosingType() {
597 if (!completed) {
598 completed = true;
599 tsym.apiComplete();
600 Type enclosingType = tsym.type.getEnclosingType();
601 if (enclosingType != Type.noType) {
602 List<Type> typeArgs =
603 super.getEnclosingType().allparams();
604 List<Type> typeParams =
605 enclosingType.allparams();
606 if (typeParams.length() != typeArgs.length()) {
607 // no "rare" types
608 super.setEnclosingType(types.erasure(enclosingType));
609 } else {
610 super.setEnclosingType(types.subst(enclosingType,
611 typeParams,
612 typeArgs));
613 }
636 signatureBuffer[sbp++] = (byte)'$';
637 break;
638 } else {
639 sbp = startSbp;
640 return outer;
641 }
642 case '.':
643 signatureBuffer[sbp++] = (byte)'$';
644 break;
645 default:
646 throw new AssertionError(signature[sigp-1]);
647 }
648 continue;
649
650 case '.':
651 //we have seen an enclosing non-generic class
652 if (outer != Type.noType) {
653 t = enterClass(readName(signatureBuffer,
654 startSbp,
655 sbp - startSbp));
656 outer = new ClassType(outer, List.nil(), t);
657 }
658 signatureBuffer[sbp++] = (byte)'$';
659 continue;
660 case '/':
661 signatureBuffer[sbp++] = (byte)'.';
662 continue;
663 default:
664 signatureBuffer[sbp++] = c;
665 continue;
666 }
667 }
668 }
669
670 /** Quote a bogus signature for display inside an error message.
671 */
672 String quoteBadSignature() {
673 String sigString;
674 try {
675 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
676 } catch (InvalidUtfException e) {
1494 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1495 for (CompoundAnnotationProxy proxy : annotations) {
1496 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1497 sym.flags_field |= PROPRIETARY;
1498 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1499 if (profile != Profile.DEFAULT) {
1500 for (Pair<Name, Attribute> v : proxy.values) {
1501 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1502 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1503 sym.flags_field |= NOT_IN_PROFILE;
1504 }
1505 }
1506 }
1507 }
1508 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1509 sym.flags_field |= PREVIEW_API;
1510 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1511 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1512 Assert.check(sym.kind == TYP);
1513 sym.flags_field |= VALUE_BASED;
1514 } else if (proxy.type.tsym.flatName() == syms.restrictedType.tsym.flatName()) {
1515 Assert.check(sym.kind == MTH);
1516 sym.flags_field |= RESTRICTED;
1517 } else {
1518 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1519 target = proxy;
1520 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1521 repeatable = proxy;
1522 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1523 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1524 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1525 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1526 sym.flags_field |= PREVIEW_API;
1527 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1528 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1529 sym.flags_field |= VALUE_BASED;
1530 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1531 Assert.check(sym.kind == MTH);
1532 sym.flags_field |= RESTRICTED;
1533 }
1534 proxies.append(proxy);
1535 }
1536 }
1537 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1538 }
1539 //where:
1540 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1541 for (Pair<Name, Attribute> v : proxy.values) {
1542 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1543 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1544 sym.flags_field |= flag;
1545 }
1546 }
1547 }
1548 }
1549
2876 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2877 return syms.enterClass(currentModule, name, owner);
2878 }
2879
2880 /** Read contents of a given class symbol `c'. Both external and internal
2881 * versions of an inner class are read.
2882 */
2883 void readClass(ClassSymbol c) {
2884 ClassType ct = (ClassType)c.type;
2885
2886 // allocate scope for members
2887 c.members_field = WriteableScope.create(c);
2888
2889 // prepare type variable table
2890 typevars = typevars.dup(currentOwner);
2891 if (ct.getEnclosingType().hasTag(CLASS))
2892 enterTypevars(c.owner, ct.getEnclosingType());
2893
2894 // read flags, or skip if this is an inner class
2895 long f = nextChar();
2896 long flags = adjustClassFlags(f);
2897 if ((flags & MODULE) == 0) {
2898 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2899 // read own class name and check that it matches
2900 currentModule = c.packge().modle;
2901 ClassSymbol self = poolReader.getClass(nextChar());
2902 if (c != self) {
2903 throw badClassFile("class.file.wrong.class",
2904 self.flatname);
2905 }
2906 } else {
2907 if (majorVersion < Version.V53.major) {
2908 throw badClassFile("anachronistic.module.info",
2909 Integer.toString(majorVersion),
2910 Integer.toString(minorVersion));
2911 }
2912 c.flags_field = flags;
2913 if (c.owner.kind != MDL) {
2914 throw badClassFile("module.info.definition.expected");
2915 }
2916 currentModule = (ModuleSymbol) c.owner;
2968 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
2969 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
2970 return (MethodSymbol) s;
2971 }
2972 }
2973 return null;
2974 }
2975
2976 /** Read inner class info. For each inner/outer pair allocate a
2977 * member class.
2978 */
2979 void readInnerClasses(ClassSymbol c) {
2980 int n = nextChar();
2981 for (int i = 0; i < n; i++) {
2982 nextChar(); // skip inner class symbol
2983 int outerIdx = nextChar();
2984 int nameIdx = nextChar();
2985 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
2986 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
2987 if (name == null) name = names.empty;
2988 long flags = adjustClassFlags(nextChar());
2989 if (outer != null) { // we have a member class
2990 if (name == names.empty)
2991 name = names.one;
2992 ClassSymbol member = enterClass(name, outer);
2993 if ((flags & STATIC) == 0) {
2994 ((ClassType)member.type).setEnclosingType(outer.type);
2995 if (member.erasure_field != null)
2996 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
2997 }
2998 if (c == outer && member.owner == c) {
2999 member.flags_field = flags;
3000 enterMember(c, member);
3001 }
3002 }
3003 }
3004 }
3005
3006 /** Read a class definition from the bytes in buf.
3007 */
3008 private void readClassBuffer(ClassSymbol c) throws IOException {
3110 } finally {
3111 interimUses = List.nil();
3112 interimProvides = List.nil();
3113 missingTypeVariables = List.nil();
3114 foundTypeVariables = List.nil();
3115 filling = false;
3116 }
3117 }
3118
3119 /** We can only read a single class file at a time; this
3120 * flag keeps track of when we are currently reading a class
3121 * file.
3122 */
3123 public boolean filling = false;
3124
3125 /************************************************************************
3126 * Adjusting flags
3127 ***********************************************************************/
3128
3129 long adjustFieldFlags(long flags) {
3130 return flags;
3131 }
3132
3133 long adjustMethodFlags(long flags) {
3134 if ((flags & ACC_BRIDGE) != 0) {
3135 flags &= ~ACC_BRIDGE;
3136 flags |= BRIDGE;
3137 }
3138 if ((flags & ACC_VARARGS) != 0) {
3139 flags &= ~ACC_VARARGS;
3140 flags |= VARARGS;
3141 }
3142 return flags;
3143 }
3144
3145 long adjustClassFlags(long flags) {
3146 if ((flags & ACC_MODULE) != 0) {
3147 flags &= ~ACC_MODULE;
3148 flags |= MODULE;
3149 }
3150 return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
3151 }
3152
3153 /**
3154 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3155 * The attribute is only the last component of the original filename, so is unlikely
3156 * to be valid as is, so operations other than those to access the name throw
3157 * UnsupportedOperationException
3158 */
3159 private static class SourceFileObject implements JavaFileObject {
3160
3161 /** The file's name.
3162 */
3163 private final Name name;
3164
3165 public SourceFileObject(Name name) {
3166 this.name = name;
3167 }
3168
3169 @Override @DefinedBy(Api.COMPILER)
3170 public URI toUri() {
|
45 import javax.tools.JavaFileManager;
46 import javax.tools.JavaFileObject;
47
48 import com.sun.tools.javac.code.Source;
49 import com.sun.tools.javac.code.Source.Feature;
50 import com.sun.tools.javac.comp.Annotate;
51 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
52 import com.sun.tools.javac.code.*;
53 import com.sun.tools.javac.code.Directive.*;
54 import com.sun.tools.javac.code.Lint.LintCategory;
55 import com.sun.tools.javac.code.Scope.WriteableScope;
56 import com.sun.tools.javac.code.Symbol.*;
57 import com.sun.tools.javac.code.Symtab;
58 import com.sun.tools.javac.code.Type.*;
59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
60 import com.sun.tools.javac.file.BaseFileManager;
61 import com.sun.tools.javac.file.PathFileObject;
62 import com.sun.tools.javac.jvm.ClassFile.Version;
63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
64 import com.sun.tools.javac.main.Option;
65 import com.sun.tools.javac.resources.CompilerProperties;
66 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
67 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
68 import com.sun.tools.javac.tree.JCTree;
69 import com.sun.tools.javac.util.*;
70 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
71 import com.sun.tools.javac.util.DefinedBy.Api;
72 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
73 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
74
75 import static com.sun.tools.javac.code.Flags.*;
76 import static com.sun.tools.javac.code.Kinds.Kind.*;
77
78 import com.sun.tools.javac.code.Scope.LookupKind;
79
80 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
81 import static com.sun.tools.javac.code.TypeTag.ARRAY;
82 import static com.sun.tools.javac.code.TypeTag.CLASS;
83 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
84 import static com.sun.tools.javac.jvm.ClassFile.*;
85 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
86
87 import static com.sun.tools.javac.main.Option.PARAMETERS;
88
89 /** This class provides operations to read a classfile into an internal
90 * representation. The internal representation is anchored in a
91 * ClassSymbol which contains in its scope symbol representations
92 * for all other definitions in the classfile. Top-level Classes themselves
93 * appear as members of the scopes of PackageSymbols.
94 *
95 * <p><b>This is NOT part of any supported API.
96 * If you write code that depends on this, you do so at your own risk.
97 * This code and its internal interfaces are subject to change or
98 * deletion without notice.</b>
99 */
100 public class ClassReader {
101 /** The context key for the class reader. */
102 protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
103
104 public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
105
106 private final Annotate annotate;
107
108 /** Switch: verbose output.
109 */
110 boolean verbose;
111
112 /** Switch: allow modules.
113 */
114 boolean allowModules;
115
116 /** Switch: allow value classes.
117 */
118 boolean allowValueClasses;
119
120 /** Switch: allow sealed
121 */
122 boolean allowSealedTypes;
123
124 /** Switch: allow records
125 */
126 boolean allowRecords;
127
128 /** Lint option: warn about classfile issues
129 */
130 boolean lintClassfile;
131
132 /** Switch: warn (instead of error) on illegal UTF-8
133 */
134 boolean warnOnIllegalUtf8;
135
136 /** Switch: preserve parameter names from the variable table.
137 */
138 public boolean saveParameterNames;
139
274 protected ClassReader(Context context) {
275 context.put(classReaderKey, this);
276 annotate = Annotate.instance(context);
277 names = Names.instance(context);
278 syms = Symtab.instance(context);
279 types = Types.instance(context);
280 fileManager = context.get(JavaFileManager.class);
281 if (fileManager == null)
282 throw new AssertionError("FileManager initialization error");
283 diagFactory = JCDiagnostic.Factory.instance(context);
284 dcfh = DeferredCompletionFailureHandler.instance(context);
285
286 log = Log.instance(context);
287
288 Options options = Options.instance(context);
289 verbose = options.isSet(Option.VERBOSE);
290
291 Source source = Source.instance(context);
292 preview = Preview.instance(context);
293 allowModules = Feature.MODULES.allowedInSource(source);
294 allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
295 Feature.VALUE_CLASSES.allowedInSource(source);
296 allowRecords = Feature.RECORDS.allowedInSource(source);
297 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
298 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
299
300 saveParameterNames = options.isSet(PARAMETERS);
301
302 profile = Profile.instance(context);
303
304 typevars = WriteableScope.create(syms.noSymbol);
305
306 lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
307
308 initAttributeReaders();
309 }
310
311 /** Add member to class unless it is synthetic.
312 */
313 private void enterMember(ClassSymbol c, Symbol sym) {
314 // Synthetic members are not entered -- reason lost to history (optimization?).
315 // Lambda methods must be entered because they may have inner classes (which reference them)
570 int sbp = 0;
571 /** Convert class signature to type, where signature is implicit.
572 */
573 Type classSigToType() {
574 if (signature[sigp] != 'L')
575 throw badClassFile("bad.class.signature", quoteBadSignature());
576 sigp++;
577 Type outer = Type.noType;
578 int startSbp = sbp;
579
580 while (true) {
581 final byte c = signature[sigp++];
582 switch (c) {
583
584 case ';': { // end
585 ClassSymbol t = enterClass(readName(signatureBuffer,
586 startSbp,
587 sbp - startSbp));
588
589 try {
590 if (outer == Type.noType) {
591 ClassType et = (ClassType) t.erasure(types);
592 return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
593 }
594 return new ClassType(outer, List.nil(), t, List.nil());
595 } finally {
596 sbp = startSbp;
597 }
598 }
599
600 case '<': // generic arguments
601 ClassSymbol t = enterClass(readName(signatureBuffer,
602 startSbp,
603 sbp - startSbp));
604 outer = new ClassType(outer, sigToTypes('>'), t, List.nil()) {
605 boolean completed = false;
606 @Override @DefinedBy(Api.LANGUAGE_MODEL)
607 public Type getEnclosingType() {
608 if (!completed) {
609 completed = true;
610 tsym.apiComplete();
611 Type enclosingType = tsym.type.getEnclosingType();
612 if (enclosingType != Type.noType) {
613 List<Type> typeArgs =
614 super.getEnclosingType().allparams();
615 List<Type> typeParams =
616 enclosingType.allparams();
617 if (typeParams.length() != typeArgs.length()) {
618 // no "rare" types
619 super.setEnclosingType(types.erasure(enclosingType));
620 } else {
621 super.setEnclosingType(types.subst(enclosingType,
622 typeParams,
623 typeArgs));
624 }
647 signatureBuffer[sbp++] = (byte)'$';
648 break;
649 } else {
650 sbp = startSbp;
651 return outer;
652 }
653 case '.':
654 signatureBuffer[sbp++] = (byte)'$';
655 break;
656 default:
657 throw new AssertionError(signature[sigp-1]);
658 }
659 continue;
660
661 case '.':
662 //we have seen an enclosing non-generic class
663 if (outer != Type.noType) {
664 t = enterClass(readName(signatureBuffer,
665 startSbp,
666 sbp - startSbp));
667 outer = new ClassType(outer, List.nil(), t, List.nil());
668 }
669 signatureBuffer[sbp++] = (byte)'$';
670 continue;
671 case '/':
672 signatureBuffer[sbp++] = (byte)'.';
673 continue;
674 default:
675 signatureBuffer[sbp++] = c;
676 continue;
677 }
678 }
679 }
680
681 /** Quote a bogus signature for display inside an error message.
682 */
683 String quoteBadSignature() {
684 String sigString;
685 try {
686 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
687 } catch (InvalidUtfException e) {
1505 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1506 for (CompoundAnnotationProxy proxy : annotations) {
1507 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1508 sym.flags_field |= PROPRIETARY;
1509 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1510 if (profile != Profile.DEFAULT) {
1511 for (Pair<Name, Attribute> v : proxy.values) {
1512 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1513 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1514 sym.flags_field |= NOT_IN_PROFILE;
1515 }
1516 }
1517 }
1518 }
1519 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1520 sym.flags_field |= PREVIEW_API;
1521 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1522 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1523 Assert.check(sym.kind == TYP);
1524 sym.flags_field |= VALUE_BASED;
1525 } else if (proxy.type.tsym.flatName() == syms.migratedValueClassInternalType.tsym.flatName()) {
1526 Assert.check(sym.kind == TYP);
1527 sym.flags_field |= MIGRATED_VALUE_CLASS;
1528 if (needsValueFlag(sym, sym.flags_field)) {
1529 sym.flags_field |= VALUE_CLASS;
1530 }
1531 } else if (proxy.type.tsym.flatName() == syms.restrictedType.tsym.flatName()) {
1532 Assert.check(sym.kind == MTH);
1533 sym.flags_field |= RESTRICTED;
1534 } else {
1535 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1536 target = proxy;
1537 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1538 repeatable = proxy;
1539 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1540 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1541 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1542 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1543 sym.flags_field |= PREVIEW_API;
1544 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1545 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1546 sym.flags_field |= VALUE_BASED;
1547 } else if (proxy.type.tsym == syms.migratedValueClassType.tsym && sym.kind == TYP) {
1548 sym.flags_field |= MIGRATED_VALUE_CLASS;
1549 if (needsValueFlag(sym, sym.flags_field)) {
1550 sym.flags_field |= VALUE_CLASS;
1551 }
1552 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1553 Assert.check(sym.kind == MTH);
1554 sym.flags_field |= RESTRICTED;
1555 }
1556 proxies.append(proxy);
1557 }
1558 }
1559 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1560 }
1561 //where:
1562 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1563 for (Pair<Name, Attribute> v : proxy.values) {
1564 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1565 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1566 sym.flags_field |= flag;
1567 }
1568 }
1569 }
1570 }
1571
2898 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2899 return syms.enterClass(currentModule, name, owner);
2900 }
2901
2902 /** Read contents of a given class symbol `c'. Both external and internal
2903 * versions of an inner class are read.
2904 */
2905 void readClass(ClassSymbol c) {
2906 ClassType ct = (ClassType)c.type;
2907
2908 // allocate scope for members
2909 c.members_field = WriteableScope.create(c);
2910
2911 // prepare type variable table
2912 typevars = typevars.dup(currentOwner);
2913 if (ct.getEnclosingType().hasTag(CLASS))
2914 enterTypevars(c.owner, ct.getEnclosingType());
2915
2916 // read flags, or skip if this is an inner class
2917 long f = nextChar();
2918 long flags = adjustClassFlags(c, f);
2919 if ((flags & MODULE) == 0) {
2920 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2921 // read own class name and check that it matches
2922 currentModule = c.packge().modle;
2923 ClassSymbol self = poolReader.getClass(nextChar());
2924 if (c != self) {
2925 throw badClassFile("class.file.wrong.class",
2926 self.flatname);
2927 }
2928 } else {
2929 if (majorVersion < Version.V53.major) {
2930 throw badClassFile("anachronistic.module.info",
2931 Integer.toString(majorVersion),
2932 Integer.toString(minorVersion));
2933 }
2934 c.flags_field = flags;
2935 if (c.owner.kind != MDL) {
2936 throw badClassFile("module.info.definition.expected");
2937 }
2938 currentModule = (ModuleSymbol) c.owner;
2990 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
2991 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
2992 return (MethodSymbol) s;
2993 }
2994 }
2995 return null;
2996 }
2997
2998 /** Read inner class info. For each inner/outer pair allocate a
2999 * member class.
3000 */
3001 void readInnerClasses(ClassSymbol c) {
3002 int n = nextChar();
3003 for (int i = 0; i < n; i++) {
3004 nextChar(); // skip inner class symbol
3005 int outerIdx = nextChar();
3006 int nameIdx = nextChar();
3007 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3008 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3009 if (name == null) name = names.empty;
3010 long flags = adjustClassFlags(c, nextChar());
3011 if (outer != null) { // we have a member class
3012 if (name == names.empty)
3013 name = names.one;
3014 ClassSymbol member = enterClass(name, outer);
3015 if ((flags & STATIC) == 0) {
3016 ((ClassType)member.type).setEnclosingType(outer.type);
3017 if (member.erasure_field != null)
3018 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3019 }
3020 if (c == outer && member.owner == c) {
3021 member.flags_field = flags;
3022 enterMember(c, member);
3023 }
3024 }
3025 }
3026 }
3027
3028 /** Read a class definition from the bytes in buf.
3029 */
3030 private void readClassBuffer(ClassSymbol c) throws IOException {
3132 } finally {
3133 interimUses = List.nil();
3134 interimProvides = List.nil();
3135 missingTypeVariables = List.nil();
3136 foundTypeVariables = List.nil();
3137 filling = false;
3138 }
3139 }
3140
3141 /** We can only read a single class file at a time; this
3142 * flag keeps track of when we are currently reading a class
3143 * file.
3144 */
3145 public boolean filling = false;
3146
3147 /************************************************************************
3148 * Adjusting flags
3149 ***********************************************************************/
3150
3151 long adjustFieldFlags(long flags) {
3152 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3153 if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3154 flags &= ~ACC_STRICT;
3155 flags |= STRICT;
3156 }
3157 return flags;
3158 }
3159
3160 long adjustMethodFlags(long flags) {
3161 if ((flags & ACC_BRIDGE) != 0) {
3162 flags &= ~ACC_BRIDGE;
3163 flags |= BRIDGE;
3164 }
3165 if ((flags & ACC_VARARGS) != 0) {
3166 flags &= ~ACC_VARARGS;
3167 flags |= VARARGS;
3168 }
3169 return flags;
3170 }
3171
3172 long adjustClassFlags(ClassSymbol c, long flags) {
3173 if ((flags & ACC_MODULE) != 0) {
3174 flags &= ~ACC_MODULE;
3175 flags |= MODULE;
3176 }
3177 if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags)) || (majorVersion < V67.major && (flags & INTERFACE) == 0)) {
3178 flags |= IDENTITY_TYPE;
3179 } else if (needsValueFlag(c, flags)) {
3180 flags |= VALUE_CLASS;
3181 }
3182 flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3183 return flags;
3184 }
3185
3186 private boolean needsValueFlag(Symbol c, long flags) {
3187 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3188 if (allowValueClasses) {
3189 if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3190 majorVersion >= V67.major && isMigratedValueClass(flags)) {
3191 return true;
3192 }
3193 }
3194 return false;
3195 }
3196
3197 private boolean isMigratedValueClass(long flags) {
3198 return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3199 }
3200
3201 /**
3202 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3203 * The attribute is only the last component of the original filename, so is unlikely
3204 * to be valid as is, so operations other than those to access the name throw
3205 * UnsupportedOperationException
3206 */
3207 private static class SourceFileObject implements JavaFileObject {
3208
3209 /** The file's name.
3210 */
3211 private final Name name;
3212
3213 public SourceFileObject(Name name) {
3214 this.name = name;
3215 }
3216
3217 @Override @DefinedBy(Api.COMPILER)
3218 public URI toUri() {
|