< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java

Print this page

  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 
  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     /** Switch: warn (instead of error) on illegal UTF-8
 122      */
 123     boolean warnOnIllegalUtf8;
 124 
 125     /** Switch: preserve parameter names from the variable table.
 126      */
 127     public boolean saveParameterNames;
 128 
 129     /**
 130      * The currently selected profile.
 131      */
 132     public final Profile profile;

 272     protected ClassReader(Context context) {
 273         context.put(classReaderKey, this);
 274         annotate = Annotate.instance(context);
 275         names = Names.instance(context);
 276         syms = Symtab.instance(context);
 277         types = Types.instance(context);
 278         fileManager = context.get(JavaFileManager.class);
 279         if (fileManager == null)
 280             throw new AssertionError("FileManager initialization error");
 281         diagFactory = JCDiagnostic.Factory.instance(context);
 282         dcfh = DeferredCompletionFailureHandler.instance(context);
 283 
 284         log = Log.instance(context);
 285 
 286         Options options = Options.instance(context);
 287         verbose         = options.isSet(Option.VERBOSE);
 288 
 289         Source source = Source.instance(context);
 290         preview = Preview.instance(context);
 291         allowModules     = Feature.MODULES.allowedInSource(source);


 292         allowRecords = Feature.RECORDS.allowedInSource(source);
 293         allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 294         warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
 295 
 296         saveParameterNames = options.isSet(PARAMETERS);
 297 
 298         profile = Profile.instance(context);
 299 
 300         typevars = WriteableScope.create(syms.noSymbol);
 301 
 302         initAttributeReaders();
 303     }
 304 
 305     /** Add member to class unless it is synthetic.
 306      */
 307     private void enterMember(ClassSymbol c, Symbol sym) {
 308         // Synthetic members are not entered -- reason lost to history (optimization?).
 309         // Lambda methods must be entered because they may have inner classes (which reference them)
 310         if ((sym.flags_field & (SYNTHETIC|BRIDGE)) != SYNTHETIC || sym.name.startsWith(names.lambda))
 311             c.members_field.enter(sym);

 564     int sbp = 0;
 565     /** Convert class signature to type, where signature is implicit.
 566      */
 567     Type classSigToType() {
 568         if (signature[sigp] != 'L')
 569             throw badClassFile("bad.class.signature", quoteBadSignature());
 570         sigp++;
 571         Type outer = Type.noType;
 572         int startSbp = sbp;
 573 
 574         while (true) {
 575             final byte c = signature[sigp++];
 576             switch (c) {
 577 
 578             case ';': {         // end
 579                 ClassSymbol t = enterClass(readName(signatureBuffer,
 580                                                          startSbp,
 581                                                          sbp - startSbp));
 582 
 583                 try {
 584                     return (outer == Type.noType) ?
 585                             t.erasure(types) :
 586                         new ClassType(outer, List.nil(), t);


 587                 } finally {
 588                     sbp = startSbp;
 589                 }
 590             }
 591 
 592             case '<':           // generic arguments
 593                 ClassSymbol t = enterClass(readName(signatureBuffer,
 594                                                          startSbp,
 595                                                          sbp - startSbp));
 596                 List<Type> actuals = sigToTypes('>');
 597                 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
 598                 if (formals != null) {
 599                     if (actuals.isEmpty())
 600                         actuals = formals;
 601                 }
 602                 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
 603                  * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
 604                  * assigned to but then we would have a dependendy on the internal representation of ClassType which
 605                  * could change in the future
 606                  */
 607                 final List<Type> actualsCp = actuals;
 608                 outer = new ClassType(outer, actuals, t) {
 609                         boolean completed = false;
 610                         boolean typeArgsSet = false;
 611                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 612                         public Type getEnclosingType() {
 613                             if (!completed) {
 614                                 completed = true;
 615                                 tsym.apiComplete();
 616                                 Type enclosingType = tsym.type.getEnclosingType();
 617                                 if (enclosingType != Type.noType) {
 618                                     List<Type> typeArgs =
 619                                         super.getEnclosingType().allparams();
 620                                     List<Type> typeParams =
 621                                         enclosingType.allparams();
 622                                     if (typeParams.length() != typeArgs.length()) {
 623                                         // no "rare" types
 624                                         super.setEnclosingType(types.erasure(enclosingType));
 625                                     } else {
 626                                         super.setEnclosingType(types.subst(enclosingType,
 627                                                                            typeParams,
 628                                                                            typeArgs));

 672                         signatureBuffer[sbp++] = (byte)'$';
 673                         break;
 674                     } else {
 675                         sbp = startSbp;
 676                         return outer;
 677                     }
 678                 case '.':
 679                     signatureBuffer[sbp++] = (byte)'$';
 680                     break;
 681                 default:
 682                     throw new AssertionError(signature[sigp-1]);
 683                 }
 684                 continue;
 685 
 686             case '.':
 687                 //we have seen an enclosing non-generic class
 688                 if (outer != Type.noType) {
 689                     t = enterClass(readName(signatureBuffer,
 690                                                  startSbp,
 691                                                  sbp - startSbp));
 692                     outer = new ClassType(outer, List.nil(), t);
 693                 }
 694                 signatureBuffer[sbp++] = (byte)'$';
 695                 continue;
 696             case '/':
 697                 signatureBuffer[sbp++] = (byte)'.';
 698                 continue;
 699             default:
 700                 signatureBuffer[sbp++] = c;
 701                 continue;
 702             }
 703         }
 704     }
 705 
 706     /** Quote a bogus signature for display inside an error message.
 707      */
 708     String quoteBadSignature() {
 709         String sigString;
 710         try {
 711             sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
 712         } catch (InvalidUtfException e) {

1529         ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1530         for (CompoundAnnotationProxy proxy : annotations) {
1531             if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1532                 sym.flags_field |= PROPRIETARY;
1533             else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1534                 if (profile != Profile.DEFAULT) {
1535                     for (Pair<Name, Attribute> v : proxy.values) {
1536                         if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1537                             if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1538                                 sym.flags_field |= NOT_IN_PROFILE;
1539                             }
1540                         }
1541                     }
1542                 }
1543             } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1544                 sym.flags_field |= PREVIEW_API;
1545                 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1546             } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1547                 Assert.check(sym.kind == TYP);
1548                 sym.flags_field |= VALUE_BASED;







1549             } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1550                 Assert.check(sym.kind == MTH);
1551                 sym.flags_field |= RESTRICTED;
1552             } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1553                 Assert.check(sym.kind == VAR);
1554                 sym.flags_field |= REQUIRES_IDENTITY;
1555             } else {
1556                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1557                     target = proxy;
1558                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1559                     repeatable = proxy;
1560                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1561                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1562                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1563                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1564                     sym.flags_field |= PREVIEW_API;
1565                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1566                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1567                     sym.flags_field |= VALUE_BASED;






1568                 }  else if (proxy.type.tsym == syms.restrictedType.tsym) {
1569                     Assert.check(sym.kind == MTH);
1570                     sym.flags_field |= RESTRICTED;
1571                 }  else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1572                     Assert.check(sym.kind == VAR);
1573                     sym.flags_field |= REQUIRES_IDENTITY;
1574                 }
1575                 proxies.append(proxy);
1576             }
1577         }
1578         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1579     }
1580     //where:
1581         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1582             for (Pair<Name, Attribute> v : proxy.values) {
1583                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1584                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1585                         sym.flags_field |= flag;
1586                     }
1587                 }

