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