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);
1542 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1543 sym.flags_field |= PREVIEW_API;
1544 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1545 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1546 Assert.check(sym.kind == TYP);
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);
1550 } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1551 sym.flags_field |= PREVIEW_API;
1552 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1553 } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1554 Assert.check(sym.kind == TYP);
1555 sym.flags_field |= VALUE_BASED;
1556 } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1557 Assert.check(sym.kind == MTH);
1558 sym.flags_field |= RESTRICTED;
1559 } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1560 Assert.check(sym.kind == VAR);
1561 sym.flags_field |= REQUIRES_IDENTITY;
1562 } else {
1563 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1564 target = proxy;
1565 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1566 repeatable = proxy;
1567 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1568 sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1569 setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1570 } else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1571 sym.flags_field |= PREVIEW_API;
1572 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1573 } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1574 sym.flags_field |= VALUE_BASED;
1575 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1576 Assert.check(sym.kind == MTH);
1577 sym.flags_field |= RESTRICTED;
1578 } else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1579 Assert.check(sym.kind == VAR);
1580 sym.flags_field |= REQUIRES_IDENTITY;
1581 }
1582 proxies.append(proxy);
1583 }
1584 }
1585 annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1586 }
1587 //where:
1588 private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1589 for (Pair<Name, Attribute> v : proxy.values) {
1590 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1591 if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1592 sym.flags_field |= flag;
1593 }
1594 }
1595 }
3066 protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3067 return syms.enterClass(currentModule, name, owner);
3068 }
3069
3070 /** Read contents of a given class symbol `c'. Both external and internal
3071 * versions of an inner class are read.
3072 */
3073 void readClass(ClassSymbol c) {
3074 ClassType ct = (ClassType)c.type;
3075
3076 // allocate scope for members
3077 c.members_field = WriteableScope.create(c);
3078
3079 // prepare type variable table
3080 typevars = typevars.dup(currentOwner);
3081 if (ct.getEnclosingType().hasTag(CLASS))
3082 enterTypevars(c.owner, ct.getEnclosingType());
3083
3084 // read flags, or skip if this is an inner class
3085 long f = nextChar();
3086 long flags = adjustClassFlags(c, f);
3087 if ((flags & MODULE) == 0) {
3088 if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3089 // read own class name and check that it matches
3090 currentModule = c.packge().modle;
3091 ClassSymbol self = poolReader.getClass(nextChar());
3092 if (c != self) {
3093 throw badClassFile("class.file.wrong.class",
3094 self.flatname);
3095 }
3096 } else {
3097 if (majorVersion < Version.V53.major) {
3098 throw badClassFile("anachronistic.module.info",
3099 Integer.toString(majorVersion),
3100 Integer.toString(minorVersion));
3101 }
3102 c.flags_field = flags;
3103 if (c.owner.kind != MDL) {
3104 throw badClassFile("module.info.definition.expected");
3105 }
3106 currentModule = (ModuleSymbol) c.owner;
3158 for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3159 if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3160 return (MethodSymbol) s;
3161 }
3162 }
3163 return null;
3164 }
3165
3166 /** Read inner class info. For each inner/outer pair allocate a
3167 * member class.
3168 */
3169 void readInnerClasses(ClassSymbol c) {
3170 int n = nextChar();
3171 for (int i = 0; i < n; i++) {
3172 nextChar(); // skip inner class symbol
3173 int outerIdx = nextChar();
3174 int nameIdx = nextChar();
3175 ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3176 Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3177 if (name == null) name = names.empty;
3178 long flags = adjustClassFlags(c, nextChar());
3179 if (outer != null) { // we have a member class
3180 if (name == names.empty)
3181 name = names.one;
3182 ClassSymbol member = enterClass(name, outer);
3183 if ((member.flags_field & FROM_SOURCE) == 0) {
3184 if ((flags & STATIC) == 0) {
3185 ((ClassType)member.type).setEnclosingType(outer.type);
3186 if (member.erasure_field != null)
3187 ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3188 }
3189 if (c == outer && member.owner == c) {
3190 member.flags_field = flags;
3191 enterMember(c, member);
3192 }
3193 } else if ((flags & STATIC) != (member.flags_field & STATIC)) {
3194 log.warning(LintWarnings.InconsistentInnerClasses(member, currentClassFile));
3195 }
3196 }
3197 }
3198 }
3304 } finally {
3305 interimUses = List.nil();
3306 interimProvides = List.nil();
3307 missingTypeVariables = List.nil();
3308 foundTypeVariables = List.nil();
3309 filling = false;
3310 }
3311 }
3312
3313 /** We can only read a single class file at a time; this
3314 * flag keeps track of when we are currently reading a class
3315 * file.
3316 */
3317 public boolean filling = false;
3318
3319 /* **********************************************************************
3320 * Adjusting flags
3321 ***********************************************************************/
3322
3323 long adjustFieldFlags(long flags) {
3324 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3325 if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3326 flags &= ~ACC_STRICT;
3327 flags |= STRICT;
3328 }
3329 return flags;
3330 }
3331
3332 long adjustMethodFlags(long flags) {
3333 if ((flags & ACC_BRIDGE) != 0) {
3334 flags &= ~ACC_BRIDGE;
3335 flags |= BRIDGE;
3336 }
3337 if ((flags & ACC_VARARGS) != 0) {
3338 flags &= ~ACC_VARARGS;
3339 flags |= VARARGS;
3340 }
3341 return flags;
3342 }
3343
3344 long adjustClassFlags(ClassSymbol c, long flags) {
3345 if ((flags & ACC_MODULE) != 0) {
3346 flags &= ~ACC_MODULE;
3347 flags |= MODULE;
3348 }
3349 if (((flags & ACC_IDENTITY) != 0)
3350 || (majorVersion <= Version.MAX().major && minorVersion != PREVIEW_MINOR_VERSION && (flags & INTERFACE) == 0)) {
3351 flags |= IDENTITY_TYPE;
3352 } else if (needsValueFlag(c, flags)) {
3353 flags |= VALUE_CLASS;
3354 flags &= ~IDENTITY_TYPE;
3355 }
3356 flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3357 return flags;
3358 }
3359
3360 private boolean needsValueFlag(Symbol c, long flags) {
3361 boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3362 if (allowValueClasses) {
3363 if (previewClassFile && majorVersion >= Version.MAX().major && (flags & INTERFACE) == 0) {
3364 return true;
3365 }
3366 }
3367 return false;
3368 }
3369
3370 /**
3371 * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3372 * The attribute is only the last component of the original filename, so is unlikely
3373 * to be valid as is, so operations other than those to access the name throw
3374 * UnsupportedOperationException
3375 */
3376 private static class SourceFileObject implements JavaFileObject {
3377
3378 /** The file's name.
3379 */
3380 private final Name name;
3381
3382 public SourceFileObject(Name name) {
3383 this.name = name;
3384 }
3385
3386 @Override @DefinedBy(Api.COMPILER)
3387 public URI toUri() {
|