3038     protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3039         return syms.enterClass(currentModule, name, owner);
3040     }
3041 
3042     /** Read contents of a given class symbol `c'. Both external and internal
3043      *  versions of an inner class are read.
3044      */
3045     void readClass(ClassSymbol c) {
3046         ClassType ct = (ClassType)c.type;
3047 
3048         // allocate scope for members
3049         c.members_field = WriteableScope.create(c);
3050 
3051         // prepare type variable table
3052         typevars = typevars.dup(currentOwner);
3053         if (ct.getEnclosingType().hasTag(CLASS))
3054             enterTypevars(c.owner, ct.getEnclosingType());
3055 
3056         // read flags, or skip if this is an inner class
3057         long f = nextChar();
3058         long flags = adjustClassFlags(f);
3059         if ((flags & MODULE) == 0) {
3060             if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3061             // read own class name and check that it matches
3062             currentModule = c.packge().modle;
3063             ClassSymbol self = poolReader.getClass(nextChar());
3064             if (c != self) {
3065                 throw badClassFile("class.file.wrong.class",
3066                                    self.flatname);
3067             }
3068         } else {
3069             if (majorVersion < Version.V53.major) {
3070                 throw badClassFile("anachronistic.module.info",
3071                         Integer.toString(majorVersion),
3072                         Integer.toString(minorVersion));
3073             }
3074             c.flags_field = flags;
3075             if (c.owner.kind != MDL) {
3076                 throw badClassFile("module.info.definition.expected");
3077             }
3078             currentModule = (ModuleSymbol) c.owner;

3130         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3131             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3132                 return (MethodSymbol) s;
3133             }
3134         }
3135         return null;
3136     }
3137 
3138     /** Read inner class info. For each inner/outer pair allocate a
3139      *  member class.
3140      */
3141     void readInnerClasses(ClassSymbol c) {
3142         int n = nextChar();
3143         for (int i = 0; i < n; i++) {
3144             nextChar(); // skip inner class symbol
3145             int outerIdx = nextChar();
3146             int nameIdx = nextChar();
3147             ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3148             Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3149             if (name == null) name = names.empty;
3150             long flags = adjustClassFlags(nextChar());
3151             if (outer != null) { // we have a member class
3152                 if (name == names.empty)
3153                     name = names.one;
3154                 ClassSymbol member = enterClass(name, outer);
3155                 if ((flags & STATIC) == 0) {
3156                     ((ClassType)member.type).setEnclosingType(outer.type);
3157                     if (member.erasure_field != null)
3158                         ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3159                 }
3160                 if (c == outer && member.owner == c) {
3161                     member.flags_field = flags;
3162                     enterMember(c, member);
3163                 }
3164             }
3165         }
3166     }
3167 
3168     /** Read a class definition from the bytes in buf.
3169      */
3170     private void readClassBuffer(ClassSymbol c) throws IOException {

3272         } finally {
3273             interimUses = List.nil();
3274             interimProvides = List.nil();
3275             missingTypeVariables = List.nil();
3276             foundTypeVariables = List.nil();
3277             filling = false;
3278         }
3279     }
3280 
3281     /** We can only read a single class file at a time; this
3282      *  flag keeps track of when we are currently reading a class
3283      *  file.
3284      */
3285     public boolean filling = false;
3286 
3287 /* **********************************************************************
3288  * Adjusting flags
3289  ***********************************************************************/
3290 
3291     long adjustFieldFlags(long flags) {





3292         return flags;
3293     }
3294 
3295     long adjustMethodFlags(long flags) {
3296         if ((flags & ACC_BRIDGE) != 0) {
3297             flags &= ~ACC_BRIDGE;
3298             flags |= BRIDGE;
3299         }
3300         if ((flags & ACC_VARARGS) != 0) {
3301             flags &= ~ACC_VARARGS;
3302             flags |= VARARGS;
3303         }
3304         return flags;
3305     }
3306 
3307     long adjustClassFlags(long flags) {
3308         if ((flags & ACC_MODULE) != 0) {
3309             flags &= ~ACC_MODULE;
3310             flags |= MODULE;
3311         }
3312         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded























3313     }
3314 
3315     /**
3316      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3317      * The attribute is only the last component of the original filename, so is unlikely
3318      * to be valid as is, so operations other than those to access the name throw
3319      * UnsupportedOperationException
3320      */
3321     private static class SourceFileObject implements JavaFileObject {
3322 
3323         /** The file's name.
3324          */
3325         private final Name name;
3326 
3327         public SourceFileObject(Name name) {
3328             this.name = name;
3329         }
3330 
3331         @Override @DefinedBy(Api.COMPILER)
3332         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 
  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     /** Switch: warn (instead of error) on illegal UTF-8
 129      */
 130     boolean warnOnIllegalUtf8;
 131 
 132     /** Switch: preserve parameter names from the variable table.
 133      */
 134     public boolean saveParameterNames;
 135 
 136     /**
 137      * The currently selected profile.
 138      */
 139     public final Profile profile;

 279     protected ClassReader(Context context) {
 280         context.put(classReaderKey, this);
 281         annotate = Annotate.instance(context);
 282         names = Names.instance(context);
 283         syms = Symtab.instance(context);
 284         types = Types.instance(context);
 285         fileManager = context.get(JavaFileManager.class);
 286         if (fileManager == null)
 287             throw new AssertionError("FileManager initialization error");
 288         diagFactory = JCDiagnostic.Factory.instance(context);
 289         dcfh = DeferredCompletionFailureHandler.instance(context);
 290 
 291         log = Log.instance(context);
 292 
 293         Options options = Options.instance(context);
 294         verbose         = options.isSet(Option.VERBOSE);
 295 
 296         Source source = Source.instance(context);
 297         preview = Preview.instance(context);
 298         allowModules     = Feature.MODULES.allowedInSource(source);
 299         allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
 300                 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) {

1540         ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1541         for (CompoundAnnotationProxy proxy : annotations) {
1542             if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1543                 sym.flags_field |= PROPRIETARY;
1544             else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1545                 if (profile != Profile.DEFAULT) {
1546                     for (Pair<Name, Attribute> v : proxy.values) {
1547                         if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1548                             if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1549                                 sym.flags_field |= NOT_IN_PROFILE;
1550                             }
1551                         }
1552                     }
1553                 }
1554             } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1555                 sym.flags_field |= PREVIEW_API;
1556                 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1557             } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1558                 Assert.check(sym.kind == TYP);
1559                 sym.flags_field |= VALUE_BASED;
1560             } else if (proxy.type.tsym.flatName() == syms.migratedValueClassInternalType.tsym.flatName()) {
1561                 Assert.check(sym.kind == TYP);
1562                 sym.flags_field |= MIGRATED_VALUE_CLASS;
1563                 if (needsValueFlag(sym, sym.flags_field)) {
1564                     sym.flags_field |= VALUE_CLASS;
1565                     sym.flags_field &= ~IDENTITY_TYPE;
1566                 }
1567             } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1568                 Assert.check(sym.kind == MTH);
1569                 sym.flags_field |= RESTRICTED;
1570             } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1571                 Assert.check(sym.kind == VAR);
1572                 sym.flags_field |= REQUIRES_IDENTITY;
1573             } else {
1574                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1575                     target = proxy;
1576                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1577                     repeatable = proxy;
1578                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1579                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1580                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1581                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1582                     sym.flags_field |= PREVIEW_API;
1583                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1584                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1585                     sym.flags_field |= VALUE_BASED;
1586                 }  else if (proxy.type.tsym == syms.migratedValueClassType.tsym && sym.kind == TYP) {
1587                     sym.flags_field |= MIGRATED_VALUE_CLASS;
1588                     if (needsValueFlag(sym, sym.flags_field)) {
1589                         sym.flags_field |= VALUE_CLASS;
1590                         sym.flags_field &= ~IDENTITY_TYPE;
1591                     }
1592                 }  else if (proxy.type.tsym == syms.restrictedType.tsym) {
1593                     Assert.check(sym.kind == MTH);
1594                     sym.flags_field |= RESTRICTED;
1595                 }  else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1596                     Assert.check(sym.kind == VAR);
1597                     sym.flags_field |= REQUIRES_IDENTITY;
1598                 }
1599                 proxies.append(proxy);
1600             }
1601         }
1602         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1603     }
1604     //where:
1605         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1606             for (Pair<Name, Attribute> v : proxy.values) {
1607                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1608                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1609                         sym.flags_field |= flag;
1610                     }
1611                 }

