< prev index next >

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

Print this page

  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.Lint.LintCategory;
  55 import com.sun.tools.javac.code.Scope.WriteableScope;
  56 import com.sun.tools.javac.code.Symbol.*;
  57 import com.sun.tools.javac.code.Symtab;
  58 import com.sun.tools.javac.code.Type.*;
  59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  60 import com.sun.tools.javac.file.BaseFileManager;
  61 import com.sun.tools.javac.file.PathFileObject;
  62 import com.sun.tools.javac.jvm.ClassFile.Version;
  63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
  64 import com.sun.tools.javac.main.Option;

  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.util.*;
  70 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
  71 import com.sun.tools.javac.util.DefinedBy.Api;
  72 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  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;

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


 296         allowRecords = Feature.RECORDS.allowedInSource(source);
 297         allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 298         warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
 299 
 300         saveParameterNames = options.isSet(PARAMETERS);
 301 
 302         profile = Profile.instance(context);
 303 
 304         typevars = WriteableScope.create(syms.noSymbol);
 305 
 306         lint = Lint.instance(context);
 307 
 308         initAttributeReaders();
 309     }
 310 
 311     /** Add member to class unless it is synthetic.
 312      */
 313     private void enterMember(ClassSymbol c, Symbol sym) {
 314         // Synthetic members are not entered -- reason lost to history (optimization?).
 315         // Lambda methods must be entered because they may have inner classes (which reference them)

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


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

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

1541         ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1542         for (CompoundAnnotationProxy proxy : annotations) {
1543             if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1544                 sym.flags_field |= PROPRIETARY;
1545             else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1546                 if (profile != Profile.DEFAULT) {
1547                     for (Pair<Name, Attribute> v : proxy.values) {
1548                         if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1549                             if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1550                                 sym.flags_field |= NOT_IN_PROFILE;
1551                             }
1552                         }
1553                     }
1554                 }
1555             } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1556                 sym.flags_field |= PREVIEW_API;
1557                 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1558             } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1559                 Assert.check(sym.kind == TYP);
1560                 sym.flags_field |= VALUE_BASED;







