< 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                 outer = new ClassType(outer, sigToTypes('>'), t) {
 594                         boolean completed = false;
 595                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 596                         public Type getEnclosingType() {
 597                             if (!completed) {
 598                                 completed = true;
 599                                 tsym.apiComplete();
 600                                 Type enclosingType = tsym.type.getEnclosingType();
 601                                 if (enclosingType != Type.noType) {
 602                                     List<Type> typeArgs =
 603                                         super.getEnclosingType().allparams();
 604                                     List<Type> typeParams =
 605                                         enclosingType.allparams();
 606                                     if (typeParams.length() != typeArgs.length()) {
 607                                         // no "rare" types
 608                                         super.setEnclosingType(types.erasure(enclosingType));
 609                                     } else {
 610                                         super.setEnclosingType(types.subst(enclosingType,
 611                                                                            typeParams,
 612                                                                            typeArgs));
 613                                     }

 636                         signatureBuffer[sbp++] = (byte)'$';
 637                         break;
 638                     } else {
 639                         sbp = startSbp;
 640                         return outer;
 641                     }
 642                 case '.':
 643                     signatureBuffer[sbp++] = (byte)'$';
 644                     break;
 645                 default:
 646                     throw new AssertionError(signature[sigp-1]);
 647                 }
 648                 continue;
 649 
 650             case '.':
 651                 //we have seen an enclosing non-generic class
 652                 if (outer != Type.noType) {
 653                     t = enterClass(readName(signatureBuffer,
 654                                                  startSbp,
 655                                                  sbp - startSbp));
 656                     outer = new ClassType(outer, List.nil(), t);
 657                 }
 658                 signatureBuffer[sbp++] = (byte)'$';
 659                 continue;
 660             case '/':
 661                 signatureBuffer[sbp++] = (byte)'.';
 662                 continue;
 663             default:
 664                 signatureBuffer[sbp++] = c;
 665                 continue;
 666             }
 667         }
 668     }
 669 
 670     /** Quote a bogus signature for display inside an error message.
 671      */
 672     String quoteBadSignature() {
 673         String sigString;
 674         try {
 675             sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
 676         } catch (InvalidUtfException e) {

1494         ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1495         for (CompoundAnnotationProxy proxy : annotations) {
1496             if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1497                 sym.flags_field |= PROPRIETARY;
1498             else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1499                 if (profile != Profile.DEFAULT) {
1500                     for (Pair<Name, Attribute> v : proxy.values) {
1501                         if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1502                             if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1503                                 sym.flags_field |= NOT_IN_PROFILE;
1504                             }
1505                         }
1506                     }
1507                 }
1508             } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1509                 sym.flags_field |= PREVIEW_API;
1510                 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1511             } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1512                 Assert.check(sym.kind == TYP);
1513                 sym.flags_field |= VALUE_BASED;






1514             } else if (proxy.type.tsym.flatName() == syms.restrictedType.tsym.flatName()) {
1515                 Assert.check(sym.kind == MTH);
1516                 sym.flags_field |= RESTRICTED;
1517             } else {
1518                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1519                     target = proxy;
1520                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1521                     repeatable = proxy;
1522                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1523                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1524                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1525                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1526                     sym.flags_field |= PREVIEW_API;
1527                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1528                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1529                     sym.flags_field |= VALUE_BASED;





1530                 }  else if (proxy.type.tsym == syms.restrictedType.tsym) {
1531                     Assert.check(sym.kind == MTH);
1532                     sym.flags_field |= RESTRICTED;
1533                 }
1534                 proxies.append(proxy);
1535             }
1536         }
1537         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1538     }
1539     //where:
1540         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1541             for (Pair<Name, Attribute> v : proxy.values) {
1542                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1543                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1544                         sym.flags_field |= flag;
1545                     }
1546                 }
1547             }
1548         }
1549 

