< 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.Fragments;
  66 import com.sun.tools.javac.resources.CompilerProperties.Warnings;

  67 import com.sun.tools.javac.util.*;
  68 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
  69 import com.sun.tools.javac.util.DefinedBy.Api;
  70 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  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    /** Lint option: warn about classfile issues
 122      */
 123     boolean lintClassfile;
 124 
 125     /** Switch: warn (instead of error) on illegal UTF-8
 126      */
 127     boolean warnOnIllegalUtf8;
 128 
 129     /** Switch: preserve parameter names from the variable table.
 130      */
 131     public boolean saveParameterNames;
 132 

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


 287         allowRecords = Feature.RECORDS.allowedInSource(source);
 288         allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
 289         warnOnIllegalUtf8 = Feature.WARN_ON_ILLEGAL_UTF8.allowedInSource(source);
 290 
 291         saveParameterNames = options.isSet(PARAMETERS);
 292 
 293         profile = Profile.instance(context);
 294 
 295         typevars = WriteableScope.create(syms.noSymbol);
 296 
 297         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
 298 
 299         initAttributeReaders();
 300     }
 301 
 302     /** Add member to class unless it is synthetic.
 303      */
 304     private void enterMember(ClassSymbol c, Symbol sym) {
 305         // Synthetic members are not entered -- reason lost to history (optimization?).
 306         // Lambda methods must be entered because they may have inner classes (which reference them)

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


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

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

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







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






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

2909     protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2910         return syms.enterClass(currentModule, name, owner);
2911     }
2912 
2913     /** Read contents of a given class symbol `c'. Both external and internal
2914      *  versions of an inner class are read.
2915      */
2916     void readClass(ClassSymbol c) {
2917         ClassType ct = (ClassType)c.type;
2918 
2919         // allocate scope for members
2920         c.members_field = WriteableScope.create(c);
2921 
2922         // prepare type variable table
2923         typevars = typevars.dup(currentOwner);
2924         if (ct.getEnclosingType().hasTag(CLASS))
2925             enterTypevars(c.owner, ct.getEnclosingType());
2926 
2927         // read flags, or skip if this is an inner class
2928         long f = nextChar();
2929         long flags = adjustClassFlags(f);
2930         if ((flags & MODULE) == 0) {
2931             if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2932             // read own class name and check that it matches
2933             currentModule = c.packge().modle;
2934             ClassSymbol self = poolReader.getClass(nextChar());
2935             if (c != self) {
2936                 throw badClassFile("class.file.wrong.class",
2937                                    self.flatname);
2938             }
2939         } else {
2940             if (majorVersion < Version.V53.major) {
2941                 throw badClassFile("anachronistic.module.info",
2942                         Integer.toString(majorVersion),
2943                         Integer.toString(minorVersion));
2944             }
2945             c.flags_field = flags;
2946             if (c.owner.kind != MDL) {
2947                 throw badClassFile("module.info.definition.expected");
2948             }
2949             currentModule = (ModuleSymbol) c.owner;

3001         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3002             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3003                 return (MethodSymbol) s;
3004             }
3005         }
3006         return null;
3007     }
3008 
3009     /** Read inner class info. For each inner/outer pair allocate a
3010      *  member class.
3011      */
3012     void readInnerClasses(ClassSymbol c) {
3013         int n = nextChar();
3014         for (int i = 0; i < n; i++) {
3015             nextChar(); // skip inner class symbol
3016             int outerIdx = nextChar();
3017             int nameIdx = nextChar();
3018             ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3019             Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3020             if (name == null) name = names.empty;
3021             long flags = adjustClassFlags(nextChar());
3022             if (outer != null) { // we have a member class
3023                 if (name == names.empty)
3024                     name = names.one;
3025                 ClassSymbol member = enterClass(name, outer);
3026                 if ((flags & STATIC) == 0) {
3027                     ((ClassType)member.type).setEnclosingType(outer.type);
3028                     if (member.erasure_field != null)
3029                         ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3030                 }
3031                 if (c == outer && member.owner == c) {
3032                     member.flags_field = flags;
3033                     enterMember(c, member);
3034                 }
3035             }
3036         }
3037     }
3038 
3039     /** Read a class definition from the bytes in buf.
3040      */
3041     private void readClassBuffer(ClassSymbol c) throws IOException {

3143         } finally {
3144             interimUses = List.nil();
3145             interimProvides = List.nil();
3146             missingTypeVariables = List.nil();
3147             foundTypeVariables = List.nil();
3148             filling = false;
3149         }
3150     }
3151 
3152     /** We can only read a single class file at a time; this
3153      *  flag keeps track of when we are currently reading a class
3154      *  file.
3155      */
3156     public boolean filling = false;
3157 
3158 /* **********************************************************************
3159  * Adjusting flags
3160  ***********************************************************************/
3161 
3162     long adjustFieldFlags(long flags) {





3163         return flags;
3164     }
3165 
3166     long adjustMethodFlags(long flags) {
3167         if ((flags & ACC_BRIDGE) != 0) {
3168             flags &= ~ACC_BRIDGE;
3169             flags |= BRIDGE;
3170         }
3171         if ((flags & ACC_VARARGS) != 0) {
3172             flags &= ~ACC_VARARGS;
3173             flags |= VARARGS;
3174         }
3175         return flags;
3176     }
3177 
3178     long adjustClassFlags(long flags) {
3179         if ((flags & ACC_MODULE) != 0) {
3180             flags &= ~ACC_MODULE;
3181             flags |= MODULE;
3182         }
3183         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded






















3184     }
3185 
3186     /**
3187      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3188      * The attribute is only the last component of the original filename, so is unlikely
3189      * to be valid as is, so operations other than those to access the name throw
3190      * UnsupportedOperationException
3191      */
3192     private static class SourceFileObject implements JavaFileObject {
3193 
3194         /** The file's name.
3195          */
3196         private final Name name;
3197 
3198         public SourceFileObject(Name name) {
3199             this.name = name;
3200         }
3201 
3202         @Override @DefinedBy(Api.COMPILER)
3203         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.Fragments;
  67 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  68 import com.sun.tools.javac.tree.JCTree;
  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.DiagnosticPosition;
  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    /** Lint option: warn about classfile issues
 129      */
 130     boolean lintClassfile;
 131 
 132     /** Switch: warn (instead of error) on illegal UTF-8
 133      */
 134     boolean warnOnIllegalUtf8;
 135 
 136     /** Switch: preserve parameter names from the variable table.
 137      */
 138     public boolean saveParameterNames;
 139 

 274     protected ClassReader(Context context) {
 275         context.put(classReaderKey, this);
 276         annotate = Annotate.instance(context);
 277         names = Names.instance(context);
 278         syms = Symtab.instance(context);
 279         types = Types.instance(context);
 280         fileManager = context.get(JavaFileManager.class);
 281         if (fileManager == null)
 282             throw new AssertionError("FileManager initialization error");
 283         diagFactory = JCDiagnostic.Factory.instance(context);
 284         dcfh = DeferredCompletionFailureHandler.instance(context);
 285 
 286         log = Log.instance(context);
 287 
 288         Options options = Options.instance(context);
 289         verbose         = options.isSet(Option.VERBOSE);
 290 
 291         Source source = Source.instance(context);
 292         preview = Preview.instance(context);
 293         allowModules     = Feature.MODULES.allowedInSource(source);
 294         allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
 295                 Feature.VALUE_CLASSES.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         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
 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                     if (outer == Type.noType) {
 591                         ClassType et = (ClassType) t.erasure(types);
 592                         return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
 593                     }
 594                     return new ClassType(outer, List.nil(), t, List.nil());
 595                 } finally {
 596                     sbp = startSbp;
 597                 }
 598             }
 599 
 600             case '<':           // generic arguments
 601                 ClassSymbol t = enterClass(readName(signatureBuffer,
 602                                                          startSbp,
 603                                                          sbp - startSbp));
 604                 List<Type> actuals = sigToTypes('>');
 605                 List<Type> formals = ((ClassType)t.type.tsym.type).typarams_field;
 606                 if (formals != null) {
 607                     if (actuals.isEmpty())
 608                         actuals = formals;
 609                 }
 610                 /* actualsCp is final as it will be captured by the inner class below. We could avoid defining
 611                  * this additional local variable and depend on field ClassType::typarams_field which `actuals` is
 612                  * assigned to but then we would have a dependendy on the internal representation of ClassType which
 613                  * could change in the future
 614                  */
 615                 final List<Type> actualsCp = actuals;
 616                 outer = new ClassType(outer, actuals, t, List.nil()) {
 617                         boolean completed = false;
 618                         boolean typeArgsSet = false;
 619                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 620                         public Type getEnclosingType() {
 621                             if (!completed) {
 622                                 completed = true;
 623                                 tsym.apiComplete();
 624                                 Type enclosingType = tsym.type.getEnclosingType();
 625                                 if (enclosingType != Type.noType) {
 626                                     List<Type> typeArgs =
 627                                         super.getEnclosingType().allparams();
 628                                     List<Type> typeParams =
 629                                         enclosingType.allparams();
 630                                     if (typeParams.length() != typeArgs.length()) {
 631                                         // no "rare" types
 632                                         super.setEnclosingType(types.erasure(enclosingType));
 633                                     } else {
 634                                         super.setEnclosingType(types.subst(enclosingType,
 635                                                                            typeParams,
 636                                                                            typeArgs));

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

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

2933     protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2934         return syms.enterClass(currentModule, name, owner);
2935     }
2936 
2937     /** Read contents of a given class symbol `c'. Both external and internal
2938      *  versions of an inner class are read.
2939      */
2940     void readClass(ClassSymbol c) {
2941         ClassType ct = (ClassType)c.type;
2942 
2943         // allocate scope for members
2944         c.members_field = WriteableScope.create(c);
2945 
2946         // prepare type variable table
2947         typevars = typevars.dup(currentOwner);
2948         if (ct.getEnclosingType().hasTag(CLASS))
2949             enterTypevars(c.owner, ct.getEnclosingType());
2950 
2951         // read flags, or skip if this is an inner class
2952         long f = nextChar();
2953         long flags = adjustClassFlags(c, f);
2954         if ((flags & MODULE) == 0) {
2955             if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2956             // read own class name and check that it matches
2957             currentModule = c.packge().modle;
2958             ClassSymbol self = poolReader.getClass(nextChar());
2959             if (c != self) {
2960                 throw badClassFile("class.file.wrong.class",
2961                                    self.flatname);
2962             }
2963         } else {
2964             if (majorVersion < Version.V53.major) {
2965                 throw badClassFile("anachronistic.module.info",
2966                         Integer.toString(majorVersion),
2967                         Integer.toString(minorVersion));
2968             }
2969             c.flags_field = flags;
2970             if (c.owner.kind != MDL) {
2971                 throw badClassFile("module.info.definition.expected");
2972             }
2973             currentModule = (ModuleSymbol) c.owner;

3025         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3026             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3027                 return (MethodSymbol) s;
3028             }
3029         }
3030         return null;
3031     }
3032 
3033     /** Read inner class info. For each inner/outer pair allocate a
3034      *  member class.
3035      */
3036     void readInnerClasses(ClassSymbol c) {
3037         int n = nextChar();
3038         for (int i = 0; i < n; i++) {
3039             nextChar(); // skip inner class symbol
3040             int outerIdx = nextChar();
3041             int nameIdx = nextChar();
3042             ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3043             Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3044             if (name == null) name = names.empty;
3045             long flags = adjustClassFlags(c, nextChar());
3046             if (outer != null) { // we have a member class
3047                 if (name == names.empty)
3048                     name = names.one;
3049                 ClassSymbol member = enterClass(name, outer);
3050                 if ((flags & STATIC) == 0) {
3051                     ((ClassType)member.type).setEnclosingType(outer.type);
3052                     if (member.erasure_field != null)
3053                         ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3054                 }
3055                 if (c == outer && member.owner == c) {
3056                     member.flags_field = flags;
3057                     enterMember(c, member);
3058                 }
3059             }
3060         }
3061     }
3062 
3063     /** Read a class definition from the bytes in buf.
3064      */
3065     private void readClassBuffer(ClassSymbol c) throws IOException {

3167         } finally {
3168             interimUses = List.nil();
3169             interimProvides = List.nil();
3170             missingTypeVariables = List.nil();
3171             foundTypeVariables = List.nil();
3172             filling = false;
3173         }
3174     }
3175 
3176     /** We can only read a single class file at a time; this
3177      *  flag keeps track of when we are currently reading a class
3178      *  file.
3179      */
3180     public boolean filling = false;
3181 
3182 /* **********************************************************************
3183  * Adjusting flags
3184  ***********************************************************************/
3185 
3186     long adjustFieldFlags(long flags) {
3187         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3188         if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3189             flags &= ~ACC_STRICT;
3190             flags |= STRICT;
3191         }
3192         return flags;
3193     }
3194 
3195     long adjustMethodFlags(long flags) {
3196         if ((flags & ACC_BRIDGE) != 0) {
3197             flags &= ~ACC_BRIDGE;
3198             flags |= BRIDGE;
3199         }
3200         if ((flags & ACC_VARARGS) != 0) {
3201             flags &= ~ACC_VARARGS;
3202             flags |= VARARGS;
3203         }
3204         return flags;
3205     }
3206 
3207     long adjustClassFlags(ClassSymbol c, long flags) {
3208         if ((flags & ACC_MODULE) != 0) {
3209             flags &= ~ACC_MODULE;
3210             flags |= MODULE;
3211         }
3212         if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags)) || (majorVersion < V67.major && (flags & INTERFACE) == 0)) {
3213             flags |= IDENTITY_TYPE;
3214         } else if (needsValueFlag(c, flags)) {
3215             flags |= VALUE_CLASS;
3216             flags &= ~IDENTITY_TYPE;
3217         }
3218         flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3219         return flags;
3220     }
3221 
3222     private boolean needsValueFlag(Symbol c, long flags) {
3223         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3224         if (allowValueClasses) {
3225             if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3226                     majorVersion >= V67.major && isMigratedValueClass(flags)) {
3227                 return true;
3228             }
3229         }
3230         return false;
3231     }
3232 
3233     private boolean isMigratedValueClass(long flags) {
3234         return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3235     }
3236 
3237     /**
3238      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3239      * The attribute is only the last component of the original filename, so is unlikely
3240      * to be valid as is, so operations other than those to access the name throw
3241      * UnsupportedOperationException
3242      */
3243     private static class SourceFileObject implements JavaFileObject {
3244 
3245         /** The file's name.
3246          */
3247         private final Name name;
3248 
3249         public SourceFileObject(Name name) {
3250             this.name = name;
3251         }
3252 
3253         @Override @DefinedBy(Api.COMPILER)
3254         public URI toUri() {
< prev index next >