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.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.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.Fragment;
73
74 import static com.sun.tools.javac.code.Flags.*;
75 import static com.sun.tools.javac.code.Kinds.Kind.*;
76
77 import com.sun.tools.javac.code.Scope.LookupKind;
78
79 import static com.sun.tools.javac.code.TypeTag.ARRAY;
80 import static com.sun.tools.javac.code.TypeTag.CLASS;
81 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
82 import static com.sun.tools.javac.jvm.ClassFile.*;
83 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
84
85 import static com.sun.tools.javac.main.Option.PARAMETERS;
86
87 /** This class provides operations to read a classfile into an internal
88 * representation. The internal representation is anchored in a
89 * ClassSymbol which contains in its scope symbol representations
90 * for all other definitions in the classfile. Top-level Classes themselves
91 * appear as members of the scopes of PackageSymbols.
92 *
93 * <p><b>This is NOT part of any supported API.
94 * If you write code that depends on this, you do so at your own risk.
95 * This code and its internal interfaces are subject to change or
96 * deletion without notice.</b>
97 */
98 public class ClassReader {
99 /** The context key for the class reader. */
100 protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
101
102 public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
103
104 private final Annotate annotate;
105
106 /** Switch: verbose output.
107 */
108 boolean verbose;
109
110 /** Switch: allow modules.
111 */
112 boolean allowModules;
113
114 /** Switch: allow sealed
115 */
116 boolean allowSealedTypes;
117
118 /** Switch: allow records
119 */
120 boolean allowRecords;
121
122 /** Switch: warn (instead of error) on illegal UTF-8
123 */
124 boolean warnOnIllegalUtf8;
125
126 /** Switch: preserve parameter names from the variable table.
127 */
128 public boolean saveParameterNames;
129
130 /**
131 * The currently selected profile.
132 */
133 public final Profile profile;
276 protected ClassReader(Context context) {
277 context.put(classReaderKey, this);
278 annotate = Annotate.instance(context);
279 names = Names.instance(context);
280 syms = Symtab.instance(context);
281 types = Types.instance(context);
282 fileManager = context.get(JavaFileManager.class);
283 if (fileManager == null)
284 throw new AssertionError("FileManager initialization error");
285 diagFactory = JCDiagnostic.Factory.instance(context);
286 dcfh = DeferredCompletionFailureHandler.instance(context);
287
288 log = Log.instance(context);
289
290 Options options = Options.instance(context);
291 verbose = options.isSet(Option.VERBOSE);
292
293 Source source = Source.instance(context);
294 preview = Preview.instance(context);
295 allowModules = Feature.MODULES.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 lint = Lint.instance(context);
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 return (outer == Type.noType) ?
591 t.erasure(types) :
592 new ClassType(outer, List.nil(), t);
593 } finally {
594 sbp = startSbp;
595 }
596 }
597
598 case '<': // generic arguments
599 ClassSymbol t = enterClass(readName(signatureBuffer,
600 startSbp,
601 sbp - startSbp));
602 List<Type> actuals = sigToTypes('>');
603 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
604 if (formals != null) {
605 if (actuals.isEmpty())
606 actuals = formals;
607 }
608 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
609 * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
610 * assigned to but then we would have a dependendy on the internal representation of ClassType which
611 * could change in the future
612 */
613 final List<Type> actualsCp = actuals;
614 outer = new ClassType(outer, actuals, t) {
615 boolean completed = false;
616 boolean typeArgsSet = false;
617 @Override @DefinedBy(Api.LANGUAGE_MODEL)
618 public Type getEnclosingType() {
619 if (!completed) {
620 completed = true;
621 tsym.apiComplete();
622 Type enclosingType = tsym.type.getEnclosingType();
623 if (enclosingType != Type.noType) {
624 List<Type> typeArgs =
625 super.getEnclosingType().allparams();
626 List<Type> typeParams =
627 enclosingType.allparams();
628 if (typeParams.length() != typeArgs.length()) {
629 // no "rare" types
630 super.setEnclosingType(types.erasure(enclosingType));
631 } else {
632 super.setEnclosingType(types.subst(enclosingType,
633 typeParams,
634 typeArgs));
678 signatureBuffer[sbp++] = (byte)'$';
679 break;
680 } else {
681 sbp = startSbp;
682 return outer;
683 }
684 case '.':
685 signatureBuffer[sbp++] = (byte)'$';
686 break;
687 default:
688 throw new AssertionError(signature[sigp-1]);
689 }
690 continue;
691
692 case '.':
693 //we have seen an enclosing non-generic class
694 if (outer != Type.noType) {
695 t = enterClass(readName(signatureBuffer,
696 startSbp,
697 sbp - startSbp));
698 outer = new ClassType(outer, List.nil(), t);
699 }
700 signatureBuffer[sbp++] = (byte)'$';
701 continue;
702 case '/':
703 signatureBuffer[sbp++] = (byte)'.';
704 continue;
705 default:
706 signatureBuffer[sbp++] = c;
707 continue;
708 }
709 }
710 }
711
712 /** Quote a bogus signature for display inside an error message.
713 */
714 String quoteBadSignature() {
715 String sigString;
716 try {
717 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
718 } catch (InvalidUtfException e) {
1541 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1542 for (CompoundAnnotationProxy proxy : annotations) {
1543 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1544 sym.flags_field |= PROPRIETARY;
1545 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1546 if (profile != Profile.DEFAULT) {
1547 for (Pair<Name, Attribute> v : proxy.values) {
1548 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1549 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1550 sym.flags_field |= NOT_IN_PROFILE;
1551 }
1552 }
1553 }
1554 }
1555 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1556 sym.flags_field |= PREVIEW_API;
1557 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1558 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1559 Assert.check(sym.kind == TYP);
1560 sym.flags_field |= VALUE_BASED;
1561 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1562 Assert.check(sym.kind == MTH);
1563 sym.flags_field |= RESTRICTED;
1564 } else {
1565 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1566 target = proxy;
1567 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1568 repeatable = proxy;
1569 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1570 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1571 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1572 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1573 sym.flags_field |= PREVIEW_API;
1574 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1575 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1576 sym.flags_field |= VALUE_BASED;
1577 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1578 Assert.check(sym.kind == MTH);
1579 sym.flags_field |= RESTRICTED;
1580 }
1581 proxies.append(proxy);
1582 }
1583 }
1584 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1585 }
1586 //where:
1587 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1588 for (Pair<Name, Attribute> v : proxy.values) {
1589 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1590 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1591 sym.flags_field |= flag;
1592 }
1593 }
1594 }
1595 }
1596
3045 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3046 return syms.enterClass(currentModule, name, owner);
3047 }
3048
3049 /** Read contents of a given class symbol `c'. Both external and internal
3050 * versions of an inner class are read.
3051 */
3052 void readClass(ClassSymbol c) {
3053 ClassType ct = (ClassType)c.type;
3054
3055 // allocate scope for members
3056 c.members_field = WriteableScope.create(c);
3057
3058 // prepare type variable table
3059 typevars = typevars.dup(currentOwner);
3060 if (ct.getEnclosingType().hasTag(CLASS))
3061 enterTypevars(c.owner, ct.getEnclosingType());
3062
3063 // read flags, or skip if this is an inner class
3064 long f = nextChar();
3065 long flags = adjustClassFlags(f);
3066 if ((flags & MODULE) == 0) {
3067 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3068 // read own class name and check that it matches
3069 currentModule = c.packge().modle;
3070 ClassSymbol self = poolReader.getClass(nextChar());
3071 if (c != self) {
3072 throw badClassFile("class.file.wrong.class",
3073 self.flatname);
3074 }
3075 } else {
3076 if (majorVersion < Version.V53.major) {
3077 throw badClassFile("anachronistic.module.info",
3078 Integer.toString(majorVersion),
3079 Integer.toString(minorVersion));
3080 }
3081 c.flags_field = flags;
3082 if (c.owner.kind != MDL) {
3083 throw badClassFile("module.info.definition.expected");
3084 }
3085 currentModule = (ModuleSymbol) c.owner;
3137 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3138 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3139 return (MethodSymbol) s;
3140 }
3141 }
3142 return null;
3143 }
3144
3145 /** Read inner class info. For each inner/outer pair allocate a
3146 * member class.
3147 */
3148 void readInnerClasses(ClassSymbol c) {
3149 int n = nextChar();
3150 for (int i = 0; i < n; i++) {
3151 nextChar(); // skip inner class symbol
3152 int outerIdx = nextChar();
3153 int nameIdx = nextChar();
3154 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3155 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3156 if (name == null) name = names.empty;
3157 long flags = adjustClassFlags(nextChar());
3158 if (outer != null) { // we have a member class
3159 if (name == names.empty)
3160 name = names.one;
3161 ClassSymbol member = enterClass(name, outer);
3162 if ((flags & STATIC) == 0) {
3163 ((ClassType)member.type).setEnclosingType(outer.type);
3164 if (member.erasure_field != null)
3165 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3166 }
3167 if (c == outer && member.owner == c) {
3168 member.flags_field = flags;
3169 enterMember(c, member);
3170 }
3171 }
3172 }
3173 }
3174
3175 /** Read a class definition from the bytes in buf.
3176 */
3177 private void readClassBuffer(ClassSymbol c) throws IOException {
3279 } finally {
3280 interimUses = List.nil();
3281 interimProvides = List.nil();
3282 missingTypeVariables = List.nil();
3283 foundTypeVariables = List.nil();
3284 filling = false;
3285 }
3286 }
3287
3288 /** We can only read a single class file at a time; this
3289 * flag keeps track of when we are currently reading a class
3290 * file.
3291 */
3292 public boolean filling = false;
3293
3294 /* **********************************************************************
3295 * Adjusting flags
3296 ***********************************************************************/
3297
3298 long adjustFieldFlags(long flags) {
3299 return flags;
3300 }
3301
3302 long adjustMethodFlags(long flags) {
3303 if ((flags & ACC_BRIDGE) != 0) {
3304 flags &= ~ACC_BRIDGE;
3305 flags |= BRIDGE;
3306 }
3307 if ((flags & ACC_VARARGS) != 0) {
3308 flags &= ~ACC_VARARGS;
3309 flags |= VARARGS;
3310 }
3311 return flags;
3312 }
3313
3314 long adjustClassFlags(long flags) {
3315 if ((flags & ACC_MODULE) != 0) {
3316 flags &= ~ACC_MODULE;
3317 flags |= MODULE;
3318 }
3319 return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
3320 }
3321
3322 /**
3323 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3324 * The attribute is only the last component of the original filename, so is unlikely
3325 * to be valid as is, so operations other than those to access the name throw
3326 * UnsupportedOperationException
3327 */
3328 private static class SourceFileObject implements JavaFileObject {
3329
3330 /** The file's name.
3331 */
3332 private final Name name;
3333
3334 public SourceFileObject(Name name) {
3335 this.name = name;
3336 }
3337
3338 @Override @DefinedBy(Api.COMPILER)
3339 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.Errors;
67 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
68 import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
69 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
70 import com.sun.tools.javac.tree.JCTree;
71 import com.sun.tools.javac.util.*;
72 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
73 import com.sun.tools.javac.util.DefinedBy.Api;
74 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
75
76 import static com.sun.tools.javac.code.Flags.*;
77 import static com.sun.tools.javac.code.Kinds.Kind.*;
78
79 import com.sun.tools.javac.code.Scope.LookupKind;
80
81 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
82 import static com.sun.tools.javac.code.TypeTag.ARRAY;
83 import static com.sun.tools.javac.code.TypeTag.CLASS;
84 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
85 import static com.sun.tools.javac.jvm.ClassFile.*;
86 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
87
88 import static com.sun.tools.javac.main.Option.PARAMETERS;
89
90 /** This class provides operations to read a classfile into an internal
91 * representation. The internal representation is anchored in a
92 * ClassSymbol which contains in its scope symbol representations
93 * for all other definitions in the classfile. Top-level Classes themselves
94 * appear as members of the scopes of PackageSymbols.
95 *
96 * <p><b>This is NOT part of any supported API.
97 * If you write code that depends on this, you do so at your own risk.
98 * This code and its internal interfaces are subject to change or
99 * deletion without notice.</b>
100 */
101 public class ClassReader {
102 /** The context key for the class reader. */
103 protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
104
105 public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
106
107 private final Annotate annotate;
108
109 /** Switch: verbose output.
110 */
111 boolean verbose;
112
113 /** Switch: allow modules.
114 */
115 boolean allowModules;
116
117 /** Switch: allow value classes.
118 */
119 boolean allowValueClasses;
120
121 /** Switch: allow sealed
122 */
123 boolean allowSealedTypes;
124
125 /** Switch: allow records
126 */
127 boolean allowRecords;
128
129 /** Switch: warn (instead of error) on illegal UTF-8
130 */
131 boolean warnOnIllegalUtf8;
132
133 /** Switch: preserve parameter names from the variable table.
134 */
135 public boolean saveParameterNames;
136
137 /**
138 * The currently selected profile.
139 */
140 public final Profile profile;
283 protected ClassReader(Context context) {
284 context.put(classReaderKey, this);
285 annotate = Annotate.instance(context);
286 names = Names.instance(context);
287 syms = Symtab.instance(context);
288 types = Types.instance(context);
289 fileManager = context.get(JavaFileManager.class);
290 if (fileManager == null)
291 throw new AssertionError("FileManager initialization error");
292 diagFactory = JCDiagnostic.Factory.instance(context);
293 dcfh = DeferredCompletionFailureHandler.instance(context);
294
295 log = Log.instance(context);
296
297 Options options = Options.instance(context);
298 verbose = options.isSet(Option.VERBOSE);
299
300 Source source = Source.instance(context);
301 preview = Preview.instance(context);
302 allowModules = Feature.MODULES.allowedInSource(source);
303 allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
304 Feature.VALUE_CLASSES.allowedInSource(source);
305 allowRecords = Feature.RECORDS.allowedInSource(source);
306 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
307 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
308
309 saveParameterNames = options.isSet(PARAMETERS);
310
311 profile = Profile.instance(context);
312
313 typevars = WriteableScope.create(syms.noSymbol);
314
315 lint = Lint.instance(context);
316
317 initAttributeReaders();
318 }
319
320 /** Add member to class unless it is synthetic.
321 */
322 private void enterMember(ClassSymbol c, Symbol sym) {
323 // Synthetic members are not entered -- reason lost to history (optimization?).
324 // Lambda methods must be entered because they may have inner classes (which reference them)
579 int sbp = 0;
580 /** Convert class signature to type, where signature is implicit.
581 */
582 Type classSigToType() {
583 if (signature[sigp] != 'L')
584 throw badClassFile("bad.class.signature", quoteBadSignature());
585 sigp++;
586 Type outer = Type.noType;
587 int startSbp = sbp;
588
589 while (true) {
590 final byte c = signature[sigp++];
591 switch (c) {
592
593 case ';': { // end
594 ClassSymbol t = enterClass(readName(signatureBuffer,
595 startSbp,
596 sbp - startSbp));
597
598 try {
599 if (outer == Type.noType) {
600 ClassType et = (ClassType) t.erasure(types);
601 return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
602 }
603 return new ClassType(outer, List.nil(), t, List.nil());
604 } finally {
605 sbp = startSbp;
606 }
607 }
608
609 case '<': // generic arguments
610 ClassSymbol t = enterClass(readName(signatureBuffer,
611 startSbp,
612 sbp - startSbp));
613 List<Type> actuals = sigToTypes('>');
614 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
615 if (formals != null) {
616 if (actuals.isEmpty())
617 actuals = formals;
618 }
619 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
620 * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
621 * assigned to but then we would have a dependendy on the internal representation of ClassType which
622 * could change in the future
623 */
624 final List<Type> actualsCp = actuals;
625 outer = new ClassType(outer, actuals, t, List.nil()) {
626 boolean completed = false;
627 boolean typeArgsSet = false;
628 @Override @DefinedBy(Api.LANGUAGE_MODEL)
629 public Type getEnclosingType() {
630 if (!completed) {
631 completed = true;
632 tsym.apiComplete();
633 Type enclosingType = tsym.type.getEnclosingType();
634 if (enclosingType != Type.noType) {
635 List<Type> typeArgs =
636 super.getEnclosingType().allparams();
637 List<Type> typeParams =
638 enclosingType.allparams();
639 if (typeParams.length() != typeArgs.length()) {
640 // no "rare" types
641 super.setEnclosingType(types.erasure(enclosingType));
642 } else {
643 super.setEnclosingType(types.subst(enclosingType,
644 typeParams,
645 typeArgs));
689 signatureBuffer[sbp++] = (byte)'$';
690 break;
691 } else {
692 sbp = startSbp;
693 return outer;
694 }
695 case '.':
696 signatureBuffer[sbp++] = (byte)'$';
697 break;
698 default:
699 throw new AssertionError(signature[sigp-1]);
700 }
701 continue;
702
703 case '.':
704 //we have seen an enclosing non-generic class
705 if (outer != Type.noType) {
706 t = enterClass(readName(signatureBuffer,
707 startSbp,
708 sbp - startSbp));
709 outer = new ClassType(outer, List.nil(), t, List.nil());
710 }
711 signatureBuffer[sbp++] = (byte)'$';
712 continue;
713 case '/':
714 signatureBuffer[sbp++] = (byte)'.';
715 continue;
716 default:
717 signatureBuffer[sbp++] = c;
718 continue;
719 }
720 }
721 }
722
723 /** Quote a bogus signature for display inside an error message.
724 */
725 String quoteBadSignature() {
726 String sigString;
727 try {
728 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
729 } catch (InvalidUtfException e) {
1552 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1553 for (CompoundAnnotationProxy proxy : annotations) {
1554 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1555 sym.flags_field |= PROPRIETARY;
1556 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1557 if (profile != Profile.DEFAULT) {
1558 for (Pair<Name, Attribute> v : proxy.values) {
1559 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1560 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1561 sym.flags_field |= NOT_IN_PROFILE;
1562 }
1563 }
1564 }
1565 }
1566 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1567 sym.flags_field |= PREVIEW_API;
1568 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1569 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1570 Assert.check(sym.kind == TYP);
1571 sym.flags_field |= VALUE_BASED;
1572 } else if (proxy.type.tsym.flatName() == syms.migratedValueClassInternalType.tsym.flatName()) {
1573 Assert.check(sym.kind == TYP);
1574 sym.flags_field |= MIGRATED_VALUE_CLASS;
1575 if (needsValueFlag(sym, sym.flags_field)) {
1576 sym.flags_field |= VALUE_CLASS;
1577 sym.flags_field &= ~IDENTITY_TYPE;
1578 }
1579 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1580 Assert.check(sym.kind == MTH);
1581 sym.flags_field |= RESTRICTED;
1582 } else {
1583 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1584 target = proxy;
1585 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1586 repeatable = proxy;
1587 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1588 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1589 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1590 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1591 sym.flags_field |= PREVIEW_API;
1592 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1593 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1594 sym.flags_field |= VALUE_BASED;
1595 } else if (proxy.type.tsym == syms.migratedValueClassType.tsym && sym.kind == TYP) {
1596 sym.flags_field |= MIGRATED_VALUE_CLASS;
1597 if (needsValueFlag(sym, sym.flags_field)) {
1598 sym.flags_field |= VALUE_CLASS;
1599 sym.flags_field &= ~IDENTITY_TYPE;
1600 }
1601 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1602 Assert.check(sym.kind == MTH);
1603 sym.flags_field |= RESTRICTED;
1604 }
1605 proxies.append(proxy);
1606 }
1607 }
1608 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1609 }
1610 //where:
1611 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1612 for (Pair<Name, Attribute> v : proxy.values) {
1613 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1614 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1615 sym.flags_field |= flag;
1616 }
1617 }
1618 }
1619 }
1620
3069 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3070 return syms.enterClass(currentModule, name, owner);
3071 }
3072
3073 /** Read contents of a given class symbol `c'. Both external and internal
3074 * versions of an inner class are read.
3075 */
3076 void readClass(ClassSymbol c) {
3077 ClassType ct = (ClassType)c.type;
3078
3079 // allocate scope for members
3080 c.members_field = WriteableScope.create(c);
3081
3082 // prepare type variable table
3083 typevars = typevars.dup(currentOwner);
3084 if (ct.getEnclosingType().hasTag(CLASS))
3085 enterTypevars(c.owner, ct.getEnclosingType());
3086
3087 // read flags, or skip if this is an inner class
3088 long f = nextChar();
3089 long flags = adjustClassFlags(c, f);
3090 if ((flags & MODULE) == 0) {
3091 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3092 // read own class name and check that it matches
3093 currentModule = c.packge().modle;
3094 ClassSymbol self = poolReader.getClass(nextChar());
3095 if (c != self) {
3096 throw badClassFile("class.file.wrong.class",
3097 self.flatname);
3098 }
3099 } else {
3100 if (majorVersion < Version.V53.major) {
3101 throw badClassFile("anachronistic.module.info",
3102 Integer.toString(majorVersion),
3103 Integer.toString(minorVersion));
3104 }
3105 c.flags_field = flags;
3106 if (c.owner.kind != MDL) {
3107 throw badClassFile("module.info.definition.expected");
3108 }
3109 currentModule = (ModuleSymbol) c.owner;
3161 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3162 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3163 return (MethodSymbol) s;
3164 }
3165 }
3166 return null;
3167 }
3168
3169 /** Read inner class info. For each inner/outer pair allocate a
3170 * member class.
3171 */
3172 void readInnerClasses(ClassSymbol c) {
3173 int n = nextChar();
3174 for (int i = 0; i < n; i++) {
3175 nextChar(); // skip inner class symbol
3176 int outerIdx = nextChar();
3177 int nameIdx = nextChar();
3178 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3179 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3180 if (name == null) name = names.empty;
3181 long flags = adjustClassFlags(c, nextChar());
3182 if (outer != null) { // we have a member class
3183 if (name == names.empty)
3184 name = names.one;
3185 ClassSymbol member = enterClass(name, outer);
3186 if ((flags & STATIC) == 0) {
3187 ((ClassType)member.type).setEnclosingType(outer.type);
3188 if (member.erasure_field != null)
3189 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3190 }
3191 if (c == outer && member.owner == c) {
3192 member.flags_field = flags;
3193 enterMember(c, member);
3194 }
3195 }
3196 }
3197 }
3198
3199 /** Read a class definition from the bytes in buf.
3200 */
3201 private void readClassBuffer(ClassSymbol c) throws IOException {
3303 } finally {
3304 interimUses = List.nil();
3305 interimProvides = List.nil();
3306 missingTypeVariables = List.nil();
3307 foundTypeVariables = List.nil();
3308 filling = false;
3309 }
3310 }
3311
3312 /** We can only read a single class file at a time; this
3313 * flag keeps track of when we are currently reading a class
3314 * file.
3315 */
3316 public boolean filling = false;
3317
3318 /* **********************************************************************
3319 * Adjusting flags
3320 ***********************************************************************/
3321
3322 long adjustFieldFlags(long flags) {
3323 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3324 if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3325 flags &= ~ACC_STRICT;
3326 flags |= STRICT;
3327 }
3328 return flags;
3329 }
3330
3331 long adjustMethodFlags(long flags) {
3332 if ((flags & ACC_BRIDGE) != 0) {
3333 flags &= ~ACC_BRIDGE;
3334 flags |= BRIDGE;
3335 }
3336 if ((flags & ACC_VARARGS) != 0) {
3337 flags &= ~ACC_VARARGS;
3338 flags |= VARARGS;
3339 }
3340 return flags;
3341 }
3342
3343 long adjustClassFlags(ClassSymbol c, long flags) {
3344 if ((flags & ACC_MODULE) != 0) {
3345 flags &= ~ACC_MODULE;
3346 flags |= MODULE;
3347 }
3348 if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags)) || (majorVersion < V67.major && (flags & INTERFACE) == 0)) {
3349 flags |= IDENTITY_TYPE;
3350 } else if (needsValueFlag(c, flags)) {
3351 flags |= VALUE_CLASS;
3352 flags &= ~IDENTITY_TYPE;
3353 }
3354 flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3355 return flags;
3356 }
3357
3358 private boolean needsValueFlag(Symbol c, long flags) {
3359 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3360 if (allowValueClasses) {
3361 if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3362 majorVersion >= V67.major && isMigratedValueClass(flags)) {
3363 return true;
3364 }
3365 }
3366 return false;
3367 }
3368
3369 private boolean isMigratedValueClass(long flags) {
3370 return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3371 }
3372
3373 /**
3374 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3375 * The attribute is only the last component of the original filename, so is unlikely
3376 * to be valid as is, so operations other than those to access the name throw
3377 * UnsupportedOperationException
3378 */
3379 private static class SourceFileObject implements JavaFileObject {
3380
3381 /** The file's name.
3382 */
3383 private final Name name;
3384
3385 public SourceFileObject(Name name) {
3386 this.name = name;
3387 }
3388
3389 @Override @DefinedBy(Api.COMPILER)
3390 public URI toUri() {
|