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