44 import javax.lang.model.element.NestingKind;
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.Scope.WriteableScope;
55 import com.sun.tools.javac.code.Symbol.*;
56 import com.sun.tools.javac.code.Symtab;
57 import com.sun.tools.javac.code.Type.*;
58 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
59 import com.sun.tools.javac.file.BaseFileManager;
60 import com.sun.tools.javac.file.PathFileObject;
61 import com.sun.tools.javac.jvm.ClassFile.Version;
62 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
63 import com.sun.tools.javac.main.Option;
64 import com.sun.tools.javac.resources.CompilerProperties.Errors;
65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
66 import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
67 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
68 import com.sun.tools.javac.util.*;
69 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
70 import com.sun.tools.javac.util.DefinedBy.Api;
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 /** Switch: warn (instead of error) on illegal UTF-8
122 */
123 boolean warnOnIllegalUtf8;
124
125 /** Switch: preserve parameter names from the variable table.
126 */
127 public boolean saveParameterNames;
128
129 /**
130 * The currently selected profile.
131 */
132 public final Profile profile;
272 protected ClassReader(Context context) {
273 context.put(classReaderKey, this);
274 annotate = Annotate.instance(context);
275 names = Names.instance(context);
276 syms = Symtab.instance(context);
277 types = Types.instance(context);
278 fileManager = context.get(JavaFileManager.class);
279 if (fileManager == null)
280 throw new AssertionError("FileManager initialization error");
281 diagFactory = JCDiagnostic.Factory.instance(context);
282 dcfh = DeferredCompletionFailureHandler.instance(context);
283
284 log = Log.instance(context);
285
286 Options options = Options.instance(context);
287 verbose = options.isSet(Option.VERBOSE);
288
289 Source source = Source.instance(context);
290 preview = Preview.instance(context);
291 allowModules = Feature.MODULES.allowedInSource(source);
292 allowRecords = Feature.RECORDS.allowedInSource(source);
293 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
294 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
295
296 saveParameterNames = options.isSet(PARAMETERS);
297
298 profile = Profile.instance(context);
299
300 typevars = WriteableScope.create(syms.noSymbol);
301
302 initAttributeReaders();
303 }
304
305 /** Add member to class unless it is synthetic.
306 */
307 private void enterMember(ClassSymbol c, Symbol sym) {
308 // Synthetic members are not entered -- reason lost to history (optimization?).
309 // Lambda methods must be entered because they may have inner classes (which reference them)
310 if ((sym.flags_field & (SYNTHETIC|BRIDGE)) != SYNTHETIC || sym.name.startsWith(names.lambda))
311 c.members_field.enter(sym);
564 int sbp = 0;
565 /** Convert class signature to type, where signature is implicit.
566 */
567 Type classSigToType() {
568 if (signature[sigp] != 'L')
569 throw badClassFile("bad.class.signature", quoteBadSignature());
570 sigp++;
571 Type outer = Type.noType;
572 int startSbp = sbp;
573
574 while (true) {
575 final byte c = signature[sigp++];
576 switch (c) {
577
578 case ';': { // end
579 ClassSymbol t = enterClass(readName(signatureBuffer,
580 startSbp,
581 sbp - startSbp));
582
583 try {
584 return (outer == Type.noType) ?
585 t.erasure(types) :
586 new ClassType(outer, List.nil(), t);
587 } finally {
588 sbp = startSbp;
589 }
590 }
591
592 case '<': // generic arguments
593 ClassSymbol t = enterClass(readName(signatureBuffer,
594 startSbp,
595 sbp - startSbp));
596 List<Type> actuals = sigToTypes('>');
597 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
598 if (formals != null) {
599 if (actuals.isEmpty())
600 actuals = formals;
601 }
602 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
603 * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
604 * assigned to but then we would have a dependendy on the internal representation of ClassType which
605 * could change in the future
606 */
607 final List<Type> actualsCp = actuals;
608 outer = new ClassType(outer, actuals, t) {
609 boolean completed = false;
610 boolean typeArgsSet = false;
611 @Override @DefinedBy(Api.LANGUAGE_MODEL)
612 public Type getEnclosingType() {
613 if (!completed) {
614 completed = true;
615 tsym.apiComplete();
616 Type enclosingType = tsym.type.getEnclosingType();
617 if (enclosingType != Type.noType) {
618 List<Type> typeArgs =
619 super.getEnclosingType().allparams();
620 List<Type> typeParams =
621 enclosingType.allparams();
622 if (typeParams.length() != typeArgs.length()) {
623 // no "rare" types
624 super.setEnclosingType(types.erasure(enclosingType));
625 } else {
626 super.setEnclosingType(types.subst(enclosingType,
627 typeParams,
628 typeArgs));
672 signatureBuffer[sbp++] = (byte)'$';
673 break;
674 } else {
675 sbp = startSbp;
676 return outer;
677 }
678 case '.':
679 signatureBuffer[sbp++] = (byte)'$';
680 break;
681 default:
682 throw new AssertionError(signature[sigp-1]);
683 }
684 continue;
685
686 case '.':
687 //we have seen an enclosing non-generic class
688 if (outer != Type.noType) {
689 t = enterClass(readName(signatureBuffer,
690 startSbp,
691 sbp - startSbp));
692 outer = new ClassType(outer, List.nil(), t);
693 }
694 signatureBuffer[sbp++] = (byte)'$';
695 continue;
696 case '/':
697 signatureBuffer[sbp++] = (byte)'.';
698 continue;
699 default:
700 signatureBuffer[sbp++] = c;
701 continue;
702 }
703 }
704 }
705
706 /** Quote a bogus signature for display inside an error message.
707 */
708 String quoteBadSignature() {
709 String sigString;
710 try {
711 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
712 } catch (InvalidUtfException e) {
1529 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1530 for (CompoundAnnotationProxy proxy : annotations) {
1531 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1532 sym.flags_field |= PROPRIETARY;
1533 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1534 if (profile != Profile.DEFAULT) {
1535 for (Pair<Name, Attribute> v : proxy.values) {
1536 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1537 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1538 sym.flags_field |= NOT_IN_PROFILE;
1539 }
1540 }
1541 }
1542 }
1543 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1544 sym.flags_field |= PREVIEW_API;
1545 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1546 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1547 Assert.check(sym.kind == TYP);
1548 sym.flags_field |= VALUE_BASED;
1549 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1550 Assert.check(sym.kind == MTH);
1551 sym.flags_field |= RESTRICTED;
1552 } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1553 Assert.check(sym.kind == VAR);
1554 sym.flags_field |= REQUIRES_IDENTITY;
1555 } else {
1556 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1557 target = proxy;
1558 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1559 repeatable = proxy;
1560 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1561 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1562 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1563 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1564 sym.flags_field |= PREVIEW_API;
1565 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1566 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1567 sym.flags_field |= VALUE_BASED;
1568 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1569 Assert.check(sym.kind == MTH);
1570 sym.flags_field |= RESTRICTED;
1571 } else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1572 Assert.check(sym.kind == VAR);
1573 sym.flags_field |= REQUIRES_IDENTITY;
1574 }
1575 proxies.append(proxy);
1576 }
1577 }
1578 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1579 }
1580 //where:
1581 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1582 for (Pair<Name, Attribute> v : proxy.values) {
1583 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1584 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1585 sym.flags_field |= flag;
1586 }
1587 }
3038 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3039 return syms.enterClass(currentModule, name, owner);
3040 }
3041
3042 /** Read contents of a given class symbol `c'. Both external and internal
3043 * versions of an inner class are read.
3044 */
3045 void readClass(ClassSymbol c) {
3046 ClassType ct = (ClassType)c.type;
3047
3048 // allocate scope for members
3049 c.members_field = WriteableScope.create(c);
3050
3051 // prepare type variable table
3052 typevars = typevars.dup(currentOwner);
3053 if (ct.getEnclosingType().hasTag(CLASS))
3054 enterTypevars(c.owner, ct.getEnclosingType());
3055
3056 // read flags, or skip if this is an inner class
3057 long f = nextChar();
3058 long flags = adjustClassFlags(f);
3059 if ((flags & MODULE) == 0) {
3060 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3061 // read own class name and check that it matches
3062 currentModule = c.packge().modle;
3063 ClassSymbol self = poolReader.getClass(nextChar());
3064 if (c != self) {
3065 throw badClassFile("class.file.wrong.class",
3066 self.flatname);
3067 }
3068 } else {
3069 if (majorVersion < Version.V53.major) {
3070 throw badClassFile("anachronistic.module.info",
3071 Integer.toString(majorVersion),
3072 Integer.toString(minorVersion));
3073 }
3074 c.flags_field = flags;
3075 if (c.owner.kind != MDL) {
3076 throw badClassFile("module.info.definition.expected");
3077 }
3078 currentModule = (ModuleSymbol) c.owner;
3130 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3131 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3132 return (MethodSymbol) s;
3133 }
3134 }
3135 return null;
3136 }
3137
3138 /** Read inner class info. For each inner/outer pair allocate a
3139 * member class.
3140 */
3141 void readInnerClasses(ClassSymbol c) {
3142 int n = nextChar();
3143 for (int i = 0; i < n; i++) {
3144 nextChar(); // skip inner class symbol
3145 int outerIdx = nextChar();
3146 int nameIdx = nextChar();
3147 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3148 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3149 if (name == null) name = names.empty;
3150 long flags = adjustClassFlags(nextChar());
3151 if (outer != null) { // we have a member class
3152 if (name == names.empty)
3153 name = names.one;
3154 ClassSymbol member = enterClass(name, outer);
3155 if ((flags & STATIC) == 0) {
3156 ((ClassType)member.type).setEnclosingType(outer.type);
3157 if (member.erasure_field != null)
3158 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3159 }
3160 if (c == outer && member.owner == c) {
3161 member.flags_field = flags;
3162 enterMember(c, member);
3163 }
3164 }
3165 }
3166 }
3167
3168 /** Read a class definition from the bytes in buf.
3169 */
3170 private void readClassBuffer(ClassSymbol c) throws IOException {
3272 } finally {
3273 interimUses = List.nil();
3274 interimProvides = List.nil();
3275 missingTypeVariables = List.nil();
3276 foundTypeVariables = List.nil();
3277 filling = false;
3278 }
3279 }
3280
3281 /** We can only read a single class file at a time; this
3282 * flag keeps track of when we are currently reading a class
3283 * file.
3284 */
3285 public boolean filling = false;
3286
3287 /* **********************************************************************
3288 * Adjusting flags
3289 ***********************************************************************/
3290
3291 long adjustFieldFlags(long flags) {
3292 return flags;
3293 }
3294
3295 long adjustMethodFlags(long flags) {
3296 if ((flags & ACC_BRIDGE) != 0) {
3297 flags &= ~ACC_BRIDGE;
3298 flags |= BRIDGE;
3299 }
3300 if ((flags & ACC_VARARGS) != 0) {
3301 flags &= ~ACC_VARARGS;
3302 flags |= VARARGS;
3303 }
3304 return flags;
3305 }
3306
3307 long adjustClassFlags(long flags) {
3308 if ((flags & ACC_MODULE) != 0) {
3309 flags &= ~ACC_MODULE;
3310 flags |= MODULE;
3311 }
3312 return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
3313 }
3314
3315 /**
3316 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3317 * The attribute is only the last component of the original filename, so is unlikely
3318 * to be valid as is, so operations other than those to access the name throw
3319 * UnsupportedOperationException
3320 */
3321 private static class SourceFileObject implements JavaFileObject {
3322
3323 /** The file's name.
3324 */
3325 private final Name name;
3326
3327 public SourceFileObject(Name name) {
3328 this.name = name;
3329 }
3330
3331 @Override @DefinedBy(Api.COMPILER)
3332 public URI toUri() {
|
44 import javax.lang.model.element.NestingKind;
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.Scope.WriteableScope;
55 import com.sun.tools.javac.code.Symbol.*;
56 import com.sun.tools.javac.code.Symtab;
57 import com.sun.tools.javac.code.Type.*;
58 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
59 import com.sun.tools.javac.file.BaseFileManager;
60 import com.sun.tools.javac.file.PathFileObject;
61 import com.sun.tools.javac.jvm.ClassFile.Version;
62 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
63 import com.sun.tools.javac.main.Option;
64 import com.sun.tools.javac.resources.CompilerProperties;
65 import com.sun.tools.javac.resources.CompilerProperties.Errors;
66 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
67 import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
68 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
69 import com.sun.tools.javac.tree.JCTree;
70 import com.sun.tools.javac.util.*;
71 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
72 import com.sun.tools.javac.util.DefinedBy.Api;
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 /** Switch: warn (instead of error) on illegal UTF-8
129 */
130 boolean warnOnIllegalUtf8;
131
132 /** Switch: preserve parameter names from the variable table.
133 */
134 public boolean saveParameterNames;
135
136 /**
137 * The currently selected profile.
138 */
139 public final Profile profile;
279 protected ClassReader(Context context) {
280 context.put(classReaderKey, this);
281 annotate = Annotate.instance(context);
282 names = Names.instance(context);
283 syms = Symtab.instance(context);
284 types = Types.instance(context);
285 fileManager = context.get(JavaFileManager.class);
286 if (fileManager == null)
287 throw new AssertionError("FileManager initialization error");
288 diagFactory = JCDiagnostic.Factory.instance(context);
289 dcfh = DeferredCompletionFailureHandler.instance(context);
290
291 log = Log.instance(context);
292
293 Options options = Options.instance(context);
294 verbose = options.isSet(Option.VERBOSE);
295
296 Source source = Source.instance(context);
297 preview = Preview.instance(context);
298 allowModules = Feature.MODULES.allowedInSource(source);
299 allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
300 Feature.VALUE_CLASSES.allowedInSource(source);
301 allowRecords = Feature.RECORDS.allowedInSource(source);
302 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
303 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
304
305 saveParameterNames = options.isSet(PARAMETERS);
306
307 profile = Profile.instance(context);
308
309 typevars = WriteableScope.create(syms.noSymbol);
310
311 initAttributeReaders();
312 }
313
314 /** Add member to class unless it is synthetic.
315 */
316 private void enterMember(ClassSymbol c, Symbol sym) {
317 // Synthetic members are not entered -- reason lost to history (optimization?).
318 // Lambda methods must be entered because they may have inner classes (which reference them)
319 if ((sym.flags_field & (SYNTHETIC|BRIDGE)) != SYNTHETIC || sym.name.startsWith(names.lambda))
320 c.members_field.enter(sym);
573 int sbp = 0;
574 /** Convert class signature to type, where signature is implicit.
575 */
576 Type classSigToType() {
577 if (signature[sigp] != 'L')
578 throw badClassFile("bad.class.signature", quoteBadSignature());
579 sigp++;
580 Type outer = Type.noType;
581 int startSbp = sbp;
582
583 while (true) {
584 final byte c = signature[sigp++];
585 switch (c) {
586
587 case ';': { // end
588 ClassSymbol t = enterClass(readName(signatureBuffer,
589 startSbp,
590 sbp - startSbp));
591
592 try {
593 if (outer == Type.noType) {
594 ClassType et = (ClassType) t.erasure(types);
595 return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
596 }
597 return new ClassType(outer, List.nil(), t, List.nil());
598 } finally {
599 sbp = startSbp;
600 }
601 }
602
603 case '<': // generic arguments
604 ClassSymbol t = enterClass(readName(signatureBuffer,
605 startSbp,
606 sbp - startSbp));
607 List<Type> actuals = sigToTypes('>');
608 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
609 if (formals != null) {
610 if (actuals.isEmpty())
611 actuals = formals;
612 }
613 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
614 * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
615 * assigned to but then we would have a dependendy on the internal representation of ClassType which
616 * could change in the future
617 */
618 final List<Type> actualsCp = actuals;
619 outer = new ClassType(outer, actuals, t, List.nil()) {
620 boolean completed = false;
621 boolean typeArgsSet = false;
622 @Override @DefinedBy(Api.LANGUAGE_MODEL)
623 public Type getEnclosingType() {
624 if (!completed) {
625 completed = true;
626 tsym.apiComplete();
627 Type enclosingType = tsym.type.getEnclosingType();
628 if (enclosingType != Type.noType) {
629 List<Type> typeArgs =
630 super.getEnclosingType().allparams();
631 List<Type> typeParams =
632 enclosingType.allparams();
633 if (typeParams.length() != typeArgs.length()) {
634 // no "rare" types
635 super.setEnclosingType(types.erasure(enclosingType));
636 } else {
637 super.setEnclosingType(types.subst(enclosingType,
638 typeParams,
639 typeArgs));
683 signatureBuffer[sbp++] = (byte)'$';
684 break;
685 } else {
686 sbp = startSbp;
687 return outer;
688 }
689 case '.':
690 signatureBuffer[sbp++] = (byte)'$';
691 break;
692 default:
693 throw new AssertionError(signature[sigp-1]);
694 }
695 continue;
696
697 case '.':
698 //we have seen an enclosing non-generic class
699 if (outer != Type.noType) {
700 t = enterClass(readName(signatureBuffer,
701 startSbp,
702 sbp - startSbp));
703 outer = new ClassType(outer, List.nil(), t, List.nil());
704 }
705 signatureBuffer[sbp++] = (byte)'$';
706 continue;
707 case '/':
708 signatureBuffer[sbp++] = (byte)'.';
709 continue;
710 default:
711 signatureBuffer[sbp++] = c;
712 continue;
713 }
714 }
715 }
716
717 /** Quote a bogus signature for display inside an error message.
718 */
719 String quoteBadSignature() {
720 String sigString;
721 try {
722 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
723 } catch (InvalidUtfException e) {
1540 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1541 for (CompoundAnnotationProxy proxy : annotations) {
1542 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1543 sym.flags_field |= PROPRIETARY;
1544 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1545 if (profile != Profile.DEFAULT) {
1546 for (Pair<Name, Attribute> v : proxy.values) {
1547 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1548 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1549 sym.flags_field |= NOT_IN_PROFILE;
1550 }
1551 }
1552 }
1553 }
1554 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1555 sym.flags_field |= PREVIEW_API;
1556 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1557 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1558 Assert.check(sym.kind == TYP);
1559 sym.flags_field |= VALUE_BASED;
1560 } else if (proxy.type.tsym.flatName() == syms.migratedValueClassInternalType.tsym.flatName()) {
1561 Assert.check(sym.kind == TYP);
1562 sym.flags_field |= MIGRATED_VALUE_CLASS;
1563 if (needsValueFlag(sym, sym.flags_field)) {
1564 sym.flags_field |= VALUE_CLASS;
1565 sym.flags_field &= ~IDENTITY_TYPE;
1566 }
1567 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1568 Assert.check(sym.kind == MTH);
1569 sym.flags_field |= RESTRICTED;
1570 } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1571 Assert.check(sym.kind == VAR);
1572 sym.flags_field |= REQUIRES_IDENTITY;
1573 } else {
1574 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1575 target = proxy;
1576 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1577 repeatable = proxy;
1578 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1579 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1580 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1581 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1582 sym.flags_field |= PREVIEW_API;
1583 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1584 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1585 sym.flags_field |= VALUE_BASED;
1586 } else if (proxy.type.tsym == syms.migratedValueClassType.tsym && sym.kind == TYP) {
1587 sym.flags_field |= MIGRATED_VALUE_CLASS;
1588 if (needsValueFlag(sym, sym.flags_field)) {
1589 sym.flags_field |= VALUE_CLASS;
1590 sym.flags_field &= ~IDENTITY_TYPE;
1591 }
1592 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1593 Assert.check(sym.kind == MTH);
1594 sym.flags_field |= RESTRICTED;
1595 } else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1596 Assert.check(sym.kind == VAR);
1597 sym.flags_field |= REQUIRES_IDENTITY;
1598 }
1599 proxies.append(proxy);
1600 }
1601 }
1602 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1603 }
1604 //where:
1605 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1606 for (Pair<Name, Attribute> v : proxy.values) {
1607 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1608 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1609 sym.flags_field |= flag;
1610 }
1611 }
3062 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3063 return syms.enterClass(currentModule, name, owner);
3064 }
3065
3066 /** Read contents of a given class symbol `c'. Both external and internal
3067 * versions of an inner class are read.
3068 */
3069 void readClass(ClassSymbol c) {
3070 ClassType ct = (ClassType)c.type;
3071
3072 // allocate scope for members
3073 c.members_field = WriteableScope.create(c);
3074
3075 // prepare type variable table
3076 typevars = typevars.dup(currentOwner);
3077 if (ct.getEnclosingType().hasTag(CLASS))
3078 enterTypevars(c.owner, ct.getEnclosingType());
3079
3080 // read flags, or skip if this is an inner class
3081 long f = nextChar();
3082 long flags = adjustClassFlags(c, f);
3083 if ((flags & MODULE) == 0) {
3084 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3085 // read own class name and check that it matches
3086 currentModule = c.packge().modle;
3087 ClassSymbol self = poolReader.getClass(nextChar());
3088 if (c != self) {
3089 throw badClassFile("class.file.wrong.class",
3090 self.flatname);
3091 }
3092 } else {
3093 if (majorVersion < Version.V53.major) {
3094 throw badClassFile("anachronistic.module.info",
3095 Integer.toString(majorVersion),
3096 Integer.toString(minorVersion));
3097 }
3098 c.flags_field = flags;
3099 if (c.owner.kind != MDL) {
3100 throw badClassFile("module.info.definition.expected");
3101 }
3102 currentModule = (ModuleSymbol) c.owner;
3154 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3155 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3156 return (MethodSymbol) s;
3157 }
3158 }
3159 return null;
3160 }
3161
3162 /** Read inner class info. For each inner/outer pair allocate a
3163 * member class.
3164 */
3165 void readInnerClasses(ClassSymbol c) {
3166 int n = nextChar();
3167 for (int i = 0; i < n; i++) {
3168 nextChar(); // skip inner class symbol
3169 int outerIdx = nextChar();
3170 int nameIdx = nextChar();
3171 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3172 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3173 if (name == null) name = names.empty;
3174 long flags = adjustClassFlags(c, nextChar());
3175 if (outer != null) { // we have a member class
3176 if (name == names.empty)
3177 name = names.one;
3178 ClassSymbol member = enterClass(name, outer);
3179 if ((flags & STATIC) == 0) {
3180 ((ClassType)member.type).setEnclosingType(outer.type);
3181 if (member.erasure_field != null)
3182 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3183 }
3184 if (c == outer && member.owner == c) {
3185 member.flags_field = flags;
3186 enterMember(c, member);
3187 }
3188 }
3189 }
3190 }
3191
3192 /** Read a class definition from the bytes in buf.
3193 */
3194 private void readClassBuffer(ClassSymbol c) throws IOException {
3296 } finally {
3297 interimUses = List.nil();
3298 interimProvides = List.nil();
3299 missingTypeVariables = List.nil();
3300 foundTypeVariables = List.nil();
3301 filling = false;
3302 }
3303 }
3304
3305 /** We can only read a single class file at a time; this
3306 * flag keeps track of when we are currently reading a class
3307 * file.
3308 */
3309 public boolean filling = false;
3310
3311 /* **********************************************************************
3312 * Adjusting flags
3313 ***********************************************************************/
3314
3315 long adjustFieldFlags(long flags) {
3316 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3317 if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3318 flags &= ~ACC_STRICT;
3319 flags |= STRICT;
3320 }
3321 return flags;
3322 }
3323
3324 long adjustMethodFlags(long flags) {
3325 if ((flags & ACC_BRIDGE) != 0) {
3326 flags &= ~ACC_BRIDGE;
3327 flags |= BRIDGE;
3328 }
3329 if ((flags & ACC_VARARGS) != 0) {
3330 flags &= ~ACC_VARARGS;
3331 flags |= VARARGS;
3332 }
3333 return flags;
3334 }
3335
3336 long adjustClassFlags(ClassSymbol c, long flags) {
3337 if ((flags & ACC_MODULE) != 0) {
3338 flags &= ~ACC_MODULE;
3339 flags |= MODULE;
3340 }
3341 if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags))
3342 || (majorVersion <= Version.MAX().major && minorVersion != PREVIEW_MINOR_VERSION && (flags & INTERFACE) == 0)) {
3343 flags |= IDENTITY_TYPE;
3344 } else if (needsValueFlag(c, flags)) {
3345 flags |= VALUE_CLASS;
3346 flags &= ~IDENTITY_TYPE;
3347 }
3348 flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3349 return flags;
3350 }
3351
3352 private boolean needsValueFlag(Symbol c, long flags) {
3353 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3354 if (allowValueClasses) {
3355 if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3356 majorVersion >= V67.major && isMigratedValueClass(flags)) {
3357 return true;
3358 }
3359 }
3360 return false;
3361 }
3362
3363 private boolean isMigratedValueClass(long flags) {
3364 return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3365 }
3366
3367 /**
3368 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3369 * The attribute is only the last component of the original filename, so is unlikely
3370 * to be valid as is, so operations other than those to access the name throw
3371 * UnsupportedOperationException
3372 */
3373 private static class SourceFileObject implements JavaFileObject {
3374
3375 /** The file's name.
3376 */
3377 private final Name name;
3378
3379 public SourceFileObject(Name name) {
3380 this.name = name;
3381 }
3382
3383 @Override @DefinedBy(Api.COMPILER)
3384 public URI toUri() {
|