1561             } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1562                 Assert.check(sym.kind == MTH);
1563                 sym.flags_field |= RESTRICTED;
1564             } else {
1565                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1566                     target = proxy;
1567                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1568                     repeatable = proxy;
1569                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1570                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1571                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1572                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1573                     sym.flags_field |= PREVIEW_API;
1574                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1575                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1576                     sym.flags_field |= VALUE_BASED;






1577                 }  else if (proxy.type.tsym == syms.restrictedType.tsym) {
1578                     Assert.check(sym.kind == MTH);
1579                     sym.flags_field |= RESTRICTED;
1580                 }
1581                 proxies.append(proxy);
1582             }
1583         }
1584         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1585     }
1586     //where:
1587         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1588             for (Pair<Name, Attribute> v : proxy.values) {
1589                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1590                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1591                         sym.flags_field |= flag;
1592                     }
1593                 }
1594             }
1595         }
1596 

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

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

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





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






















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

  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.Lint.LintCategory;
  55 import com.sun.tools.javac.code.Scope.WriteableScope;
  56 import com.sun.tools.javac.code.Symbol.*;
  57 import com.sun.tools.javac.code.Symtab;
  58 import com.sun.tools.javac.code.Type.*;
  59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  60 import com.sun.tools.javac.file.BaseFileManager;
  61 import com.sun.tools.javac.file.PathFileObject;
  62 import com.sun.tools.javac.jvm.ClassFile.Version;
  63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
  64 import com.sun.tools.javac.main.Option;
  65 import com.sun.tools.javac.resources.CompilerProperties;
  66 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  67 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  68 import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
  69 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  70 import com.sun.tools.javac.tree.JCTree;
  71 import com.sun.tools.javac.util.*;
  72 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
  73 import com.sun.tools.javac.util.DefinedBy.Api;
  74 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  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;

 283     protected ClassReader(Context context) {
 284         context.put(classReaderKey, this);
 285         annotate = Annotate.instance(context);
 286         names = Names.instance(context);
 287         syms = Symtab.instance(context);
 288         types = Types.instance(context);
 289         fileManager = context.get(JavaFileManager.class);
 290         if (fileManager == null)
 291             throw new AssertionError("FileManager initialization error");
 292         diagFactory = JCDiagnostic.Factory.instance(context);
 293         dcfh = DeferredCompletionFailureHandler.instance(context);
 294 
 295         log = Log.instance(context);
 296 
 297         Options options = Options.instance(context);
 298         verbose         = options.isSet(Option.VERBOSE);
 299 
 300         Source source = Source.instance(context);
 301         preview = Preview.instance(context);
 302         allowModules     = Feature.MODULES.allowedInSource(source);
 303         allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
 304                 Feature.VALUE_CLASSES.allowedInSource(source);
 305         allowRecords = Feature.RECORDS.allowedInSource(source);
 306         allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 307         warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
 308 
 309         saveParameterNames = options.isSet(PARAMETERS);
 310 
 311         profile = Profile.instance(context);
 312 
 313         typevars = WriteableScope.create(syms.noSymbol);
 314 
 315         lint = Lint.instance(context);
 316 
 317         initAttributeReaders();
 318     }
 319 
 320     /** Add member to class unless it is synthetic.
 321      */
 322     private void enterMember(ClassSymbol c, Symbol sym) {
 323         // Synthetic members are not entered -- reason lost to history (optimization?).
 324         // Lambda methods must be entered because they may have inner classes (which reference them)

 579     int sbp = 0;
 580     /** Convert class signature to type, where signature is implicit.
 581      */
 582     Type classSigToType() {
 583         if (signature[sigp] != 'L')
 584             throw badClassFile("bad.class.signature", quoteBadSignature());
 585         sigp++;
 586         Type outer = Type.noType;
 587         int startSbp = sbp;
 588 
 589         while (true) {
 590             final byte c = signature[sigp++];
 591             switch (c) {
 592 
 593             case ';': {         // end
 594                 ClassSymbol t = enterClass(readName(signatureBuffer,
 595                                                          startSbp,
 596                                                          sbp - startSbp));
 597 
 598                 try {
 599                     if (outer == Type.noType) {
 600                         ClassType et = (ClassType) t.erasure(types);
 601                         return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
 602                     }
 603                     return new ClassType(outer, List.nil(), t, List.nil());
 604                 } finally {
 605                     sbp = startSbp;
 606                 }
 607             }
 608 
 609             case '<':           // generic arguments
 610                 ClassSymbol t = enterClass(readName(signatureBuffer,
 611                                                          startSbp,
 612                                                          sbp - startSbp));
 613                 List<Type> actuals = sigToTypes('>');
 614                 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
 615                 if (formals != null) {
 616                     if (actuals.isEmpty())
 617                         actuals = formals;
 618                 }
 619                 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
 620                  * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
 621                  * assigned to but then we would have a dependendy on the internal representation of ClassType which
 622                  * could change in the future
 623                  */
 624                 final List<Type> actualsCp = actuals;
 625                 outer = new ClassType(outer, actuals, t, List.nil()) {
 626                         boolean completed = false;
 627                         boolean typeArgsSet = false;
 628                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 629                         public Type getEnclosingType() {
 630                             if (!completed) {
 631                                 completed = true;
 632                                 tsym.apiComplete();
 633                                 Type enclosingType = tsym.type.getEnclosingType();
 634                                 if (enclosingType != Type.noType) {
 635                                     List<Type> typeArgs =
 636                                         super.getEnclosingType().allparams();
 637                                     List<Type> typeParams =
 638                                         enclosingType.allparams();
 639                                     if (typeParams.length() != typeArgs.length()) {
 640                                         // no "rare" types
 641                                         super.setEnclosingType(types.erasure(enclosingType));
 642                                     } else {
 643                                         super.setEnclosingType(types.subst(enclosingType,
 644                                                                            typeParams,
 645                                                                            typeArgs));

 689                         signatureBuffer[sbp++] = (byte)'$';
 690                         break;
 691                     } else {
 692                         sbp = startSbp;
 693                         return outer;
 694                     }
 695                 case '.':
 696                     signatureBuffer[sbp++] = (byte)'$';
 697                     break;
 698                 default:
 699                     throw new AssertionError(signature[sigp-1]);
 700                 }
 701                 continue;
 702 
 703             case '.':
 704                 //we have seen an enclosing non-generic class
 705                 if (outer != Type.noType) {
 706                     t = enterClass(readName(signatureBuffer,
 707                                                  startSbp,
 708                                                  sbp - startSbp));
 709                     outer = new ClassType(outer, List.nil(), t, List.nil());
 710                 }
 711                 signatureBuffer[sbp++] = (byte)'$';
 712                 continue;
 713             case '/':
 714                 signatureBuffer[sbp++] = (byte)'.';
 715                 continue;
 716             default:
 717                 signatureBuffer[sbp++] = c;
 718                 continue;
 719             }
 720         }
 721     }
 722 
 723     /** Quote a bogus signature for display inside an error message.
 724      */
 725     String quoteBadSignature() {
 726         String sigString;
 727         try {
 728             sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
 729         } catch (InvalidUtfException e) {

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

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

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

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