< prev index next >

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

Print this page

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

  64 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  66 import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
  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.Fragment;
  72 import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
  73 
  74 import static com.sun.tools.javac.code.Flags.*;
  75 import static com.sun.tools.javac.code.Kinds.Kind.*;
  76 
  77 import com.sun.tools.javac.code.Scope.LookupKind;
  78 

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




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

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


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

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


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

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

1547                 sym.flags_field |= VALUE_BASED;
1548             } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1549                 Assert.check(sym.kind == MTH);
1550                 sym.flags_field |= RESTRICTED;
1551             } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1552                 Assert.check(sym.kind == VAR);
1553                 sym.flags_field |= REQUIRES_IDENTITY;
1554             } else {
1555                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1556                     target = proxy;
1557                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1558                     repeatable = proxy;
1559                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1560                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1561                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1562                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1563                     sym.flags_field |= PREVIEW_API;
1564                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1565                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1566                     sym.flags_field |= VALUE_BASED;
1567                 }  else if (proxy.type.tsym == syms.restrictedType.tsym) {
1568                     Assert.check(sym.kind == MTH);
1569                     sym.flags_field |= RESTRICTED;
1570                 }  else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1571                     Assert.check(sym.kind == VAR);
1572                     sym.flags_field |= REQUIRES_IDENTITY;
1573                 }
1574                 proxies.append(proxy);
1575             }
1576         }
1577         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1578     }
1579     //where:
1580         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1581             for (Pair<Name, Attribute> v : proxy.values) {
1582                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1583                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1584                         sym.flags_field |= flag;
1585                     }
1586                 }
1587             }

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

3150         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
3151             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
3152                 return (MethodSymbol) s;
3153             }
3154         }
3155         return null;
3156     }
3157 
3158     /** Read inner class info. For each inner/outer pair allocate a
3159      *  member class.
3160      */
3161     void readInnerClasses(ClassSymbol c) {
3162         int n = nextChar();
3163         for (int i = 0; i < n; i++) {
3164             nextChar(); // skip inner class symbol
3165             int outerIdx = nextChar();
3166             int nameIdx = nextChar();
3167             ClassSymbol outer = optPoolEntry(outerIdx, poolReader::getClass, null);
3168             Name name = optPoolEntry(nameIdx, poolReader::getName, names.empty);
3169             if (name == null) name = names.empty;
3170             long flags = adjustClassFlags(nextChar());
3171             if (outer != null) { // we have a member class
3172                 if (name == names.empty)
3173                     name = names.one;
3174                 ClassSymbol member = enterClass(name, outer);
3175                 if ((member.flags_field & FROM_SOURCE) == 0) {
3176                     if ((flags & STATIC) == 0) {
3177                         ((ClassType)member.type).setEnclosingType(outer.type);
3178                         if (member.erasure_field != null)
3179                             ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
3180                     }
3181                     if (c == outer && member.owner == c) {
3182                         member.flags_field = flags;
3183                         enterMember(c, member);
3184                     }
3185                 } else if ((flags & STATIC) != (member.flags_field & STATIC)) {
3186                     log.warning(LintWarnings.InconsistentInnerClasses(member, currentClassFile));
3187                 }
3188             }
3189         }
3190     }

3296         } finally {
3297             interimUses = List.nil();
3298             interimProvides = List.nil();
3299             missingTypeVariables = List.nil();
3300             foundTypeVariables = List.nil();
3301             filling = false;
3302         }
3303     }
3304 
3305     /** We can only read a single class file at a time; this
3306      *  flag keeps track of when we are currently reading a class
3307      *  file.
3308      */
3309     public boolean filling = false;
3310 
3311 /* **********************************************************************
3312  * Adjusting flags
3313  ***********************************************************************/
3314 
3315     long adjustFieldFlags(long flags) {





3316         return flags;
3317     }
3318 
3319     long adjustMethodFlags(long flags) {
3320         if ((flags & ACC_BRIDGE) != 0) {
3321             flags &= ~ACC_BRIDGE;
3322             flags |= BRIDGE;
3323         }
3324         if ((flags & ACC_VARARGS) != 0) {
3325             flags &= ~ACC_VARARGS;
3326             flags |= VARARGS;
3327         }
3328         return flags;
3329     }
3330 
3331     long adjustClassFlags(long flags) {
3332         if ((flags & ACC_MODULE) != 0) {
3333             flags &= ~ACC_MODULE;
3334             flags |= MODULE;
3335         }
3336         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded























3337     }
3338 
3339     /**
3340      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
3341      * The attribute is only the last component of the original filename, so is unlikely
3342      * to be valid as is, so operations other than those to access the name throw
3343      * UnsupportedOperationException
3344      */
3345     private static class SourceFileObject implements JavaFileObject {
3346 
3347         /** The file's name.
3348          */
3349         private final Name name;
3350 
3351         public SourceFileObject(Name name) {
3352             this.name = name;
3353         }
3354 
3355         @Override @DefinedBy(Api.COMPILER)
3356         public URI toUri() {

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

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

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

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

1558                 sym.flags_field |= VALUE_BASED;
1559             } else if (proxy.type.tsym.flatName() == syms.restrictedInternalType.tsym.flatName()) {
1560                 Assert.check(sym.kind == MTH);
1561                 sym.flags_field |= RESTRICTED;
1562             } else if (proxy.type.tsym.flatName() == syms.requiresIdentityInternalType.tsym.flatName()) {
1563                 Assert.check(sym.kind == VAR);
1564                 sym.flags_field |= REQUIRES_IDENTITY;
1565             } else {
1566                 if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1567                     target = proxy;
1568                 } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1569                     repeatable = proxy;
1570                 } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1571                     sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
1572                     setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL);
1573                 }  else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
1574                     sym.flags_field |= PREVIEW_API;
1575                     setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
1576                 }  else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
1577                     sym.flags_field |= VALUE_BASED;
1578                 } else if (proxy.type.tsym == syms.restrictedType.tsym) {
1579                     Assert.check(sym.kind == MTH);
1580                     sym.flags_field |= RESTRICTED;
1581                 }  else if (proxy.type.tsym == syms.requiresIdentityType.tsym) {
1582                     Assert.check(sym.kind == VAR);
1583                     sym.flags_field |= REQUIRES_IDENTITY;
1584                 }
1585                 proxies.append(proxy);
1586             }
1587         }
1588         annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1589     }
1590     //where:
1591         private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) {
1592             for (Pair<Name, Attribute> v : proxy.values) {
1593                 if (v.fst == attribute && v.snd instanceof Attribute.Constant constant) {
1594                     if (constant.type == syms.booleanType && ((Integer) constant.value) != 0) {
1595                         sym.flags_field |= flag;
1596                     }
1597                 }
1598             }

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

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

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