src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java
author Dusan Balek <dbalek@netbeans.org>
Mon, 31 Jul 2017 11:07:41 +0200
changeset 5955 f54cccaf6e6c
parent 5950 993a3fed49b2
permissions -rw-r--r--
Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
     1 /*
     2  * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package com.sun.tools.javac.jvm;
    27 
    28 import java.io.*;
    29 import java.net.URI;
    30 import java.net.URISyntaxException;
    31 import java.nio.CharBuffer;
    32 import java.nio.file.ClosedFileSystemException;
    33 import java.util.Arrays;
    34 import java.util.EnumSet;
    35 import java.util.HashMap;
    36 import java.util.HashSet;
    37 import java.util.Map;
    38 import java.util.Set;
    39 
    40 import javax.lang.model.element.Modifier;
    41 import javax.lang.model.element.NestingKind;
    42 import javax.tools.JavaFileManager;
    43 import javax.tools.JavaFileObject;
    44 
    45 import com.sun.tools.javac.comp.Annotate;
    46 import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
    47 import com.sun.tools.javac.code.*;
    48 import com.sun.tools.javac.code.Directive.*;
    49 import com.sun.tools.javac.code.Lint.LintCategory;
    50 import com.sun.tools.javac.code.Scope.WriteableScope;
    51 import com.sun.tools.javac.code.Symbol.*;
    52 import com.sun.tools.javac.code.Symtab;
    53 import com.sun.tools.javac.code.Type.*;
    54 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
    55 import com.sun.tools.javac.file.BaseFileManager;
    56 import com.sun.tools.javac.file.PathFileObject;
    57 import com.sun.tools.javac.jvm.ClassFile.NameAndType;
    58 import com.sun.tools.javac.jvm.ClassFile.Version;
    59 import com.sun.tools.javac.main.Option;
    60 import com.sun.tools.javac.util.*;
    61 import com.sun.tools.javac.util.DefinedBy.Api;
    62 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    63 
    64 import static com.sun.tools.javac.code.Flags.*;
    65 import static com.sun.tools.javac.code.Kinds.Kind.*;
    66 
    67 import com.sun.tools.javac.code.Scope.LookupKind;
    68 
    69 import static com.sun.tools.javac.code.TypeTag.ARRAY;
    70 import static com.sun.tools.javac.code.TypeTag.CLASS;
    71 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
    72 import static com.sun.tools.javac.jvm.ClassFile.*;
    73 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
    74 
    75 import static com.sun.tools.javac.main.Option.PARAMETERS;
    76 
    77 /** This class provides operations to read a classfile into an internal
    78  *  representation. The internal representation is anchored in a
    79  *  ClassSymbol which contains in its scope symbol representations
    80  *  for all other definitions in the classfile. Top-level Classes themselves
    81  *  appear as members of the scopes of PackageSymbols.
    82  *
    83  *  <p><b>This is NOT part of any supported API.
    84  *  If you write code that depends on this, you do so at your own risk.
    85  *  This code and its internal interfaces are subject to change or
    86  *  deletion without notice.</b>
    87  */
    88 public class ClassReader {
    89     /** The context key for the class reader. */
    90     public static final Context.Key<ClassReader> classReaderKey = new Context.Key<>();
    91 
    92     public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
    93 
    94     private final Annotate annotate;
    95 
    96     /** Switch: verbose output.
    97      */
    98     boolean verbose;
    99 
   100     /** Switch: read constant pool and code sections. This switch is initially
   101      *  set to false but can be turned on from outside.
   102      */
   103     public boolean readAllOfClassFile = false;
   104 
   105     /** Switch: allow simplified varargs.
   106      */
   107     boolean allowSimplifiedVarargs;
   108 
   109     /** Switch: allow modules.
   110      */
   111     boolean allowModules;
   112 
   113    /** Lint option: warn about classfile issues
   114      */
   115     boolean lintClassfile;
   116 
   117     /** Switch: preserve parameter names from the variable table.
   118      */
   119     public boolean saveParameterNames;
   120 
   121     /**
   122      * The currently selected profile.
   123      */
   124     public final Profile profile;
   125 
   126     /** The log to use for verbose output
   127      */
   128     final Log log;
   129 
   130     /** The symbol table. */
   131     Symtab syms;
   132 
   133     Types types;
   134 
   135     /** The name table. */
   136     final Names names;
   137 
   138     /** Access to files
   139      */
   140     private final JavaFileManager fileManager;
   141 
   142     /** Factory for diagnostics
   143      */
   144     JCDiagnostic.Factory diagFactory;
   145 
   146     private final boolean ideMode;
   147 
   148     /** The current scope where type variables are entered.
   149      */
   150     protected WriteableScope typevars;
   151 
   152     private List<InterimUsesDirective> interimUses = List.nil();
   153     private List<InterimProvidesDirective> interimProvides = List.nil();
   154 
   155     /** The path name of the class file currently being read.
   156      */
   157     protected JavaFileObject currentClassFile = null;
   158 
   159     /** The class or method currently being read.
   160      */
   161     protected Symbol currentOwner = null;
   162 
   163     /** The module containing the class currently being read.
   164      */
   165     protected ModuleSymbol currentModule = null;
   166 
   167     /** The buffer containing the currently read class file.
   168      */
   169     byte[] buf = new byte[INITIAL_BUFFER_SIZE];
   170 
   171     /** The current input pointer.
   172      */
   173     protected int bp;
   174 
   175     /** The objects of the constant pool.
   176      */
   177     Object[] poolObj;
   178 
   179     /** For every constant pool entry, an index into buf where the
   180      *  defining section of the entry is found.
   181      */
   182     int[] poolIdx;
   183 
   184     /** The major version number of the class file being read. */
   185     int majorVersion;
   186     /** The minor version number of the class file being read. */
   187     int minorVersion;
   188 
   189     /** A table to hold the constant pool indices for method parameter
   190      * names, as given in LocalVariableTable attributes.
   191      */
   192     int[] parameterNameIndices;
   193 
   194     /**
   195      * Whether or not any parameter names have been found.
   196      */
   197     boolean haveParameterNameIndices;
   198 
   199     /** Set this to false every time we start reading a method
   200      * and are saving parameter names.  Set it to true when we see
   201      * MethodParameters, if it's set when we see a LocalVariableTable,
   202      * then we ignore the parameter names from the LVT.
   203      */
   204     boolean sawMethodParameters;
   205 
   206     /**
   207      * The set of attribute names for which warnings have been generated for the current class
   208      */
   209     Set<Name> warnedAttrs = new HashSet<>();
   210 
   211     /**
   212      * The prototype @Target Attribute.Compound if this class is an annotation annotated with
   213      * @Target
   214      */
   215     CompoundAnnotationProxy target;
   216 
   217     /**
   218      * The prototype @Repetable Attribute.Compound if this class is an annotation annotated with
   219      * @Repeatable
   220      */
   221     CompoundAnnotationProxy repeatable;
   222 
   223     /** Get the ClassReader instance for this invocation. */
   224     public static ClassReader instance(Context context) {
   225         ClassReader instance = context.get(classReaderKey);
   226         if (instance == null)
   227             instance = new ClassReader(context);
   228         return instance;
   229     }
   230 
   231     /** Construct a new class reader. */
   232     protected ClassReader(Context context) {
   233         context.put(classReaderKey, this);
   234         annotate = Annotate.instance(context);
   235         names = Names.instance(context);
   236         syms = Symtab.instance(context);
   237         types = Types.instance(context);
   238         fileManager = context.get(JavaFileManager.class);
   239         if (fileManager == null)
   240             throw new AssertionError("FileManager initialization error");
   241         diagFactory = JCDiagnostic.Factory.instance(context);
   242 
   243         log = Log.instance(context);
   244 
   245         Options options = Options.instance(context);
   246         verbose         = options.isSet(Option.VERBOSE);
   247 
   248         ideMode = options.get("ide") != null;
   249         Source source = Source.instance(context);
   250         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
   251         allowModules     = source.allowModules();
   252 
   253         saveParameterNames = options.isSet(PARAMETERS);
   254 
   255         profile = Profile.instance(context);
   256 
   257         typevars = WriteableScope.create(syms.noSymbol);
   258 
   259         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
   260 
   261         initAttributeReaders();
   262     }
   263 
   264     /** Add member to class unless it is synthetic.
   265      */
   266     private void enterMember(ClassSymbol c, Symbol sym) {
   267         // Synthetic members are not entered -- reason lost to history (optimization?).
   268         // Lambda methods must be entered because they may have inner classes (which reference them)
   269         if ((sym.flags_field & (SYNTHETIC|BRIDGE)) != SYNTHETIC || sym.name.startsWith(names.lambda))
   270             c.members_field.enter(sym);
   271     }
   272 
   273 /************************************************************************
   274  * Error Diagnoses
   275  ***********************************************************************/
   276 
   277     public ClassFinder.BadClassFile badClassFile(String key, Object... args) {
   278         return new ClassFinder.BadClassFile (
   279             currentOwner.enclClass(),
   280             currentClassFile,
   281             diagFactory.fragment(key, args),
   282             diagFactory);
   283     }
   284 
   285     public ClassFinder.BadEnclosingMethodAttr badEnclosingMethod(Object... args) {
   286         return new ClassFinder.BadEnclosingMethodAttr (
   287             currentOwner.enclClass(),
   288             currentClassFile,
   289             diagFactory.fragment("bad.enclosing.method", args),
   290             diagFactory);
   291     }
   292 
   293 /************************************************************************
   294  * Buffer Access
   295  ***********************************************************************/
   296 
   297     /** Read a character.
   298      */
   299     protected char nextChar() {
   300         return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF));
   301     }
   302 
   303     /** Read a byte.
   304      */
   305     int nextByte() {
   306         return buf[bp++] & 0xFF;
   307     }
   308 
   309     /** Read an integer.
   310      */
   311     int nextInt() {
   312         return
   313             ((buf[bp++] & 0xFF) << 24) +
   314             ((buf[bp++] & 0xFF) << 16) +
   315             ((buf[bp++] & 0xFF) << 8) +
   316             (buf[bp++] & 0xFF);
   317     }
   318 
   319     /** Extract a character at position bp from buf.
   320      */
   321     char getChar(int bp) {
   322         return
   323             (char)(((buf[bp] & 0xFF) << 8) + (buf[bp+1] & 0xFF));
   324     }
   325 
   326     /** Extract an integer at position bp from buf.
   327      */
   328     int getInt(int bp) {
   329         return
   330             ((buf[bp] & 0xFF) << 24) +
   331             ((buf[bp+1] & 0xFF) << 16) +
   332             ((buf[bp+2] & 0xFF) << 8) +
   333             (buf[bp+3] & 0xFF);
   334     }
   335 
   336 
   337     /** Extract a long integer at position bp from buf.
   338      */
   339     long getLong(int bp) {
   340         DataInputStream bufin =
   341             new DataInputStream(new ByteArrayInputStream(buf, bp, 8));
   342         try {
   343             return bufin.readLong();
   344         } catch (IOException e) {
   345             throw new AssertionError(e);
   346         }
   347     }
   348 
   349     /** Extract a float at position bp from buf.
   350      */
   351     float getFloat(int bp) {
   352         DataInputStream bufin =
   353             new DataInputStream(new ByteArrayInputStream(buf, bp, 4));
   354         try {
   355             return bufin.readFloat();
   356         } catch (IOException e) {
   357             throw new AssertionError(e);
   358         }
   359     }
   360 
   361     /** Extract a double at position bp from buf.
   362      */
   363     double getDouble(int bp) {
   364         DataInputStream bufin =
   365             new DataInputStream(new ByteArrayInputStream(buf, bp, 8));
   366         try {
   367             return bufin.readDouble();
   368         } catch (IOException e) {
   369             throw new AssertionError(e);
   370         }
   371     }
   372 
   373 /************************************************************************
   374  * Constant Pool Access
   375  ***********************************************************************/
   376 
   377     /** Index all constant pool entries, writing their start addresses into
   378      *  poolIdx.
   379      */
   380     void indexPool() {
   381         poolIdx = new int[nextChar()];
   382         poolObj = new Object[poolIdx.length];
   383         int i = 1;
   384         while (i < poolIdx.length) {
   385             poolIdx[i++] = bp;
   386             byte tag = buf[bp++];
   387             switch (tag) {
   388             case CONSTANT_Utf8: case CONSTANT_Unicode: {
   389                 int len = nextChar();
   390                 bp = bp + len;
   391                 break;
   392             }
   393             case CONSTANT_Class:
   394             case CONSTANT_String:
   395             case CONSTANT_MethodType:
   396             case CONSTANT_Module:
   397             case CONSTANT_Package:
   398                 bp = bp + 2;
   399                 break;
   400             case CONSTANT_MethodHandle:
   401                 bp = bp + 3;
   402                 break;
   403             case CONSTANT_Fieldref:
   404             case CONSTANT_Methodref:
   405             case CONSTANT_InterfaceMethodref:
   406             case CONSTANT_NameandType:
   407             case CONSTANT_Integer:
   408             case CONSTANT_Float:
   409             case CONSTANT_InvokeDynamic:
   410                 bp = bp + 4;
   411                 break;
   412             case CONSTANT_Long:
   413             case CONSTANT_Double:
   414                 bp = bp + 8;
   415                 i++;
   416                 break;
   417             default:
   418                 throw badClassFile("bad.const.pool.tag.at",
   419                                    Byte.toString(tag),
   420                                    Integer.toString(bp -1));
   421             }
   422         }
   423     }
   424 
   425     /** Read constant pool entry at start address i, use pool as a cache.
   426      */
   427     Object readPool(int i) {
   428         Object result = poolObj[i];
   429         if (result != null) return result;
   430 
   431         int index = poolIdx[i];
   432         if (index == 0) return null;
   433 
   434         byte tag = buf[index];
   435         switch (tag) {
   436         case CONSTANT_Utf8:
   437             poolObj[i] = names.fromUtf(buf, index + 3, getChar(index + 1));
   438             break;
   439         case CONSTANT_Unicode:
   440             throw badClassFile("unicode.str.not.supported");
   441         case CONSTANT_Class:
   442             poolObj[i] = readClassOrType(getChar(index + 1));
   443             break;
   444         case CONSTANT_String:
   445             // FIXME: (footprint) do not use toString here
   446             poolObj[i] = readName(getChar(index + 1)).toString();
   447             break;
   448         case CONSTANT_Fieldref: {
   449             ClassSymbol owner = readClassSymbol(getChar(index + 1));
   450             NameAndType nt = readNameAndType(getChar(index + 3));
   451             poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner);
   452             break;
   453         }
   454         case CONSTANT_Methodref:
   455         case CONSTANT_InterfaceMethodref: {
   456             ClassSymbol owner = readClassSymbol(getChar(index + 1));
   457             NameAndType nt = readNameAndType(getChar(index + 3));
   458             poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner);
   459             break;
   460         }
   461         case CONSTANT_NameandType:
   462             poolObj[i] = new NameAndType(
   463                 readName(getChar(index + 1)),
   464                 readType(getChar(index + 3)), types);
   465             break;
   466         case CONSTANT_Integer:
   467             poolObj[i] = getInt(index + 1);
   468             break;
   469         case CONSTANT_Float:
   470             poolObj[i] = Float.valueOf(getFloat(index + 1));
   471             break;
   472         case CONSTANT_Long:
   473             poolObj[i] = Long.valueOf(getLong(index + 1));
   474             break;
   475         case CONSTANT_Double:
   476             poolObj[i] = Double.valueOf(getDouble(index + 1));
   477             break;
   478         case CONSTANT_MethodHandle:
   479             skipBytes(4);
   480             break;
   481         case CONSTANT_MethodType:
   482             skipBytes(3);
   483             break;
   484         case CONSTANT_InvokeDynamic:
   485             skipBytes(5);
   486             break;
   487         case CONSTANT_Module:
   488         case CONSTANT_Package:
   489             // this is temporary for now: treat as a simple reference to the underlying Utf8.
   490             poolObj[i] = readName(getChar(index + 1));
   491             break;
   492         default:
   493             throw badClassFile("bad.const.pool.tag", Byte.toString(tag));
   494         }
   495         return poolObj[i];
   496     }
   497 
   498     /** Read signature and convert to type.
   499      */
   500     protected Type readType(int i) {
   501         int index = poolIdx[i];
   502         return sigToType(buf, index + 3, getChar(index + 1));
   503     }
   504 
   505     /** If name is an array type or class signature, return the
   506      *  corresponding type; otherwise return a ClassSymbol with given name.
   507      */
   508     Object readClassOrType(int i) {
   509         int index =  poolIdx[i];
   510         int len = getChar(index + 1);
   511         int start = index + 3;
   512         Assert.check(buf[start] == '[' || buf[start + len - 1] != ';');
   513         // by the above assertion, the following test can be
   514         // simplified to (buf[start] == '[')
   515         return (buf[start] == '[' || buf[start + len - 1] == ';')
   516             ? (Object)sigToType(buf, start, len)
   517             : (Object)enterClass(names.fromUtf(internalize(buf, start,
   518                                                            len)));
   519     }
   520 
   521     /** Read signature and convert to type parameters.
   522      */
   523     List<Type> readTypeParams(int i) {
   524         int index = poolIdx[i];
   525         return sigToTypeParams(buf, index + 3, getChar(index + 1));
   526     }
   527 
   528     /** Read class entry.
   529      */
   530     ClassSymbol readClassSymbol(int i) {
   531         Object obj = readPool(i);
   532         if (obj != null && !(obj instanceof ClassSymbol))
   533             throw badClassFile("bad.const.pool.entry",
   534                                currentClassFile.toString(),
   535                                "CONSTANT_Class_info", i);
   536         return (ClassSymbol)obj;
   537     }
   538 
   539     Name readClassName(int i) {
   540         int index = poolIdx[i];
   541         if (index == 0) return null;
   542         byte tag = buf[index];
   543         if (tag != CONSTANT_Class) {
   544             throw badClassFile("bad.const.pool.entry",
   545                                currentClassFile.toString(),
   546                                "CONSTANT_Class_info", i);
   547         }
   548         int nameIndex =  poolIdx[getChar(index + 1)];
   549         int len = getChar(nameIndex + 1);
   550         int start = nameIndex + 3;
   551         if (buf[start] == '[' || buf[start + len - 1] == ';')
   552             throw badClassFile("wrong class name"); //TODO: proper diagnostics
   553         return names.fromUtf(internalize(buf, start, len));
   554     }
   555 
   556     /** Read name.
   557      */
   558     protected Name readName(int i) {
   559         Object obj = readPool(i);
   560         if (obj != null && !(obj instanceof Name))
   561             throw badClassFile("bad.const.pool.entry",
   562                                currentClassFile.toString(),
   563                                "CONSTANT_Utf8_info or CONSTANT_String_info", i);
   564         return (Name)obj;
   565     }
   566 
   567     /** Read name and type.
   568      */
   569     NameAndType readNameAndType(int i) {
   570         Object obj = readPool(i);
   571         if (obj != null && !(obj instanceof NameAndType))
   572             throw badClassFile("bad.const.pool.entry",
   573                                currentClassFile.toString(),
   574                                "CONSTANT_NameAndType_info", i);
   575         return (NameAndType)obj;
   576     }
   577 
   578     /** Read the name of a module.
   579      * The name is stored in a CONSTANT_Module entry, in
   580      * JVMS 4.2 binary form (using ".", not "/")
   581      */
   582     Name readModuleName(int i) {
   583         return readName(i);
   584     }
   585 
   586     /** Read module_flags.
   587      */
   588     Set<ModuleFlags> readModuleFlags(int flags) {
   589         Set<ModuleFlags> set = EnumSet.noneOf(ModuleFlags.class);
   590         for (ModuleFlags f : ModuleFlags.values()) {
   591             if ((flags & f.value) != 0)
   592                 set.add(f);
   593         }
   594         return set;
   595     }
   596 
   597     /** Read resolution_flags.
   598      */
   599     Set<ModuleResolutionFlags> readModuleResolutionFlags(int flags) {
   600         Set<ModuleResolutionFlags> set = EnumSet.noneOf(ModuleResolutionFlags.class);
   601         for (ModuleResolutionFlags f : ModuleResolutionFlags.values()) {
   602             if ((flags & f.value) != 0)
   603                 set.add(f);
   604         }
   605         return set;
   606     }
   607 
   608     /** Read exports_flags.
   609      */
   610     Set<ExportsFlag> readExportsFlags(int flags) {
   611         Set<ExportsFlag> set = EnumSet.noneOf(ExportsFlag.class);
   612         for (ExportsFlag f: ExportsFlag.values()) {
   613             if ((flags & f.value) != 0)
   614                 set.add(f);
   615         }
   616         return set;
   617     }
   618 
   619     /** Read opens_flags.
   620      */
   621     Set<OpensFlag> readOpensFlags(int flags) {
   622         Set<OpensFlag> set = EnumSet.noneOf(OpensFlag.class);
   623         for (OpensFlag f: OpensFlag.values()) {
   624             if ((flags & f.value) != 0)
   625                 set.add(f);
   626         }
   627         return set;
   628     }
   629 
   630     /** Read requires_flags.
   631      */
   632     Set<RequiresFlag> readRequiresFlags(int flags) {
   633         Set<RequiresFlag> set = EnumSet.noneOf(RequiresFlag.class);
   634         for (RequiresFlag f: RequiresFlag.values()) {
   635             if ((flags & f.value) != 0)
   636                 set.add(f);
   637         }
   638         return set;
   639     }
   640 
   641 /************************************************************************
   642  * Reading Types
   643  ***********************************************************************/
   644 
   645     /** The unread portion of the currently read type is
   646      *  signature[sigp..siglimit-1].
   647      */
   648     byte[] signature;
   649     int sigp;
   650     int siglimit;
   651     boolean sigEnterPhase = false;
   652 
   653     /** Convert signature to type, where signature is a byte array segment.
   654      */
   655     Type sigToType(byte[] sig, int offset, int len) {
   656         signature = sig;
   657         sigp = offset;
   658         siglimit = offset + len;
   659         return sigToType();
   660     }
   661 
   662     /** Convert signature to type, where signature is implicit.
   663      */
   664     Type sigToType() {
   665         switch ((char) signature[sigp]) {
   666         case 'T':
   667             sigp++;
   668             int start = sigp;
   669             while (signature[sigp] != ';') sigp++;
   670             sigp++;
   671             return sigEnterPhase
   672                 ? Type.noType
   673                 : findTypeVar(names.fromUtf(signature, start, sigp - 1 - start));
   674         case '+': {
   675             sigp++;
   676             Type t = sigToType();
   677             return new WildcardType(t, BoundKind.EXTENDS, syms.boundClass);
   678         }
   679         case '*':
   680             sigp++;
   681             return new WildcardType(syms.objectType, BoundKind.UNBOUND,
   682                                     syms.boundClass);
   683         case '-': {
   684             sigp++;
   685             Type t = sigToType();
   686             return new WildcardType(t, BoundKind.SUPER, syms.boundClass);
   687         }
   688         case 'B':
   689             sigp++;
   690             return syms.byteType;
   691         case 'C':
   692             sigp++;
   693             return syms.charType;
   694         case 'D':
   695             sigp++;
   696             return syms.doubleType;
   697         case 'F':
   698             sigp++;
   699             return syms.floatType;
   700         case 'I':
   701             sigp++;
   702             return syms.intType;
   703         case 'J':
   704             sigp++;
   705             return syms.longType;
   706         case 'R':
   707         case 'L':
   708             {
   709                 // int oldsigp = sigp;
   710                 Type t = classSigToType();
   711                 if (sigp < siglimit && signature[sigp] == '.')
   712                     throw badClassFile("deprecated inner class signature syntax " +
   713                                        "(please recompile from source)");
   714                 /*
   715                 System.err.println(" decoded " +
   716                                    new String(signature, oldsigp, sigp-oldsigp) +
   717                                    " => " + t + " outer " + t.outer());
   718                 */
   719                 return t;
   720             }
   721         case 'S':
   722             sigp++;
   723             return syms.shortType;
   724         case 'V':
   725             sigp++;
   726             return syms.voidType;
   727         case 'Z':
   728             sigp++;
   729             return syms.booleanType;
   730         case '[':
   731             sigp++;
   732             return new ArrayType(sigToType(), syms.arrayClass);
   733         case '(':
   734             sigp++;
   735             List<Type> argtypes = sigToTypes(')');
   736             Type restype = sigToType();
   737             List<Type> thrown = List.nil();
   738             while (signature[sigp] == '^') {
   739                 sigp++;
   740                 thrown = thrown.prepend(sigToType());
   741             }
   742             // if there is a typevar in the throws clause we should state it.
   743             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail) {
   744                 if (l.head.hasTag(TYPEVAR)) {
   745                     l.head.tsym.flags_field |= THROWS;
   746                 }
   747             }
   748             return new MethodType(argtypes,
   749                                   restype,
   750                                   thrown.reverse(),
   751                                   syms.methodClass);
   752         case '<':
   753             typevars = typevars.dup(currentOwner);
   754             Type poly = new ForAll(sigToTypeParams(), sigToType());
   755             typevars = typevars.leave();
   756             return poly;
   757         default:
   758             throw badClassFile("bad.signature",
   759                                Convert.utf2string(signature, sigp, 10));
   760         }
   761     }
   762 
   763     byte[] signatureBuffer = new byte[0];
   764     int sbp = 0;
   765     /** Convert class signature to type, where signature is implicit.
   766      */
   767     Type classSigToType() {
   768         if (signature[sigp] != 'L' && signature[sigp] != 'R')
   769             throw badClassFile("bad.class.signature",
   770                                Convert.utf2string(signature, sigp, 10));
   771         boolean err = signature[sigp] == 'R';
   772         sigp++;
   773         Type outer = Type.noType;
   774         int startSbp = sbp;
   775 
   776         while (true) {
   777             final byte c = signature[sigp++];
   778             switch (c) {
   779 
   780             case ';': {         // end
   781                 ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
   782                                                          startSbp,
   783                                                          sbp - startSbp));
   784 
   785                 try {
   786                     return err ? new ErrorType(Type.noType, t) :
   787                             (outer == Type.noType) ?
   788                             t.erasure(types) :
   789                         new ClassType(outer, List.nil(), t);
   790                 } finally {
   791                     sbp = startSbp;
   792                 }
   793             }
   794 
   795             case '<':           // generic arguments
   796                 ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
   797                                                          startSbp,
   798                                                          sbp - startSbp));
   799                 outer = new ClassType(outer, sigToTypes('>'), t) {
   800                         boolean completed = false;
   801                         @Override @DefinedBy(Api.LANGUAGE_MODEL)
   802                         public Type getEnclosingType() {
   803                             if (!completed) {
   804                                 completed = true;
   805                                 try {
   806                                     tsym.complete();
   807                                 } catch (CompletionFailure cf) {}
   808                                 Type enclosingType = tsym.type.getEnclosingType();
   809                                 if (enclosingType != Type.noType) {
   810                                     List<Type> typeArgs =
   811                                         super.getEnclosingType().allparams();
   812                                     List<Type> typeParams =
   813                                         enclosingType.allparams();
   814                                     if (typeParams.length() != typeArgs.length()) {
   815                                         // no "rare" types
   816                                         super.setEnclosingType(types.erasure(enclosingType));
   817                                     } else {
   818                                         super.setEnclosingType(types.subst(enclosingType,
   819                                                                            typeParams,
   820                                                                            typeArgs));
   821                                     }
   822                                 } else {
   823                                     super.setEnclosingType(Type.noType);
   824                                 }
   825                             }
   826                             return super.getEnclosingType();
   827                         }
   828                         @Override
   829                         public void setEnclosingType(Type outer) {
   830                             throw new UnsupportedOperationException();
   831                         }
   832                     };
   833                 switch (signature[sigp++]) {
   834                 case ';':
   835                     if (sigp < signature.length && signature[sigp] == '.') {
   836                         // support old-style GJC signatures
   837                         // The signature produced was
   838                         // Lfoo/Outer<Lfoo/X;>;.Lfoo/Outer$Inner<Lfoo/Y;>;
   839                         // rather than say
   840                         // Lfoo/Outer<Lfoo/X;>.Inner<Lfoo/Y;>;
   841                         // so we skip past ".Lfoo/Outer$"
   842                         sigp += (sbp - startSbp) + // "foo/Outer"
   843                             3;  // ".L" and "$"
   844                         signatureBuffer[sbp++] = (byte)'$';
   845                         break;
   846                     } else {
   847                         sbp = startSbp;
   848                         return outer;
   849                     }
   850                 case '.':
   851                     signatureBuffer[sbp++] = (byte)'$';
   852                     break;
   853                 default:
   854                     throw new AssertionError(signature[sigp-1]);
   855                 }
   856                 continue;
   857 
   858             case '.':
   859                 //we have seen an enclosing non-generic class
   860                 if (outer != Type.noType) {
   861                     t = enterClass(names.fromUtf(signatureBuffer,
   862                                                  startSbp,
   863                                                  sbp - startSbp));
   864                     outer = new ClassType(outer, List.nil(), t);
   865                 }
   866                 signatureBuffer[sbp++] = (byte)'$';
   867                 continue;
   868             case '/':
   869                 signatureBuffer[sbp++] = (byte)'.';
   870                 continue;
   871             default:
   872                 signatureBuffer[sbp++] = c;
   873                 continue;
   874             }
   875         }
   876     }
   877 
   878     /** Convert (implicit) signature to list of types
   879      *  until `terminator' is encountered.
   880      */
   881     List<Type> sigToTypes(char terminator) {
   882         List<Type> head = List.of(null);
   883         List<Type> tail = head;
   884         while (signature[sigp] != terminator)
   885             tail = tail.setTail(List.of(sigToType()));
   886         sigp++;
   887         return head.tail;
   888     }
   889 
   890     /** Convert signature to type parameters, where signature is a byte
   891      *  array segment.
   892      */
   893     List<Type> sigToTypeParams(byte[] sig, int offset, int len) {
   894         signature = sig;
   895         sigp = offset;
   896         siglimit = offset + len;
   897         return sigToTypeParams();
   898     }
   899 
   900     /** Convert signature to type parameters, where signature is implicit.
   901      */
   902     List<Type> sigToTypeParams() {
   903         List<Type> tvars = List.nil();
   904         if (signature[sigp] == '<') {
   905             sigp++;
   906             int start = sigp;
   907             sigEnterPhase = true;
   908             while (signature[sigp] != '>')
   909                 tvars = tvars.prepend(sigToTypeParam());
   910             sigEnterPhase = false;
   911             sigp = start;
   912             while (signature[sigp] != '>')
   913                 sigToTypeParam();
   914             sigp++;
   915         }
   916         return tvars.reverse();
   917     }
   918 
   919     /** Convert (implicit) signature to type parameter.
   920      */
   921     Type sigToTypeParam() {
   922         int start = sigp;
   923         while (signature[sigp] != ':') sigp++;
   924         Name name = names.fromUtf(signature, start, sigp - start);
   925         TypeVar tvar;
   926         if (sigEnterPhase) {
   927             tvar = new TypeVar(name, currentOwner, syms.botType);
   928             typevars.enter(tvar.tsym);
   929         } else {
   930             tvar = (TypeVar)findTypeVar(name);
   931         }
   932         List<Type> bounds = List.nil();
   933         boolean allInterfaces = false;
   934         if (signature[sigp] == ':' && signature[sigp+1] == ':') {
   935             sigp++;
   936             allInterfaces = true;
   937         }
   938         while (signature[sigp] == ':') {
   939             sigp++;
   940             bounds = bounds.prepend(sigToType());
   941         }
   942         if (!sigEnterPhase) {
   943             types.setBounds(tvar, bounds.reverse(), allInterfaces);
   944         }
   945         return tvar;
   946     }
   947 
   948     /** Find type variable with given name in `typevars' scope.
   949      */
   950     Type findTypeVar(Name name) {
   951         Symbol s = typevars.findFirst(name);
   952         if (s != null) {
   953             return s.type;
   954         } else {
   955             if (readingClassAttr) {
   956                 // While reading the class attribute, the supertypes
   957                 // might refer to a type variable from an enclosing element
   958                 // (method or class).
   959                 // If the type variable is defined in the enclosing class,
   960                 // we can actually find it in
   961                 // currentOwner.owner.type.getTypeArguments()
   962                 // However, until we have read the enclosing method attribute
   963                 // we don't know for sure if this owner is correct.  It could
   964                 // be a method and there is no way to tell before reading the
   965                 // enclosing method attribute.
   966                 TypeVar t = new TypeVar(name, currentOwner, syms.botType);
   967                 missingTypeVariables = missingTypeVariables.prepend(t);
   968                 // System.err.println("Missing type var " + name);
   969                 return t;
   970             }
   971             throw badClassFile("undecl.type.var", name);
   972         }
   973     }
   974 
   975 /************************************************************************
   976  * Reading Attributes
   977  ***********************************************************************/
   978 
   979     protected enum AttributeKind { CLASS, MEMBER }
   980 
   981     protected abstract class AttributeReader {
   982         protected AttributeReader(Name name, ClassFile.Version version, Set<AttributeKind> kinds) {
   983             this.name = name;
   984             this.version = version;
   985             this.kinds = kinds;
   986         }
   987 
   988         protected boolean accepts(AttributeKind kind) {
   989             if (kinds.contains(kind)) {
   990                 if (majorVersion > version.major || (majorVersion == version.major && minorVersion >= version.minor))
   991                     return true;
   992 
   993                 if (lintClassfile && !warnedAttrs.contains(name)) {
   994                     JavaFileObject prev = log.useSource(currentClassFile);
   995                     try {
   996                         log.warning(LintCategory.CLASSFILE, (DiagnosticPosition) null, "future.attr",
   997                                 name, version.major, version.minor, majorVersion, minorVersion);
   998                     } finally {
   999                         log.useSource(prev);
  1000                     }
  1001                     warnedAttrs.add(name);
  1002                 }
  1003                 
  1004                 return ideMode;
  1005             }
  1006             return false;
  1007         }
  1008 
  1009         protected abstract void read(Symbol sym, int attrLen);
  1010 
  1011         protected final Name name;
  1012         protected final ClassFile.Version version;
  1013         protected final Set<AttributeKind> kinds;
  1014     }
  1015 
  1016     protected Set<AttributeKind> CLASS_ATTRIBUTE =
  1017             EnumSet.of(AttributeKind.CLASS);
  1018     protected Set<AttributeKind> MEMBER_ATTRIBUTE =
  1019             EnumSet.of(AttributeKind.MEMBER);
  1020     protected Set<AttributeKind> CLASS_OR_MEMBER_ATTRIBUTE =
  1021             EnumSet.of(AttributeKind.CLASS, AttributeKind.MEMBER);
  1022 
  1023     protected Map<Name, AttributeReader> attributeReaders = new HashMap<>();
  1024 
  1025     private void initAttributeReaders() {
  1026         AttributeReader[] readers = {
  1027             // v45.3 attributes
  1028 
  1029             new AttributeReader(names.Code, V45_3, MEMBER_ATTRIBUTE) {
  1030                 protected void read(Symbol sym, int attrLen) {
  1031                     if (readAllOfClassFile || saveParameterNames)
  1032                         ((MethodSymbol)sym).code = readCode(sym);
  1033                     else
  1034                         bp = bp + attrLen;
  1035                 }
  1036             },
  1037 
  1038             new AttributeReader(names.ConstantValue, V45_3, MEMBER_ATTRIBUTE) {
  1039                 protected void read(Symbol sym, int attrLen) {
  1040                     Object v = readPool(nextChar());
  1041                     // Ignore ConstantValue attribute if field not final.
  1042                     if ((sym.flags() & FINAL) == 0) {
  1043                         return;
  1044                     }
  1045                     VarSymbol var = (VarSymbol) sym;
  1046                     switch (var.type.getTag()) {
  1047                        case BOOLEAN:
  1048                        case BYTE:
  1049                        case CHAR:
  1050                        case SHORT:
  1051                        case INT:
  1052                            checkType(var, Integer.class, v);
  1053                            break;
  1054                        case LONG:
  1055                            checkType(var, Long.class, v);
  1056                            break;
  1057                        case FLOAT:
  1058                            checkType(var, Float.class, v);
  1059                            break;
  1060                        case DOUBLE:
  1061                            checkType(var, Double.class, v);
  1062                            break;
  1063                        case CLASS:
  1064                            Assert.check(var.type.tsym == syms.stringType.tsym);
  1065                            checkType(var, String.class, v);
  1066                            break;
  1067                        default:
  1068                            // ignore ConstantValue attribute if type is not primitive or String
  1069                            return;
  1070                     }
  1071                     if (v instanceof Integer && !var.type.getTag().checkRange((Integer) v)) {
  1072                         throw badClassFile("bad.constant.range", v, var, var.type);
  1073                     }
  1074                     var.setData(v);
  1075                 }
  1076 
  1077                 void checkType(Symbol var, Class<?> clazz, Object value) {
  1078                     if (!clazz.isInstance(value)) {
  1079                         throw badClassFile("bad.constant.value", value, var, clazz.getSimpleName());
  1080                     }
  1081                 }
  1082             },
  1083 
  1084             new AttributeReader(names.Deprecated, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
  1085                 protected void read(Symbol sym, int attrLen) {
  1086                     Symbol s = sym.owner.kind == MDL ? sym.owner : sym;
  1087 
  1088                     s.flags_field |= DEPRECATED;
  1089                 }
  1090             },
  1091 
  1092             new AttributeReader(names.Exceptions, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
  1093                 protected void read(Symbol sym, int attrLen) {
  1094                     int nexceptions = nextChar();
  1095                     List<Type> thrown = List.nil();
  1096                     for (int j = 0; j < nexceptions; j++)
  1097                         thrown = thrown.prepend(readClassSymbol(nextChar()).type);
  1098                     if (sym.type.getThrownTypes().isEmpty())
  1099                         sym.type.asMethodType().thrown = thrown.reverse();
  1100                 }
  1101             },
  1102 
  1103             new AttributeReader(names.InnerClasses, V45_3, CLASS_ATTRIBUTE) {
  1104                 protected void read(Symbol sym, int attrLen) {
  1105                     ClassSymbol c = (ClassSymbol) sym;
  1106                     if (currentModule.module_info == c) {
  1107                         //prevent entering the classes too soon:
  1108                         skipInnerClasses();
  1109                     } else {
  1110                         readInnerClasses(c);
  1111                     }
  1112                 }
  1113             },
  1114 
  1115             new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
  1116                 protected void read(Symbol sym, int attrLen) {
  1117                     int newbp = bp + attrLen;
  1118                     if (saveParameterNames && !sawMethodParameters) {
  1119                         // Pick up parameter names from the variable table.
  1120                         // Parameter names are not explicitly identified as such,
  1121                         // but all parameter name entries in the LocalVariableTable
  1122                         // have a start_pc of 0.  Therefore, we record the name
  1123                         // indicies of all slots with a start_pc of zero in the
  1124                         // parameterNameIndicies array.
  1125                         // Note that this implicitly honors the JVMS spec that
  1126                         // there may be more than one LocalVariableTable, and that
  1127                         // there is no specified ordering for the entries.
  1128                         int numEntries = nextChar();
  1129                         for (int i = 0; i < numEntries; i++) {
  1130                             int start_pc = nextChar();
  1131                             int length = nextChar();
  1132                             int nameIndex = nextChar();
  1133                             int sigIndex = nextChar();
  1134                             int register = nextChar();
  1135                             if (start_pc == 0) {
  1136                                 // ensure array large enough
  1137                                 if (register >= parameterNameIndices.length) {
  1138                                     int newSize =
  1139                                             Math.max(register + 1, parameterNameIndices.length + 8);
  1140                                     parameterNameIndices =
  1141                                             Arrays.copyOf(parameterNameIndices, newSize);
  1142                                 }
  1143                                 parameterNameIndices[register] = nameIndex;
  1144                                 haveParameterNameIndices = true;
  1145                             }
  1146                         }
  1147                     }
  1148                     bp = newbp;
  1149                 }
  1150             },
  1151 
  1152             new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
  1153                 protected void read(Symbol sym, int attrLen) {
  1154                     ClassSymbol c = (ClassSymbol) sym;
  1155                     Name n = readName(nextChar());
  1156                     c.sourcefile = new SourceFileObject(n, c.flatname);
  1157                     // If the class is a toplevel class, originating from a Java source file,
  1158                     // but the class name does not match the file name, then it is
  1159                     // an auxiliary class.
  1160                     String sn = n.toString();
  1161                     if (c.owner.kind == PCK &&
  1162                         sn.endsWith(".java") &&
  1163                         !sn.equals(c.name.toString()+".java")) {
  1164                         c.flags_field |= AUXILIARY;
  1165                     }
  1166                 }
  1167             },
  1168 
  1169             new AttributeReader(names.Synthetic, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
  1170                 protected void read(Symbol sym, int attrLen) {
  1171                     sym.flags_field |= SYNTHETIC;
  1172                 }
  1173             },
  1174 
  1175             // standard v49 attributes
  1176 
  1177             new AttributeReader(names.EnclosingMethod, V49, CLASS_ATTRIBUTE) {
  1178                 protected void read(Symbol sym, int attrLen) {
  1179                     int newbp = bp + attrLen;
  1180                     readEnclosingMethodAttr(sym);
  1181                     bp = newbp;
  1182                 }
  1183             },
  1184 
  1185             new AttributeReader(names.Signature, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1186                 protected void read(Symbol sym, int attrLen) {
  1187                     if (sym.kind == TYP) {
  1188                         ClassSymbol c = (ClassSymbol) sym;
  1189                         readingClassAttr = true;
  1190                         try {
  1191                             ClassType ct1 = (ClassType)c.type;
  1192                             Assert.check(c == currentOwner);
  1193                             ct1.typarams_field = readTypeParams(nextChar());
  1194                             ct1.supertype_field = sigToType();
  1195                             ListBuffer<Type> is = new ListBuffer<>();
  1196                             while (sigp != siglimit) is.append(sigToType());
  1197                             ct1.interfaces_field = is.toList();
  1198                         } finally {
  1199                             readingClassAttr = false;
  1200                         }
  1201                     } else {
  1202                         List<Type> thrown = sym.type.getThrownTypes();
  1203                         sym.type = readType(nextChar());
  1204                         //- System.err.println(" # " + sym.type);
  1205                         if (sym.kind == MTH && sym.type.getThrownTypes().isEmpty())
  1206                             sym.type.asMethodType().thrown = thrown;
  1207 
  1208                     }
  1209                 }
  1210             },
  1211 
  1212             // v49 annotation attributes
  1213 
  1214             new AttributeReader(names.AnnotationDefault, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1215                 protected void read(Symbol sym, int attrLen) {
  1216                     attachAnnotationDefault(sym);
  1217                 }
  1218             },
  1219 
  1220             new AttributeReader(names.RuntimeInvisibleAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1221                 protected void read(Symbol sym, int attrLen) {
  1222                     attachAnnotations(sym);
  1223                 }
  1224             },
  1225 
  1226             new AttributeReader(names.RuntimeInvisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1227                 protected void read(Symbol sym, int attrLen) {
  1228                     attachParameterAnnotations(sym);
  1229                 }
  1230             },
  1231 
  1232             new AttributeReader(names.RuntimeVisibleAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1233                 protected void read(Symbol sym, int attrLen) {
  1234                     attachAnnotations(sym);
  1235                 }
  1236             },
  1237 
  1238             new AttributeReader(names.RuntimeVisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1239                 protected void read(Symbol sym, int attrLen) {
  1240                     attachParameterAnnotations(sym);
  1241                 }
  1242             },
  1243 
  1244             // additional "legacy" v49 attributes, superceded by flags
  1245 
  1246             new AttributeReader(names.Annotation, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1247                 protected void read(Symbol sym, int attrLen) {
  1248                     sym.flags_field |= ANNOTATION;
  1249                 }
  1250             },
  1251 
  1252             new AttributeReader(names.Bridge, V49, MEMBER_ATTRIBUTE) {
  1253                 protected void read(Symbol sym, int attrLen) {
  1254                     sym.flags_field |= BRIDGE;
  1255                 }
  1256             },
  1257 
  1258             new AttributeReader(names.Enum, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1259                 protected void read(Symbol sym, int attrLen) {
  1260                     sym.flags_field |= ENUM;
  1261                 }
  1262             },
  1263 
  1264             new AttributeReader(names.Varargs, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
  1265                 protected void read(Symbol sym, int attrLen) {
  1266                     sym.flags_field |= VARARGS;
  1267                 }
  1268             },
  1269 
  1270             new AttributeReader(names.RuntimeVisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) {
  1271                 protected void read(Symbol sym, int attrLen) {
  1272                     attachTypeAnnotations(sym);
  1273                 }
  1274             },
  1275 
  1276             new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) {
  1277                 protected void read(Symbol sym, int attrLen) {
  1278                     attachTypeAnnotations(sym);
  1279                 }
  1280             },
  1281 
  1282             // The following attributes for a Code attribute are not currently handled
  1283             // StackMapTable
  1284             // SourceDebugExtension
  1285             // LineNumberTable
  1286             // LocalVariableTypeTable
  1287 
  1288             // standard v52 attributes
  1289 
  1290             new AttributeReader(names.MethodParameters, V52, MEMBER_ATTRIBUTE) {
  1291                 protected void read(Symbol sym, int attrlen) {
  1292                     int newbp = bp + attrlen;
  1293                     if (saveParameterNames) {
  1294                         sawMethodParameters = true;
  1295                         int numEntries = nextByte();
  1296                         parameterNameIndices = new int[numEntries];
  1297                         haveParameterNameIndices = true;
  1298                         for (int i = 0; i < numEntries; i++) {
  1299                             int nameIndex = nextChar();
  1300                             int flags = nextChar();
  1301                             parameterNameIndices[i] = nameIndex;
  1302                         }
  1303                     }
  1304                     bp = newbp;
  1305                 }
  1306             },
  1307 
  1308             // standard v53 attributes
  1309 
  1310             new AttributeReader(names.Module, V53, CLASS_ATTRIBUTE) {
  1311                 @Override
  1312                 protected boolean accepts(AttributeKind kind) {
  1313                     return super.accepts(kind) && allowModules;
  1314                 }
  1315                 protected void read(Symbol sym, int attrLen) {
  1316                     if (sym.kind == TYP && sym.owner.kind == MDL) {
  1317                         ModuleSymbol msym = (ModuleSymbol) sym.owner;
  1318                         ListBuffer<Directive> directives = new ListBuffer<>();
  1319 
  1320                         Name moduleName = readModuleName(nextChar());
  1321                         if (currentModule.name != moduleName) {
  1322                             throw badClassFile("module.name.mismatch", moduleName, currentModule.name);
  1323                         }
  1324 
  1325                         msym.flags.addAll(readModuleFlags(nextChar()));
  1326                         msym.version = readName(nextChar());
  1327 
  1328                         ListBuffer<RequiresDirective> requires = new ListBuffer<>();
  1329                         int nrequires = nextChar();
  1330                         for (int i = 0; i < nrequires; i++) {
  1331                             ModuleSymbol rsym = syms.enterModule(readModuleName(nextChar()));
  1332                             Set<RequiresFlag> flags = readRequiresFlags(nextChar());
  1333                             nextChar(); // skip compiled version
  1334                             requires.add(new RequiresDirective(rsym, flags));
  1335                         }
  1336                         msym.requires = requires.toList();
  1337                         directives.addAll(msym.requires);
  1338 
  1339                         ListBuffer<ExportsDirective> exports = new ListBuffer<>();
  1340                         int nexports = nextChar();
  1341                         for (int i = 0; i < nexports; i++) {
  1342                             Name n = readName(nextChar());
  1343                             PackageSymbol p = syms.enterPackage(currentModule, names.fromUtf(internalize(n)));
  1344                             Set<ExportsFlag> flags = readExportsFlags(nextChar());
  1345                             int nto = nextChar();
  1346                             List<ModuleSymbol> to;
  1347                             if (nto == 0) {
  1348                                 to = null;
  1349                             } else {
  1350                                 ListBuffer<ModuleSymbol> lb = new ListBuffer<>();
  1351                                 for (int t = 0; t < nto; t++)
  1352                                     lb.append(syms.enterModule(readModuleName(nextChar())));
  1353                                 to = lb.toList();
  1354                             }
  1355                             exports.add(new ExportsDirective(p, to, flags));
  1356                         }
  1357                         msym.exports = exports.toList();
  1358                         directives.addAll(msym.exports);
  1359                         ListBuffer<OpensDirective> opens = new ListBuffer<>();
  1360                         int nopens = nextChar();
  1361                         if (nopens != 0 && msym.flags.contains(ModuleFlags.OPEN)) {
  1362                             throw badClassFile("module.non.zero.opens", currentModule.name);
  1363                         }
  1364                         for (int i = 0; i < nopens; i++) {
  1365                             Name n = readName(nextChar());
  1366                             PackageSymbol p = syms.enterPackage(currentModule, names.fromUtf(internalize(n)));
  1367                             Set<OpensFlag> flags = readOpensFlags(nextChar());
  1368                             int nto = nextChar();
  1369                             List<ModuleSymbol> to;
  1370                             if (nto == 0) {
  1371                                 to = null;
  1372                             } else {
  1373                                 ListBuffer<ModuleSymbol> lb = new ListBuffer<>();
  1374                                 for (int t = 0; t < nto; t++)
  1375                                     lb.append(syms.enterModule(readModuleName(nextChar())));
  1376                                 to = lb.toList();
  1377                             }
  1378                             opens.add(new OpensDirective(p, to, flags));
  1379                         }
  1380                         msym.opens = opens.toList();
  1381                         directives.addAll(msym.opens);
  1382 
  1383                         msym.directives = directives.toList();
  1384 
  1385                         ListBuffer<InterimUsesDirective> uses = new ListBuffer<>();
  1386                         int nuses = nextChar();
  1387                         for (int i = 0; i < nuses; i++) {
  1388                             Name srvc = readClassName(nextChar());
  1389                             uses.add(new InterimUsesDirective(srvc));
  1390                         }
  1391                         interimUses = uses.toList();
  1392 
  1393                         ListBuffer<InterimProvidesDirective> provides = new ListBuffer<>();
  1394                         int nprovides = nextChar();
  1395                         for (int p = 0; p < nprovides; p++) {
  1396                             Name srvc = readClassName(nextChar());
  1397                             int nimpls = nextChar();
  1398                             ListBuffer<Name> impls = new ListBuffer<>();
  1399                             for (int i = 0; i < nimpls; i++) {
  1400                                 impls.append(readClassName(nextChar()));
  1401                             provides.add(new InterimProvidesDirective(srvc, impls.toList()));
  1402                             }
  1403                         }
  1404                         interimProvides = provides.toList();
  1405                     }
  1406                 }
  1407             },
  1408 
  1409             new AttributeReader(names.ModuleResolution, V53, CLASS_ATTRIBUTE) {
  1410                 @Override
  1411                 protected boolean accepts(AttributeKind kind) {
  1412                     return super.accepts(kind) && allowModules;
  1413                 }
  1414                 protected void read(Symbol sym, int attrLen) {
  1415                     if (sym.kind == TYP && sym.owner.kind == MDL) {
  1416                         ModuleSymbol msym = (ModuleSymbol) sym.owner;
  1417                         msym.resolutionFlags.addAll(readModuleResolutionFlags(nextChar()));
  1418                     }
  1419                 }
  1420             },
  1421         };
  1422 
  1423         for (AttributeReader r: readers)
  1424             attributeReaders.put(r.name, r);
  1425     }
  1426 
  1427     protected void readEnclosingMethodAttr(Symbol sym) {
  1428         // sym is a nested class with an "Enclosing Method" attribute
  1429         // remove sym from it's current owners scope and place it in
  1430         // the scope specified by the attribute
  1431         if (sym.owner.members() != null) {
  1432             sym.owner.members().remove(sym);
  1433         }
  1434         ClassSymbol self = (ClassSymbol)sym;
  1435         ClassSymbol c = readClassSymbol(nextChar());
  1436         NameAndType nt = readNameAndType(nextChar());
  1437 
  1438         if (c.members_field == null || c.kind != TYP)
  1439             throw badClassFile("bad.enclosing.class", self, c);
  1440 
  1441         MethodSymbol m = findMethod(nt, c.members_field, self.flags());
  1442         if (nt != null && m == null)
  1443             throw badEnclosingMethod(self);
  1444 
  1445         self.name = simpleBinaryName(self.flatname, c.flatname) ;
  1446         self.owner = m != null ? m : c;
  1447         if (self.name.isEmpty())
  1448             self.fullname = names.empty;
  1449         else
  1450             self.fullname = ClassSymbol.formFullName(self.name, self.owner);
  1451 
  1452         if (c.classfile != null && c.classfile.getKind() == JavaFileObject.Kind.SOURCE)
  1453             throw new Abort();
  1454 
  1455         if (m != null) {
  1456             ((ClassType)sym.type).setEnclosingType(m.type);
  1457         } else if ((self.flags_field & STATIC) == 0) {
  1458             ((ClassType)sym.type).setEnclosingType(c.type);
  1459         } else {
  1460             ((ClassType)sym.type).setEnclosingType(Type.noType);
  1461         }
  1462         enterTypevars(self, self.type);
  1463         if (!missingTypeVariables.isEmpty()) {
  1464             ListBuffer<Type> typeVars =  new ListBuffer<>();
  1465             for (Type typevar : missingTypeVariables) {
  1466                 typeVars.append(findTypeVar(typevar.tsym.name));
  1467             }
  1468             foundTypeVariables = typeVars.toList();
  1469         } else {
  1470             foundTypeVariables = List.nil();
  1471         }
  1472     }
  1473 
  1474     // See java.lang.Class
  1475     protected Name simpleBinaryName(Name self, Name enclosing) {
  1476         String selfStr = self.toString();
  1477         String enclStr = enclosing.toString();
  1478         if (selfStr.length() <= enclStr.length())
  1479             throw badClassFile("bad.enclosing.method", self);
  1480         String simpleBinaryName = selfStr.substring(enclStr.length());
  1481         if (simpleBinaryName.length() < 1 || simpleBinaryName.charAt(0) != '$')
  1482             throw badClassFile("bad.enclosing.method", self);
  1483         int index = 1;
  1484         while (index < simpleBinaryName.length() &&
  1485                isAsciiDigit(simpleBinaryName.charAt(index)))
  1486             index++;
  1487         return names.fromString(simpleBinaryName.substring(index));
  1488     }
  1489 
  1490     private MethodSymbol findMethod(NameAndType nt, Scope scope, long flags) {
  1491         if (nt == null)
  1492             return null;
  1493 
  1494         MethodType type = nt.uniqueType.type.asMethodType();
  1495 
  1496         for (Symbol sym : scope.getSymbolsByName(nt.name)) {
  1497             if (sym.kind == MTH && isSameBinaryType(sym.type.asMethodType(), type))
  1498                 return (MethodSymbol)sym;
  1499         }
  1500 
  1501         if (nt.name != names.init)
  1502             // not a constructor
  1503             return null;
  1504         if ((flags & INTERFACE) != 0)
  1505             // no enclosing instance
  1506             return null;
  1507         if (nt.uniqueType.type.getParameterTypes().isEmpty())
  1508             // no parameters
  1509             return null;
  1510 
  1511         // A constructor of an inner class.
  1512         // Remove the first argument (the enclosing instance)
  1513         nt.setType(new MethodType(nt.uniqueType.type.getParameterTypes().tail,
  1514                                  nt.uniqueType.type.getReturnType(),
  1515                                  nt.uniqueType.type.getThrownTypes(),
  1516                                  syms.methodClass));
  1517         // Try searching again
  1518         return findMethod(nt, scope, flags);
  1519     }
  1520 
  1521     /** Similar to Types.isSameType but avoids completion */
  1522     protected boolean isSameBinaryType(MethodType mt1, MethodType mt2) {
  1523         List<Type> types1 = types.erasure(mt1.getParameterTypes())
  1524             .prepend(types.erasure(mt1.getReturnType()));
  1525         List<Type> types2 = mt2.getParameterTypes().prepend(mt2.getReturnType());
  1526         while (!types1.isEmpty() && !types2.isEmpty()) {
  1527             if (types1.head.tsym != types2.head.tsym)
  1528                 return false;
  1529             types1 = types1.tail;
  1530             types2 = types2.tail;
  1531         }
  1532         return types1.isEmpty() && types2.isEmpty();
  1533     }
  1534 
  1535     /**
  1536      * Character.isDigit answers <tt>true</tt> to some non-ascii
  1537      * digits.  This one does not.  <b>copied from java.lang.Class</b>
  1538      */
  1539     private static boolean isAsciiDigit(char c) {
  1540         return '0' <= c && c <= '9';
  1541     }
  1542 
  1543     /** Read member attributes.
  1544      */
  1545     void readMemberAttrs(Symbol sym) {
  1546         readAttrs(sym, AttributeKind.MEMBER);
  1547     }
  1548 
  1549     void readAttrs(Symbol sym, AttributeKind kind) {
  1550         char ac = nextChar();
  1551         for (int i = 0; i < ac; i++) {
  1552             Name attrName = readName(nextChar());
  1553             int attrLen = nextInt();
  1554             AttributeReader r = attributeReaders.get(attrName);
  1555             if (r != null && r.accepts(kind))
  1556                 r.read(sym, attrLen);
  1557             else  {
  1558                 bp = bp + attrLen;
  1559             }
  1560         }
  1561     }
  1562 
  1563     private boolean readingClassAttr = false;
  1564     private List<Type> missingTypeVariables = List.nil();
  1565     private List<Type> foundTypeVariables = List.nil();
  1566 
  1567     /** Read class attributes.
  1568      */
  1569     void readClassAttrs(ClassSymbol c) {
  1570         readAttrs(c, AttributeKind.CLASS);
  1571     }
  1572 
  1573     /** Read code block.
  1574      */
  1575     Code readCode(Symbol owner) {
  1576         nextChar(); // max_stack
  1577         nextChar(); // max_locals
  1578         final int  code_length = nextInt();
  1579         bp += code_length;
  1580         final char exception_table_length = nextChar();
  1581         bp += exception_table_length * 8;
  1582         readMemberAttrs(owner);
  1583         return null;
  1584     }
  1585 
  1586 /************************************************************************
  1587  * Reading Java-language annotations
  1588  ***********************************************************************/
  1589 
  1590     /** Attach annotations.
  1591      */
  1592     protected void attachAnnotations(final Symbol sym) {
  1593         int numAttributes = nextChar();
  1594         if (numAttributes != 0) {
  1595             ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
  1596             for (int i = 0; i<numAttributes; i++) {
  1597                 CompoundAnnotationProxy proxy = readCompoundAnnotation();
  1598                 if (proxy.type.tsym == syms.proprietaryType.tsym)
  1599                     sym.flags_field |= PROPRIETARY;
  1600                 else if (proxy.type.tsym == syms.profileType.tsym) {
  1601                     if (profile != Profile.DEFAULT) {
  1602                         for (Pair<Name,Attribute> v: proxy.values) {
  1603                             if (v.fst == names.value && v.snd instanceof Attribute.Constant) {
  1604                                 Attribute.Constant c = (Attribute.Constant) v.snd;
  1605                                 if (c.type == syms.intType && ((Integer) c.value) > profile.value) {
  1606                                     sym.flags_field |= NOT_IN_PROFILE;
  1607                                 }
  1608                             }
  1609                         }
  1610                     }
  1611                 } else {
  1612                     if (proxy.type.tsym == syms.annotationTargetType.tsym) {
  1613                         target = proxy;
  1614                     } else if (proxy.type.tsym == syms.repeatableType.tsym) {
  1615                         repeatable = proxy;
  1616                     } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
  1617                         sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
  1618                         for (Pair<Name, Attribute> v : proxy.values) {
  1619                             if (v.fst == names.forRemoval && v.snd instanceof Attribute.Constant) {
  1620                                 Attribute.Constant c = (Attribute.Constant) v.snd;
  1621                                 if (c.type == syms.booleanType && ((Integer) c.value) != 0) {
  1622                                     sym.flags_field |= DEPRECATED_REMOVAL;
  1623                                 }
  1624                             }
  1625                         }
  1626                     }
  1627 
  1628                     proxies.append(proxy);
  1629                 }
  1630             }
  1631             annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
  1632         }
  1633     }
  1634 
  1635     /** Attach parameter annotations.
  1636      */
  1637     protected void attachParameterAnnotations(final Symbol method) {
  1638         final MethodSymbol meth = (MethodSymbol)method;
  1639         int numParameters = buf[bp++] & 0xFF;
  1640         List<VarSymbol> parameters = meth.params();
  1641         int pnum = 0;
  1642         while (parameters.tail != null) {
  1643             attachAnnotations(parameters.head);
  1644             parameters = parameters.tail;
  1645             pnum++;
  1646         }
  1647         if (pnum != numParameters) {
  1648             throw badClassFile("bad.runtime.invisible.param.annotations", meth);
  1649         }
  1650     }
  1651 
  1652     protected void attachTypeAnnotations(final Symbol sym) {
  1653         int numAttributes = nextChar();
  1654         if (numAttributes != 0) {
  1655             ListBuffer<TypeAnnotationProxy> proxies = new ListBuffer<>();
  1656             for (int i = 0; i < numAttributes; i++)
  1657                 proxies.append(readTypeAnnotation());
  1658             annotate.normal(new TypeAnnotationCompleter(sym, proxies.toList()));
  1659         }
  1660     }
  1661 
  1662     /** Attach the default value for an annotation element.
  1663      */
  1664     void attachAnnotationDefault(final Symbol sym) {
  1665         final MethodSymbol meth = (MethodSymbol)sym; // only on methods
  1666         final Attribute value = readAttributeValue();
  1667 
  1668         // The default value is set later during annotation. It might
  1669         // be the case that the Symbol sym is annotated _after_ the
  1670         // repeating instances that depend on this default value,
  1671         // because of this we set an interim value that tells us this
  1672         // element (most likely) has a default.
  1673         //
  1674         // Set interim value for now, reset just before we do this
  1675         // properly at annotate time.
  1676         meth.defaultValue = value;
  1677         annotate.normal(new AnnotationDefaultCompleter(meth, value));
  1678     }
  1679 
  1680     Type readTypeOrClassSymbol(int i) {
  1681         // support preliminary jsr175-format class files
  1682         if (buf[poolIdx[i]] == CONSTANT_Class)
  1683             return readClassSymbol(i).type;
  1684         return readTypeToProxy(i);
  1685     }
  1686     Type readEnumType(int i) {
  1687         // support preliminary jsr175-format class files
  1688         int index = poolIdx[i];
  1689         int length = getChar(index + 1);
  1690         if (buf[index + length + 2] != ';')
  1691             return enterClass(readName(i)).type;
  1692         return readTypeToProxy(i);
  1693     }
  1694     Type readTypeToProxy(int i) {
  1695         if (currentModule.module_info == currentOwner) {
  1696             int index = poolIdx[i];
  1697             return new ProxyType(Arrays.copyOfRange(buf, index + 3, index + 3 + getChar(index + 1)));
  1698         } else {
  1699             return readType(i);
  1700         }
  1701     }
  1702 
  1703     CompoundAnnotationProxy readCompoundAnnotation() {
  1704         Type t;
  1705         if (currentModule.module_info == currentOwner) {
  1706             int index = poolIdx[nextChar()];
  1707             t = new ProxyType(Arrays.copyOfRange(buf, index + 3, index + 3 + getChar(index + 1)));
  1708         } else {
  1709             t = readTypeOrClassSymbol(nextChar());
  1710         }
  1711         int numFields = nextChar();
  1712         ListBuffer<Pair<Name,Attribute>> pairs = new ListBuffer<>();
  1713         for (int i=0; i<numFields; i++) {
  1714             Name name = readName(nextChar());
  1715             Attribute value = readAttributeValue();
  1716             pairs.append(new Pair<>(name, value));
  1717         }
  1718         return new CompoundAnnotationProxy(t, pairs.toList());
  1719     }
  1720 
  1721     TypeAnnotationProxy readTypeAnnotation() {
  1722         TypeAnnotationPosition position = readPosition();
  1723         CompoundAnnotationProxy proxy = readCompoundAnnotation();
  1724 
  1725         return new TypeAnnotationProxy(proxy, position);
  1726     }
  1727 
  1728     TypeAnnotationPosition readPosition() {
  1729         int tag = nextByte(); // TargetType tag is a byte
  1730 
  1731         if (!TargetType.isValidTargetTypeValue(tag))
  1732             throw badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
  1733 
  1734         TargetType type = TargetType.fromTargetTypeValue(tag);
  1735 
  1736         switch (type) {
  1737         // instanceof
  1738         case INSTANCEOF: {
  1739             final int offset = nextChar();
  1740             final TypeAnnotationPosition position =
  1741                 TypeAnnotationPosition.instanceOf(readTypePath());
  1742             position.offset = offset;
  1743             return position;
  1744         }
  1745         // new expression
  1746         case NEW: {
  1747             final int offset = nextChar();
  1748             final TypeAnnotationPosition position =
  1749                 TypeAnnotationPosition.newObj(readTypePath());
  1750             position.offset = offset;
  1751             return position;
  1752         }
  1753         // constructor/method reference receiver
  1754         case CONSTRUCTOR_REFERENCE: {
  1755             final int offset = nextChar();
  1756             final TypeAnnotationPosition position =
  1757                 TypeAnnotationPosition.constructorRef(readTypePath());
  1758             position.offset = offset;
  1759             return position;
  1760         }
  1761         case METHOD_REFERENCE: {
  1762             final int offset = nextChar();
  1763             final TypeAnnotationPosition position =
  1764                 TypeAnnotationPosition.methodRef(readTypePath());
  1765             position.offset = offset;
  1766             return position;
  1767         }
  1768         // local variable
  1769         case LOCAL_VARIABLE: {
  1770             final int table_length = nextChar();
  1771             final int[] newLvarOffset = new int[table_length];
  1772             final int[] newLvarLength = new int[table_length];
  1773             final int[] newLvarIndex = new int[table_length];
  1774 
  1775             for (int i = 0; i < table_length; ++i) {
  1776                 newLvarOffset[i] = nextChar();
  1777                 newLvarLength[i] = nextChar();
  1778                 newLvarIndex[i] = nextChar();
  1779             }
  1780 
  1781             final TypeAnnotationPosition position =
  1782                     TypeAnnotationPosition.localVariable(readTypePath());
  1783             position.lvarOffset = newLvarOffset;
  1784             position.lvarLength = newLvarLength;
  1785             position.lvarIndex = newLvarIndex;
  1786             return position;
  1787         }
  1788         // resource variable
  1789         case RESOURCE_VARIABLE: {
  1790             final int table_length = nextChar();
  1791             final int[] newLvarOffset = new int[table_length];
  1792             final int[] newLvarLength = new int[table_length];
  1793             final int[] newLvarIndex = new int[table_length];
  1794 
  1795             for (int i = 0; i < table_length; ++i) {
  1796                 newLvarOffset[i] = nextChar();
  1797                 newLvarLength[i] = nextChar();
  1798                 newLvarIndex[i] = nextChar();
  1799             }
  1800 
  1801             final TypeAnnotationPosition position =
  1802                     TypeAnnotationPosition.resourceVariable(readTypePath());
  1803             position.lvarOffset = newLvarOffset;
  1804             position.lvarLength = newLvarLength;
  1805             position.lvarIndex = newLvarIndex;
  1806             return position;
  1807         }
  1808         // exception parameter
  1809         case EXCEPTION_PARAMETER: {
  1810             final int exception_index = nextChar();
  1811             final TypeAnnotationPosition position =
  1812                 TypeAnnotationPosition.exceptionParameter(readTypePath());
  1813             position.setExceptionIndex(exception_index);
  1814             return position;
  1815         }
  1816         // method receiver
  1817         case METHOD_RECEIVER:
  1818             return TypeAnnotationPosition.methodReceiver(readTypePath());
  1819         // type parameter
  1820         case CLASS_TYPE_PARAMETER: {
  1821             final int parameter_index = nextByte();
  1822             return TypeAnnotationPosition
  1823                 .typeParameter(readTypePath(), parameter_index);
  1824         }
  1825         case METHOD_TYPE_PARAMETER: {
  1826             final int parameter_index = nextByte();
  1827             return TypeAnnotationPosition
  1828                 .methodTypeParameter(readTypePath(), parameter_index);
  1829         }
  1830         // type parameter bound
  1831         case CLASS_TYPE_PARAMETER_BOUND: {
  1832             final int parameter_index = nextByte();
  1833             final int bound_index = nextByte();
  1834             return TypeAnnotationPosition
  1835                 .typeParameterBound(readTypePath(), parameter_index,
  1836                                     bound_index);
  1837         }
  1838         case METHOD_TYPE_PARAMETER_BOUND: {
  1839             final int parameter_index = nextByte();
  1840             final int bound_index = nextByte();
  1841             return TypeAnnotationPosition
  1842                 .methodTypeParameterBound(readTypePath(), parameter_index,
  1843                                           bound_index);
  1844         }
  1845         // class extends or implements clause
  1846         case CLASS_EXTENDS: {
  1847             final int type_index = nextChar();
  1848             return TypeAnnotationPosition.classExtends(readTypePath(),
  1849                                                        type_index);
  1850         }
  1851         // throws
  1852         case THROWS: {
  1853             final int type_index = nextChar();
  1854             return TypeAnnotationPosition.methodThrows(readTypePath(),
  1855                                                        type_index);
  1856         }
  1857         // method parameter
  1858         case METHOD_FORMAL_PARAMETER: {
  1859             final int parameter_index = nextByte();
  1860             return TypeAnnotationPosition.methodParameter(readTypePath(),
  1861                                                           parameter_index);
  1862         }
  1863         // type cast
  1864         case CAST: {
  1865             final int offset = nextChar();
  1866             final int type_index = nextByte();
  1867             final TypeAnnotationPosition position =
  1868                 TypeAnnotationPosition.typeCast(readTypePath(), type_index);
  1869             position.offset = offset;
  1870             return position;
  1871         }
  1872         // method/constructor/reference type argument
  1873         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: {
  1874             final int offset = nextChar();
  1875             final int type_index = nextByte();
  1876             final TypeAnnotationPosition position = TypeAnnotationPosition
  1877                 .constructorInvocationTypeArg(readTypePath(), type_index);
  1878             position.offset = offset;
  1879             return position;
  1880         }
  1881         case METHOD_INVOCATION_TYPE_ARGUMENT: {
  1882             final int offset = nextChar();
  1883             final int type_index = nextByte();
  1884             final TypeAnnotationPosition position = TypeAnnotationPosition
  1885                 .methodInvocationTypeArg(readTypePath(), type_index);
  1886             position.offset = offset;
  1887             return position;
  1888         }
  1889         case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: {
  1890             final int offset = nextChar();
  1891             final int type_index = nextByte();
  1892             final TypeAnnotationPosition position = TypeAnnotationPosition
  1893                 .constructorRefTypeArg(readTypePath(), type_index);
  1894             position.offset = offset;
  1895             return position;
  1896         }
  1897         case METHOD_REFERENCE_TYPE_ARGUMENT: {
  1898             final int offset = nextChar();
  1899             final int type_index = nextByte();
  1900             final TypeAnnotationPosition position = TypeAnnotationPosition
  1901                 .methodRefTypeArg(readTypePath(), type_index);
  1902             position.offset = offset;
  1903             return position;
  1904         }
  1905         // We don't need to worry about these
  1906         case METHOD_RETURN:
  1907             return TypeAnnotationPosition.methodReturn(readTypePath());
  1908         case FIELD:
  1909             return TypeAnnotationPosition.field(readTypePath());
  1910         case UNKNOWN:
  1911             throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
  1912         default:
  1913             throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + type);
  1914         }
  1915     }
  1916 
  1917     List<TypeAnnotationPosition.TypePathEntry> readTypePath() {
  1918         int len = nextByte();
  1919         ListBuffer<Integer> loc = new ListBuffer<>();
  1920         for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i)
  1921             loc = loc.append(nextByte());
  1922 
  1923         return TypeAnnotationPosition.getTypePathFromBinary(loc.toList());
  1924 
  1925     }
  1926 
  1927     Attribute readAttributeValue() {
  1928         char c = (char) buf[bp++];
  1929         switch (c) {
  1930         case 'B':
  1931             return new Attribute.Constant(syms.byteType, readPool(nextChar()));
  1932         case 'C':
  1933             return new Attribute.Constant(syms.charType, readPool(nextChar()));
  1934         case 'D':
  1935             return new Attribute.Constant(syms.doubleType, readPool(nextChar()));
  1936         case 'F':
  1937             return new Attribute.Constant(syms.floatType, readPool(nextChar()));
  1938         case 'I':
  1939             return new Attribute.Constant(syms.intType, readPool(nextChar()));
  1940         case 'J':
  1941             return new Attribute.Constant(syms.longType, readPool(nextChar()));
  1942         case 'S':
  1943             return new Attribute.Constant(syms.shortType, readPool(nextChar()));
  1944         case 'Z':
  1945             return new Attribute.Constant(syms.booleanType, readPool(nextChar()));
  1946         case 's':
  1947             return new Attribute.Constant(syms.stringType, readPool(nextChar()).toString());
  1948         case 'e':
  1949             return new EnumAttributeProxy(readEnumType(nextChar()), readName(nextChar()));
  1950         case 'c':
  1951             return new ClassAttributeProxy(readTypeOrClassSymbol(nextChar()));
  1952         case '[': {
  1953             int n = nextChar();
  1954             ListBuffer<Attribute> l = new ListBuffer<>();
  1955             for (int i=0; i<n; i++)
  1956                 l.append(readAttributeValue());
  1957             return new ArrayAttributeProxy(l.toList());
  1958         }
  1959         case '@':
  1960             return readCompoundAnnotation();
  1961         default:
  1962             throw new AssertionError("unknown annotation tag '" + c + "'");
  1963         }
  1964     }
  1965 
  1966     interface ProxyVisitor extends Attribute.Visitor {
  1967         void visitEnumAttributeProxy(EnumAttributeProxy proxy);
  1968         void visitClassAttributeProxy(ClassAttributeProxy proxy);
  1969         void visitArrayAttributeProxy(ArrayAttributeProxy proxy);
  1970         void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy);
  1971     }
  1972 
  1973     protected static class EnumAttributeProxy extends Attribute {
  1974         Type enumType;
  1975         Name enumerator;
  1976         public EnumAttributeProxy(Type enumType, Name enumerator) {
  1977             super(null);
  1978             this.enumType = enumType;
  1979             this.enumerator = enumerator;
  1980         }
  1981         public void accept(Visitor v) { ((ProxyVisitor)v).visitEnumAttributeProxy(this); }
  1982         @Override @DefinedBy(Api.LANGUAGE_MODEL)
  1983         public String toString() {
  1984             return "/*proxy enum*/" + enumType + "." + enumerator;
  1985         }
  1986     }
  1987 
  1988     protected static class ClassAttributeProxy extends Attribute {
  1989         Type classType;
  1990         public ClassAttributeProxy(Type classType) {
  1991             super(null);
  1992             this.classType = classType;
  1993         }
  1994         public void accept(Visitor v) { ((ProxyVisitor)v).visitClassAttributeProxy(this); }
  1995         @Override @DefinedBy(Api.LANGUAGE_MODEL)
  1996         public String toString() {
  1997             return "/*proxy class*/" + classType + ".class";
  1998         }
  1999     }
  2000 
  2001     protected static class ArrayAttributeProxy extends Attribute {
  2002         List<Attribute> values;
  2003         public ArrayAttributeProxy(List<Attribute> values) {
  2004             super(null);
  2005             this.values = values;
  2006         }
  2007         public void accept(Visitor v) { ((ProxyVisitor)v).visitArrayAttributeProxy(this); }
  2008         @Override @DefinedBy(Api.LANGUAGE_MODEL)
  2009         public String toString() {
  2010             return "{" + values + "}";
  2011         }
  2012     }
  2013 
  2014     /** A temporary proxy representing a compound attribute.
  2015      */
  2016     protected static class CompoundAnnotationProxy extends Attribute {
  2017         final List<Pair<Name,Attribute>> values;
  2018         public CompoundAnnotationProxy(Type type,
  2019                                       List<Pair<Name,Attribute>> values) {
  2020             super(type);
  2021             this.values = values;
  2022         }
  2023         public void accept(Visitor v) { ((ProxyVisitor)v).visitCompoundAnnotationProxy(this); }
  2024         @Override @DefinedBy(Api.LANGUAGE_MODEL)
  2025         public String toString() {
  2026             StringBuilder buf = new StringBuilder();
  2027             buf.append("@");
  2028             buf.append(type.tsym.getQualifiedName());
  2029             buf.append("/*proxy*/{");
  2030             boolean first = true;
  2031             for (List<Pair<Name,Attribute>> v = values;
  2032                  v.nonEmpty(); v = v.tail) {
  2033                 Pair<Name,Attribute> value = v.head;
  2034                 if (!first) buf.append(",");
  2035                 first = false;
  2036                 buf.append(value.fst);
  2037                 buf.append("=");
  2038                 buf.append(value.snd);
  2039             }
  2040             buf.append("}");
  2041             return buf.toString();
  2042         }
  2043     }
  2044 
  2045     /** A temporary proxy representing a type annotation.
  2046      */
  2047     static class TypeAnnotationProxy {
  2048         final CompoundAnnotationProxy compound;
  2049         final TypeAnnotationPosition position;
  2050         public TypeAnnotationProxy(CompoundAnnotationProxy compound,
  2051                 TypeAnnotationPosition position) {
  2052             this.compound = compound;
  2053             this.position = position;
  2054         }
  2055     }
  2056 
  2057     class AnnotationDeproxy implements ProxyVisitor {
  2058         private ClassSymbol requestingOwner;
  2059 
  2060         AnnotationDeproxy(ClassSymbol owner) {
  2061             this.requestingOwner = owner;
  2062         }
  2063 
  2064         List<Attribute.Compound> deproxyCompoundList(List<CompoundAnnotationProxy> pl) {
  2065             // also must fill in types!!!!
  2066             ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
  2067             for (List<CompoundAnnotationProxy> l = pl; l.nonEmpty(); l=l.tail) {
  2068                 buf.append(deproxyCompound(l.head));
  2069             }
  2070             return buf.toList();
  2071         }
  2072 
  2073         Attribute.Compound deproxyCompound(CompoundAnnotationProxy a) {
  2074             Type annotationType = resolvePossibleProxyType(a.type);
  2075             ListBuffer<Pair<Symbol.MethodSymbol,Attribute>> buf = new ListBuffer<>();
  2076             for (List<Pair<Name,Attribute>> l = a.values;
  2077                  l.nonEmpty();
  2078                  l = l.tail) {
  2079                 MethodSymbol meth = findAccessMethod(annotationType, l.head.fst);
  2080                 buf.append(new Pair<>(meth, deproxy(meth.type.getReturnType(), l.head.snd)));
  2081             }
  2082             return new Attribute.Compound(annotationType, buf.toList());
  2083         }
  2084 
  2085         MethodSymbol findAccessMethod(Type container, Name name) {
  2086             CompletionFailure failure = null;
  2087             try {
  2088                 for (Symbol sym : container.tsym.members().getSymbolsByName(name)) {
  2089                     if (sym.kind == MTH && sym.type.getParameterTypes().length() == 0)
  2090                         return (MethodSymbol) sym;
  2091                 }
  2092             } catch (CompletionFailure ex) {
  2093                 failure = ex;
  2094             }
  2095             // The method wasn't found: emit a warning and recover
  2096             JavaFileObject prevSource = log.useSource(requestingOwner.classfile);
  2097             try {
  2098                 if (lintClassfile) {
  2099                     if (failure == null) {
  2100                         log.warning("annotation.method.not.found",
  2101                                     container,
  2102                                     name);
  2103                     } else {
  2104                         log.warning("annotation.method.not.found.reason",
  2105                                     container,
  2106                                     name,
  2107                                     failure.getDetailValue());//diagnostic, if present
  2108                     }
  2109                 }
  2110             } finally {
  2111                 log.useSource(prevSource);
  2112             }
  2113             // Construct a new method type and symbol.  Use bottom
  2114             // type (typeof null) as return type because this type is
  2115             // a subtype of all reference types and can be converted
  2116             // to primitive types by unboxing.
  2117             MethodType mt = new MethodType(List.nil(),
  2118                                            syms.botType,
  2119                                            List.nil(),
  2120                                            syms.methodClass);
  2121             return new MethodSymbol(PUBLIC | ABSTRACT, name, mt, container.tsym);
  2122         }
  2123 
  2124         Attribute result;
  2125         Type type;
  2126         Attribute deproxy(Type t, Attribute a) {
  2127             Type oldType = type;
  2128             try {
  2129                 type = t;
  2130                 a.accept(this);
  2131                 return result;
  2132             } finally {
  2133                 type = oldType;
  2134             }
  2135         }
  2136 
  2137         // implement Attribute.Visitor below
  2138 
  2139         public void visitConstant(Attribute.Constant value) {
  2140             // assert value.type == type;
  2141             result = value;
  2142         }
  2143 
  2144         public void visitClass(Attribute.Class clazz) {
  2145             result = clazz;
  2146         }
  2147 
  2148         public void visitEnum(Attribute.Enum e) {
  2149             throw new AssertionError(); // shouldn't happen
  2150         }
  2151 
  2152         public void visitCompound(Attribute.Compound compound) {
  2153             throw new AssertionError(); // shouldn't happen
  2154         }
  2155 
  2156         public void visitArray(Attribute.Array array) {
  2157             throw new AssertionError(); // shouldn't happen
  2158         }
  2159 
  2160         public void visitError(Attribute.Error e) {
  2161             throw new AssertionError(); // shouldn't happen
  2162         }
  2163 
  2164         public void visitEnumAttributeProxy(EnumAttributeProxy proxy) {
  2165             // type.tsym.flatName() should == proxy.enumFlatName
  2166             Type enumType = resolvePossibleProxyType(proxy.enumType);
  2167             TypeSymbol enumTypeSym = enumType.tsym;
  2168             VarSymbol enumerator = null;
  2169             CompletionFailure failure = null;
  2170             try {
  2171                 for (Symbol sym : enumTypeSym.members().getSymbolsByName(proxy.enumerator)) {
  2172                     if (sym.kind == VAR) {
  2173                         enumerator = (VarSymbol)sym;
  2174                         break;
  2175                     }
  2176                 }
  2177             }
  2178             catch (CompletionFailure ex) {
  2179                 failure = ex;
  2180             }
  2181             if (enumerator == null) {
  2182                 if (failure != null) {
  2183                     log.warning("unknown.enum.constant.reason",
  2184                               currentClassFile, enumTypeSym, proxy.enumerator,
  2185                               failure.getDiagnostic());
  2186                 } else {
  2187                     log.warning("unknown.enum.constant",
  2188                               currentClassFile, enumTypeSym, proxy.enumerator);
  2189                 }
  2190                 result = new Attribute.Enum(enumTypeSym.type,
  2191                         new VarSymbol(0, proxy.enumerator, syms.botType, enumTypeSym));
  2192             } else {
  2193                 result = new Attribute.Enum(enumTypeSym.type, enumerator);
  2194             }
  2195         }
  2196 
  2197         @Override
  2198         public void visitClassAttributeProxy(ClassAttributeProxy proxy) {
  2199             Type classType = resolvePossibleProxyType(proxy.classType);
  2200             result = new Attribute.Class(types, classType);
  2201         }
  2202 
  2203         public void visitArrayAttributeProxy(ArrayAttributeProxy proxy) {
  2204             int length = proxy.values.length();
  2205             Attribute[] ats = new Attribute[length];
  2206             Type elemtype = types.elemtype(type);
  2207             int i = 0;
  2208             for (List<Attribute> p = proxy.values; p.nonEmpty(); p = p.tail) {
  2209                 ats[i++] = deproxy(elemtype, p.head);
  2210             }
  2211             result = new Attribute.Array(type, ats);
  2212         }
  2213 
  2214         public void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy) {
  2215             result = deproxyCompound(proxy);
  2216         }
  2217 
  2218         Type resolvePossibleProxyType(Type t) {
  2219             if (t instanceof ProxyType) {
  2220                 Assert.check(requestingOwner.owner.kind == MDL);
  2221                 ModuleSymbol prevCurrentModule = currentModule;
  2222                 currentModule = (ModuleSymbol) requestingOwner.owner;
  2223                 try {
  2224                     return ((ProxyType) t).resolve();
  2225                 } finally {
  2226                     currentModule = prevCurrentModule;
  2227                 }
  2228             } else {
  2229                 return t;
  2230             }
  2231         }
  2232     }
  2233 
  2234     protected class AnnotationDefaultCompleter extends AnnotationDeproxy implements Runnable {
  2235         final MethodSymbol sym;
  2236         final Attribute value;
  2237         final JavaFileObject classFile = currentClassFile;
  2238 
  2239         public AnnotationDefaultCompleter(MethodSymbol sym, Attribute value) {
  2240             super(currentOwner.kind == MTH
  2241                     ? currentOwner.enclClass() : (ClassSymbol)currentOwner);
  2242             this.sym = sym;
  2243             this.value = value;
  2244         }
  2245 
  2246         @Override
  2247         public void run() {
  2248             JavaFileObject previousClassFile = currentClassFile;
  2249             try {
  2250                 // Reset the interim value set earlier in
  2251                 // attachAnnotationDefault().
  2252                 sym.defaultValue = null;
  2253                 currentClassFile = classFile;
  2254                 sym.defaultValue = deproxy(sym.type.getReturnType(), value);
  2255             } finally {
  2256                 currentClassFile = previousClassFile;
  2257             }
  2258         }
  2259 
  2260         @Override
  2261         public String toString() {
  2262             return " ClassReader store default for " + sym.owner + "." + sym + " is " + value;
  2263         }
  2264     }
  2265 
  2266     protected class AnnotationCompleter extends AnnotationDeproxy implements Runnable {
  2267         final Symbol sym;
  2268         final List<CompoundAnnotationProxy> l;
  2269         final JavaFileObject classFile;
  2270 
  2271         public AnnotationCompleter(Symbol sym, List<CompoundAnnotationProxy> l) {
  2272             super(currentOwner.kind == MTH
  2273                     ? currentOwner.enclClass() : (ClassSymbol)currentOwner);
  2274             if (sym.kind == TYP && sym.owner.kind == MDL) {
  2275                 this.sym = sym.owner;
  2276             } else {
  2277                 this.sym = sym;
  2278             }
  2279             this.l = l;
  2280             this.classFile = currentClassFile;
  2281         }
  2282 
  2283         @Override
  2284         public void run() {
  2285             if ((sym.flags_field & FROMCLASS) == 0 && ((sym.flags_field & PARAMETER) == 0 || (sym.owner.flags_field & FROMCLASS) == 0))
  2286                 return;
  2287             JavaFileObject previousClassFile = currentClassFile;
  2288             try {
  2289                 currentClassFile = classFile;
  2290                 List<Attribute.Compound> newList = deproxyCompoundList(l);
  2291                 for (Attribute.Compound attr : newList) {
  2292                     if (attr.type.tsym == syms.deprecatedType.tsym) {
  2293                         sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
  2294                         Attribute forRemoval = attr.member(names.forRemoval);
  2295                         if (forRemoval instanceof Attribute.Constant) {
  2296                             Attribute.Constant c = (Attribute.Constant) forRemoval;
  2297                             if (c.type == syms.booleanType && ((Integer) c.value) != 0) {
  2298                                 sym.flags_field |= DEPRECATED_REMOVAL;
  2299                             }
  2300                         }
  2301                     }
  2302                 }
  2303                 if (sym.annotationsPendingCompletion()) {
  2304                     sym.setDeclarationAttributes(newList);
  2305                 } else {
  2306                     sym.appendAttributes(newList);
  2307                 }
  2308             } finally {
  2309                 currentClassFile = previousClassFile;
  2310             }
  2311         }
  2312 
  2313         @Override
  2314         public String toString() {
  2315             return " ClassReader annotate " + sym.owner + "." + sym + " with " + l;
  2316         }
  2317     }
  2318 
  2319     class TypeAnnotationCompleter extends AnnotationCompleter {
  2320 
  2321         List<TypeAnnotationProxy> proxies;
  2322 
  2323         TypeAnnotationCompleter(Symbol sym,
  2324                 List<TypeAnnotationProxy> proxies) {
  2325             super(sym, List.nil());
  2326             this.proxies = proxies;
  2327         }
  2328 
  2329         List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
  2330             ListBuffer<Attribute.TypeCompound> buf = new ListBuffer<>();
  2331             for (TypeAnnotationProxy proxy: proxies) {
  2332                 Attribute.Compound compound = deproxyCompound(proxy.compound);
  2333                 Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position);
  2334                 buf.add(typeCompound);
  2335             }
  2336             return buf.toList();
  2337         }
  2338 
  2339         @Override
  2340         public void run() {
  2341             JavaFileObject previousClassFile = currentClassFile;
  2342             try {
  2343                 currentClassFile = classFile;
  2344                 List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies);
  2345                 sym.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes()));
  2346             } finally {
  2347                 currentClassFile = previousClassFile;
  2348             }
  2349         }
  2350     }
  2351 
  2352 
  2353 /************************************************************************
  2354  * Reading Symbols
  2355  ***********************************************************************/
  2356 
  2357     /** Read a field.
  2358      */
  2359     VarSymbol readField() {
  2360         long flags = adjustFieldFlags(nextChar());
  2361         Name name = readName(nextChar());
  2362         Type type = readType(nextChar());
  2363         VarSymbol v = new VarSymbol(flags, name, type, currentOwner);
  2364         readMemberAttrs(v);
  2365         return v;
  2366     }
  2367 
  2368     /** Read a method.
  2369      */
  2370     MethodSymbol readMethod() {
  2371         long flags = adjustMethodFlags(nextChar());
  2372         Name name = readName(nextChar());
  2373         Type type = readType(nextChar());
  2374         if (currentOwner.isInterface() &&
  2375                 (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
  2376             if (majorVersion > Version.V52.major ||
  2377                     (majorVersion == Version.V52.major && minorVersion >= Version.V52.minor)) {
  2378                 if ((flags & (STATIC | PRIVATE)) == 0) {
  2379                     currentOwner.flags_field |= DEFAULT;
  2380                     flags |= DEFAULT | ABSTRACT;
  2381                 }
  2382             } else {
  2383                 //protect against ill-formed classfiles
  2384                 throw badClassFile((flags & STATIC) == 0 ? "invalid.default.interface" : "invalid.static.interface",
  2385                                    Integer.toString(majorVersion),
  2386                                    Integer.toString(minorVersion));
  2387             }
  2388         }
  2389         if (name == names.init && currentOwner.hasOuterInstance()) {
  2390             // Sometimes anonymous classes don't have an outer
  2391             // instance, however, there is no reliable way to tell so
  2392             // we never strip this$n
  2393             // ditto for local classes. Local classes that have an enclosing method set
  2394             // won't pass the "hasOuterInstance" check above, but those that don't have an
  2395             // enclosing method (i.e. from initializers) will pass that check.
  2396             boolean local = !currentOwner.owner.members().includes(currentOwner, LookupKind.NON_RECURSIVE);
  2397             if (!currentOwner.name.isEmpty() && !local)
  2398                 type = new MethodType(adjustMethodParams(flags, type.getParameterTypes()),
  2399                                       type.getReturnType(),
  2400                                       type.getThrownTypes(),
  2401                                       syms.methodClass);
  2402         }
  2403         MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
  2404         if (types.isSignaturePolymorphic(m)) {
  2405             m.flags_field |= SIGNATURE_POLYMORPHIC;
  2406         }
  2407         if (saveParameterNames)
  2408             initParameterNames(m);
  2409         Symbol prevOwner = currentOwner;
  2410         currentOwner = m;
  2411         try {
  2412             readMemberAttrs(m);
  2413         } finally {
  2414             currentOwner = prevOwner;
  2415         }
  2416         if (saveParameterNames)
  2417             setParameterNames(m, type);
  2418 
  2419         if ((flags & VARARGS) != 0) {
  2420             final Type last = type.getParameterTypes().last();
  2421             if (last == null || !last.hasTag(ARRAY)) {
  2422                 m.flags_field &= ~VARARGS;
  2423                 throw badClassFile("malformed.vararg.method", m);
  2424             }
  2425         }
  2426 
  2427         return m;
  2428     }
  2429 
  2430     private List<Type> adjustMethodParams(long flags, List<Type> args) {
  2431         boolean isVarargs = (flags & VARARGS) != 0;
  2432         if (isVarargs) {
  2433             Type varargsElem = args.last();
  2434             ListBuffer<Type> adjustedArgs = new ListBuffer<>();
  2435             for (Type t : args) {
  2436                 adjustedArgs.append(t != varargsElem ?
  2437                     t :
  2438                     ((ArrayType)t).makeVarargs());
  2439             }
  2440             args = adjustedArgs.toList();
  2441         }
  2442         return args.tail;
  2443     }
  2444 
  2445     /**
  2446      * Init the parameter names array.
  2447      * Parameter names are currently inferred from the names in the
  2448      * LocalVariableTable attributes of a Code attribute.
  2449      * (Note: this means parameter names are currently not available for
  2450      * methods without a Code attribute.)
  2451      * This method initializes an array in which to store the name indexes
  2452      * of parameter names found in LocalVariableTable attributes. It is
  2453      * slightly supersized to allow for additional slots with a start_pc of 0.
  2454      */
  2455     void initParameterNames(MethodSymbol sym) {
  2456         // make allowance for synthetic parameters.
  2457         final int excessSlots = 4;
  2458         int expectedParameterSlots =
  2459                 Code.width(sym.type.getParameterTypes()) + excessSlots;
  2460         if (parameterNameIndices == null
  2461                 || parameterNameIndices.length < expectedParameterSlots) {
  2462             parameterNameIndices = new int[expectedParameterSlots];
  2463         } else
  2464             Arrays.fill(parameterNameIndices, 0);
  2465         haveParameterNameIndices = false;
  2466         sawMethodParameters = false;
  2467     }
  2468 
  2469     /**
  2470      * Set the parameter names for a symbol from the name index in the
  2471      * parameterNameIndicies array. The type of the symbol may have changed
  2472      * while reading the method attributes (see the Signature attribute).
  2473      * This may be because of generic information or because anonymous
  2474      * synthetic parameters were added.   The original type (as read from
  2475      * the method descriptor) is used to help guess the existence of
  2476      * anonymous synthetic parameters.
  2477      * On completion, sym.savedParameter names will either be null (if
  2478      * no parameter names were found in the class file) or will be set to a
  2479      * list of names, one per entry in sym.type.getParameterTypes, with
  2480      * any missing names represented by the empty name.
  2481      */
  2482     void setParameterNames(MethodSymbol sym, Type jvmType) {
  2483         // if no names were found in the class file, there's nothing more to do
  2484         if (!haveParameterNameIndices || sym.type == null || sym.type.getParameterTypes() == null)
  2485             return;
  2486         // If we get parameter names from MethodParameters, then we
  2487         // don't need to skip.
  2488         int firstParam = 0;
  2489         if (!sawMethodParameters) {
  2490             firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
  2491             // the code in readMethod may have skipped the first
  2492             // parameter when setting up the MethodType. If so, we
  2493             // make a corresponding allowance here for the position of
  2494             // the first parameter.  Note that this assumes the
  2495             // skipped parameter has a width of 1 -- i.e. it is not
  2496         // a double width type (long or double.)
  2497         if (sym.name == names.init && currentOwner.hasOuterInstance()) {
  2498             // Sometimes anonymous classes don't have an outer
  2499             // instance, however, there is no reliable way to tell so
  2500             // we never strip this$n
  2501             if (!currentOwner.name.isEmpty())
  2502                 firstParam += 1;
  2503         }
  2504 
  2505         if (sym.type != jvmType) {
  2506                 // reading the method attributes has caused the
  2507                 // symbol's type to be changed. (i.e. the Signature
  2508                 // attribute.)  This may happen if there are hidden
  2509                 // (synthetic) parameters in the descriptor, but not
  2510                 // in the Signature.  The position of these hidden
  2511                 // parameters is unspecified; for now, assume they are
  2512                 // at the beginning, and so skip over them. The
  2513                 // primary case for this is two hidden parameters
  2514                 // passed into Enum constructors.
  2515             int skip = Code.width(jvmType.getParameterTypes())
  2516                     - Code.width(sym.type.getParameterTypes());
  2517             firstParam += skip;
  2518         }
  2519         }
  2520         List<Name> paramNames = List.nil();
  2521         int index = firstParam;
  2522         for (Type t: sym.type.getParameterTypes()) {
  2523             int nameIdx = (index >= 0 && index < parameterNameIndices.length
  2524                     ? parameterNameIndices[index] : 0);
  2525             Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
  2526             paramNames = paramNames.prepend(name);
  2527             index += sawMethodParameters ? 1 : Code.width(t);
  2528         }
  2529         sym.savedParameterNames = paramNames.reverse();
  2530     }
  2531 
  2532     /**
  2533      * skip n bytes
  2534      */
  2535     void skipBytes(int n) {
  2536         bp = bp + n;
  2537     }
  2538 
  2539     /** Skip a field or method
  2540      */
  2541     void skipMember() {
  2542         bp = bp + 6;
  2543         char ac = nextChar();
  2544         for (int i = 0; i < ac; i++) {
  2545             bp = bp + 2;
  2546             int attrLen = nextInt();
  2547             bp = bp + attrLen;
  2548         }
  2549     }
  2550 
  2551     void skipInnerClasses() {
  2552         int n = nextChar();
  2553         for (int i = 0; i < n; i++) {
  2554             nextChar();
  2555             nextChar();
  2556             nextChar();
  2557             nextChar();
  2558         }
  2559     }
  2560 
  2561     /** Enter type variables of this classtype and all enclosing ones in
  2562      *  `typevars'.
  2563      */
  2564     protected void enterTypevars(Symbol sym, Type t) {
  2565         if (t.getEnclosingType() != null) {
  2566             if (!t.getEnclosingType().hasTag(TypeTag.NONE)) {
  2567                 enterTypevars(sym.owner, t.getEnclosingType());
  2568             }
  2569         } else if (sym.kind == MTH && !sym.isStatic()) {
  2570             enterTypevars(sym.owner, sym.owner.type);
  2571         }
  2572         for (List<Type> xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail) {
  2573             typevars.enter(xs.head.tsym);
  2574         }
  2575     }
  2576 
  2577     protected ClassSymbol enterClass(Name name) {
  2578         return syms.enterClass(currentModule, name);
  2579     }
  2580 
  2581     protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
  2582         return syms.enterClass(currentModule, name, owner);
  2583     }
  2584 
  2585     /** Read contents of a given class symbol `c'. Both external and internal
  2586      *  versions of an inner class are read.
  2587      */
  2588     void readClass(ClassSymbol c) {
  2589         ClassType ct = (ClassType)c.type;
  2590 
  2591         // allocate scope for members
  2592         c.members_field = WriteableScope.create(c);
  2593 
  2594         // prepare type variable table
  2595         typevars = typevars.dup(currentOwner);
  2596         if (ct.getEnclosingType().hasTag(CLASS))
  2597             enterTypevars(c.owner, ct.getEnclosingType());
  2598 
  2599         // read flags, or skip if this is an inner class
  2600         long f = nextChar();
  2601         long flags = adjustClassFlags(f);
  2602         if ((flags & MODULE) == 0) {
  2603             if (c.owner.kind == PCK) c.flags_field = flags;
  2604             // read own class name and check that it matches
  2605             currentModule = c.packge().modle;
  2606             ClassSymbol self = readClassSymbol(nextChar());
  2607             if (c != self) {
  2608                 throw badClassFile("class.file.wrong.class",
  2609                                    self.flatname);
  2610             }
  2611         } else {
  2612             if (majorVersion < Version.V53.major) {
  2613                 throw badClassFile("anachronistic.module.info",
  2614                         Integer.toString(majorVersion),
  2615                         Integer.toString(minorVersion));
  2616             }
  2617             c.flags_field = flags;
  2618             currentModule = (ModuleSymbol) c.owner;
  2619             currentModule.flags_field |= FROMCLASS;
  2620             int this_class = nextChar();
  2621             // temp, no check on this_class
  2622         }
  2623 
  2624         // class attributes must be read before class
  2625         // skip ahead to read class attributes
  2626         int startbp = bp;
  2627         nextChar();
  2628         char interfaceCount = nextChar();
  2629         bp += interfaceCount * 2;
  2630         char fieldCount = nextChar();
  2631         for (int i = 0; i < fieldCount; i++) skipMember();
  2632         char methodCount = nextChar();
  2633         for (int i = 0; i < methodCount; i++) skipMember();
  2634         readClassAttrs(c);
  2635 
  2636         if (readAllOfClassFile) {
  2637             for (int i = 1; i < poolObj.length; i++) readPool(i);
  2638             c.pool = new Pool(poolObj.length, poolObj, types);
  2639         }
  2640 
  2641         // reset and read rest of classinfo
  2642         bp = startbp;
  2643         int n = nextChar();
  2644         if ((flags & MODULE) != 0 && n > 0) {
  2645             throw badClassFile("module.info.invalid.super.class");
  2646         }
  2647         if (ct.supertype_field == null)
  2648             ct.supertype_field = (n == 0)
  2649                 ? Type.noType
  2650                 : readClassSymbol(n).erasure(types);
  2651         n = nextChar();
  2652         List<Type> is = List.nil();
  2653         for (int i = 0; i < n; i++) {
  2654             Type _inter = readClassSymbol(nextChar()).erasure(types);
  2655             is = is.prepend(_inter);
  2656         }
  2657         if (ct.interfaces_field == null)
  2658             ct.interfaces_field = is.reverse();
  2659 
  2660         Assert.check(fieldCount == nextChar());
  2661         for (int i = 0; i < fieldCount; i++) enterMember(c, readField());
  2662         Assert.check(methodCount == nextChar());
  2663         for (int i = 0; i < methodCount; i++) enterMember(c, readMethod());
  2664 
  2665         typevars = typevars.leave();
  2666     }
  2667 
  2668     /** Read inner class info. For each inner/outer pair allocate a
  2669      *  member class.
  2670      */
  2671     void readInnerClasses(ClassSymbol c) {
  2672         int n = nextChar();
  2673         for (int i = 0; i < n; i++) {
  2674             nextChar(); // skip inner class symbol
  2675             ClassSymbol outer = readClassSymbol(nextChar());
  2676             Name name = readName(nextChar());
  2677             if (name == null) name = names.empty;
  2678             long flags = adjustClassFlags(nextChar());
  2679             if (outer != null) { // we have a member class
  2680                 if (name == names.empty)
  2681                     name = names.one;
  2682                 ClassSymbol member = enterClass(name, outer);
  2683                 if ((flags & STATIC) == 0) {
  2684                     ((ClassType)member.type).setEnclosingType(outer.type);
  2685                     if (member.erasure_field != null)
  2686                         ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
  2687                 }
  2688                 if (c == outer) {
  2689                     member.flags_field = flags;
  2690                     enterMember(c, member);
  2691                 }
  2692             }
  2693         }
  2694     }
  2695 
  2696     /** Read a class definition from the bytes in buf.
  2697      */
  2698     private void readClassBuffer(ClassSymbol c) throws IOException {
  2699         int magic = nextInt();
  2700         if (magic != JAVA_MAGIC)
  2701             throw badClassFile("illegal.start.of.class.file");
  2702 
  2703         minorVersion = nextChar();
  2704         majorVersion = nextChar();
  2705         int maxMajor = 53; // Version.MAX().major;  //******* TEMPORARY *******
  2706         int maxMinor = Version.MAX().minor;
  2707         if (majorVersion > maxMajor ||
  2708             majorVersion * 1000 + minorVersion <
  2709             Version.MIN().major * 1000 + Version.MIN().minor) {
  2710             if (majorVersion == (maxMajor + 1))
  2711                 log.warning("big.major.version",
  2712                             currentClassFile,
  2713                             majorVersion,
  2714                             maxMajor);
  2715             else
  2716                 throw badClassFile("wrong.version",
  2717                                    Integer.toString(majorVersion),
  2718                                    Integer.toString(minorVersion),
  2719                                    Integer.toString(maxMajor),
  2720                                    Integer.toString(maxMinor));
  2721         }
  2722 
  2723         indexPool();
  2724         if (signatureBuffer.length < bp) {
  2725             int ns = Integer.highestOneBit(bp) << 1;
  2726             signatureBuffer = new byte[ns];
  2727         }
  2728         readClass(c);
  2729     }
  2730 
  2731     public void readClassFile(ClassSymbol c) {
  2732         currentOwner = c;
  2733         currentClassFile = c.classfile;
  2734         warnedAttrs.clear();
  2735         filling = true;
  2736         target = null;
  2737         repeatable = null;
  2738         try {
  2739             bp = 0;
  2740             buf = readInputStream(buf, c.classfile.openInputStream());
  2741             readClassBuffer(c);
  2742             if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
  2743                 List<Type> missing = missingTypeVariables;
  2744                 List<Type> found = foundTypeVariables;
  2745                 missingTypeVariables = List.nil();
  2746                 foundTypeVariables = List.nil();
  2747                 interimUses = List.nil();
  2748                 interimProvides = List.nil();
  2749                 filling = false;
  2750                 ClassType ct = (ClassType)currentOwner.type;
  2751                 ct.supertype_field =
  2752                     types.subst(ct.supertype_field, missing, found);
  2753                 ct.interfaces_field =
  2754                     types.subst(ct.interfaces_field, missing, found);
  2755                 ct.typarams_field =
  2756                     types.substBounds(ct.typarams_field, missing, found);
  2757                 for (List<Type> types = ct.typarams_field; types.nonEmpty(); types = types.tail) {
  2758                     types.head.tsym.type = types.head;
  2759                 }
  2760             } else if (missingTypeVariables.isEmpty() !=
  2761                        foundTypeVariables.isEmpty()) {
  2762                 Name name = missingTypeVariables.head.tsym.name;
  2763                 throw badClassFile("undecl.type.var", name);
  2764             }
  2765 
  2766             if ((c.flags_field & Flags.ANNOTATION) != 0) {
  2767                 c.setAnnotationTypeMetadata(new AnnotationTypeMetadata(c, new CompleterDeproxy(c, target, repeatable)));
  2768             } else {
  2769                 c.setAnnotationTypeMetadata(AnnotationTypeMetadata.notAnAnnotationType());
  2770             }
  2771 
  2772             if (c == currentModule.module_info) {
  2773                 Assert.check(currentModule.isCompleted());
  2774                 currentModule.usesProvidesCompleter =
  2775                             new UsesProvidesCompleter(currentModule, interimUses, interimProvides);
  2776             }
  2777         } catch (IOException | ClosedFileSystemException ex) {
  2778             throw badClassFile("unable.to.access.file", ex.toString());
  2779         } catch (ArrayIndexOutOfBoundsException ex) {
  2780             throw badClassFile("bad.class.file", c.flatname);
  2781         } finally {
  2782             interimUses = List.nil();
  2783             interimProvides = List.nil();
  2784             missingTypeVariables = List.nil();
  2785             foundTypeVariables = List.nil();
  2786             filling = false;
  2787         }
  2788     }
  2789     // where
  2790         static byte[] readInputStream(byte[] buf, InputStream s) throws IOException {
  2791             try {
  2792                 buf = ensureCapacity(buf, s.available());
  2793                 int r = s.read(buf);
  2794                 int bp = 0;
  2795                 while (r != -1) {
  2796                     bp += r;
  2797                     buf = ensureCapacity(buf, bp);
  2798                     r = s.read(buf, bp, buf.length - bp);
  2799                 }
  2800                 return buf;
  2801             } finally {
  2802                 try {
  2803                     s.close();
  2804                 } catch (IOException e) {
  2805                     /* Ignore any errors, as this stream may have already
  2806                      * thrown a related exception which is the one that
  2807                      * should be reported.
  2808                      */
  2809                 }
  2810             }
  2811         }
  2812         /*
  2813          * ensureCapacity will increase the buffer as needed, taking note that
  2814          * the new buffer will always be greater than the needed and never
  2815          * exactly equal to the needed size or bp. If equal then the read (above)
  2816          * will infinitely loop as buf.length - bp == 0.
  2817          */
  2818         private static byte[] ensureCapacity(byte[] buf, int needed) {
  2819             if (buf.length <= needed) {
  2820                 byte[] old = buf;
  2821                 buf = new byte[Integer.highestOneBit(needed) << 1];
  2822                 System.arraycopy(old, 0, buf, 0, old.length);
  2823             }
  2824             return buf;
  2825         }
  2826 
  2827     /** We can only read a single class file at a time; this
  2828      *  flag keeps track of when we are currently reading a class
  2829      *  file.
  2830      */
  2831     public boolean filling = false;
  2832 
  2833 /************************************************************************
  2834  * Adjusting flags
  2835  ***********************************************************************/
  2836 
  2837     long adjustFieldFlags(long flags) {
  2838         return flags | FROMCLASS;
  2839     }
  2840 
  2841     long adjustMethodFlags(long flags) {
  2842         if ((flags & ACC_BRIDGE) != 0) {
  2843             flags &= ~ACC_BRIDGE;
  2844             flags |= BRIDGE;
  2845         }
  2846         if ((flags & ACC_VARARGS) != 0) {
  2847             flags &= ~ACC_VARARGS;
  2848             flags |= VARARGS;
  2849         }
  2850         flags |= FROMCLASS;
  2851         return flags;
  2852     }
  2853 
  2854     long adjustClassFlags(long flags) {
  2855         if ((flags & ACC_MODULE) != 0) {
  2856             flags &= ~ACC_MODULE;
  2857             flags |= MODULE;
  2858         }
  2859         flags |= FROMCLASS;
  2860         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
  2861     }
  2862 
  2863     /**
  2864      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
  2865      * The attribute is only the last component of the original filename, so is unlikely
  2866      * to be valid as is, so operations other than those to access the name throw
  2867      * UnsupportedOperationException
  2868      */
  2869     private static class SourceFileObject implements JavaFileObject {
  2870 
  2871         /** The file's name.
  2872          */
  2873         private final Name name;
  2874         private final Name flatname;
  2875 
  2876         public SourceFileObject(Name name, Name flatname) {
  2877             this.name = name;
  2878             this.flatname = flatname;
  2879         }
  2880 
  2881         @Override @DefinedBy(Api.COMPILER)
  2882         public URI toUri() {
  2883             try {
  2884                 return new URI(null, name.toString(), null);
  2885             } catch (URISyntaxException e) {
  2886                 throw new PathFileObject.CannotCreateUriError(name.toString(), e);
  2887             }
  2888         }
  2889 
  2890         @Override @DefinedBy(Api.COMPILER)
  2891         public String getName() {
  2892             return name.toString();
  2893         }
  2894 
  2895         @Override @DefinedBy(Api.COMPILER)
  2896         public JavaFileObject.Kind getKind() {
  2897             return BaseFileManager.getKind(getName());
  2898         }
  2899 
  2900         @Override @DefinedBy(Api.COMPILER)
  2901         public InputStream openInputStream() {
  2902             throw new UnsupportedOperationException();
  2903         }
  2904 
  2905         @Override @DefinedBy(Api.COMPILER)
  2906         public OutputStream openOutputStream() {
  2907             throw new UnsupportedOperationException();
  2908         }
  2909 
  2910         @Override @DefinedBy(Api.COMPILER)
  2911         public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
  2912             throw new UnsupportedOperationException();
  2913         }
  2914 
  2915         @Override @DefinedBy(Api.COMPILER)
  2916         public Reader openReader(boolean ignoreEncodingErrors) {
  2917             throw new UnsupportedOperationException();
  2918         }
  2919 
  2920         @Override @DefinedBy(Api.COMPILER)
  2921         public Writer openWriter() {
  2922             throw new UnsupportedOperationException();
  2923         }
  2924 
  2925         @Override @DefinedBy(Api.COMPILER)
  2926         public long getLastModified() {
  2927             throw new UnsupportedOperationException();
  2928         }
  2929 
  2930         @Override @DefinedBy(Api.COMPILER)
  2931         public boolean delete() {
  2932             throw new UnsupportedOperationException();
  2933         }
  2934 
  2935         @Override @DefinedBy(Api.COMPILER)
  2936         public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) {
  2937             return true; // fail-safe mode
  2938         }
  2939 
  2940         @Override @DefinedBy(Api.COMPILER)
  2941         public NestingKind getNestingKind() {
  2942             return null;
  2943         }
  2944 
  2945         @Override @DefinedBy(Api.COMPILER)
  2946         public Modifier getAccessLevel() {
  2947             return null;
  2948         }
  2949 
  2950         /**
  2951          * Check if two file objects are equal.
  2952          * SourceFileObjects are just placeholder objects for the value of a
  2953          * SourceFile attribute, and do not directly represent specific files.
  2954          * Two SourceFileObjects are equal if their names are equal.
  2955          */
  2956         @Override
  2957         public boolean equals(Object other) {
  2958             if (this == other)
  2959                 return true;
  2960 
  2961             if (!(other instanceof SourceFileObject))
  2962                 return false;
  2963 
  2964             SourceFileObject o = (SourceFileObject) other;
  2965             return name.equals(o.name);
  2966         }
  2967 
  2968         @Override
  2969         public int hashCode() {
  2970             return name.hashCode();
  2971         }
  2972     }
  2973 
  2974     private class CompleterDeproxy implements AnnotationTypeCompleter {
  2975         ClassSymbol proxyOn;
  2976         CompoundAnnotationProxy target;
  2977         CompoundAnnotationProxy repeatable;
  2978 
  2979         public CompleterDeproxy(ClassSymbol c, CompoundAnnotationProxy target,
  2980                 CompoundAnnotationProxy repeatable)
  2981         {
  2982             this.proxyOn = c;
  2983             this.target = target;
  2984             this.repeatable = repeatable;
  2985         }
  2986 
  2987         @Override
  2988         public void complete(ClassSymbol sym) {
  2989             Assert.check(proxyOn == sym);
  2990             Attribute.Compound theTarget = null, theRepeatable = null;
  2991             AnnotationDeproxy deproxy;
  2992 
  2993             try {
  2994                 if (target != null) {
  2995                     deproxy = new AnnotationDeproxy(proxyOn);
  2996                     theTarget = deproxy.deproxyCompound(target);
  2997                 }
  2998 
  2999                 if (repeatable != null) {
  3000                     deproxy = new AnnotationDeproxy(proxyOn);
  3001                     theRepeatable = deproxy.deproxyCompound(repeatable);
  3002                 }
  3003             } catch (Exception e) {
  3004                 throw new CompletionFailure(sym, e.getMessage());
  3005             }
  3006 
  3007             sym.getAnnotationTypeMetadata().setTarget(theTarget);
  3008             sym.getAnnotationTypeMetadata().setRepeatable(theRepeatable);
  3009         }
  3010     }
  3011 
  3012     private class ProxyType extends Type {
  3013 
  3014         private final byte[] content;
  3015 
  3016         public ProxyType(byte[] content) {
  3017             super(syms.noSymbol, TypeMetadata.EMPTY);
  3018             this.content = content;
  3019         }
  3020 
  3021         @Override
  3022         public TypeTag getTag() {
  3023             return TypeTag.NONE;
  3024         }
  3025 
  3026         @Override
  3027         public Type cloneWithMetadata(TypeMetadata metadata) {
  3028             throw new UnsupportedOperationException();
  3029         }
  3030 
  3031         public Type resolve() {
  3032             return sigToType(content, 0, content.length);
  3033         }
  3034 
  3035         @Override @DefinedBy(Api.LANGUAGE_MODEL)
  3036         public String toString() {
  3037             return "<ProxyType>";
  3038         }
  3039 
  3040     }
  3041 
  3042     private static final class InterimUsesDirective {
  3043         public final Name service;
  3044 
  3045         public InterimUsesDirective(Name service) {
  3046             this.service = service;
  3047         }
  3048 
  3049     }
  3050 
  3051     private static final class InterimProvidesDirective {
  3052         public final Name service;
  3053         public final List<Name> impls;
  3054 
  3055         public InterimProvidesDirective(Name service, List<Name> impls) {
  3056             this.service = service;
  3057             this.impls = impls;
  3058         }
  3059 
  3060     }
  3061 
  3062     private final class UsesProvidesCompleter implements Completer {
  3063         private final ModuleSymbol currentModule;
  3064         private final List<InterimUsesDirective> interimUsesCopy;
  3065         private final List<InterimProvidesDirective> interimProvidesCopy;
  3066 
  3067         public UsesProvidesCompleter(ModuleSymbol currentModule, List<InterimUsesDirective> interimUsesCopy, List<InterimProvidesDirective> interimProvidesCopy) {
  3068             this.currentModule = currentModule;
  3069             this.interimUsesCopy = interimUsesCopy;
  3070             this.interimProvidesCopy = interimProvidesCopy;
  3071         }
  3072 
  3073         @Override
  3074         public void complete(Symbol sym) throws CompletionFailure {
  3075             ListBuffer<Directive> directives = new ListBuffer<>();
  3076             directives.addAll(currentModule.directives);
  3077             ListBuffer<UsesDirective> uses = new ListBuffer<>();
  3078             for (InterimUsesDirective interim : interimUsesCopy) {
  3079                 UsesDirective d = new UsesDirective(syms.enterClass(currentModule, interim.service));
  3080                 uses.add(d);
  3081                 directives.add(d);
  3082             }
  3083             currentModule.uses = uses.toList();
  3084             ListBuffer<ProvidesDirective> provides = new ListBuffer<>();
  3085             for (InterimProvidesDirective interim : interimProvidesCopy) {
  3086                 ListBuffer<ClassSymbol> impls = new ListBuffer<>();
  3087                 for (Name impl : interim.impls) {
  3088                     impls.append(syms.enterClass(currentModule, impl));
  3089                 }
  3090                 ProvidesDirective d = new ProvidesDirective(syms.enterClass(currentModule, interim.service),
  3091                                                             impls.toList());
  3092                 provides.add(d);
  3093                 directives.add(d);
  3094             }
  3095             currentModule.provides = provides.toList();
  3096             for (RequiresDirective rd : currentModule.requires) {
  3097                 if (rd.flags.contains(RequiresFlag.EXTRA)) {
  3098                     directives.add(rd);
  3099                 }
  3100             }
  3101             currentModule.directives = directives.toList();
  3102         }
  3103     }
  3104 }