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.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
301 Feature.VALUE_CLASSES.allowedInSource(source);
302 allowRecords = Feature.RECORDS.allowedInSource(source);
303 allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
304 warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
305
306 saveParameterNames = options.isSet(PARAMETERS);
307
308 profile = Profile.instance(context);
309
310 typevars = WriteableScope.create(syms.noSymbol);
311
312 initAttributeReaders();
313 }
314
315 /** Add member to class unless it is synthetic.
316 */
317 private void enterMember(ClassSymbol c, Symbol sym) {
318 // Synthetic members are not entered -- reason lost to history (optimization?).
319 // Lambda methods must be entered because they may have inner classes (which reference them)
320 if ((sym.flags_field & (SYNTHETIC|BRIDGE)) != SYNTHETIC || sym.name.startsWith(names.lambda))
321 c.members_field.enter(sym);
574 int sbp = 0;
575 /** Convert class signature to type, where signature is implicit.
576 */
577 Type classSigToType() {
578 if (signature[sigp] != 'L')
579 throw badClassFile("bad.class.signature", quoteBadSignature());
580 sigp++;
581 Type outer = Type.noType;
582 int startSbp = sbp;
583
584 while (true) {
585 final byte c = signature[sigp++];
586 switch (c) {
587
588 case ';': { // end
589 ClassSymbol t = enterClass(readName(signatureBuffer,
590 startSbp,
591 sbp - startSbp));
592
593 try {
594 if (outer == Type.noType) {
595 ClassType et = (ClassType) t.erasure(types);
596 return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
597 }
598 return new ClassType(outer, List.nil(), t, List.nil());
599 } finally {
600 sbp = startSbp;
601 }
602 }
603
604 case '<': // generic arguments
605 ClassSymbol t = enterClass(readName(signatureBuffer,
606 startSbp,
607 sbp - startSbp));
608 List<Type> actuals = sigToTypes('>');
609 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
610 if (formals != null) {
611 if (actuals.isEmpty())
612 actuals = formals;
613 }
614 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
615 * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
616 * assigned to but then we would have a dependendy on the internal representation of ClassType which
617 * could change in the future
618 */
619 final List<Type> actualsCp = actuals;
620 outer = new ClassType(outer, actuals, t, List.nil()) {
621 boolean completed = false;
622 boolean typeArgsSet = false;
623 @Override @DefinedBy(Api.LANGUAGE_MODEL)
624 public Type getEnclosingType() {
625 if (!completed) {
626 completed = true;
627 tsym.apiComplete();
628 Type enclosingType = tsym.type.getEnclosingType();
629 if (enclosingType != Type.noType) {
630 List<Type> typeArgs =
631 super.getEnclosingType().allparams();
632 List<Type> typeParams =
633 enclosingType.allparams();
634 if (typeParams.length() != typeArgs.length()) {
635 // no "rare" types
636 super.setEnclosingType(types.erasure(enclosingType));
637 } else {
638 super.setEnclosingType(types.subst(enclosingType,
639 typeParams,
640 typeArgs));
684 signatureBuffer[sbp++] = (byte)'$';
685 break;
686 } else {
687 sbp = startSbp;
688 return outer;
689 }
690 case '.':
691 signatureBuffer[sbp++] = (byte)'$';
692 break;
693 default:
694 throw new AssertionError(signature[sigp-1]);
695 }
696 continue;
697
698 case '.':
699 //we have seen an enclosing non-generic class
700 if (outer != Type.noType) {
701 t = enterClass(readName(signatureBuffer,
702 startSbp,
703 sbp - startSbp));
704 outer = new ClassType(outer, List.nil(), t, List.nil());
705 }
706 signatureBuffer[sbp++] = (byte)'$';
707 continue;
708 case '/':
709 signatureBuffer[sbp++] = (byte)'.';
710 continue;
711 default:
712 signatureBuffer[sbp++] = c;
713 continue;
714 }
715 }
716 }
717
718 /** Quote a bogus signature for display inside an error message.
719 */
720 String quoteBadSignature() {
721 String sigString;
722 try {
723 sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
724 } catch (InvalidUtfException e) {
1558 sym.flags_field |= VALUE_BASED;
1559 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1560 Assert.check(sym.kind == MTH);
1561 sym.flags_field |= RESTRICTED;
1562 } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1563 Assert.check(sym.kind == VAR);
1564 sym.flags_field |= REQUIRES_IDENTITY;
1565 } else {
1566 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1567 target = proxy;
1568 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1569 repeatable = proxy;
1570 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1571 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1572 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1573 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1574 sym.flags_field |= PREVIEW_API;
1575 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1576 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1577 sym.flags_field |= VALUE_BASED;
1578 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1579 Assert.check(sym.kind == MTH);
1580 sym.flags_field |= RESTRICTED;
1581 } else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1582 Assert.check(sym.kind == VAR);
1583 sym.flags_field |= REQUIRES_IDENTITY;
1584 }
1585 proxies.append(proxy);
1586 }
1587 }
1588 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1589 }
1590 //where:
1591 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1592 for (Pair<Name, Attribute> v : proxy.values) {
1593 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1594 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1595 sym.flags_field |= flag;
1596 }
1597 }
1598 }
3069 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3070 return syms.enterClass(currentModule, name, owner);
3071 }
3072
3073 /** Read contents of a given class symbol `c'. Both external and internal
3074 * versions of an inner class are read.
3075 */
3076 void readClass(ClassSymbol c) {
3077 ClassType ct = (ClassType)c.type;
3078
3079 // allocate scope for members
3080 c.members_field = WriteableScope.create(c);
3081
3082 // prepare type variable table
3083 typevars = typevars.dup(currentOwner);
3084 if (ct.getEnclosingType().hasTag(CLASS))
3085 enterTypevars(c.owner, ct.getEnclosingType());
3086
3087 // read flags, or skip if this is an inner class
3088 long f = nextChar();
3089 long flags = adjustClassFlags(c, f);
3090 if ((flags & MODULE) == 0) {
3091 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3092 // read own class name and check that it matches
3093 currentModule = c.packge().modle;
3094 ClassSymbol self = poolReader.getClass(nextChar());
3095 if (c != self) {
3096 throw badClassFile("class.file.wrong.class",
3097 self.flatname);
3098 }
3099 } else {
3100 if (majorVersion < Version.V53.major) {
3101 throw badClassFile("anachronistic.module.info",
3102 Integer.toString(majorVersion),
3103 Integer.toString(minorVersion));
3104 }
3105 c.flags_field = flags;
3106 if (c.owner.kind != MDL) {
3107 throw badClassFile("module.info.definition.expected");
3108 }
3109 currentModule = (ModuleSymbol) c.owner;
3161 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3162 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3163 return (MethodSymbol) s;
3164 }
3165 }
3166 return null;
3167 }
3168
3169 /** Read inner class info. For each inner/outer pair allocate a
3170 * member class.
3171 */
3172 void readInnerClasses(ClassSymbol c) {
3173 int n = nextChar();
3174 for (int i = 0; i < n; i++) {
3175 nextChar(); // skip inner class symbol
3176 int outerIdx = nextChar();
3177 int nameIdx = nextChar();
3178 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3179 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3180 if (name == null) name = names.empty;
3181 long flags = adjustClassFlags(c, nextChar());
3182 if (outer != null) { // we have a member class
3183 if (name == names.empty)
3184 name = names.one;
3185 ClassSymbol member = enterClass(name, outer);
3186 if ((member.flags_field & FROM_SOURCE) == 0) {
3187 if ((flags & STATIC) == 0) {
3188 ((ClassType)member.type).setEnclosingType(outer.type);
3189 if (member.erasure_field != null)
3190 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3191 }
3192 if (c == outer && member.owner == c) {
3193 member.flags_field = flags;
3194 enterMember(c, member);
3195 }
3196 } else if ((flags & STATIC) != (member.flags_field & STATIC)) {
3197 log.warning(LintWarnings.InconsistentInnerClasses(member, currentClassFile));
3198 }
3199 }
3200 }
3201 }
3307 } finally {
3308 interimUses = List.nil();
3309 interimProvides = List.nil();
3310 missingTypeVariables = List.nil();
3311 foundTypeVariables = List.nil();
3312 filling = false;
3313 }
3314 }
3315
3316 /** We can only read a single class file at a time; this
3317 * flag keeps track of when we are currently reading a class
3318 * file.
3319 */
3320 public boolean filling = false;
3321
3322 /* **********************************************************************
3323 * Adjusting flags
3324 ***********************************************************************/
3325
3326 long adjustFieldFlags(long flags) {
3327 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3328 if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3329 flags &= ~ACC_STRICT;
3330 flags |= STRICT;
3331 }
3332 return flags;
3333 }
3334
3335 long adjustMethodFlags(long flags) {
3336 if ((flags & ACC_BRIDGE) != 0) {
3337 flags &= ~ACC_BRIDGE;
3338 flags |= BRIDGE;
3339 }
3340 if ((flags & ACC_VARARGS) != 0) {
3341 flags &= ~ACC_VARARGS;
3342 flags |= VARARGS;
3343 }
3344 return flags;
3345 }
3346
3347 long adjustClassFlags(ClassSymbol c, long flags) {
3348 if ((flags & ACC_MODULE) != 0) {
3349 flags &= ~ACC_MODULE;
3350 flags |= MODULE;
3351 }
3352 if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags))
3353 || (majorVersion <= Version.MAX().major && minorVersion != PREVIEW_MINOR_VERSION && (flags & INTERFACE) == 0)) {
3354 flags |= IDENTITY_TYPE;
3355 } else if (needsValueFlag(c, flags)) {
3356 flags |= VALUE_CLASS;
3357 flags &= ~IDENTITY_TYPE;
3358 }
3359 flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3360 return flags;
3361 }
3362
3363 private boolean needsValueFlag(Symbol c, long flags) {
3364 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3365 if (allowValueClasses) {
3366 if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3367 majorVersion >= V67.major && isMigratedValueClass(flags)) {
3368 return true;
3369 }
3370 }
3371 return false;
3372 }
3373
3374 private boolean isMigratedValueClass(long flags) {
3375 return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3376 }
3377
3378 /**
3379 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3380 * The attribute is only the last component of the original filename, so is unlikely
3381 * to be valid as is, so operations other than those to access the name throw
3382 * UnsupportedOperationException
3383 */
3384 private static class SourceFileObject implements JavaFileObject {
3385
3386 /** The file's name.
3387 */
3388 private final Name name;
3389
3390 public SourceFileObject(Name name) {
3391 this.name = name;
3392 }
3393
3394 @Override @DefinedBy(Api.COMPILER)
3395 public URI toUri() {
|