45 import javax.tools.JavaFileManager;
46 import javax.tools.JavaFileObject;
47
48 import com.sun.tools.javac.code.Source;
49 import com.sun.tools.javac.code.Source.Feature;
50 import com.sun.tools.javac.comp.Annotate;
51 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
52 import com.sun.tools.javac.code.*;
53 import com.sun.tools.javac.code.Directive.*;
54 import com.sun.tools.javac.code.Lint.LintCategory;
55 import com.sun.tools.javac.code.Scope.WriteableScope;
56 import com.sun.tools.javac.code.Symbol.*;
57 import com.sun.tools.javac.code.Symtab;
58 import com.sun.tools.javac.code.Type.*;
59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
60 import com.sun.tools.javac.file.BaseFileManager;
61 import com.sun.tools.javac.file.PathFileObject;
62 import com.sun.tools.javac.jvm.ClassFile.Version;
63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
64 import com.sun.tools.javac.main.Option;
65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
66 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
67 import com.sun.tools.javac.util.*;
68 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
69 import com.sun.tools.javac.util.DefinedBy.Api;
70 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
71 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
72
73 import static com.sun.tools.javac.code.Flags.*;
74 import static com.sun.tools.javac.code.Kinds.Kind.*;
75
76 import com.sun.tools.javac.code.Scope.LookupKind;
77
78 import static com.sun.tools.javac.code.TypeTag.ARRAY;
79 import static com.sun.tools.javac.code.TypeTag.CLASS;
80 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
81 import static com.sun.tools.javac.jvm.ClassFile.*;
82 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
83
84 import static com.sun.tools.javac.main.Option.PARAMETERS;
85
86 /** This class provides operations to read a classfile into an internal
87 * representation. The internal representation is anchored in a
88 * ClassSymbol which contains in its scope symbol representations
89 * for all other definitions in the classfile. Top-level Classes themselves
90 * appear as members of the scopes of PackageSymbols.
91 *
92 * <p><b>This is NOT part of any supported API.
93 * If you write code that depends on this, you do so at your own risk.
94 * This code and its internal interfaces are subject to change or
95 * deletion without notice.</b>
96 */
97 public class ClassReader {
98 /** The context key for the class reader. */
99 protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
100
101 public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
102
103 private final Annotate annotate;
104
105 /** Switch: verbose output.
106 */
107 boolean verbose;
108
109 /** Switch: allow modules.
110 */
111 boolean allowModules;
112
113 /** Switch: allow sealed
114 */
115 boolean allowSealedTypes;
116
117 /** Switch: allow records
118 */
119 boolean allowRecords;
120
121 /** Lint option: warn about classfile issues
122 */
123 boolean lintClassfile;
124
125 /** Switch: warn (instead of error) on illegal UTF-8
126 */
127 boolean warnOnIllegalUtf8;
128
129 /** Switch: preserve parameter names from the variable table.
130 */
131 public boolean saveParameterNames;
132
267 protected ClassReader(Context context) {
268 context.put(classReaderKey, this);
269 annotate = Annotate.instance(context);
270 names = Names.instance(context);
271 syms = Symtab.instance(context);
272 types = Types.instance(context);
273 fileManager = context.get(JavaFileManager.class);
274 if (fileManager == null)
275 throw new AssertionError("FileManager initialization error");
276 diagFactory = JCDiagnostic.Factory.instance(context);
277 dcfh = DeferredCompletionFailureHandler.instance(context);
278
279 log = Log.instance(context);
280
281 Options options = Options.instance(context);
282 verbose = options.isSet(Option.VERBOSE);
283
284 Source source = Source.instance(context);
285 preview = Preview.instance(context);
286 allowModules = Feature.MODULES.allowedInSource(source);
287 allowRecords = Feature.RECORDS.allowedInSource(source);
288 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
289 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
290
291 saveParameterNames = options.isSet(PARAMETERS);
292
293 profile = Profile.instance(context);
294
295 typevars = WriteableScope.create(syms.noSymbol);
296
297 lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
298
299 initAttributeReaders();
300 }
301
302 /** Add member to class unless it is synthetic.
303 */
304 private void enterMember(ClassSymbol c, Symbol sym) {
305 // Synthetic members are not entered -- reason lost to history (optimization?).
306 // Lambda methods must be entered because they may have inner classes (which reference them)
561 int sbp = 0;
562 /** Convert class signature to type, where signature is implicit.
563 */
564 Type classSigToType() {
565 if (signature[sigp] != 'L')
566 throw badClassFile("bad.class.signature", quoteBadSignature());
567 sigp++;
568 Type outer = Type.noType;
569 int startSbp = sbp;
570
571 while (true) {
572 final byte c = signature[sigp++];
573 switch (c) {
574
575 case ';': { // end
576 ClassSymbol t = enterClass(readName(signatureBuffer,
577 startSbp,
578 sbp - startSbp));
579
580 try {
581 return (outer == Type.noType) ?
582 t.erasure(types) :
583 new ClassType(outer, List.nil(), t);
584 } finally {
585 sbp = startSbp;
586 }
587 }
588
589 case '<': // generic arguments
590 ClassSymbol t = enterClass(readName(signatureBuffer,
591 startSbp,
592 sbp - startSbp));
593 List<Type> actuals = sigToTypes('>');
594 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
595 if (formals != null) {
596 if (actuals.isEmpty())
597 actuals = formals;
598 }
599 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
600 * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
601 * assigned to but then we would have a dependendy on the internal representation of ClassType which
602 * could change in the future
603 */
604 final List<Type> actualsCp = actuals;
605 outer = new ClassType(outer, actuals, t) {
606 boolean completed = false;
607 boolean typeArgsSet = false;
608 @Override @DefinedBy(Api.LANGUAGE_MODEL)
609 public Type getEnclosingType() {
610 if (!completed) {
611 completed = true;
612 tsym.apiComplete();
613 Type enclosingType = tsym.type.getEnclosingType();
614 if (enclosingType != Type.noType) {
615 List<Type> typeArgs =
616 super.getEnclosingType().allparams();
617 List<Type> typeParams =
618 enclosingType.allparams();
619 if (typeParams.length() != typeArgs.length()) {
620 // no "rare" types
621 super.setEnclosingType(types.erasure(enclosingType));
622 } else {
623 super.setEnclosingType(types.subst(enclosingType,
624 typeParams,
625 typeArgs));
669 signatureBuffer[sbp++] = (byte)'$';
670 break;
671 } else {
672 sbp = startSbp;
673 return outer;
674 }
675 case '.':
676 signatureBuffer[sbp++] = (byte)'$';
677 break;
678 default:
679 throw new AssertionError(signature[sigp-1]);
680 }
681 continue;
682
683 case '.':
684 //we have seen an enclosing non-generic class
685 if (outer != Type.noType) {
686 t = enterClass(readName(signatureBuffer,
687 startSbp,
688 sbp - startSbp));
689 outer = new ClassType(outer, List.nil(), t);
690 }
691 signatureBuffer[sbp++] = (byte)'$';
692 continue;
693 case '/':
694 signatureBuffer[sbp++] = (byte)'.';
695 continue;
696 default:
697 signatureBuffer[sbp++] = c;
698 continue;
699 }
700 }
701 }
702
703 /** Quote a bogus signature for display inside an error message.
704 */
705 String quoteBadSignature() {
706 String sigString;
707 try {
708 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
709 } catch (InvalidUtfException e) {
1527 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1528 for (CompoundAnnotationProxy proxy : annotations) {
1529 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1530 sym.flags_field |= PROPRIETARY;
1531 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1532 if (profile != Profile.DEFAULT) {
1533 for (Pair<Name, Attribute> v : proxy.values) {
1534 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1535 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1536 sym.flags_field |= NOT_IN_PROFILE;
1537 }
1538 }
1539 }
1540 }
1541 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1542 sym.flags_field |= PREVIEW_API;
1543 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1544 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1545 Assert.check(sym.kind == TYP);
1546 sym.flags_field |= VALUE_BASED;
1547 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1548 Assert.check(sym.kind == MTH);
1549 sym.flags_field |= RESTRICTED;
1550 } else {
1551 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1552 target = proxy;
1553 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1554 repeatable = proxy;
1555 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1556 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1557 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1558 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1559 sym.flags_field |= PREVIEW_API;
1560 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1561 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1562 sym.flags_field |= VALUE_BASED;
1563 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1564 Assert.check(sym.kind == MTH);
1565 sym.flags_field |= RESTRICTED;
1566 }
1567 proxies.append(proxy);
1568 }
1569 }
1570 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1571 }
1572 //where:
1573 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1574 for (Pair<Name, Attribute> v : proxy.values) {
1575 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1576 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1577 sym.flags_field |= flag;
1578 }
1579 }
1580 }
1581 }
1582
2909 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2910 return syms.enterClass(currentModule, name, owner);
2911 }
2912
2913 /** Read contents of a given class symbol `c'. Both external and internal
2914 * versions of an inner class are read.
2915 */
2916 void readClass(ClassSymbol c) {
2917 ClassType ct = (ClassType)c.type;
2918
2919 // allocate scope for members
2920 c.members_field = WriteableScope.create(c);
2921
2922 // prepare type variable table
2923 typevars = typevars.dup(currentOwner);
2924 if (ct.getEnclosingType().hasTag(CLASS))
2925 enterTypevars(c.owner, ct.getEnclosingType());
2926
2927 // read flags, or skip if this is an inner class
2928 long f = nextChar();
2929 long flags = adjustClassFlags(f);
2930 if ((flags & MODULE) == 0) {
2931 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2932 // read own class name and check that it matches
2933 currentModule = c.packge().modle;
2934 ClassSymbol self = poolReader.getClass(nextChar());
2935 if (c != self) {
2936 throw badClassFile("class.file.wrong.class",
2937 self.flatname);
2938 }
2939 } else {
2940 if (majorVersion < Version.V53.major) {
2941 throw badClassFile("anachronistic.module.info",
2942 Integer.toString(majorVersion),
2943 Integer.toString(minorVersion));
2944 }
2945 c.flags_field = flags;
2946 if (c.owner.kind != MDL) {
2947 throw badClassFile("module.info.definition.expected");
2948 }
2949 currentModule = (ModuleSymbol) c.owner;
3001 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3002 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3003 return (MethodSymbol) s;
3004 }
3005 }
3006 return null;
3007 }
3008
3009 /** Read inner class info. For each inner/outer pair allocate a
3010 * member class.
3011 */
3012 void readInnerClasses(ClassSymbol c) {
3013 int n = nextChar();
3014 for (int i = 0; i < n; i++) {
3015 nextChar(); // skip inner class symbol
3016 int outerIdx = nextChar();
3017 int nameIdx = nextChar();
3018 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3019 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3020 if (name == null) name = names.empty;
3021 long flags = adjustClassFlags(nextChar());
3022 if (outer != null) { // we have a member class
3023 if (name == names.empty)
3024 name = names.one;
3025 ClassSymbol member = enterClass(name, outer);
3026 if ((flags & STATIC) == 0) {
3027 ((ClassType)member.type).setEnclosingType(outer.type);
3028 if (member.erasure_field != null)
3029 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3030 }
3031 if (c == outer && member.owner == c) {
3032 member.flags_field = flags;
3033 enterMember(c, member);
3034 }
3035 }
3036 }
3037 }
3038
3039 /** Read a class definition from the bytes in buf.
3040 */
3041 private void readClassBuffer(ClassSymbol c) throws IOException {
3143 } finally {
3144 interimUses = List.nil();
3145 interimProvides = List.nil();
3146 missingTypeVariables = List.nil();
3147 foundTypeVariables = List.nil();
3148 filling = false;
3149 }
3150 }
3151
3152 /** We can only read a single class file at a time; this
3153 * flag keeps track of when we are currently reading a class
3154 * file.
3155 */
3156 public boolean filling = false;
3157
3158 /* **********************************************************************
3159 * Adjusting flags
3160 ***********************************************************************/
3161
3162 long adjustFieldFlags(long flags) {
3163 return flags;
3164 }
3165
3166 long adjustMethodFlags(long flags) {
3167 if ((flags & ACC_BRIDGE) != 0) {
3168 flags &= ~ACC_BRIDGE;
3169 flags |= BRIDGE;
3170 }
3171 if ((flags & ACC_VARARGS) != 0) {
3172 flags &= ~ACC_VARARGS;
3173 flags |= VARARGS;
3174 }
3175 return flags;
3176 }
3177
3178 long adjustClassFlags(long flags) {
3179 if ((flags & ACC_MODULE) != 0) {
3180 flags &= ~ACC_MODULE;
3181 flags |= MODULE;
3182 }
3183 return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
3184 }
3185
3186 /**
3187 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3188 * The attribute is only the last component of the original filename, so is unlikely
3189 * to be valid as is, so operations other than those to access the name throw
3190 * UnsupportedOperationException
3191 */
3192 private static class SourceFileObject implements JavaFileObject {
3193
3194 /** The file's name.
3195 */
3196 private final Name name;
3197
3198 public SourceFileObject(Name name) {
3199 this.name = name;
3200 }
3201
3202 @Override @DefinedBy(Api.COMPILER)
3203 public URI toUri() {
|
45 import javax.tools.JavaFileManager;
46 import javax.tools.JavaFileObject;
47
48 import com.sun.tools.javac.code.Source;
49 import com.sun.tools.javac.code.Source.Feature;
50 import com.sun.tools.javac.comp.Annotate;
51 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
52 import com.sun.tools.javac.code.*;
53 import com.sun.tools.javac.code.Directive.*;
54 import com.sun.tools.javac.code.Lint.LintCategory;
55 import com.sun.tools.javac.code.Scope.WriteableScope;
56 import com.sun.tools.javac.code.Symbol.*;
57 import com.sun.tools.javac.code.Symtab;
58 import com.sun.tools.javac.code.Type.*;
59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
60 import com.sun.tools.javac.file.BaseFileManager;
61 import com.sun.tools.javac.file.PathFileObject;
62 import com.sun.tools.javac.jvm.ClassFile.Version;
63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
64 import com.sun.tools.javac.main.Option;
65 import com.sun.tools.javac.resources.CompilerProperties;
66 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
67 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
68 import com.sun.tools.javac.tree.JCTree;
69 import com.sun.tools.javac.util.*;
70 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
71 import com.sun.tools.javac.util.DefinedBy.Api;
72 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
73 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
74
75 import static com.sun.tools.javac.code.Flags.*;
76 import static com.sun.tools.javac.code.Kinds.Kind.*;
77
78 import com.sun.tools.javac.code.Scope.LookupKind;
79
80 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
81 import static com.sun.tools.javac.code.TypeTag.ARRAY;
82 import static com.sun.tools.javac.code.TypeTag.CLASS;
83 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
84 import static com.sun.tools.javac.jvm.ClassFile.*;
85 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
86
87 import static com.sun.tools.javac.main.Option.PARAMETERS;
88
89 /** This class provides operations to read a classfile into an internal
90 * representation. The internal representation is anchored in a
91 * ClassSymbol which contains in its scope symbol representations
92 * for all other definitions in the classfile. Top-level Classes themselves
93 * appear as members of the scopes of PackageSymbols.
94 *
95 * <p><b>This is NOT part of any supported API.
96 * If you write code that depends on this, you do so at your own risk.
97 * This code and its internal interfaces are subject to change or
98 * deletion without notice.</b>
99 */
100 public class ClassReader {
101 /** The context key for the class reader. */
102 protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
103
104 public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
105
106 private final Annotate annotate;
107
108 /** Switch: verbose output.
109 */
110 boolean verbose;
111
112 /** Switch: allow modules.
113 */
114 boolean allowModules;
115
116 /** Switch: allow value classes.
117 */
118 boolean allowValueClasses;
119
120 /** Switch: allow sealed
121 */
122 boolean allowSealedTypes;
123
124 /** Switch: allow records
125 */
126 boolean allowRecords;
127
128 /** Lint option: warn about classfile issues
129 */
130 boolean lintClassfile;
131
132 /** Switch: warn (instead of error) on illegal UTF-8
133 */
134 boolean warnOnIllegalUtf8;
135
136 /** Switch: preserve parameter names from the variable table.
137 */
138 public boolean saveParameterNames;
139
274 protected ClassReader(Context context) {
275 context.put(classReaderKey, this);
276 annotate = Annotate.instance(context);
277 names = Names.instance(context);
278 syms = Symtab.instance(context);
279 types = Types.instance(context);
280 fileManager = context.get(JavaFileManager.class);
281 if (fileManager == null)
282 throw new AssertionError("FileManager initialization error");
283 diagFactory = JCDiagnostic.Factory.instance(context);
284 dcfh = DeferredCompletionFailureHandler.instance(context);
285
286 log = Log.instance(context);
287
288 Options options = Options.instance(context);
289 verbose = options.isSet(Option.VERBOSE);
290
291 Source source = Source.instance(context);
292 preview = Preview.instance(context);
293 allowModules = Feature.MODULES.allowedInSource(source);
294 allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
295 Feature.VALUE_CLASSES.allowedInSource(source);
296 allowRecords = Feature.RECORDS.allowedInSource(source);
297 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
298 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
299
300 saveParameterNames = options.isSet(PARAMETERS);
301
302 profile = Profile.instance(context);
303
304 typevars = WriteableScope.create(syms.noSymbol);
305
306 lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
307
308 initAttributeReaders();
309 }
310
311 /** Add member to class unless it is synthetic.
312 */
313 private void enterMember(ClassSymbol c, Symbol sym) {
314 // Synthetic members are not entered -- reason lost to history (optimization?).
315 // Lambda methods must be entered because they may have inner classes (which reference them)
570 int sbp = 0;
571 /** Convert class signature to type, where signature is implicit.
572 */
573 Type classSigToType() {
574 if (signature[sigp] != 'L')
575 throw badClassFile("bad.class.signature", quoteBadSignature());
576 sigp++;
577 Type outer = Type.noType;
578 int startSbp = sbp;
579
580 while (true) {
581 final byte c = signature[sigp++];
582 switch (c) {
583
584 case ';': { // end
585 ClassSymbol t = enterClass(readName(signatureBuffer,
586 startSbp,
587 sbp - startSbp));
588
589 try {
590 if (outer == Type.noType) {
591 ClassType et = (ClassType) t.erasure(types);
592 return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
593 }
594 return new ClassType(outer, List.nil(), t, List.nil());
595 } finally {
596 sbp = startSbp;
597 }
598 }
599
600 case '<': // generic arguments
601 ClassSymbol t = enterClass(readName(signatureBuffer,
602 startSbp,
603 sbp - startSbp));
604 List<Type> actuals = sigToTypes('>');
605 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
606 if (formals != null) {
607 if (actuals.isEmpty())
608 actuals = formals;
609 }
610 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
611 * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
612 * assigned to but then we would have a dependendy on the internal representation of ClassType which
613 * could change in the future
614 */
615 final List<Type> actualsCp = actuals;
616 outer = new ClassType(outer, actuals, t, List.nil()) {
617 boolean completed = false;
618 boolean typeArgsSet = false;
619 @Override @DefinedBy(Api.LANGUAGE_MODEL)
620 public Type getEnclosingType() {
621 if (!completed) {
622 completed = true;
623 tsym.apiComplete();
624 Type enclosingType = tsym.type.getEnclosingType();
625 if (enclosingType != Type.noType) {
626 List<Type> typeArgs =
627 super.getEnclosingType().allparams();
628 List<Type> typeParams =
629 enclosingType.allparams();
630 if (typeParams.length() != typeArgs.length()) {
631 // no "rare" types
632 super.setEnclosingType(types.erasure(enclosingType));
633 } else {
634 super.setEnclosingType(types.subst(enclosingType,
635 typeParams,
636 typeArgs));
680 signatureBuffer[sbp++] = (byte)'$';
681 break;
682 } else {
683 sbp = startSbp;
684 return outer;
685 }
686 case '.':
687 signatureBuffer[sbp++] = (byte)'$';
688 break;
689 default:
690 throw new AssertionError(signature[sigp-1]);
691 }
692 continue;
693
694 case '.':
695 //we have seen an enclosing non-generic class
696 if (outer != Type.noType) {
697 t = enterClass(readName(signatureBuffer,
698 startSbp,
699 sbp - startSbp));
700 outer = new ClassType(outer, List.nil(), t, List.nil());
701 }
702 signatureBuffer[sbp++] = (byte)'$';
703 continue;
704 case '/':
705 signatureBuffer[sbp++] = (byte)'.';
706 continue;
707 default:
708 signatureBuffer[sbp++] = c;
709 continue;
710 }
711 }
712 }
713
714 /** Quote a bogus signature for display inside an error message.
715 */
716 String quoteBadSignature() {
717 String sigString;
718 try {
719 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
720 } catch (InvalidUtfException e) {
1538 ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1539 for (CompoundAnnotationProxy proxy : annotations) {
1540 if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1541 sym.flags_field |= PROPRIETARY;
1542 else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1543 if (profile != Profile.DEFAULT) {
1544 for (Pair<Name, Attribute> v : proxy.values) {
1545 if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1546 if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1547 sym.flags_field |= NOT_IN_PROFILE;
1548 }
1549 }
1550 }
1551 }
1552 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1553 sym.flags_field |= PREVIEW_API;
1554 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1555 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1556 Assert.check(sym.kind == TYP);
1557 sym.flags_field |= VALUE_BASED;
1558 } else if (proxy.type.tsym.flatName() == syms.migratedValueClassInternalType.tsym.flatName()) {
1559 Assert.check(sym.kind == TYP);
1560 sym.flags_field |= MIGRATED_VALUE_CLASS;
1561 if (needsValueFlag(sym, sym.flags_field)) {
1562 sym.flags_field |= VALUE_CLASS;
1563 sym.flags_field &= ~IDENTITY_TYPE;
1564 }
1565 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1566 Assert.check(sym.kind == MTH);
1567 sym.flags_field |= RESTRICTED;
1568 } else {
1569 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1570 target = proxy;
1571 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1572 repeatable = proxy;
1573 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1574 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1575 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1576 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1577 sym.flags_field |= PREVIEW_API;
1578 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1579 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1580 sym.flags_field |= VALUE_BASED;
1581 } else if (proxy.type.tsym == syms.migratedValueClassType.tsym && sym.kind == TYP) {
1582 sym.flags_field |= MIGRATED_VALUE_CLASS;
1583 if (needsValueFlag(sym, sym.flags_field)) {
1584 sym.flags_field |= VALUE_CLASS;
1585 sym.flags_field &= ~IDENTITY_TYPE;
1586 }
1587 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1588 Assert.check(sym.kind == MTH);
1589 sym.flags_field |= RESTRICTED;
1590 }
1591 proxies.append(proxy);
1592 }
1593 }
1594 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1595 }
1596 //where:
1597 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1598 for (Pair<Name, Attribute> v : proxy.values) {
1599 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1600 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1601 sym.flags_field |= flag;
1602 }
1603 }
1604 }
1605 }
1606
2933 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2934 return syms.enterClass(currentModule, name, owner);
2935 }
2936
2937 /** Read contents of a given class symbol `c'. Both external and internal
2938 * versions of an inner class are read.
2939 */
2940 void readClass(ClassSymbol c) {
2941 ClassType ct = (ClassType)c.type;
2942
2943 // allocate scope for members
2944 c.members_field = WriteableScope.create(c);
2945
2946 // prepare type variable table
2947 typevars = typevars.dup(currentOwner);
2948 if (ct.getEnclosingType().hasTag(CLASS))
2949 enterTypevars(c.owner, ct.getEnclosingType());
2950
2951 // read flags, or skip if this is an inner class
2952 long f = nextChar();
2953 long flags = adjustClassFlags(c, f);
2954 if ((flags & MODULE) == 0) {
2955 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2956 // read own class name and check that it matches
2957 currentModule = c.packge().modle;
2958 ClassSymbol self = poolReader.getClass(nextChar());
2959 if (c != self) {
2960 throw badClassFile("class.file.wrong.class",
2961 self.flatname);
2962 }
2963 } else {
2964 if (majorVersion < Version.V53.major) {
2965 throw badClassFile("anachronistic.module.info",
2966 Integer.toString(majorVersion),
2967 Integer.toString(minorVersion));
2968 }
2969 c.flags_field = flags;
2970 if (c.owner.kind != MDL) {
2971 throw badClassFile("module.info.definition.expected");
2972 }
2973 currentModule = (ModuleSymbol) c.owner;
3025 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3026 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3027 return (MethodSymbol) s;
3028 }
3029 }
3030 return null;
3031 }
3032
3033 /** Read inner class info. For each inner/outer pair allocate a
3034 * member class.
3035 */
3036 void readInnerClasses(ClassSymbol c) {
3037 int n = nextChar();
3038 for (int i = 0; i < n; i++) {
3039 nextChar(); // skip inner class symbol
3040 int outerIdx = nextChar();
3041 int nameIdx = nextChar();
3042 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3043 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3044 if (name == null) name = names.empty;
3045 long flags = adjustClassFlags(c, nextChar());
3046 if (outer != null) { // we have a member class
3047 if (name == names.empty)
3048 name = names.one;
3049 ClassSymbol member = enterClass(name, outer);
3050 if ((flags & STATIC) == 0) {
3051 ((ClassType)member.type).setEnclosingType(outer.type);
3052 if (member.erasure_field != null)
3053 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3054 }
3055 if (c == outer && member.owner == c) {
3056 member.flags_field = flags;
3057 enterMember(c, member);
3058 }
3059 }
3060 }
3061 }
3062
3063 /** Read a class definition from the bytes in buf.
3064 */
3065 private void readClassBuffer(ClassSymbol c) throws IOException {
3167 } finally {
3168 interimUses = List.nil();
3169 interimProvides = List.nil();
3170 missingTypeVariables = List.nil();
3171 foundTypeVariables = List.nil();
3172 filling = false;
3173 }
3174 }
3175
3176 /** We can only read a single class file at a time; this
3177 * flag keeps track of when we are currently reading a class
3178 * file.
3179 */
3180 public boolean filling = false;
3181
3182 /* **********************************************************************
3183 * Adjusting flags
3184 ***********************************************************************/
3185
3186 long adjustFieldFlags(long flags) {
3187 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3188 if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3189 flags &= ~ACC_STRICT;
3190 flags |= STRICT;
3191 }
3192 return flags;
3193 }
3194
3195 long adjustMethodFlags(long flags) {
3196 if ((flags & ACC_BRIDGE) != 0) {
3197 flags &= ~ACC_BRIDGE;
3198 flags |= BRIDGE;
3199 }
3200 if ((flags & ACC_VARARGS) != 0) {
3201 flags &= ~ACC_VARARGS;
3202 flags |= VARARGS;
3203 }
3204 return flags;
3205 }
3206
3207 long adjustClassFlags(ClassSymbol c, long flags) {
3208 if ((flags & ACC_MODULE) != 0) {
3209 flags &= ~ACC_MODULE;
3210 flags |= MODULE;
3211 }
3212 if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags)) || (majorVersion < V67.major && (flags & INTERFACE) == 0)) {
3213 flags |= IDENTITY_TYPE;
3214 } else if (needsValueFlag(c, flags)) {
3215 flags |= VALUE_CLASS;
3216 flags &= ~IDENTITY_TYPE;
3217 }
3218 flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3219 return flags;
3220 }
3221
3222 private boolean needsValueFlag(Symbol c, long flags) {
3223 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3224 if (allowValueClasses) {
3225 if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3226 majorVersion >= V67.major && isMigratedValueClass(flags)) {
3227 return true;
3228 }
3229 }
3230 return false;
3231 }
3232
3233 private boolean isMigratedValueClass(long flags) {
3234 return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3235 }
3236
3237 /**
3238 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3239 * The attribute is only the last component of the original filename, so is unlikely
3240 * to be valid as is, so operations other than those to access the name throw
3241 * UnsupportedOperationException
3242 */
3243 private static class SourceFileObject implements JavaFileObject {
3244
3245 /** The file's name.
3246 */
3247 private final Name name;
3248
3249 public SourceFileObject(Name name) {
3250 this.name = name;
3251 }
3252
3253 @Override @DefinedBy(Api.COMPILER)
3254 public URI toUri() {
|