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