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