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                 if (proxy.type.tsym == syms.proprietaryType.tsym)
1464                     sym.flags_field |= PROPRIETARY;
1465                 else if (proxy.type.tsym == syms.profileType.tsym) {
1466                     if (profile != Profile.DEFAULT) {
1467                         for (Pair<Name,Attribute> v: proxy.values) {
1468                             if (v.fst == names.value && v.snd instanceof Attribute.Constant) {
1469                                 Attribute.Constant c = (Attribute.Constant) v.snd;
1470                                 if (c.type == syms.intType && ((Integer) c.value) > profile.value) {
1471                                     sym.flags_field |= NOT_IN_PROFILE;
1472                                 }
1473                             }
1474                         }
1475                     }
1476                 } else {
1477                     if (proxy.type.tsym == syms.annotationTargetType.tsym) {
1478                         target = proxy;
1479                     } else if (proxy.type.tsym == syms.repeatableType.tsym) {
1480                         repeatable = proxy;
1481                     } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
1482                         sym.flags_field |= DEPRECATED;
1483                         for (Pair<Name, Attribute> v : proxy.values) {
1484                             if (v.fst == names.forRemoval && v.snd instanceof Attribute.Constant) {
1485                                 Attribute.Constant c = (Attribute.Constant) v.snd;
1486                                 if (c.type == syms.booleanType && ((Integer) c.value) != 0) {
1487                                     sym.flags_field |= DEPRECATED_REMOVAL;
1488                                 }
1489                             }
1490                         }
1491                     }
1492 
1493                     proxies.append(proxy);
1494                 }
1495             }
1496             annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
1497         }
1498     }
1499 
1500     /** Attach parameter annotations.
1501      */
1502     void attachParameterAnnotations(final Symbol method) {
1503         final MethodSymbol meth = (MethodSymbol)method;
1504         int numParameters = buf[bp++] & 0xFF;
1505         List<VarSymbol> parameters = meth.params();
1506         int pnum = 0;
1507         while (parameters.tail != null) {
1508             attachAnnotations(parameters.head);
1509             parameters = parameters.tail;
1510             pnum++;
1511         }
1512         if (pnum != numParameters) {
1513             throw badClassFile("bad.runtime.invisible.param.annotations", meth);
1514         }
1515     }
1516 
1517     void attachTypeAnnotations(final Symbol sym) {
1518         int numAttributes = nextChar();
1519         if (numAttributes != 0) {
1520             ListBuffer<TypeAnnotationProxy> proxies = new ListBuffer<>();
1521             for (int i = 0; i < numAttributes; i++)
1522                 proxies.append(readTypeAnnotation());
1523             annotate.normal(new TypeAnnotationCompleter(sym, proxies.toList()));
1524         }
1525     }
1526 
1527     /** Attach the default value for an annotation element.
1528      */
1529     void attachAnnotationDefault(final Symbol sym) {
1530         final MethodSymbol meth = (MethodSymbol)sym; // only on methods
1531         final Attribute value = readAttributeValue();
1532 
1533         // The default value is set later during annotation. It might
1534         // be the case that the Symbol sym is annotated _after_ the
1535         // repeating instances that depend on this default value,
1536         // because of this we set an interim value that tells us this
1537         // element (most likely) has a default.
1538         //
1539         // Set interim value for now, reset just before we do this
1540         // properly at annotate time.
1541         meth.defaultValue = value;
1542         annotate.normal(new AnnotationDefaultCompleter(meth, value));
1543     }
1544 
1545     Type readTypeOrClassSymbol(int i) {
1546         // support preliminary jsr175-format class files
1547         if (buf[poolIdx[i]] == CONSTANT_Class)
1548             return readClassSymbol(i).type;
1549         return readType(i);
1550     }
1551     Type readEnumType(int i) {
1552         // support preliminary jsr175-format class files
1553         int index = poolIdx[i];
1554         int length = getChar(index + 1);
1555         if (buf[index + length + 2] != ';')
1556             return enterClass(readName(i)).type;
1557         return readType(i);
1558     }
1559 
1560     CompoundAnnotationProxy readCompoundAnnotation() {
1561         Type t = readTypeOrClassSymbol(nextChar());
1562         int numFields = nextChar();
1563         ListBuffer<Pair<Name,Attribute>> pairs = new ListBuffer<>();
1564         for (int i=0; i<numFields; i++) {
1565             Name name = readName(nextChar());
1566             Attribute value = readAttributeValue();
1567             pairs.append(new Pair<>(name, value));
1568         }
1569         return new CompoundAnnotationProxy(t, pairs.toList());
1570     }
1571 
1572     TypeAnnotationProxy readTypeAnnotation() {
1573         TypeAnnotationPosition position = readPosition();
1574         CompoundAnnotationProxy proxy = readCompoundAnnotation();
1575 
1576         return new TypeAnnotationProxy(proxy, position);
1577     }
1578 
1579     TypeAnnotationPosition readPosition() {
1580         int tag = nextByte(); // TargetType tag is a byte
1581 
1582         if (!TargetType.isValidTargetTypeValue(tag))
1583             throw badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
1584 
1585         TargetType type = TargetType.fromTargetTypeValue(tag);
1586 
1587         switch (type) {
1588         // instanceof
1589         case INSTANCEOF: {
1590             final int offset = nextChar();
1591             final TypeAnnotationPosition position =
1592                 TypeAnnotationPosition.instanceOf(readTypePath());
1593             position.offset = offset;
1594             return position;
1595         }
1596         // new expression
1597         case NEW: {
1598             final int offset = nextChar();
1599             final TypeAnnotationPosition position =
1600                 TypeAnnotationPosition.newObj(readTypePath());
1601             position.offset = offset;
1602             return position;
1603         }
1604         // constructor/method reference receiver
1605         case CONSTRUCTOR_REFERENCE: {
1606             final int offset = nextChar();
1607             final TypeAnnotationPosition position =
1608                 TypeAnnotationPosition.constructorRef(readTypePath());
1609             position.offset = offset;
1610             return position;
1611         }
1612         case METHOD_REFERENCE: {
1613             final int offset = nextChar();
1614             final TypeAnnotationPosition position =
1615                 TypeAnnotationPosition.methodRef(readTypePath());
1616             position.offset = offset;
1617             return position;
1618         }
1619         // local variable
1620         case LOCAL_VARIABLE: {
1621             final int table_length = nextChar();
1622             final int[] newLvarOffset = new int[table_length];
1623             final int[] newLvarLength = new int[table_length];
1624             final int[] newLvarIndex = new int[table_length];
1625 
1626             for (int i = 0; i < table_length; ++i) {
1627                 newLvarOffset[i] = nextChar();
1628                 newLvarLength[i] = nextChar();
1629                 newLvarIndex[i] = nextChar();
1630             }
1631 
1632             final TypeAnnotationPosition position =
1633                     TypeAnnotationPosition.localVariable(readTypePath());
1634             position.lvarOffset = newLvarOffset;
1635             position.lvarLength = newLvarLength;
1636             position.lvarIndex = newLvarIndex;
1637             return position;
1638         }
1639         // resource variable
1640         case RESOURCE_VARIABLE: {
1641             final int table_length = nextChar();
1642             final int[] newLvarOffset = new int[table_length];
1643             final int[] newLvarLength = new int[table_length];
1644             final int[] newLvarIndex = new int[table_length];
1645 
1646             for (int i = 0; i < table_length; ++i) {
1647                 newLvarOffset[i] = nextChar();
1648                 newLvarLength[i] = nextChar();
1649                 newLvarIndex[i] = nextChar();
1650             }
1651 
1652             final TypeAnnotationPosition position =
1653                     TypeAnnotationPosition.resourceVariable(readTypePath());
1654             position.lvarOffset = newLvarOffset;
1655             position.lvarLength = newLvarLength;
1656             position.lvarIndex = newLvarIndex;
1657             return position;
1658         }
1659         // exception parameter
1660         case EXCEPTION_PARAMETER: {
1661             final int exception_index = nextChar();
1662             final TypeAnnotationPosition position =
1663                 TypeAnnotationPosition.exceptionParameter(readTypePath());
1664             position.setExceptionIndex(exception_index);
1665             return position;
1666         }
1667         // method receiver
1668         case METHOD_RECEIVER:
1669             return TypeAnnotationPosition.methodReceiver(readTypePath());
1670         // type parameter
1671         case CLASS_TYPE_PARAMETER: {
1672             final int parameter_index = nextByte();
1673             return TypeAnnotationPosition
1674                 .typeParameter(readTypePath(), parameter_index);
1675         }
1676         case METHOD_TYPE_PARAMETER: {
1677             final int parameter_index = nextByte();
1678             return TypeAnnotationPosition
1679                 .methodTypeParameter(readTypePath(), parameter_index);
1680         }
1681         // type parameter bound
1682         case CLASS_TYPE_PARAMETER_BOUND: {
1683             final int parameter_index = nextByte();
1684             final int bound_index = nextByte();
1685             return TypeAnnotationPosition
1686                 .typeParameterBound(readTypePath(), parameter_index,
1687                                     bound_index);
1688         }
1689         case METHOD_TYPE_PARAMETER_BOUND: {
1690             final int parameter_index = nextByte();
1691             final int bound_index = nextByte();
1692             return TypeAnnotationPosition
1693                 .methodTypeParameterBound(readTypePath(), parameter_index,
1694                                           bound_index);
1695         }
1696         // class extends or implements clause
1697         case CLASS_EXTENDS: {
1698             final int type_index = nextChar();
1699             return TypeAnnotationPosition.classExtends(readTypePath(),
1700                                                        type_index);
1701         }
1702         // throws
1703         case THROWS: {
1704             final int type_index = nextChar();
1705             return TypeAnnotationPosition.methodThrows(readTypePath(),
1706                                                        type_index);
1707         }
1708         // method parameter
1709         case METHOD_FORMAL_PARAMETER: {
1710             final int parameter_index = nextByte();
1711             return TypeAnnotationPosition.methodParameter(readTypePath(),
1712                                                           parameter_index);
1713         }
1714         // type cast
1715         case CAST: {
1716             final int offset = nextChar();
1717             final int type_index = nextByte();
1718             final TypeAnnotationPosition position =
1719                 TypeAnnotationPosition.typeCast(readTypePath(), type_index);
1720             position.offset = offset;
1721             return position;
1722         }
1723         // method/constructor/reference type argument
1724         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: {
1725             final int offset = nextChar();
1726             final int type_index = nextByte();
1727             final TypeAnnotationPosition position = TypeAnnotationPosition
1728                 .constructorInvocationTypeArg(readTypePath(), type_index);
1729             position.offset = offset;
1730             return position;
1731         }
1732         case METHOD_INVOCATION_TYPE_ARGUMENT: {
1733             final int offset = nextChar();
1734             final int type_index = nextByte();
1735             final TypeAnnotationPosition position = TypeAnnotationPosition
1736                 .methodInvocationTypeArg(readTypePath(), type_index);
1737             position.offset = offset;
1738             return position;
1739         }
1740         case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: {
1741             final int offset = nextChar();
1742             final int type_index = nextByte();
1743             final TypeAnnotationPosition position = TypeAnnotationPosition
1744                 .constructorRefTypeArg(readTypePath(), type_index);
1745             position.offset = offset;
1746             return position;
1747         }
1748         case METHOD_REFERENCE_TYPE_ARGUMENT: {
1749             final int offset = nextChar();
1750             final int type_index = nextByte();
1751             final TypeAnnotationPosition position = TypeAnnotationPosition
1752                 .methodRefTypeArg(readTypePath(), type_index);
1753             position.offset = offset;
1754             return position;
1755         }
1756         // We don't need to worry about these
1757         case METHOD_RETURN:
1758             return TypeAnnotationPosition.methodReturn(readTypePath());
1759         case FIELD:
1760             return TypeAnnotationPosition.field(readTypePath());
1761         case UNKNOWN:
1762             throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
1763         default:
1764             throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + type);
1765         }
1766     }
1767 
1768     List<TypeAnnotationPosition.TypePathEntry> readTypePath() {
1769         int len = nextByte();
1770         ListBuffer<Integer> loc = new ListBuffer<>();
1771         for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i)
1772             loc = loc.append(nextByte());
1773 
1774         return TypeAnnotationPosition.getTypePathFromBinary(loc.toList());
1775 
1776     }
1777 
1778     Attribute readAttributeValue() {
1779         char c = (char) buf[bp++];
1780         switch (c) {
1781         case 'B':
1782             return new Attribute.Constant(syms.byteType, readPool(nextChar()));
1783         case 'C':
1784             return new Attribute.Constant(syms.charType, readPool(nextChar()));
1785         case 'D':
1786             return new Attribute.Constant(syms.doubleType, readPool(nextChar()));
1787         case 'F':
1788             return new Attribute.Constant(syms.floatType, readPool(nextChar()));
1789         case 'I':
1790             return new Attribute.Constant(syms.intType, readPool(nextChar()));
1791         case 'J':
1792             return new Attribute.Constant(syms.longType, readPool(nextChar()));
1793         case 'S':
1794             return new Attribute.Constant(syms.shortType, readPool(nextChar()));
1795         case 'Z':
1796             return new Attribute.Constant(syms.booleanType, readPool(nextChar()));
1797         case 's':
1798             return new Attribute.Constant(syms.stringType, readPool(nextChar()).toString());
1799         case 'e':
1800             return new EnumAttributeProxy(readEnumType(nextChar()), readName(nextChar()));
1801         case 'c':
1802             return new Attribute.Class(types, readTypeOrClassSymbol(nextChar()));
1803         case '[': {
1804             int n = nextChar();
1805             ListBuffer<Attribute> l = new ListBuffer<>();
1806             for (int i=0; i<n; i++)
1807                 l.append(readAttributeValue());
1808             return new ArrayAttributeProxy(l.toList());
1809         }
1810         case '@':
1811             return readCompoundAnnotation();
1812         default:
1813             throw new AssertionError("unknown annotation tag '" + c + "'");
1814         }
1815     }
1816 
1817     interface ProxyVisitor extends Attribute.Visitor {
1818         void visitEnumAttributeProxy(EnumAttributeProxy proxy);
1819         void visitArrayAttributeProxy(ArrayAttributeProxy proxy);
1820         void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy);
1821     }
1822 
1823     static class EnumAttributeProxy extends Attribute {
1824         Type enumType;
1825         Name enumerator;
1826         public EnumAttributeProxy(Type enumType, Name enumerator) {
1827             super(null);
1828             this.enumType = enumType;
1829             this.enumerator = enumerator;
1830         }
1831         public void accept(Visitor v) { ((ProxyVisitor)v).visitEnumAttributeProxy(this); }
1832         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1833         public String toString() {
1834             return "/*proxy enum*/" + enumType + "." + enumerator;
1835         }
1836     }
1837 
1838     static class ArrayAttributeProxy extends Attribute {
1839         List<Attribute> values;
1840         ArrayAttributeProxy(List<Attribute> values) {
1841             super(null);
1842             this.values = values;
1843         }
1844         public void accept(Visitor v) { ((ProxyVisitor)v).visitArrayAttributeProxy(this); }
1845         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1846         public String toString() {
1847             return "{" + values + "}";
1848         }
1849     }
1850 
1851     /** A temporary proxy representing a compound attribute.
1852      */
1853     static class CompoundAnnotationProxy extends Attribute {
1854         final List<Pair<Name,Attribute>> values;
1855         public CompoundAnnotationProxy(Type type,
1856                                       List<Pair<Name,Attribute>> values) {
1857             super(type);
1858             this.values = values;
1859         }
1860         public void accept(Visitor v) { ((ProxyVisitor)v).visitCompoundAnnotationProxy(this); }
1861         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1862         public String toString() {
1863             StringBuilder buf = new StringBuilder();
1864             buf.append("@");
1865             buf.append(type.tsym.getQualifiedName());
1866             buf.append("/*proxy*/{");
1867             boolean first = true;
1868             for (List<Pair<Name,Attribute>> v = values;
1869                  v.nonEmpty(); v = v.tail) {
1870                 Pair<Name,Attribute> value = v.head;
1871                 if (!first) buf.append(",");
1872                 first = false;
1873                 buf.append(value.fst);
1874                 buf.append("=");
1875                 buf.append(value.snd);
1876             }
1877             buf.append("}");
1878             return buf.toString();
1879         }
1880     }
1881 
1882     /** A temporary proxy representing a type annotation.
1883      */
1884     static class TypeAnnotationProxy {
1885         final CompoundAnnotationProxy compound;
1886         final TypeAnnotationPosition position;
1887         public TypeAnnotationProxy(CompoundAnnotationProxy compound,
1888                 TypeAnnotationPosition position) {
1889             this.compound = compound;
1890             this.position = position;
1891         }
1892     }
1893 
1894     class AnnotationDeproxy implements ProxyVisitor {
1895         private ClassSymbol requestingOwner;
1896 
1897         AnnotationDeproxy(ClassSymbol owner) {
1898             this.requestingOwner = owner;
1899         }
1900 
1901         List<Attribute.Compound> deproxyCompoundList(List<CompoundAnnotationProxy> pl) {
1902             // also must fill in types!!!!
1903             ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
1904             for (List<CompoundAnnotationProxy> l = pl; l.nonEmpty(); l=l.tail) {
1905                 buf.append(deproxyCompound(l.head));
1906             }
1907             return buf.toList();
1908         }
1909 
1910         Attribute.Compound deproxyCompound(CompoundAnnotationProxy a) {
1911             ListBuffer<Pair<Symbol.MethodSymbol,Attribute>> buf = new ListBuffer<>();
1912             for (List<Pair<Name,Attribute>> l = a.values;
1913                  l.nonEmpty();
1914                  l = l.tail) {
1915                 MethodSymbol meth = findAccessMethod(a.type, l.head.fst);
1916                 buf.append(new Pair<>(meth, deproxy(meth.type.getReturnType(), l.head.snd)));
1917             }
1918             return new Attribute.Compound(a.type, buf.toList());
1919         }
1920 
1921         MethodSymbol findAccessMethod(Type container, Name name) {
1922             CompletionFailure failure = null;
1923             try {
1924                 for (Symbol sym : container.tsym.members().getSymbolsByName(name)) {
1925                     if (sym.kind == MTH && sym.type.getParameterTypes().length() == 0)
1926                         return (MethodSymbol) sym;
1927                 }
1928             } catch (CompletionFailure ex) {
1929                 failure = ex;
1930             }
1931             // The method wasn't found: emit a warning and recover
1932             JavaFileObject prevSource = log.useSource(requestingOwner.classfile);
1933             try {
1934                 if (lintClassfile) {
1935                     if (failure == null) {
1936                         log.warning("annotation.method.not.found",
1937                                     container,
1938                                     name);
1939                     } else {
1940                         log.warning("annotation.method.not.found.reason",
1941                                     container,
1942                                     name,
1943                                     failure.getDetailValue());//diagnostic, if present
1944                     }
1945                 }
1946             } finally {
1947                 log.useSource(prevSource);
1948             }
1949             // Construct a new method type and symbol.  Use bottom
1950             // type (typeof null) as return type because this type is
1951             // a subtype of all reference types and can be converted
1952             // to primitive types by unboxing.
1953             MethodType mt = new MethodType(List.<Type>nil(),
1954                                            syms.botType,
1955                                            List.<Type>nil(),
1956                                            syms.methodClass);
1957             return new MethodSymbol(PUBLIC | ABSTRACT, name, mt, container.tsym);
1958         }
1959 
1960         Attribute result;
1961         Type type;
1962         Attribute deproxy(Type t, Attribute a) {
1963             Type oldType = type;
1964             try {
1965                 type = t;
1966                 a.accept(this);
1967                 return result;
1968             } finally {
1969                 type = oldType;
1970             }
1971         }
1972 
1973         // implement Attribute.Visitor below
1974 
1975         public void visitConstant(Attribute.Constant value) {
1976             // assert value.type == type;
1977             result = value;
1978         }
1979 
1980         public void visitClass(Attribute.Class clazz) {
1981             result = clazz;
1982         }
1983 
1984         public void visitEnum(Attribute.Enum e) {
1985             throw new AssertionError(); // shouldn't happen
1986         }
1987 
1988         public void visitCompound(Attribute.Compound compound) {
1989             throw new AssertionError(); // shouldn't happen
1990         }
1991 
1992         public void visitArray(Attribute.Array array) {
1993             throw new AssertionError(); // shouldn't happen
1994         }
1995 
1996         public void visitError(Attribute.Error e) {
1997             throw new AssertionError(); // shouldn't happen
1998         }
1999 
2000         public void visitEnumAttributeProxy(EnumAttributeProxy proxy) {
2001             // type.tsym.flatName() should == proxy.enumFlatName
2002             TypeSymbol enumTypeSym = proxy.enumType.tsym;
2003             VarSymbol enumerator = null;
2004             CompletionFailure failure = null;
2005             try {
2006                 for (Symbol sym : enumTypeSym.members().getSymbolsByName(proxy.enumerator)) {
2007                     if (sym.kind == VAR) {
2008                         enumerator = (VarSymbol)sym;
2009                         break;
2010                     }
2011                 }
2012             }
2013             catch (CompletionFailure ex) {
2014                 failure = ex;
2015             }
2016             if (enumerator == null) {
2017                 if (failure != null) {
2018                     log.warning("unknown.enum.constant.reason",
2019                               currentClassFile, enumTypeSym, proxy.enumerator,
2020                               failure.getDiagnostic());
2021                 } else {
2022                     log.warning("unknown.enum.constant",
2023                               currentClassFile, enumTypeSym, proxy.enumerator);
2024                 }
2025                 result = new Attribute.Enum(enumTypeSym.type,
2026                         new VarSymbol(0, proxy.enumerator, syms.botType, enumTypeSym));
2027             } else {
2028                 result = new Attribute.Enum(enumTypeSym.type, enumerator);
2029             }
2030         }
2031 
2032         public void visitArrayAttributeProxy(ArrayAttributeProxy proxy) {
2033             int length = proxy.values.length();
2034             Attribute[] ats = new Attribute[length];
2035             Type elemtype = types.elemtype(type);
2036             int i = 0;
2037             for (List<Attribute> p = proxy.values; p.nonEmpty(); p = p.tail) {
2038                 ats[i++] = deproxy(elemtype, p.head);
2039             }
2040             result = new Attribute.Array(type, ats);
2041         }
2042 
2043         public void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy) {
2044             result = deproxyCompound(proxy);
2045         }
2046     }
2047 
2048     class AnnotationDefaultCompleter extends AnnotationDeproxy implements Runnable {
2049         final MethodSymbol sym;
2050         final Attribute value;
2051         final JavaFileObject classFile = currentClassFile;
2052 
2053         AnnotationDefaultCompleter(MethodSymbol sym, Attribute value) {
2054             super(currentOwner.kind == MTH
2055                     ? currentOwner.enclClass() : (ClassSymbol)currentOwner);
2056             this.sym = sym;
2057             this.value = value;
2058         }
2059 
2060         @Override
2061         public void run() {
2062             JavaFileObject previousClassFile = currentClassFile;
2063             try {
2064                 // Reset the interim value set earlier in
2065                 // attachAnnotationDefault().
2066                 sym.defaultValue = null;
2067                 currentClassFile = classFile;
2068                 sym.defaultValue = deproxy(sym.type.getReturnType(), value);
2069             } finally {
2070                 currentClassFile = previousClassFile;
2071             }
2072         }
2073 
2074         @Override
2075         public String toString() {
2076             return " ClassReader store default for " + sym.owner + "." + sym + " is " + value;
2077         }
2078     }
2079 
2080     class AnnotationCompleter extends AnnotationDeproxy implements Runnable {
2081         final Symbol sym;
2082         final List<CompoundAnnotationProxy> l;
2083         final JavaFileObject classFile;
2084 
2085         AnnotationCompleter(Symbol sym, List<CompoundAnnotationProxy> l) {
2086             super(currentOwner.kind == MTH
2087                     ? currentOwner.enclClass() : (ClassSymbol)currentOwner);
2088             this.sym = sym;
2089             this.l = l;
2090             this.classFile = currentClassFile;
2091         }
2092 
2093         @Override
2094         public void run() {
2095             JavaFileObject previousClassFile = currentClassFile;
2096             try {
2097                 currentClassFile = classFile;
2098                 List<Attribute.Compound> newList = deproxyCompoundList(l);
2099                 if (sym.annotationsPendingCompletion()) {
2100                     sym.setDeclarationAttributes(newList);
2101                 } else {
2102                     sym.appendAttributes(newList);
2103                 }
2104             } finally {
2105                 currentClassFile = previousClassFile;
2106             }
2107         }
2108 
2109         @Override
2110         public String toString() {
2111             return " ClassReader annotate " + sym.owner + "." + sym + " with " + l;
2112         }
2113     }
2114 
2115     class TypeAnnotationCompleter extends AnnotationCompleter {
2116 
2117         List<TypeAnnotationProxy> proxies;
2118 
2119         TypeAnnotationCompleter(Symbol sym,
2120                 List<TypeAnnotationProxy> proxies) {
2121             super(sym, List.<CompoundAnnotationProxy>nil());
2122             this.proxies = proxies;
2123         }
2124 
2125         List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
2126             ListBuffer<Attribute.TypeCompound> buf = new ListBuffer<>();
2127             for (TypeAnnotationProxy proxy: proxies) {
2128                 Attribute.Compound compound = deproxyCompound(proxy.compound);
2129                 Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position);
2130                 buf.add(typeCompound);
2131             }
2132             return buf.toList();
2133         }
2134 
2135         @Override
2136         public void run() {
2137             JavaFileObject previousClassFile = currentClassFile;
2138             try {
2139                 currentClassFile = classFile;
2140                 List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies);
2141                 sym.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes()));
2142             } finally {
2143                 currentClassFile = previousClassFile;
2144             }
2145         }
2146     }
2147 
2148 
2149 /************************************************************************
2150  * Reading Symbols
2151  ***********************************************************************/
2152 
2153     /** Read a field.
2154      */
2155     VarSymbol readField() {
2156         long flags = adjustFieldFlags(nextChar());
2157         Name name = readName(nextChar());
2158         Type type = readType(nextChar());
2159         VarSymbol v = new VarSymbol(flags, name, type, currentOwner);
2160         readMemberAttrs(v);
2161         return v;
2162     }
2163 
2164     /** Read a method.
2165      */
2166     MethodSymbol readMethod() {
2167         long flags = adjustMethodFlags(nextChar());
2168         Name name = readName(nextChar());
2169         Type type = readType(nextChar());
2170         if (currentOwner.isInterface() &&
2171                 (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
2172             if (majorVersion > Version.V52.major ||
2173                     (majorVersion == Version.V52.major && minorVersion >= Version.V52.minor)) {
2174                 if ((flags & STATIC) == 0) {
2175                     currentOwner.flags_field |= DEFAULT;
2176                     flags |= DEFAULT | ABSTRACT;
2177                 }
2178             } else {
2179                 //protect against ill-formed classfiles
2180                 throw badClassFile((flags & STATIC) == 0 ? "invalid.default.interface" : "invalid.static.interface",
2181                                    Integer.toString(majorVersion),
2182                                    Integer.toString(minorVersion));
2183             }
2184         }
2185         if (name == names.init && currentOwner.hasOuterInstance()) {
2186             // Sometimes anonymous classes don't have an outer
2187             // instance, however, there is no reliable way to tell so
2188             // we never strip this$n
2189             if (!currentOwner.name.isEmpty())
2190                 type = new MethodType(adjustMethodParams(flags, type.getParameterTypes()),
2191                                       type.getReturnType(),
2192                                       type.getThrownTypes(),
2193                                       syms.methodClass);
2194         }
2195         MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
2196         if (types.isSignaturePolymorphic(m)) {
2197             m.flags_field |= SIGNATURE_POLYMORPHIC;
2198         }
2199         if (saveParameterNames)
2200             initParameterNames(m);
2201         Symbol prevOwner = currentOwner;
2202         currentOwner = m;
2203         try {
2204             readMemberAttrs(m);
2205         } finally {
2206             currentOwner = prevOwner;
2207         }
2208         if (saveParameterNames)
2209             setParameterNames(m, type);
2210 
2211         if ((flags & VARARGS) != 0) {
2212             final Type last = type.getParameterTypes().last();
2213             if (last == null || !last.hasTag(ARRAY)) {
2214                 m.flags_field &= ~VARARGS;
2215                 throw badClassFile("malformed.vararg.method", m);
2216             }
2217         }
2218 
2219         return m;
2220     }
2221 
2222     private List<Type> adjustMethodParams(long flags, List<Type> args) {
2223         boolean isVarargs = (flags & VARARGS) != 0;
2224         if (isVarargs) {
2225             Type varargsElem = args.last();
2226             ListBuffer<Type> adjustedArgs = new ListBuffer<>();
2227             for (Type t : args) {
2228                 adjustedArgs.append(t != varargsElem ?
2229                     t :
2230                     ((ArrayType)t).makeVarargs());
2231             }
2232             args = adjustedArgs.toList();
2233         }
2234         return args.tail;
2235     }
2236 
2237     /**
2238      * Init the parameter names array.
2239      * Parameter names are currently inferred from the names in the
2240      * LocalVariableTable attributes of a Code attribute.
2241      * (Note: this means parameter names are currently not available for
2242      * methods without a Code attribute.)
2243      * This method initializes an array in which to store the name indexes
2244      * of parameter names found in LocalVariableTable attributes. It is
2245      * slightly supersized to allow for additional slots with a start_pc of 0.
2246      */
2247     void initParameterNames(MethodSymbol sym) {
2248         // make allowance for synthetic parameters.
2249         final int excessSlots = 4;
2250         int expectedParameterSlots =
2251                 Code.width(sym.type.getParameterTypes()) + excessSlots;
2252         if (parameterNameIndices == null
2253                 || parameterNameIndices.length < expectedParameterSlots) {
2254             parameterNameIndices = new int[expectedParameterSlots];
2255         } else
2256             Arrays.fill(parameterNameIndices, 0);
2257         haveParameterNameIndices = false;
2258         sawMethodParameters = false;
2259     }
2260 
2261     /**
2262      * Set the parameter names for a symbol from the name index in the
2263      * parameterNameIndicies array. The type of the symbol may have changed
2264      * while reading the method attributes (see the Signature attribute).
2265      * This may be because of generic information or because anonymous
2266      * synthetic parameters were added.   The original type (as read from
2267      * the method descriptor) is used to help guess the existence of
2268      * anonymous synthetic parameters.
2269      * On completion, sym.savedParameter names will either be null (if
2270      * no parameter names were found in the class file) or will be set to a
2271      * list of names, one per entry in sym.type.getParameterTypes, with
2272      * any missing names represented by the empty name.
2273      */
2274     void setParameterNames(MethodSymbol sym, Type jvmType) {
2275         // if no names were found in the class file, there's nothing more to do
2276         if (!haveParameterNameIndices)
2277             return;
2278         // If we get parameter names from MethodParameters, then we
2279         // don't need to skip.
2280         int firstParam = 0;
2281         if (!sawMethodParameters) {
2282             firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
2283             // the code in readMethod may have skipped the first
2284             // parameter when setting up the MethodType. If so, we
2285             // make a corresponding allowance here for the position of
2286             // the first parameter.  Note that this assumes the
2287             // skipped parameter has a width of 1 -- i.e. it is not
2288         // a double width type (long or double.)
2289         if (sym.name == names.init && currentOwner.hasOuterInstance()) {
2290             // Sometimes anonymous classes don't have an outer
2291             // instance, however, there is no reliable way to tell so
2292             // we never strip this$n
2293             if (!currentOwner.name.isEmpty())
2294                 firstParam += 1;
2295         }
2296 
2297         if (sym.type != jvmType) {
2298                 // reading the method attributes has caused the
2299                 // symbol's type to be changed. (i.e. the Signature
2300                 // attribute.)  This may happen if there are hidden
2301                 // (synthetic) parameters in the descriptor, but not
2302                 // in the Signature.  The position of these hidden
2303                 // parameters is unspecified; for now, assume they are
2304                 // at the beginning, and so skip over them. The
2305                 // primary case for this is two hidden parameters
2306                 // passed into Enum constructors.
2307             int skip = Code.width(jvmType.getParameterTypes())
2308                     - Code.width(sym.type.getParameterTypes());
2309             firstParam += skip;
2310         }
2311         }
2312         List<Name> paramNames = List.nil();
2313         int index = firstParam;
2314         for (Type t: sym.type.getParameterTypes()) {
2315             int nameIdx = (index < parameterNameIndices.length
2316                     ? parameterNameIndices[index] : 0);
2317             Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
2318             paramNames = paramNames.prepend(name);
2319             index += Code.width(t);
2320         }
2321         sym.savedParameterNames = paramNames.reverse();
2322     }
2323 
2324     /**
2325      * skip n bytes
2326      */
2327     void skipBytes(int n) {
2328         bp = bp + n;
2329     }
2330 
2331     /** Skip a field or method
2332      */
2333     void skipMember() {
2334         bp = bp + 6;
2335         char ac = nextChar();
2336         for (int i = 0; i < ac; i++) {
2337             bp = bp + 2;
2338             int attrLen = nextInt();
2339             bp = bp + attrLen;
2340         }
2341     }
2342 
2343     void skipInnerClasses() {
2344         int n = nextChar();
2345         for (int i = 0; i < n; i++) {
2346             nextChar();
2347             nextChar();
2348             nextChar();
2349             nextChar();
2350         }
2351     }
2352 
2353     /** Enter type variables of this classtype and all enclosing ones in
2354      *  `typevars'.
2355      */
2356     protected void enterTypevars(Type t) {
2357         if (t.getEnclosingType() != null && t.getEnclosingType().hasTag(CLASS))
2358             enterTypevars(t.getEnclosingType());
2359         for (List<Type> xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail)
2360             typevars.enter(xs.head.tsym);
2361     }
2362 
2363     protected void enterTypevars(Symbol sym) {
2364         if (sym.owner.kind == MTH) {
2365             enterTypevars(sym.owner);
2366             enterTypevars(sym.owner.owner);
2367         }
2368         enterTypevars(sym.type);
2369     }
2370 
2371     protected ClassSymbol enterClass(Name name) {
2372         return syms.enterClass(currentModule, name);
2373     }
2374 
2375     protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
2376         return syms.enterClass(currentModule, name, owner);
2377     }
2378 
2379     /** Read contents of a given class symbol `c'. Both external and internal
2380      *  versions of an inner class are read.
2381      */
2382     void readClass(ClassSymbol c) {
2383         ClassType ct = (ClassType)c.type;
2384 
2385         // allocate scope for members
2386         c.members_field = WriteableScope.create(c);
2387 
2388         // prepare type variable table
2389         typevars = typevars.dup(currentOwner);
2390         if (ct.getEnclosingType().hasTag(CLASS))
2391             enterTypevars(ct.getEnclosingType());
2392 
2393         // read flags, or skip if this is an inner class
2394         long f = nextChar();
2395         long flags = adjustClassFlags(f);
2396         if ((flags & MODULE) == 0) {
2397             if (c.owner.kind == PCK) c.flags_field = flags;
2398             // read own class name and check that it matches
2399             currentModule = c.packge().modle;
2400             ClassSymbol self = readClassSymbol(nextChar());
2401             if (c != self) {
2402                 throw badClassFile("class.file.wrong.class",
2403                                    self.flatname);
2404             }
2405         } else {
2406             c.flags_field = flags;
2407             Name modInfoName = readModuleInfoName(nextChar());
2408             currentModule = (ModuleSymbol) c.owner;
2409             if (currentModule.name.append('.', names.module_info) != modInfoName) {
2410                 //strip trailing .module-info, if exists:
2411                 int modInfoStart = modInfoName.length() - names.module_info.length();
2412                 modInfoName = modInfoName.subName(modInfoStart, modInfoName.length()) == names.module_info &&
2413                               modInfoName.charAt(modInfoStart - 1) == '.' ?
2414                                   modInfoName.subName(0, modInfoStart - 1) : modInfoName;
2415                 throw badClassFile("module.name.mismatch", modInfoName, currentModule.name);
2416             }
2417         }
2418 
2419         // class attributes must be read before class
2420         // skip ahead to read class attributes
2421         int startbp = bp;
2422         nextChar();
2423         char interfaceCount = nextChar();
2424         bp += interfaceCount * 2;
2425         char fieldCount = nextChar();
2426         for (int i = 0; i < fieldCount; i++) skipMember();
2427         char methodCount = nextChar();
2428         for (int i = 0; i < methodCount; i++) skipMember();
2429         readClassAttrs(c);
2430 
2431         if (readAllOfClassFile) {
2432             for (int i = 1; i < poolObj.length; i++) readPool(i);
2433             c.pool = new Pool(poolObj.length, poolObj, types);
2434         }
2435 
2436         // reset and read rest of classinfo
2437         bp = startbp;
2438         int n = nextChar();
2439         if ((flags & MODULE) != 0 && n > 0) {
2440             throw badClassFile("module.info.invalid.super.class");
2441         }
2442         if (ct.supertype_field == null)
2443             ct.supertype_field = (n == 0)
2444                 ? Type.noType
2445                 : readClassSymbol(n).erasure(types);
2446         n = nextChar();
2447         List<Type> is = List.nil();
2448         for (int i = 0; i < n; i++) {
2449             Type _inter = readClassSymbol(nextChar()).erasure(types);
2450             is = is.prepend(_inter);
2451         }
2452         if (ct.interfaces_field == null)
2453             ct.interfaces_field = is.reverse();
2454 
2455         Assert.check(fieldCount == nextChar());
2456         for (int i = 0; i < fieldCount; i++) enterMember(c, readField());
2457         Assert.check(methodCount == nextChar());
2458         for (int i = 0; i < methodCount; i++) enterMember(c, readMethod());
2459 
2460         typevars = typevars.leave();
2461     }
2462 
2463     /** Read inner class info. For each inner/outer pair allocate a
2464      *  member class.
2465      */
2466     void readInnerClasses(ClassSymbol c) {
2467         int n = nextChar();
2468         for (int i = 0; i < n; i++) {
2469             nextChar(); // skip inner class symbol
2470             ClassSymbol outer = readClassSymbol(nextChar());
2471             Name name = readName(nextChar());
2472             if (name == null) name = names.empty;
2473             long flags = adjustClassFlags(nextChar());
2474             if (outer != null) { // we have a member class
2475                 if (name == names.empty)
2476                     name = names.one;
2477                 ClassSymbol member = enterClass(name, outer);
2478                 if ((flags & STATIC) == 0) {
2479                     ((ClassType)member.type).setEnclosingType(outer.type);
2480                     if (member.erasure_field != null)
2481                         ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type));
2482                 }
2483                 if (c == outer) {
2484                     member.flags_field = flags;
2485                     enterMember(c, member);
2486                 }
2487             }
2488         }
2489     }
2490 
2491     /** Read a class definition from the bytes in buf.
2492      */
2493     private void readClassBuffer(ClassSymbol c) throws IOException {
2494         int magic = nextInt();
2495         if (magic != JAVA_MAGIC)
2496             throw badClassFile("illegal.start.of.class.file");
2497 
2498         minorVersion = nextChar();
2499         majorVersion = nextChar();
2500         int maxMajor = Version.MAX().major;
2501         int maxMinor = Version.MAX().minor;
2502         if (majorVersion > maxMajor ||
2503             majorVersion * 1000 + minorVersion <
2504             Version.MIN().major * 1000 + Version.MIN().minor) {
2505             if (majorVersion == (maxMajor + 1))
2506                 log.warning("big.major.version",
2507                             currentClassFile,
2508                             majorVersion,
2509                             maxMajor);
2510             else
2511                 throw badClassFile("wrong.version",
2512                                    Integer.toString(majorVersion),
2513                                    Integer.toString(minorVersion),
2514                                    Integer.toString(maxMajor),
2515                                    Integer.toString(maxMinor));
2516         }
2517 
2518         indexPool();
2519         if (signatureBuffer.length < bp) {
2520             int ns = Integer.highestOneBit(bp) << 1;
2521             signatureBuffer = new byte[ns];
2522         }
2523         readClass(c);
2524     }
2525 
2526     public void readClassFile(ClassSymbol c) {
2527         currentOwner = c;
2528         currentClassFile = c.classfile;
2529         warnedAttrs.clear();
2530         filling = true;
2531         target = null;
2532         repeatable = null;
2533         try {
2534             bp = 0;
2535             buf = readInputStream(buf, c.classfile.openInputStream());
2536             readClassBuffer(c);
2537             if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
2538                 List<Type> missing = missingTypeVariables;
2539                 List<Type> found = foundTypeVariables;
2540                 missingTypeVariables = List.nil();
2541                 foundTypeVariables = List.nil();
2542                 filling = false;
2543                 ClassType ct = (ClassType)currentOwner.type;
2544                 ct.supertype_field =
2545                     types.subst(ct.supertype_field, missing, found);
2546                 ct.interfaces_field =
2547                     types.subst(ct.interfaces_field, missing, found);
2548             } else if (missingTypeVariables.isEmpty() !=
2549                        foundTypeVariables.isEmpty()) {
2550                 Name name = missingTypeVariables.head.tsym.name;
2551                 throw badClassFile("undecl.type.var", name);
2552             }
2553 
2554             if ((c.flags_field & Flags.ANNOTATION) != 0) {
2555                 c.setAnnotationTypeMetadata(new AnnotationTypeMetadata(c, new CompleterDeproxy(c, target, repeatable)));
2556             } else {
2557                 c.setAnnotationTypeMetadata(AnnotationTypeMetadata.notAnAnnotationType());
2558             }
2559 
2560             if (c == currentModule.module_info) {
2561                 if (interimUses.nonEmpty() || interimProvides.nonEmpty()) {
2562                     Assert.check(currentModule.isCompleted());
2563                     currentModule.usesProvidesCompleter =
2564                             new UsesProvidesCompleter(currentModule, interimUses, interimProvides);
2565                 } else {
2566                     currentModule.uses = List.nil();
2567                     currentModule.provides = List.nil();
2568                 }
2569             }
2570         } catch (IOException ex) {
2571             throw badClassFile("unable.to.access.file", ex.getMessage());
2572         } catch (ArrayIndexOutOfBoundsException ex) {
2573             throw badClassFile("bad.class.file", c.flatname);
2574         } finally {
2575             interimUses = List.nil();
2576             interimProvides = List.nil();
2577             missingTypeVariables = List.nil();
2578             foundTypeVariables = List.nil();
2579             filling = false;
2580         }
2581     }
2582     // where
2583         private static byte[] readInputStream(byte[] buf, InputStream s) throws IOException {
2584             try {
2585                 buf = ensureCapacity(buf, s.available());
2586                 int r = s.read(buf);
2587                 int bp = 0;
2588                 while (r != -1) {
2589                     bp += r;
2590                     buf = ensureCapacity(buf, bp);
2591                     r = s.read(buf, bp, buf.length - bp);
2592                 }
2593                 return buf;
2594             } finally {
2595                 try {
2596                     s.close();
2597                 } catch (IOException e) {
2598                     /* Ignore any errors, as this stream may have already
2599                      * thrown a related exception which is the one that
2600                      * should be reported.
2601                      */
2602                 }
2603             }
2604         }
2605         /*
2606          * ensureCapacity will increase the buffer as needed, taking note that
2607          * the new buffer will always be greater than the needed and never
2608          * exactly equal to the needed size or bp. If equal then the read (above)
2609          * will infinitely loop as buf.length - bp == 0.
2610          */
2611         private static byte[] ensureCapacity(byte[] buf, int needed) {
2612             if (buf.length <= needed) {
2613                 byte[] old = buf;
2614                 buf = new byte[Integer.highestOneBit(needed) << 1];
2615                 System.arraycopy(old, 0, buf, 0, old.length);
2616             }
2617             return buf;
2618         }
2619 
2620     /** We can only read a single class file at a time; this
2621      *  flag keeps track of when we are currently reading a class
2622      *  file.
2623      */
2624     public boolean filling = false;
2625 
2626 /************************************************************************
2627  * Adjusting flags
2628  ***********************************************************************/
2629 
2630     long adjustFieldFlags(long flags) {
2631         return flags;
2632     }
2633 
2634     long adjustMethodFlags(long flags) {
2635         if ((flags & ACC_BRIDGE) != 0) {
2636             flags &= ~ACC_BRIDGE;
2637             flags |= BRIDGE;
2638         }
2639         if ((flags & ACC_VARARGS) != 0) {
2640             flags &= ~ACC_VARARGS;
2641             flags |= VARARGS;
2642         }
2643         return flags;
2644     }
2645 
2646     long adjustClassFlags(long flags) {
2647         if ((flags & ACC_MODULE) != 0) {
2648             flags &= ~ACC_MODULE;
2649             flags |= MODULE;
2650         }
2651         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
2652     }
2653 
2654     /**
2655      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
2656      * The attribute is only the last component of the original filename, so is unlikely
2657      * to be valid as is, so operations other than those to access the name throw
2658      * UnsupportedOperationException
2659      */
2660     private static class SourceFileObject implements JavaFileObject {
2661 
2662         /** The file's name.
2663          */
2664         private final Name name;
2665         private final Name flatname;
2666 
2667         public SourceFileObject(Name name, Name flatname) {
2668             this.name = name;
2669             this.flatname = flatname;
2670         }
2671 
2672         @Override @DefinedBy(Api.COMPILER)
2673         public URI toUri() {
2674             try {
2675                 return new URI(null, name.toString(), null);
2676             } catch (URISyntaxException e) {
2677                 throw new PathFileObject.CannotCreateUriError(name.toString(), e);
2678             }
2679         }
2680 
2681         @Override @DefinedBy(Api.COMPILER)
2682         public String getName() {
2683             return name.toString();
2684         }
2685 
2686         @Override @DefinedBy(Api.COMPILER)
2687         public JavaFileObject.Kind getKind() {
2688             return BaseFileManager.getKind(getName());
2689         }
2690 
2691         @Override @DefinedBy(Api.COMPILER)
2692         public InputStream openInputStream() {
2693             throw new UnsupportedOperationException();
2694         }
2695 
2696         @Override @DefinedBy(Api.COMPILER)
2697         public OutputStream openOutputStream() {
2698             throw new UnsupportedOperationException();
2699         }
2700 
2701         @Override @DefinedBy(Api.COMPILER)
2702         public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
2703             throw new UnsupportedOperationException();
2704         }
2705 
2706         @Override @DefinedBy(Api.COMPILER)
2707         public Reader openReader(boolean ignoreEncodingErrors) {
2708             throw new UnsupportedOperationException();
2709         }
2710 
2711         @Override @DefinedBy(Api.COMPILER)
2712         public Writer openWriter() {
2713             throw new UnsupportedOperationException();
2714         }
2715 
2716         @Override @DefinedBy(Api.COMPILER)
2717         public long getLastModified() {
2718             throw new UnsupportedOperationException();
2719         }
2720 
2721         @Override @DefinedBy(Api.COMPILER)
2722         public boolean delete() {
2723             throw new UnsupportedOperationException();
2724         }
2725 
2726         @Override @DefinedBy(Api.COMPILER)
2727         public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) {
2728             return true; // fail-safe mode
2729         }
2730 
2731         @Override @DefinedBy(Api.COMPILER)
2732         public NestingKind getNestingKind() {
2733             return null;
2734         }
2735 
2736         @Override @DefinedBy(Api.COMPILER)
2737         public Modifier getAccessLevel() {
2738             return null;
2739         }
2740 
2741         /**
2742          * Check if two file objects are equal.
2743          * SourceFileObjects are just placeholder objects for the value of a
2744          * SourceFile attribute, and do not directly represent specific files.
2745          * Two SourceFileObjects are equal if their names are equal.
2746          */
2747         @Override
2748         public boolean equals(Object other) {
2749             if (this == other)
2750                 return true;
2751 
2752             if (!(other instanceof SourceFileObject))
2753                 return false;
2754 
2755             SourceFileObject o = (SourceFileObject) other;
2756             return name.equals(o.name);
2757         }
2758 
2759         @Override
2760         public int hashCode() {
2761             return name.hashCode();
2762         }
2763     }
2764 
2765     private class CompleterDeproxy implements AnnotationTypeCompleter {
2766         ClassSymbol proxyOn;
2767         CompoundAnnotationProxy target;
2768         CompoundAnnotationProxy repeatable;
2769 
2770         public CompleterDeproxy(ClassSymbol c, CompoundAnnotationProxy target,
2771                 CompoundAnnotationProxy repeatable)
2772         {
2773             this.proxyOn = c;
2774             this.target = target;
2775             this.repeatable = repeatable;
2776         }
2777 
2778         @Override
2779         public void complete(ClassSymbol sym) {
2780             Assert.check(proxyOn == sym);
2781             Attribute.Compound theTarget = null, theRepeatable = null;
2782             AnnotationDeproxy deproxy;
2783 
2784             try {
2785                 if (target != null) {
2786                     deproxy = new AnnotationDeproxy(proxyOn);
2787                     theTarget = deproxy.deproxyCompound(target);
2788                 }
2789 
2790                 if (repeatable != null) {
2791                     deproxy = new AnnotationDeproxy(proxyOn);
2792                     theRepeatable = deproxy.deproxyCompound(repeatable);
2793                 }
2794             } catch (Exception e) {
2795                 throw new CompletionFailure(sym, e.getMessage());
2796             }
2797 
2798             sym.getAnnotationTypeMetadata().setTarget(theTarget);
2799             sym.getAnnotationTypeMetadata().setRepeatable(theRepeatable);
2800         }
2801     }
2802 
2803     private static final class InterimUsesDirective {
2804         public final Name service;
2805 
2806         public InterimUsesDirective(Name service) {
2807             this.service = service;
2808         }
2809 
2810     }
2811 
2812     private static final class InterimProvidesDirective {
2813         public final Name service;
2814         public final Name impl;
2815 
2816         public InterimProvidesDirective(Name service, Name impl) {
2817             this.service = service;
2818             this.impl = impl;
2819         }
2820 
2821     }
2822 
2823     private final class UsesProvidesCompleter implements Completer {
2824         private final ModuleSymbol currentModule;
2825         private final List<InterimUsesDirective> interimUsesCopy;
2826         private final List<InterimProvidesDirective> interimProvidesCopy;
2827 
2828         public UsesProvidesCompleter(ModuleSymbol currentModule, List<InterimUsesDirective> interimUsesCopy, List<InterimProvidesDirective> interimProvidesCopy) {
2829             this.currentModule = currentModule;
2830             this.interimUsesCopy = interimUsesCopy;
2831             this.interimProvidesCopy = interimProvidesCopy;
2832         }
2833 
2834         @Override
2835         public void complete(Symbol sym) throws CompletionFailure {
2836             ListBuffer<Directive> directives = new ListBuffer<>();
2837             directives.addAll(currentModule.directives);
2838             ListBuffer<UsesDirective> uses = new ListBuffer<>();
2839             for (InterimUsesDirective interim : interimUsesCopy) {
2840                 UsesDirective d = new UsesDirective(syms.enterClass(currentModule, interim.service));
2841                 uses.add(d);
2842                 directives.add(d);
2843             }
2844             currentModule.uses = uses.toList();
2845             ListBuffer<ProvidesDirective> provides = new ListBuffer<>();
2846             for (InterimProvidesDirective interim : interimProvidesCopy) {
2847                 ProvidesDirective d = new ProvidesDirective(syms.enterClass(currentModule, interim.service),
2848                                                             syms.enterClass(currentModule, interim.impl));
2849                 provides.add(d);
2850                 directives.add(d);
2851             }
2852             currentModule.provides = provides.toList();
2853             currentModule.directives = directives.toList();
2854         }
2855     }
2856 }