1 /* 2 * Copyright (c) 2022, 2024, 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 package jdk.internal.classfile.impl; 26 27 import java.util.Collection; 28 import java.util.List; 29 import java.util.Optional; 30 31 import java.lang.classfile.Annotation; 32 import java.lang.classfile.AnnotationValue; 33 import java.lang.classfile.Attribute; 34 import java.lang.classfile.AttributeMapper; 35 import java.lang.classfile.Attributes; 36 import java.lang.classfile.BootstrapMethodEntry; 37 import java.lang.classfile.constantpool.ClassEntry; 38 import java.lang.classfile.TypeAnnotation; 39 import java.lang.classfile.attribute.AnnotationDefaultAttribute; 40 import java.lang.classfile.attribute.BootstrapMethodsAttribute; 41 import java.lang.classfile.attribute.CharacterRangeInfo; 42 import java.lang.classfile.attribute.CharacterRangeTableAttribute; 43 import java.lang.classfile.attribute.CompilationIDAttribute; 44 import java.lang.classfile.attribute.ConstantValueAttribute; 45 import java.lang.classfile.attribute.DeprecatedAttribute; 46 import java.lang.classfile.attribute.EnclosingMethodAttribute; 47 import java.lang.classfile.attribute.ExceptionsAttribute; 48 import java.lang.classfile.attribute.InnerClassInfo; 49 import java.lang.classfile.attribute.InnerClassesAttribute; 50 import java.lang.classfile.attribute.LineNumberInfo; 51 import java.lang.classfile.attribute.LineNumberTableAttribute; 52 import java.lang.classfile.attribute.LocalVariableInfo; 53 import java.lang.classfile.attribute.LocalVariableTableAttribute; 54 import java.lang.classfile.attribute.LocalVariableTypeInfo; 55 import java.lang.classfile.attribute.LocalVariableTypeTableAttribute; 56 import java.lang.classfile.attribute.MethodParameterInfo; 57 import java.lang.classfile.attribute.MethodParametersAttribute; 58 import java.lang.classfile.attribute.ModuleAttribute; 59 import java.lang.classfile.attribute.ModuleExportInfo; 60 import java.lang.classfile.attribute.ModuleHashInfo; 61 import java.lang.classfile.attribute.ModuleHashesAttribute; 62 import java.lang.classfile.attribute.ModuleMainClassAttribute; 63 import java.lang.classfile.attribute.ModuleOpenInfo; 64 import java.lang.classfile.attribute.ModulePackagesAttribute; 65 import java.lang.classfile.attribute.ModuleProvideInfo; 66 import java.lang.classfile.attribute.ModuleRequireInfo; 67 import java.lang.classfile.attribute.ModuleResolutionAttribute; 68 import java.lang.classfile.attribute.ModuleTargetAttribute; 69 import java.lang.classfile.attribute.NestHostAttribute; 70 import java.lang.classfile.attribute.NestMembersAttribute; 71 import java.lang.classfile.attribute.PermittedSubclassesAttribute; 72 import java.lang.classfile.attribute.RecordAttribute; 73 import java.lang.classfile.attribute.RecordComponentInfo; 74 import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute; 75 import java.lang.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute; 76 import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute; 77 import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; 78 import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute; 79 import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; 80 import java.lang.classfile.attribute.SignatureAttribute; 81 import java.lang.classfile.attribute.SourceDebugExtensionAttribute; 82 import java.lang.classfile.attribute.SourceFileAttribute; 83 import java.lang.classfile.attribute.SourceIDAttribute; 84 import java.lang.classfile.attribute.StackMapTableAttribute; 85 import java.lang.classfile.attribute.StackMapFrameInfo; 86 import java.lang.classfile.attribute.SyntheticAttribute; 87 import java.lang.classfile.constantpool.ConstantValueEntry; 88 import java.lang.classfile.constantpool.ModuleEntry; 89 import java.lang.classfile.constantpool.NameAndTypeEntry; 90 import java.lang.classfile.constantpool.PackageEntry; 91 import java.lang.classfile.constantpool.Utf8Entry; 92 93 import jdk.internal.access.SharedSecrets; 94 95 import static java.util.Objects.requireNonNull; 96 97 public abstract sealed class UnboundAttribute<T extends Attribute<T>> 98 extends AbstractElement 99 implements Attribute<T>, Util.Writable { 100 protected final AttributeMapper<T> mapper; 101 102 public UnboundAttribute(AttributeMapper<T> mapper) { 103 this.mapper = mapper; 104 } 105 106 @Override 107 public AttributeMapper<T> attributeMapper() { 108 return mapper; 109 } 110 111 @Override 112 public String attributeName() { 113 return mapper.name(); 114 } 115 116 @Override 117 @SuppressWarnings("unchecked") 118 public void writeTo(BufWriterImpl buf) { 119 mapper.writeAttribute(buf, (T) this); 120 } 121 122 @Override 123 public void writeTo(DirectClassBuilder builder) { 124 builder.writeAttribute(this); 125 } 126 127 @Override 128 public void writeTo(DirectCodeBuilder builder) { 129 builder.writeAttribute(this); 130 } 131 132 @Override 133 public void writeTo(DirectMethodBuilder builder) { 134 builder.writeAttribute(this); 135 } 136 137 @Override 138 public void writeTo(DirectFieldBuilder builder) { 139 builder.writeAttribute(this); 140 } 141 142 @Override 143 public String toString() { 144 return String.format("Attribute[name=%s]", mapper.name()); 145 } 146 public static final class UnboundConstantValueAttribute 147 extends UnboundAttribute<ConstantValueAttribute> 148 implements ConstantValueAttribute { 149 150 private final ConstantValueEntry entry; 151 152 public UnboundConstantValueAttribute(ConstantValueEntry entry) { 153 super(Attributes.constantValue()); 154 this.entry = requireNonNull(entry); 155 } 156 157 @Override 158 public ConstantValueEntry constant() { 159 return entry; 160 } 161 162 } 163 164 public static final class UnboundDeprecatedAttribute 165 extends UnboundAttribute<DeprecatedAttribute> 166 implements DeprecatedAttribute { 167 public UnboundDeprecatedAttribute() { 168 super(Attributes.deprecated()); 169 } 170 } 171 172 public static final class UnboundSyntheticAttribute 173 extends UnboundAttribute<SyntheticAttribute> 174 implements SyntheticAttribute { 175 public UnboundSyntheticAttribute() { 176 super(Attributes.synthetic()); 177 } 178 } 179 180 public static final class UnboundSignatureAttribute 181 extends UnboundAttribute<SignatureAttribute> 182 implements SignatureAttribute { 183 private final Utf8Entry signature; 184 185 public UnboundSignatureAttribute(Utf8Entry signature) { 186 super(Attributes.signature()); 187 this.signature = requireNonNull(signature); 188 } 189 190 @Override 191 public Utf8Entry signature() { 192 return signature; 193 } 194 } 195 196 public static final class UnboundExceptionsAttribute 197 extends UnboundAttribute<ExceptionsAttribute> 198 implements ExceptionsAttribute { 199 private final List<ClassEntry> exceptions; 200 201 public UnboundExceptionsAttribute(List<ClassEntry> exceptions) { 202 super(Attributes.exceptions()); 203 this.exceptions = List.copyOf(exceptions); 204 } 205 206 @Override 207 public List<ClassEntry> exceptions() { 208 return exceptions; 209 } 210 } 211 212 public static final class UnboundAnnotationDefaultAttribute 213 extends UnboundAttribute<AnnotationDefaultAttribute> 214 implements AnnotationDefaultAttribute { 215 private final AnnotationValue annotationDefault; 216 217 public UnboundAnnotationDefaultAttribute(AnnotationValue annotationDefault) { 218 super(Attributes.annotationDefault()); 219 this.annotationDefault = requireNonNull(annotationDefault); 220 } 221 222 @Override 223 public AnnotationValue defaultValue() { 224 return annotationDefault; 225 } 226 } 227 228 public static final class UnboundSourceFileAttribute extends UnboundAttribute<SourceFileAttribute> 229 implements SourceFileAttribute { 230 private final Utf8Entry sourceFile; 231 232 public UnboundSourceFileAttribute(Utf8Entry sourceFile) { 233 super(Attributes.sourceFile()); 234 this.sourceFile = requireNonNull(sourceFile); 235 } 236 237 @Override 238 public Utf8Entry sourceFile() { 239 return sourceFile; 240 } 241 242 } 243 244 public static final class UnboundStackMapTableAttribute extends UnboundAttribute<StackMapTableAttribute> 245 implements StackMapTableAttribute { 246 private final List<StackMapFrameInfo> entries; 247 248 public UnboundStackMapTableAttribute(List<StackMapFrameInfo> entries) { 249 super(Attributes.stackMapTable()); 250 this.entries = List.copyOf(entries); 251 } 252 253 @Override 254 public List<StackMapFrameInfo> entries() { 255 return entries; 256 } 257 } 258 259 public static final class UnboundInnerClassesAttribute 260 extends UnboundAttribute<InnerClassesAttribute> 261 implements InnerClassesAttribute { 262 private final List<InnerClassInfo> innerClasses; 263 264 public UnboundInnerClassesAttribute(List<InnerClassInfo> innerClasses) { 265 super(Attributes.innerClasses()); 266 this.innerClasses = List.copyOf(innerClasses); 267 } 268 269 @Override 270 public List<InnerClassInfo> classes() { 271 return innerClasses; 272 } 273 } 274 275 public static final class UnboundRecordAttribute 276 extends UnboundAttribute<RecordAttribute> 277 implements RecordAttribute { 278 private final List<RecordComponentInfo> components; 279 280 public UnboundRecordAttribute(List<RecordComponentInfo> components) { 281 super(Attributes.record()); 282 this.components = List.copyOf(components); 283 } 284 285 @Override 286 public List<RecordComponentInfo> components() { 287 return components; 288 } 289 } 290 291 public static final class UnboundEnclosingMethodAttribute 292 extends UnboundAttribute<EnclosingMethodAttribute> 293 implements EnclosingMethodAttribute { 294 private final ClassEntry classEntry; 295 private final NameAndTypeEntry method; 296 297 public UnboundEnclosingMethodAttribute(ClassEntry classEntry, NameAndTypeEntry method) { 298 super(Attributes.enclosingMethod()); 299 this.classEntry = requireNonNull(classEntry); 300 this.method = method; 301 } 302 303 @Override 304 public ClassEntry enclosingClass() { 305 return classEntry; 306 } 307 308 @Override 309 public Optional<NameAndTypeEntry> enclosingMethod() { 310 return Optional.ofNullable(method); 311 } 312 } 313 314 public static final class UnboundMethodParametersAttribute 315 extends UnboundAttribute<MethodParametersAttribute> 316 implements MethodParametersAttribute { 317 private final List<MethodParameterInfo> parameters; 318 319 public UnboundMethodParametersAttribute(List<MethodParameterInfo> parameters) { 320 super(Attributes.methodParameters()); 321 this.parameters = List.copyOf(parameters); 322 } 323 324 @Override 325 public List<MethodParameterInfo> parameters() { 326 return parameters; 327 } 328 } 329 330 public static final class UnboundModuleTargetAttribute 331 extends UnboundAttribute<ModuleTargetAttribute> 332 implements ModuleTargetAttribute { 333 final Utf8Entry moduleTarget; 334 335 public UnboundModuleTargetAttribute(Utf8Entry moduleTarget) { 336 super(Attributes.moduleTarget()); 337 this.moduleTarget = requireNonNull(moduleTarget); 338 } 339 340 @Override 341 public Utf8Entry targetPlatform() { 342 return moduleTarget; 343 } 344 } 345 346 public static final class UnboundModuleMainClassAttribute 347 extends UnboundAttribute<ModuleMainClassAttribute> 348 implements ModuleMainClassAttribute { 349 final ClassEntry mainClass; 350 351 public UnboundModuleMainClassAttribute(ClassEntry mainClass) { 352 super(Attributes.moduleMainClass()); 353 this.mainClass = requireNonNull(mainClass); 354 } 355 356 @Override 357 public ClassEntry mainClass() { 358 return mainClass; 359 } 360 } 361 362 public static final class UnboundModuleHashesAttribute 363 extends UnboundAttribute<ModuleHashesAttribute> 364 implements ModuleHashesAttribute { 365 private final Utf8Entry algorithm; 366 private final List<ModuleHashInfo> hashes; 367 368 public UnboundModuleHashesAttribute(Utf8Entry algorithm, List<ModuleHashInfo> hashes) { 369 super(Attributes.moduleHashes()); 370 this.algorithm = requireNonNull(algorithm); 371 this.hashes = List.copyOf(hashes); 372 } 373 374 @Override 375 public Utf8Entry algorithm() { 376 return algorithm; 377 } 378 379 @Override 380 public List<ModuleHashInfo> hashes() { 381 return hashes; 382 } 383 } 384 385 public static final class UnboundModulePackagesAttribute 386 extends UnboundAttribute<ModulePackagesAttribute> 387 implements ModulePackagesAttribute { 388 private final Collection<PackageEntry> packages; 389 390 public UnboundModulePackagesAttribute(Collection<PackageEntry> packages) { 391 super(Attributes.modulePackages()); 392 this.packages = List.copyOf(packages); 393 } 394 395 @Override 396 public List<PackageEntry> packages() { 397 return List.copyOf(packages); 398 } 399 } 400 401 public static final class UnboundModuleResolutionAttribute 402 extends UnboundAttribute<ModuleResolutionAttribute> 403 implements ModuleResolutionAttribute { 404 private final int resolutionFlags; 405 406 public UnboundModuleResolutionAttribute(int flags) { 407 super(Attributes.moduleResolution()); 408 resolutionFlags = flags; 409 } 410 411 @Override 412 public int resolutionFlags() { 413 return resolutionFlags; 414 } 415 } 416 417 public static final class UnboundPermittedSubclassesAttribute 418 extends UnboundAttribute<PermittedSubclassesAttribute> 419 implements PermittedSubclassesAttribute { 420 private final List<ClassEntry> permittedSubclasses; 421 422 public UnboundPermittedSubclassesAttribute(List<ClassEntry> permittedSubclasses) { 423 super(Attributes.permittedSubclasses()); 424 this.permittedSubclasses = List.copyOf(permittedSubclasses); 425 } 426 427 @Override 428 public List<ClassEntry> permittedSubclasses() { 429 return permittedSubclasses; 430 } 431 } 432 433 public static final class UnboundNestMembersAttribute 434 extends UnboundAttribute<NestMembersAttribute> 435 implements NestMembersAttribute { 436 private final List<ClassEntry> memberEntries; 437 438 public UnboundNestMembersAttribute(List<ClassEntry> memberEntries) { 439 super(Attributes.nestMembers()); 440 this.memberEntries = List.copyOf(memberEntries); 441 } 442 443 @Override 444 public List<ClassEntry> nestMembers() { 445 return memberEntries; 446 } 447 } 448 449 public static final class UnboundNestHostAttribute 450 extends UnboundAttribute<NestHostAttribute> 451 implements NestHostAttribute { 452 private final ClassEntry hostEntry; 453 454 public UnboundNestHostAttribute(ClassEntry hostEntry) { 455 super(Attributes.nestHost()); 456 this.hostEntry = requireNonNull(hostEntry); 457 } 458 459 @Override 460 public ClassEntry nestHost() { 461 return hostEntry; 462 } 463 } 464 465 public static final class UnboundCompilationIDAttribute 466 extends UnboundAttribute<CompilationIDAttribute> 467 implements CompilationIDAttribute { 468 private final Utf8Entry idEntry; 469 470 public UnboundCompilationIDAttribute(Utf8Entry idEntry) { 471 super(Attributes.compilationId()); 472 this.idEntry = requireNonNull(idEntry); 473 } 474 475 @Override 476 public Utf8Entry compilationId() { 477 return idEntry; 478 } 479 } 480 481 public static final class UnboundSourceIDAttribute 482 extends UnboundAttribute<SourceIDAttribute> 483 implements SourceIDAttribute { 484 private final Utf8Entry idEntry; 485 486 public UnboundSourceIDAttribute(Utf8Entry idEntry) { 487 super(Attributes.sourceId()); 488 this.idEntry = requireNonNull(idEntry); 489 } 490 491 @Override 492 public Utf8Entry sourceId() { 493 return idEntry; 494 } 495 } 496 497 public static final class UnboundSourceDebugExtensionAttribute 498 extends UnboundAttribute<SourceDebugExtensionAttribute> 499 implements SourceDebugExtensionAttribute { 500 private final byte[] contents; 501 502 public UnboundSourceDebugExtensionAttribute(byte[] contents) { 503 super(Attributes.sourceDebugExtension()); 504 this.contents = requireNonNull(contents); 505 } 506 507 @Override 508 public byte[] contents() { 509 return contents; 510 } 511 } 512 513 public static final class UnboundCharacterRangeTableAttribute 514 extends UnboundAttribute<CharacterRangeTableAttribute> 515 implements CharacterRangeTableAttribute { 516 private final List<CharacterRangeInfo> ranges; 517 518 public UnboundCharacterRangeTableAttribute(List<CharacterRangeInfo> ranges) { 519 super(Attributes.characterRangeTable()); 520 this.ranges = List.copyOf(ranges); 521 } 522 523 @Override 524 public List<CharacterRangeInfo> characterRangeTable() { 525 return ranges; 526 } 527 } 528 529 public static final class UnboundLineNumberTableAttribute 530 extends UnboundAttribute<LineNumberTableAttribute> 531 implements LineNumberTableAttribute { 532 private final List<LineNumberInfo> lines; 533 534 public UnboundLineNumberTableAttribute(List<LineNumberInfo> lines) { 535 super(Attributes.lineNumberTable()); 536 this.lines = List.copyOf(lines); 537 } 538 539 @Override 540 public List<LineNumberInfo> lineNumbers() { 541 return lines; 542 } 543 } 544 545 public static final class UnboundLocalVariableTableAttribute 546 extends UnboundAttribute<LocalVariableTableAttribute> 547 implements LocalVariableTableAttribute { 548 private final List<LocalVariableInfo> locals; 549 550 public UnboundLocalVariableTableAttribute(List<LocalVariableInfo> locals) { 551 super(Attributes.localVariableTable()); 552 this.locals = List.copyOf(locals); 553 } 554 555 @Override 556 public List<LocalVariableInfo> localVariables() { 557 return locals; 558 } 559 } 560 561 public static final class UnboundLocalVariableTypeTableAttribute 562 extends UnboundAttribute<LocalVariableTypeTableAttribute> 563 implements LocalVariableTypeTableAttribute { 564 private final List<LocalVariableTypeInfo> locals; 565 566 public UnboundLocalVariableTypeTableAttribute(List<LocalVariableTypeInfo> locals) { 567 super(Attributes.localVariableTypeTable()); 568 this.locals = List.copyOf(locals); 569 } 570 571 @Override 572 public List<LocalVariableTypeInfo> localVariableTypes() { 573 return locals; 574 } 575 } 576 577 public static final class UnboundRuntimeVisibleAnnotationsAttribute 578 extends UnboundAttribute<RuntimeVisibleAnnotationsAttribute> 579 implements RuntimeVisibleAnnotationsAttribute { 580 private final List<Annotation> elements; 581 582 public UnboundRuntimeVisibleAnnotationsAttribute(List<Annotation> elements) { 583 super(Attributes.runtimeVisibleAnnotations()); 584 this.elements = List.copyOf(elements); 585 } 586 587 @Override 588 public List<Annotation> annotations() { 589 return elements; 590 } 591 } 592 593 public static final class UnboundRuntimeInvisibleAnnotationsAttribute 594 extends UnboundAttribute<RuntimeInvisibleAnnotationsAttribute> 595 implements RuntimeInvisibleAnnotationsAttribute { 596 private final List<Annotation> elements; 597 598 public UnboundRuntimeInvisibleAnnotationsAttribute(List<Annotation> elements) { 599 super(Attributes.runtimeInvisibleAnnotations()); 600 this.elements = List.copyOf(elements); 601 } 602 603 @Override 604 public List<Annotation> annotations() { 605 return elements; 606 } 607 } 608 609 public static final class UnboundRuntimeVisibleParameterAnnotationsAttribute 610 extends UnboundAttribute<RuntimeVisibleParameterAnnotationsAttribute> 611 implements RuntimeVisibleParameterAnnotationsAttribute { 612 private final List<List<Annotation>> elements; 613 614 public UnboundRuntimeVisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 615 super(Attributes.runtimeVisibleParameterAnnotations()); 616 // deep copy 617 var array = elements.toArray().clone(); 618 for (int i = 0; i < array.length; i++) { 619 array[i] = List.copyOf((List<?>) array[i]); 620 } 621 622 this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array); 623 } 624 625 @Override 626 public List<List<Annotation>> parameterAnnotations() { 627 return elements; 628 } 629 } 630 631 public static final class UnboundRuntimeInvisibleParameterAnnotationsAttribute 632 extends UnboundAttribute<RuntimeInvisibleParameterAnnotationsAttribute> 633 implements RuntimeInvisibleParameterAnnotationsAttribute { 634 private final List<List<Annotation>> elements; 635 636 public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 637 super(Attributes.runtimeInvisibleParameterAnnotations()); 638 // deep copy 639 var array = elements.toArray().clone(); 640 for (int i = 0; i < array.length; i++) { 641 array[i] = List.copyOf((List<?>) array[i]); 642 } 643 644 this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array); 645 } 646 647 @Override 648 public List<List<Annotation>> parameterAnnotations() { 649 return elements; 650 } 651 } 652 653 public static final class UnboundRuntimeVisibleTypeAnnotationsAttribute 654 extends UnboundAttribute<RuntimeVisibleTypeAnnotationsAttribute> 655 implements RuntimeVisibleTypeAnnotationsAttribute { 656 private final List<TypeAnnotation> elements; 657 658 public UnboundRuntimeVisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 659 super(Attributes.runtimeVisibleTypeAnnotations()); 660 this.elements = List.copyOf(elements); 661 } 662 663 @Override 664 public List<TypeAnnotation> annotations() { 665 return elements; 666 } 667 } 668 669 public static final class UnboundRuntimeInvisibleTypeAnnotationsAttribute 670 extends UnboundAttribute<RuntimeInvisibleTypeAnnotationsAttribute> 671 implements RuntimeInvisibleTypeAnnotationsAttribute { 672 private final List<TypeAnnotation> elements; 673 674 public UnboundRuntimeInvisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 675 super(Attributes.runtimeInvisibleTypeAnnotations()); 676 this.elements = List.copyOf(elements); 677 } 678 679 @Override 680 public List<TypeAnnotation> annotations() { 681 return elements; 682 } 683 } 684 685 public record UnboundCharacterRangeInfo(int startPc, int endPc, 686 int characterRangeStart, 687 int characterRangeEnd, 688 int flags) 689 implements CharacterRangeInfo { } 690 691 public record UnboundInnerClassInfo(ClassEntry innerClass, 692 Optional<ClassEntry> outerClass, 693 Optional<Utf8Entry> innerName, 694 int flagsMask) 695 implements InnerClassInfo { 696 public UnboundInnerClassInfo { 697 requireNonNull(innerClass); 698 requireNonNull(outerClass); 699 requireNonNull(innerName); 700 } 701 } 702 703 public record UnboundLineNumberInfo(int startPc, int lineNumber) 704 implements LineNumberInfo { } 705 706 public record UnboundLocalVariableInfo(int startPc, int length, 707 Utf8Entry name, 708 Utf8Entry type, 709 int slot) 710 implements LocalVariableInfo { 711 public UnboundLocalVariableInfo { 712 requireNonNull(name); 713 requireNonNull(type); 714 } 715 } 716 717 public record UnboundLocalVariableTypeInfo(int startPc, int length, 718 Utf8Entry name, 719 Utf8Entry signature, 720 int slot) 721 implements LocalVariableTypeInfo { 722 public UnboundLocalVariableTypeInfo { 723 requireNonNull(name); 724 requireNonNull(signature); 725 } 726 } 727 728 public record UnboundMethodParameterInfo(Optional<Utf8Entry> name, int flagsMask) 729 implements MethodParameterInfo { 730 public UnboundMethodParameterInfo { 731 requireNonNull(name); 732 } 733 } 734 735 public record UnboundModuleExportInfo(PackageEntry exportedPackage, 736 int exportsFlagsMask, 737 List<ModuleEntry> exportsTo) 738 implements ModuleExportInfo { 739 public UnboundModuleExportInfo { 740 requireNonNull(exportedPackage); 741 exportsTo = List.copyOf(exportsTo); 742 } 743 } 744 745 public record UnboundModuleHashInfo(ModuleEntry moduleName, 746 byte[] hash) implements ModuleHashInfo { 747 public UnboundModuleHashInfo { 748 requireNonNull(moduleName); 749 requireNonNull(hash); 750 } 751 } 752 753 public record UnboundModuleOpenInfo(PackageEntry openedPackage, int opensFlagsMask, 754 List<ModuleEntry> opensTo) 755 implements ModuleOpenInfo { 756 public UnboundModuleOpenInfo { 757 requireNonNull(openedPackage); 758 opensTo = List.copyOf(opensTo); 759 } 760 } 761 762 public record UnboundModuleProvideInfo(ClassEntry provides, 763 List<ClassEntry> providesWith) 764 implements ModuleProvideInfo { 765 public UnboundModuleProvideInfo { 766 requireNonNull(provides); 767 providesWith = List.copyOf(providesWith); 768 } 769 } 770 771 public record UnboundModuleRequiresInfo(ModuleEntry requires, int requiresFlagsMask, 772 Optional<Utf8Entry> requiresVersion) 773 implements ModuleRequireInfo { 774 public UnboundModuleRequiresInfo { 775 requireNonNull(requires); 776 requireNonNull(requiresVersion); 777 } 778 } 779 780 public record UnboundRecordComponentInfo(Utf8Entry name, 781 Utf8Entry descriptor, 782 List<Attribute<?>> attributes) 783 implements RecordComponentInfo { 784 public UnboundRecordComponentInfo { 785 requireNonNull(name); 786 requireNonNull(descriptor); 787 attributes = List.copyOf(attributes); 788 } 789 } 790 791 public record UnboundTypeAnnotation(TargetInfo targetInfo, 792 List<TypePathComponent> targetPath, 793 Annotation annotation) implements TypeAnnotation { 794 795 public UnboundTypeAnnotation { 796 requireNonNull(targetInfo); 797 targetPath = List.copyOf(targetPath); 798 requireNonNull(annotation); 799 } 800 } 801 802 public record TypePathComponentImpl(TypeAnnotation.TypePathComponent.Kind typePathKind, int typeArgumentIndex) 803 implements TypeAnnotation.TypePathComponent {} 804 805 public static final class UnboundModuleAttribute extends UnboundAttribute<ModuleAttribute> implements ModuleAttribute { 806 private final ModuleEntry moduleName; 807 private final int moduleFlags; 808 private final Utf8Entry moduleVersion; 809 private final List<ModuleRequireInfo> requires; 810 private final List<ModuleExportInfo> exports; 811 private final List<ModuleOpenInfo> opens; 812 private final List<ClassEntry> uses; 813 private final List<ModuleProvideInfo> provides; 814 815 public UnboundModuleAttribute(ModuleEntry moduleName, 816 int moduleFlags, 817 Utf8Entry moduleVersion, 818 Collection<ModuleRequireInfo> requires, 819 Collection<ModuleExportInfo> exports, 820 Collection<ModuleOpenInfo> opens, 821 Collection<ClassEntry> uses, 822 Collection<ModuleProvideInfo> provides) 823 { 824 super(Attributes.module()); 825 this.moduleName = requireNonNull(moduleName); 826 this.moduleFlags = moduleFlags; 827 this.moduleVersion = moduleVersion; 828 this.requires = List.copyOf(requires); 829 this.exports = List.copyOf(exports); 830 this.opens = List.copyOf(opens); 831 this.uses = List.copyOf(uses); 832 this.provides = List.copyOf(provides); 833 } 834 835 @Override 836 public ModuleEntry moduleName() { 837 return moduleName; 838 } 839 840 @Override 841 public int moduleFlagsMask() { 842 return moduleFlags; 843 } 844 845 @Override 846 public Optional<Utf8Entry> moduleVersion() { 847 return Optional.ofNullable(moduleVersion); 848 } 849 850 @Override 851 public List<ModuleRequireInfo> requires() { 852 return requires; 853 } 854 855 @Override 856 public List<ModuleExportInfo> exports() { 857 return exports; 858 } 859 860 @Override 861 public List<ModuleOpenInfo> opens() { 862 return opens; 863 } 864 865 @Override 866 public List<ClassEntry> uses() { 867 return uses; 868 } 869 870 @Override 871 public List<ModuleProvideInfo> provides() { 872 return provides; 873 } 874 } 875 876 public abstract static non-sealed class AdHocAttribute<T extends Attribute<T>> 877 extends UnboundAttribute<T> { 878 879 public AdHocAttribute(AttributeMapper<T> mapper) { 880 super(mapper); 881 } 882 883 public abstract void writeBody(BufWriterImpl b); 884 885 @Override 886 public void writeTo(BufWriterImpl b) { 887 b.writeIndex(b.constantPool().utf8Entry(mapper.name())); 888 int lengthIndex = b.skip(4); 889 writeBody(b); 890 int written = b.size() - lengthIndex - 4; 891 b.patchInt(lengthIndex, written); 892 } 893 } 894 895 public static final class EmptyBootstrapAttribute 896 extends UnboundAttribute<BootstrapMethodsAttribute> 897 implements BootstrapMethodsAttribute { 898 public EmptyBootstrapAttribute() { 899 super(Attributes.bootstrapMethods()); 900 } 901 902 @Override 903 public int bootstrapMethodsSize() { 904 return 0; 905 } 906 907 @Override 908 public List<BootstrapMethodEntry> bootstrapMethods() { 909 return List.of(); 910 } 911 } 912 }