2876     protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2877         return syms.enterClass(currentModule, name, owner);
2878     }
2879 
2880     /** Read contents of a given class symbol `c'. Both external and internal
2881      *  versions of an inner class are read.
2882      */
2883     void readClass(ClassSymbol c) {
2884         ClassType ct = (ClassType)c.type;
2885 
2886         // allocate scope for members
2887         c.members_field = WriteableScope.create(c);
2888 
2889         // prepare type variable table
2890         typevars = typevars.dup(currentOwner);
2891         if (ct.getEnclosingType().hasTag(CLASS))
2892             enterTypevars(c.owner, ct.getEnclosingType());
2893 
2894         // read flags, or skip if this is an inner class
2895         long f = nextChar();
2896         long flags = adjustClassFlags(f);
2897         if ((flags & MODULE) == 0) {
2898             if (c.owner.kind == PCK || c.owner.kind == ERR) c.flags_field = flags;
2899             // read own class name and check that it matches
2900             currentModule = c.packge().modle;
2901             ClassSymbol self = poolReader.getClass(nextChar());
2902             if (c != self) {
2903                 throw badClassFile("class.file.wrong.class",
2904                                    self.flatname);
2905             }
2906         } else {
2907             if (majorVersion < Version.V53.major) {
2908                 throw badClassFile("anachronistic.module.info",
2909                         Integer.toString(majorVersion),
2910                         Integer.toString(minorVersion));
2911             }
2912             c.flags_field = flags;
2913             if (c.owner.kind != MDL) {
2914                 throw badClassFile("module.info.definition.expected");
2915             }
2916             currentModule = (ModuleSymbol) c.owner;

2968         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
2969             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
2970                 return (MethodSymbol) s;
2971             }
2972         }
2973         return null;
2974     }
2975 
2976     /** Read inner class info. For each inner/outer pair allocate a
2977      *  member class.
2978      */
2979     void readInnerClasses(ClassSymbol c) {
2980         int n = nextChar();
2981         for (int i = 0; i < n; i++) {
2982             nextChar(); // skip inner class symbol
2983             int outerIdx = nextChar();
2984             int nameIdx = nextChar();
2985             ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
2986             Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
2987             if (name == null) name = names.empty;
2988             long flags = adjustClassFlags(nextChar());
2989             if (outer != null) { // we have a member class
2990                 if (name == names.empty)
2991                     name = names.one;
2992                 ClassSymbol member = enterClass(name, outer);
2993                 if ((flags & STATIC) == 0) {
2994                     ((ClassType)member.type).setEnclosingType(outer.type);
2995                     if (member.erasure_field != null)
2996                         ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
2997                 }
2998                 if (c == outer && member.owner == c) {
2999                     member.flags_field = flags;
3000                     enterMember(c, member);
3001                 }
3002             }
3003         }
3004     }
3005 
3006     /** Read a class definition from the bytes in buf.
3007      */
3008     private void readClassBuffer(ClassSymbol c) throws IOException {

3110         } finally {
3111             interimUses = List.nil();
3112             interimProvides = List.nil();
3113             missingTypeVariables = List.nil();
3114             foundTypeVariables = List.nil();
3115             filling = false;
3116         }
3117     }
3118 
3119     /** We can only read a single class file at a time; this
3120      *  flag keeps track of when we are currently reading a class
3121      *  file.
3122      */
3123     public boolean filling = false;
3124 
3125 /************************************************************************
3126  * Adjusting flags
3127  ***********************************************************************/
3128 
3129     long adjustFieldFlags(long flags) {





3130         return flags;
3131     }
3132 
3133     long adjustMethodFlags(long flags) {
3134         if ((flags & ACC_BRIDGE) != 0) {
3135             flags &= ~ACC_BRIDGE;
3136             flags |= BRIDGE;
3137         }
3138         if ((flags & ACC_VARARGS) != 0) {
3139             flags &= ~ACC_VARARGS;
3140             flags |= VARARGS;
3141         }
3142         return flags;
3143     }
3144 
3145     long adjustClassFlags(long flags) {
3146         if ((flags & ACC_MODULE) != 0) {
3147             flags &= ~ACC_MODULE;
3148             flags |= MODULE;
3149         }
3150         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded





















3151     }
3152 
3153     /**
3154      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3155      * The attribute is only the last component of the original filename, so is unlikely
3156      * to be valid as is, so operations other than those to access the name throw
3157      * UnsupportedOperationException
3158      */
3159     private static class SourceFileObject implements JavaFileObject {
3160 
3161         /** The file's name.
3162          */
3163         private final Name name;
3164 
3165         public SourceFileObject(Name name) {
3166             this.name = name;
3167         }
3168 
3169         @Override @DefinedBy(Api.COMPILER)
3170         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                 outer = new ClassType(outer, sigToTypes('>'), t, List.nil()) {
 605                         boolean completed = false;
 606                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 607                         public Type getEnclosingType() {
 608                             if (!completed) {
 609                                 completed = true;
 610                                 tsym.apiComplete();
 611                                 Type enclosingType = tsym.type.getEnclosingType();
 612                                 if (enclosingType != Type.noType) {
 613                                     List<Type> typeArgs =
 614                                         super.getEnclosingType().allparams();
 615                                     List<Type> typeParams =
 616                                         enclosingType.allparams();
 617                                     if (typeParams.length() != typeArgs.length()) {
 618                                         // no "rare" types
 619                                         super.setEnclosingType(types.erasure(enclosingType));
 620                                     } else {
 621                                         super.setEnclosingType(types.subst(enclosingType,
 622                                                                            typeParams,
 623                                                                            typeArgs));
 624                                     }

 647                         signatureBuffer[sbp++] = (byte)'$';
 648                         break;
 649                     } else {
 650                         sbp = startSbp;
 651                         return outer;
 652                     }
 653                 case '.':
 654                     signatureBuffer[sbp++] = (byte)'$';
 655                     break;
 656                 default:
 657                     throw new AssertionError(signature[sigp-1]);
 658                 }
 659                 continue;
 660 
 661             case '.':
 662                 //we have seen an enclosing non-generic class
 663                 if (outer != Type.noType) {
 664                     t = enterClass(readName(signatureBuffer,
 665                                                  startSbp,
 666                                                  sbp - startSbp));
 667                     outer = new ClassType(outer, List.nil(), t, List.nil());
 668                 }
 669                 signatureBuffer[sbp++] = (byte)'$';
 670                 continue;
 671             case '/':
 672                 signatureBuffer[sbp++] = (byte)'.';
 673                 continue;
 674             default:
 675                 signatureBuffer[sbp++] = c;
 676                 continue;
 677             }
 678         }
 679     }
 680 
 681     /** Quote a bogus signature for display inside an error message.
 682      */
 683     String quoteBadSignature() {
 684         String sigString;
 685         try {
 686             sigString = Convert.utf2string(signature, sigp, siglimit - sigp, Convert.Validation.NONE);
 687         } catch (InvalidUtfException e) {

1505         ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
1506         for (CompoundAnnotationProxy proxy : annotations) {
1507             if (proxy.type.tsym.flatName() == syms.proprietaryType.tsym.flatName())
1508                 sym.flags_field |= PROPRIETARY;
1509             else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) {
1510                 if (profile != Profile.DEFAULT) {
1511                     for (Pair<Name, Attribute> v : proxy.values) {
1512                         if (v.fst == names.value && v.snd instanceof Attribute.Constant constant) {
1513                             if (constant.type == syms.intType && ((Integer) constant.value) > profile.value) {
1514                                 sym.flags_field |= NOT_IN_PROFILE;
1515                             }
1516                         }
1517                     }
1518                 }
1519             } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
1520                 sym.flags_field |= PREVIEW_API;
1521                 setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1522             } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
1523                 Assert.check(sym.kind == TYP);
1524                 sym.flags_field |= VALUE_BASED;
1525             } else if (proxy.type.tsym.flatName() == syms.migratedValueClassInternalType.tsym.flatName()) {
1526                 Assert.check(sym.kind == TYP);
1527                 sym.flags_field |= MIGRATED_VALUE_CLASS;
1528                 if (needsValueFlag(sym, sym.flags_field)) {
1529                     sym.flags_field |= VALUE_CLASS;
1530                 }
1531             } else if (proxy.type.tsym.flatName() == syms.restrictedType.tsym.flatName()) {
1532                 Assert.check(sym.kind == MTH);
1533                 sym.flags_field |= RESTRICTED;
1534             } else {
1535                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1536                     target = proxy;
1537                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1538                     repeatable = proxy;
1539                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1540                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1541                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1542                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1543                     sym.flags_field |= PREVIEW_API;
1544                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1545                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1546                     sym.flags_field |= VALUE_BASED;
1547                 }  else if (proxy.type.tsym == syms.migratedValueClassType.tsym && sym.kind == TYP) {
1548                     sym.flags_field |= MIGRATED_VALUE_CLASS;
1549                     if (needsValueFlag(sym, sym.flags_field)) {
1550                         sym.flags_field |= VALUE_CLASS;
1551                     }
1552                 }  else if (proxy.type.tsym == syms.restrictedType.tsym) {
1553                     Assert.check(sym.kind == MTH);
1554                     sym.flags_field |= RESTRICTED;
1555                 }
1556                 proxies.append(proxy);
1557             }
1558         }
1559         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1560     }
1561     //where:
1562         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1563             for (Pair<Name, Attribute> v : proxy.values) {
1564                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1565                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1566                         sym.flags_field |= flag;
1567                     }
1568                 }
1569             }
1570         }
1571 

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

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

