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