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