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