< 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) {

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                 }
1588             }

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 ((member.flags_field & FROM_SOURCE) == 0) {
3156                     if ((flags & STATIC) == 0) {
3157                         ((ClassType)member.type).setEnclosingType(outer.type);
3158                         if (member.erasure_field != null)
3159                             ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3160                     }
3161                     if (c == outer && member.owner == c) {
3162                         member.flags_field = flags;
3163                         enterMember(c, member);
3164                     }
3165                 } else if ((flags & STATIC) != (member.flags_field & STATIC)) {
3166                     log.warning(LintWarnings.InconsistentInnerClasses(member, currentClassFile));
3167                 }
3168             }
3169         }
3170     }

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





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























3317     }
3318 
3319     /**
3320      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3321      * The attribute is only the last component of the original filename, so is unlikely
3322      * to be valid as is, so operations other than those to access the name throw
3323      * UnsupportedOperationException
3324      */
3325     private static class SourceFileObject implements JavaFileObject {
3326 
3327         /** The file's name.
3328          */
3329         private final Name name;
3330 
3331         public SourceFileObject(Name name) {
3332             this.name = name;
3333         }
3334 
3335         @Override @DefinedBy(Api.COMPILER)
3336         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) {

1559                 sym.flags_field |= VALUE_BASED;
1560             } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1561                 Assert.check(sym.kind == MTH);
1562                 sym.flags_field |= RESTRICTED;
1563             } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1564                 Assert.check(sym.kind == VAR);
1565                 sym.flags_field |= REQUIRES_IDENTITY;
1566             } else {
1567                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1568                     target = proxy;
1569                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1570                     repeatable = proxy;
1571                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1572                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1573                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1574                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1575                     sym.flags_field |= PREVIEW_API;
1576                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1577                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1578                     sym.flags_field |= VALUE_BASED;
1579                 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1580                     Assert.check(sym.kind == MTH);
1581                     sym.flags_field |= RESTRICTED;
1582                 }  else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1583                     Assert.check(sym.kind == VAR);
1584                     sym.flags_field |= REQUIRES_IDENTITY;
1585                 }
1586                 proxies.append(proxy);
1587             }
1588         }
1589         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1590     }
1591     //where:
1592         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1593             for (Pair<Name, Attribute> v : proxy.values) {
1594                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1595                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1596                         sym.flags_field |= flag;
1597                     }
1598                 }
1599             }

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

3141         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3142             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3143                 return (MethodSymbol) s;
3144             }
3145         }
3146         return null;
3147     }
3148 
3149     /** Read inner class info. For each inner/outer pair allocate a
3150      *  member class.
3151      */
3152     void readInnerClasses(ClassSymbol c) {
3153         int n = nextChar();
3154         for (int i = 0; i < n; i++) {
3155             nextChar(); // skip inner class symbol
3156             int outerIdx = nextChar();
3157             int nameIdx = nextChar();
3158             ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3159             Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3160             if (name == null) name = names.empty;
3161             long flags = adjustClassFlags(c, nextChar());
3162             if (outer != null) { // we have a member class
3163                 if (name == names.empty)
3164                     name = names.one;
3165                 ClassSymbol member = enterClass(name, outer);
3166                 if ((member.flags_field & FROM_SOURCE) == 0) {
3167                     if ((flags & STATIC) == 0) {
3168                         ((ClassType)member.type).setEnclosingType(outer.type);
3169                         if (member.erasure_field != null)
3170                             ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3171                     }
3172                     if (c == outer && member.owner == c) {
3173                         member.flags_field = flags;
3174                         enterMember(c, member);
3175                     }
3176                 } else if ((flags & STATIC) != (member.flags_field & STATIC)) {
3177                     log.warning(LintWarnings.InconsistentInnerClasses(member, currentClassFile));
3178                 }
3179             }
3180         }
3181     }

3287         } finally {
3288             interimUses = List.nil();
3289             interimProvides = List.nil();
3290             missingTypeVariables = List.nil();
3291             foundTypeVariables = List.nil();
3292             filling = false;
3293         }
3294     }
3295 
3296     /** We can only read a single class file at a time; this
3297      *  flag keeps track of when we are currently reading a class
3298      *  file.
3299      */
3300     public boolean filling = false;
3301 
3302 /* **********************************************************************
3303  * Adjusting flags
3304  ***********************************************************************/
3305 
3306     long adjustFieldFlags(long flags) {
3307         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3308         if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3309             flags &= ~ACC_STRICT;
3310             flags |= STRICT;
3311         }
3312         return flags;
3313     }
3314 
3315     long adjustMethodFlags(long flags) {
3316         if ((flags & ACC_BRIDGE) != 0) {
3317             flags &= ~ACC_BRIDGE;
3318             flags |= BRIDGE;
3319         }
3320         if ((flags & ACC_VARARGS) != 0) {
3321             flags &= ~ACC_VARARGS;
3322             flags |= VARARGS;
3323         }
3324         return flags;
3325     }
3326 
3327     long adjustClassFlags(ClassSymbol c, long flags) {
3328         if ((flags & ACC_MODULE) != 0) {
3329             flags &= ~ACC_MODULE;
3330             flags |= MODULE;
3331         }
3332         if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags))
3333                 || (majorVersion <= Version.MAX().major && minorVersion != PREVIEW_MINOR_VERSION && (flags & INTERFACE) == 0)) {
3334             flags |= IDENTITY_TYPE;
3335         } else if (needsValueFlag(c, flags)) {
3336             flags |= VALUE_CLASS;
3337             flags &= ~IDENTITY_TYPE;
3338         }
3339         flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3340         return flags;
3341     }
3342 
3343     private boolean needsValueFlag(Symbol c, long flags) {
3344         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3345         if (allowValueClasses) {
3346             if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3347                     majorVersion >= V67.major && isMigratedValueClass(flags)) {
3348                 return true;
3349             }
3350         }
3351         return false;
3352     }
3353 
3354     private boolean isMigratedValueClass(long flags) {
3355         return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3356     }
3357 
3358     /**
3359      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3360      * The attribute is only the last component of the original filename, so is unlikely
3361      * to be valid as is, so operations other than those to access the name throw
3362      * UnsupportedOperationException
3363      */
3364     private static class SourceFileObject implements JavaFileObject {
3365 
3366         /** The file's name.
3367          */
3368         private final Name name;
3369 
3370         public SourceFileObject(Name name) {
3371             this.name = name;
3372         }
3373 
3374         @Override @DefinedBy(Api.COMPILER)
3375         public URI toUri() {
< prev index next >