< prev index next >

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

Print this page

  45 import javax.tools.JavaFileManager;
  46 import javax.tools.JavaFileObject;
  47 
  48 import com.sun.tools.javac.code.Source;
  49 import com.sun.tools.javac.code.Source.Feature;
  50 import com.sun.tools.javac.comp.Annotate;
  51 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
  52 import com.sun.tools.javac.code.*;
  53 import com.sun.tools.javac.code.Directive.*;
  54 import com.sun.tools.javac.code.Lint.LintCategory;
  55 import com.sun.tools.javac.code.Scope.WriteableScope;
  56 import com.sun.tools.javac.code.Symbol.*;
  57 import com.sun.tools.javac.code.Symtab;
  58 import com.sun.tools.javac.code.Type.*;
  59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  60 import com.sun.tools.javac.file.BaseFileManager;
  61 import com.sun.tools.javac.file.PathFileObject;
  62 import com.sun.tools.javac.jvm.ClassFile.Version;
  63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
  64 import com.sun.tools.javac.main.Option;

  65 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  66 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  67 import com.sun.tools.javac.resources.CompilerProperties.Warnings;

  68 import com.sun.tools.javac.util.*;
  69 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
  70 import com.sun.tools.javac.util.DefinedBy.Api;
  71 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  72 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  73 
  74 import static com.sun.tools.javac.code.Flags.*;
  75 import static com.sun.tools.javac.code.Kinds.Kind.*;
  76 
  77 import com.sun.tools.javac.code.Scope.LookupKind;
  78 

  79 import static com.sun.tools.javac.code.TypeTag.ARRAY;
  80 import static com.sun.tools.javac.code.TypeTag.CLASS;
  81 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
  82 import static com.sun.tools.javac.jvm.ClassFile.*;
  83 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
  84 
  85 import static com.sun.tools.javac.main.Option.PARAMETERS;
  86 
  87 /** This class provides operations to read a classfile into an internal
  88  *  representation. The internal representation is anchored in a
  89  *  ClassSymbol which contains in its scope symbol representations
  90  *  for all other definitions in the classfile. Top-level Classes themselves
  91  *  appear as members of the scopes of PackageSymbols.
  92  *
  93  *  <p><b>This is NOT part of any supported API.
  94  *  If you write code that depends on this, you do so at your own risk.
  95  *  This code and its internal interfaces are subject to change or
  96  *  deletion without notice.</b>
  97  */
  98 public class ClassReader {
  99     /** The context key for the class reader. */
 100     protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
 101 
 102     public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
 103 
 104     private final Annotate annotate;
 105 
 106     /** Switch: verbose output.
 107      */
 108     boolean verbose;
 109 
 110     /** Switch: allow modules.
 111      */
 112     boolean allowModules;
 113 




 114     /** Switch: allow sealed
 115      */
 116     boolean allowSealedTypes;
 117 
 118     /** Switch: allow records
 119      */
 120     boolean allowRecords;
 121 
 122    /** Lint option: warn about classfile issues
 123      */
 124     boolean lintClassfile;
 125 
 126     /** Switch: warn (instead of error) on illegal UTF-8
 127      */
 128     boolean warnOnIllegalUtf8;
 129 
 130     /** Switch: preserve parameter names from the variable table.
 131      */
 132     public boolean saveParameterNames;
 133 

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

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


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

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

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







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






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

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

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

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





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






















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

  45 import javax.tools.JavaFileManager;
  46 import javax.tools.JavaFileObject;
  47 
  48 import com.sun.tools.javac.code.Source;
  49 import com.sun.tools.javac.code.Source.Feature;
  50 import com.sun.tools.javac.comp.Annotate;
  51 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
  52 import com.sun.tools.javac.code.*;
  53 import com.sun.tools.javac.code.Directive.*;
  54 import com.sun.tools.javac.code.Lint.LintCategory;
  55 import com.sun.tools.javac.code.Scope.WriteableScope;
  56 import com.sun.tools.javac.code.Symbol.*;
  57 import com.sun.tools.javac.code.Symtab;
  58 import com.sun.tools.javac.code.Type.*;
  59 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
  60 import com.sun.tools.javac.file.BaseFileManager;
  61 import com.sun.tools.javac.file.PathFileObject;
  62 import com.sun.tools.javac.jvm.ClassFile.Version;
  63 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
  64 import com.sun.tools.javac.main.Option;
  65 import com.sun.tools.javac.resources.CompilerProperties;
  66 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  67 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  68 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  69 import com.sun.tools.javac.tree.JCTree;
  70 import com.sun.tools.javac.util.*;
  71 import com.sun.tools.javac.util.ByteBuffer.UnderflowException;
  72 import com.sun.tools.javac.util.DefinedBy.Api;
  73 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  74 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  75 
  76 import static com.sun.tools.javac.code.Flags.*;
  77 import static com.sun.tools.javac.code.Kinds.Kind.*;
  78 
  79 import com.sun.tools.javac.code.Scope.LookupKind;
  80 
  81 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  82 import static com.sun.tools.javac.code.TypeTag.ARRAY;
  83 import static com.sun.tools.javac.code.TypeTag.CLASS;
  84 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
  85 import static com.sun.tools.javac.jvm.ClassFile.*;
  86 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
  87 
  88 import static com.sun.tools.javac.main.Option.PARAMETERS;
  89 
  90 /** This class provides operations to read a classfile into an internal
  91  *  representation. The internal representation is anchored in a
  92  *  ClassSymbol which contains in its scope symbol representations
  93  *  for all other definitions in the classfile. Top-level Classes themselves
  94  *  appear as members of the scopes of PackageSymbols.
  95  *
  96  *  <p><b>This is NOT part of any supported API.
  97  *  If you write code that depends on this, you do so at your own risk.
  98  *  This code and its internal interfaces are subject to change or
  99  *  deletion without notice.</b>
 100  */
 101 public class ClassReader {
 102     /** The context key for the class reader. */
 103     protected static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
 104 
 105     public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
 106 
 107     private final Annotate annotate;
 108 
 109     /** Switch: verbose output.
 110      */
 111     boolean verbose;
 112 
 113     /** Switch: allow modules.
 114      */
 115     boolean allowModules;
 116 
 117     /** Switch: allow value classes.
 118      */
 119     boolean allowValueClasses;
 120 
 121     /** Switch: allow sealed
 122      */
 123     boolean allowSealedTypes;
 124 
 125     /** Switch: allow records
 126      */
 127     boolean allowRecords;
 128 
 129    /** Lint option: warn about classfile issues
 130      */
 131     boolean lintClassfile;
 132 
 133     /** Switch: warn (instead of error) on illegal UTF-8
 134      */
 135     boolean warnOnIllegalUtf8;
 136 
 137     /** Switch: preserve parameter names from the variable table.
 138      */
 139     public boolean saveParameterNames;
 140 

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

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

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

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

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

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

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