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

 549                                   syms.methodClass);
 550         case '<':
 551             typevars = typevars.dup(currentOwner);
 552             Type poly = new ForAll(sigToTypeParams(), sigToType());
 553             typevars = typevars.leave();
 554             return poly;
 555         default:
 556             throw badClassFile("bad.signature", quoteBadSignature());
 557         }
 558     }
 559 
 560     byte[] signatureBuffer = new byte[0];
 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)

 558                                   syms.methodClass);
 559         case '<':
 560             typevars = typevars.dup(currentOwner);
 561             Type poly = new ForAll(sigToTypeParams(), sigToType());
 562             typevars = typevars.leave();
 563             return poly;
 564         default:
 565             throw badClassFile("bad.signature", quoteBadSignature());
 566         }
 567     }
 568 
 569     byte[] signatureBuffer = new byte[0];
 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         Name name;
 579         int startSbp = sbp;
 580 
 581         while (true) {
 582             final byte c = signature[sigp++];
 583             switch (c) {
 584 
 585             case ';': {         // end
 586                 ClassSymbol t = enterClass(readName(signatureBuffer,
 587                                                          startSbp,
 588                                                          sbp - startSbp));
 589 
 590                 try {
 591                     if (outer == Type.noType) {
 592                         ClassType et = (ClassType) t.erasure(types);
 593                         return new ClassType(et.getEnclosingType(), List.nil(), et.tsym, et.getMetadata());
 594                     }
 595                     return new ClassType(outer, List.nil(), t, List.nil());
 596                 } finally {
 597                     sbp = startSbp;
 598                 }
 599             }
 600 
 601             case '<':           // generic arguments
 602                 ClassSymbol t = enterClass(readName(signatureBuffer,
 603                                                          startSbp,
 604                                                          sbp - startSbp));
 605                 outer = new ClassType(outer, sigToTypes('>'), t, List.nil()) {
 606                         boolean completed = false;
 607                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 608                         public Type getEnclosingType() {
 609                             if (!completed) {
 610                                 completed = true;
 611                                 tsym.apiComplete();
 612                                 Type enclosingType = tsym.type.getEnclosingType();
 613                                 if (enclosingType != Type.noType) {
 614                                     List<Type> typeArgs =
 615                                         super.getEnclosingType().allparams();
 616                                     List<Type> typeParams =
 617                                         enclosingType.allparams();
 618                                     if (typeParams.length() != typeArgs.length()) {
 619                                         // no "rare" types
 620                                         super.setEnclosingType(types.erasure(enclosingType));
 621                                     } else {
 622                                         super.setEnclosingType(types.subst(enclosingType,
 623                                                                            typeParams,
 624                                                                            typeArgs));
 625                                     }

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

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

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

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

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