3062     protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
3063         return syms.enterClass(currentModule, name, owner);
3064     }
3065 
3066     /** Read contents of a given class symbol `c'. Both external and internal
3067      *  versions of an inner class are read.
3068      */
3069     void readClass(ClassSymbol c) {
3070         ClassType ct = (ClassType)c.type;
3071 
3072         // allocate scope for members
3073         c.members_field = WriteableScope.create(c);
3074 
3075         // prepare type variable table
3076         typevars = typevars.dup(currentOwner);
3077         if (ct.getEnclosingType().hasTag(CLASS))
3078             enterTypevars(c.owner, ct.getEnclosingType());
3079 
3080         // read flags, or skip if this is an inner class
3081         long f = nextChar();
3082         long flags = adjustClassFlags(c, f);
3083         if ((flags & MODULE) == 0) {
3084             if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
3085             // read own class name and check that it matches
3086             currentModule = c.packge().modle;
3087             ClassSymbol self = poolReader.getClass(nextChar());
3088             if (c != self) {
3089                 throw badClassFile("class.file.wrong.class",
3090                                    self.flatname);
3091             }
3092         } else {
3093             if (majorVersion < Version.V53.major) {
3094                 throw badClassFile("anachronistic.module.info",
3095                         Integer.toString(majorVersion),
3096                         Integer.toString(minorVersion));
3097             }
3098             c.flags_field = flags;
3099             if (c.owner.kind != MDL) {
3100                 throw badClassFile("module.info.definition.expected");
3101             }
3102             currentModule = (ModuleSymbol) c.owner;

3154         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3155             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3156                 return (MethodSymbol) s;
3157             }
3158         }
3159         return null;
3160     }
3161 
3162     /** Read inner class info. For each inner/outer pair allocate a
3163      *  member class.
3164      */
3165     void readInnerClasses(ClassSymbol c) {
3166         int n = nextChar();
3167         for (int i = 0; i < n; i++) {
3168             nextChar(); // skip inner class symbol
3169             int outerIdx = nextChar();
3170             int nameIdx = nextChar();
3171             ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3172             Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3173             if (name == null) name = names.empty;
3174             long flags = adjustClassFlags(c, nextChar());
3175             if (outer != null) { // we have a member class
3176                 if (name == names.empty)
3177                     name = names.one;
3178                 ClassSymbol member = enterClass(name, outer);
3179                 if ((flags & STATIC) == 0) {
3180                     ((ClassType)member.type).setEnclosingType(outer.type);
3181                     if (member.erasure_field != null)
3182                         ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3183                 }
3184                 if (c == outer && member.owner == c) {
3185                     member.flags_field = flags;
3186                     enterMember(c, member);
3187                 }
3188             }
3189         }
3190     }
3191 
3192     /** Read a class definition from the bytes in buf.
3193      */
3194     private void readClassBuffer(ClassSymbol c) throws IOException {

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         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3317         if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3318             flags &= ~ACC_STRICT;
3319             flags |= STRICT;
3320         }
3321         return flags;
3322     }
3323 
3324     long adjustMethodFlags(long flags) {
3325         if ((flags & ACC_BRIDGE) != 0) {
3326             flags &= ~ACC_BRIDGE;
3327             flags |= BRIDGE;
3328         }
3329         if ((flags & ACC_VARARGS) != 0) {
3330             flags &= ~ACC_VARARGS;
3331             flags |= VARARGS;
3332         }
3333         return flags;
3334     }
3335 
3336     long adjustClassFlags(ClassSymbol c, long flags) {
3337         if ((flags & ACC_MODULE) != 0) {
3338             flags &= ~ACC_MODULE;
3339             flags |= MODULE;
3340         }
3341         if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags))
3342                 || (majorVersion <= Version.MAX().major && minorVersion != PREVIEW_MINOR_VERSION && (flags & INTERFACE) == 0)) {
3343             flags |= IDENTITY_TYPE;
3344         } else if (needsValueFlag(c, flags)) {
3345             flags |= VALUE_CLASS;
3346             flags &= ~IDENTITY_TYPE;
3347         }
3348         flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3349         return flags;
3350     }
3351 
3352     private boolean needsValueFlag(Symbol c, long flags) {
3353         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3354         if (allowValueClasses) {
3355             if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3356                     majorVersion >= V67.major && isMigratedValueClass(flags)) {
3357                 return true;
3358             }
3359         }
3360         return false;
3361     }
3362 
3363     private boolean isMigratedValueClass(long flags) {
3364         return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3365     }
3366 
3367     /**
3368      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3369      * The attribute is only the last component of the original filename, so is unlikely
3370      * to be valid as is, so operations other than those to access the name throw
3371      * UnsupportedOperationException
3372      */
3373     private static class SourceFileObject implements JavaFileObject {
3374 
3375         /** The file's name.
3376          */
3377         private final Name name;
3378 
3379         public SourceFileObject(Name name) {
3380             this.name = name;
3381         }
3382 
3383         @Override @DefinedBy(Api.COMPILER)
3384         public URI toUri() {
< prev index next >