3132         } finally {
3133             interimUses = List.nil();
3134             interimProvides = List.nil();
3135             missingTypeVariables = List.nil();
3136             foundTypeVariables = List.nil();
3137             filling = false;
3138         }
3139     }
3140 
3141     /** We can only read a single class file at a time; this
3142      *  flag keeps track of when we are currently reading a class
3143      *  file.
3144      */
3145     public boolean filling = false;
3146 
3147 /************************************************************************
3148  * Adjusting flags
3149  ***********************************************************************/
3150 
3151     long adjustFieldFlags(long flags) {
3152         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3153         if (allowValueClasses && previewClassFile && (flags & ACC_STRICT) != 0) {
3154             flags &= ~ACC_STRICT;
3155             flags |= STRICT;
3156         }
3157         return flags;
3158     }
3159 
3160     long adjustMethodFlags(long flags) {
3161         if ((flags & ACC_BRIDGE) != 0) {
3162             flags &= ~ACC_BRIDGE;
3163             flags |= BRIDGE;
3164         }
3165         if ((flags & ACC_VARARGS) != 0) {
3166             flags &= ~ACC_VARARGS;
3167             flags |= VARARGS;
3168         }
3169         return flags;
3170     }
3171 
3172     long adjustClassFlags(ClassSymbol c, long flags) {
3173         if ((flags & ACC_MODULE) != 0) {
3174             flags &= ~ACC_MODULE;
3175             flags |= MODULE;
3176         }
3177         if (((flags & ACC_IDENTITY) != 0 && !isMigratedValueClass(flags)) || (majorVersion < V67.major && (flags & INTERFACE) == 0)) {
3178             flags |= IDENTITY_TYPE;
3179         } else if (needsValueFlag(c, flags)) {
3180             flags |= VALUE_CLASS;
3181         }
3182         flags &= ~ACC_IDENTITY; // ACC_IDENTITY and SYNCHRONIZED bits overloaded
3183         return flags;
3184     }
3185 
3186     private boolean needsValueFlag(Symbol c, long flags) {
3187         boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
3188         if (allowValueClasses) {
3189             if (previewClassFile && majorVersion >= V67.major && (flags & INTERFACE) == 0 ||
3190                     majorVersion >= V67.major && isMigratedValueClass(flags)) {
3191                 return true;
3192             }
3193         }
3194         return false;
3195     }
3196 
3197     private boolean isMigratedValueClass(long flags) {
3198         return allowValueClasses && ((flags & MIGRATED_VALUE_CLASS) != 0);
3199     }
3200 
3201     /**
3202      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3203      * The attribute is only the last component of the original filename, so is unlikely
3204      * to be valid as is, so operations other than those to access the name throw
3205      * UnsupportedOperationException
3206      */
3207     private static class SourceFileObject implements JavaFileObject {
3208 
3209         /** The file's name.
3210          */
3211         private final Name name;
3212 
3213         public SourceFileObject(Name name) {
3214             this.name = name;
3215         }
3216 
3217         @Override @DefinedBy(Api.COMPILER)
3218         public URI toUri() {
< prev index next >