1 /* 2 * Copyright (c) 2022, 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.AnnotationElement; 33 import java.lang.classfile.AnnotationValue; 34 import java.lang.classfile.Attribute; 35 import java.lang.classfile.AttributeMapper; 36 import java.lang.classfile.Attributes; 37 import java.lang.classfile.BootstrapMethodEntry; 38 import java.lang.classfile.BufWriter; 39 import java.lang.classfile.constantpool.ClassEntry; 40 import java.lang.classfile.Label; 41 import java.lang.classfile.TypeAnnotation; 42 import java.lang.classfile.attribute.AnnotationDefaultAttribute; 43 import java.lang.classfile.attribute.BootstrapMethodsAttribute; 44 import java.lang.classfile.attribute.CharacterRangeInfo; 45 import java.lang.classfile.attribute.CharacterRangeTableAttribute; 46 import java.lang.classfile.attribute.CompilationIDAttribute; 47 import java.lang.classfile.attribute.ConstantValueAttribute; 48 import java.lang.classfile.attribute.DeprecatedAttribute; 49 import java.lang.classfile.attribute.EnclosingMethodAttribute; 50 import java.lang.classfile.attribute.ExceptionsAttribute; 51 import java.lang.classfile.attribute.InnerClassInfo; 52 import java.lang.classfile.attribute.InnerClassesAttribute; 53 import java.lang.classfile.attribute.LineNumberInfo; 54 import java.lang.classfile.attribute.LineNumberTableAttribute; 55 import java.lang.classfile.attribute.LoadableDescriptorsAttribute; 56 import java.lang.classfile.attribute.LocalVariableInfo; 57 import java.lang.classfile.attribute.LocalVariableTableAttribute; 58 import java.lang.classfile.attribute.LocalVariableTypeInfo; 59 import java.lang.classfile.attribute.LocalVariableTypeTableAttribute; 60 import java.lang.classfile.attribute.MethodParameterInfo; 61 import java.lang.classfile.attribute.MethodParametersAttribute; 62 import java.lang.classfile.attribute.ModuleAttribute; 63 import java.lang.classfile.attribute.ModuleExportInfo; 64 import java.lang.classfile.attribute.ModuleHashInfo; 65 import java.lang.classfile.attribute.ModuleHashesAttribute; 66 import java.lang.classfile.attribute.ModuleMainClassAttribute; 67 import java.lang.classfile.attribute.ModuleOpenInfo; 68 import java.lang.classfile.attribute.ModulePackagesAttribute; 69 import java.lang.classfile.attribute.ModuleProvideInfo; 70 import java.lang.classfile.attribute.ModuleRequireInfo; 71 import java.lang.classfile.attribute.ModuleResolutionAttribute; 72 import java.lang.classfile.attribute.ModuleTargetAttribute; 73 import java.lang.classfile.attribute.NestHostAttribute; 74 import java.lang.classfile.attribute.NestMembersAttribute; 75 import java.lang.classfile.attribute.PermittedSubclassesAttribute; 76 import java.lang.classfile.attribute.RecordAttribute; 77 import java.lang.classfile.attribute.RecordComponentInfo; 78 import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute; 79 import java.lang.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute; 80 import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute; 81 import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; 82 import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute; 83 import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; 84 import java.lang.classfile.attribute.SignatureAttribute; 85 import java.lang.classfile.attribute.SourceDebugExtensionAttribute; 86 import java.lang.classfile.attribute.SourceFileAttribute; 87 import java.lang.classfile.attribute.SourceIDAttribute; 88 import java.lang.classfile.attribute.StackMapTableAttribute; 89 import java.lang.classfile.attribute.StackMapFrameInfo; 90 import java.lang.classfile.attribute.SyntheticAttribute; 91 import java.lang.classfile.constantpool.ConstantValueEntry; 92 import java.lang.classfile.constantpool.ModuleEntry; 93 import java.lang.classfile.constantpool.NameAndTypeEntry; 94 import java.lang.classfile.constantpool.PackageEntry; 95 import java.lang.classfile.constantpool.Utf8Entry; 96 97 public abstract sealed class UnboundAttribute<T extends Attribute<T>> 98 extends AbstractElement 99 implements Attribute<T> { 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(BufWriter 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 UnboundLoadableDescriptorsAttribute 434 extends UnboundAttribute<LoadableDescriptorsAttribute> 435 implements LoadableDescriptorsAttribute { 436 private final List<Utf8Entry> loadableDescriptors; 437 438 public UnboundLoadableDescriptorsAttribute(List<Utf8Entry> loadableDescriptors) { 439 super(Attributes.loadableDescriptors()); 440 this.loadableDescriptors = List.copyOf(loadableDescriptors); 441 } 442 443 @Override 444 public List<Utf8Entry> loadableDescriptors() { 445 return loadableDescriptors; 446 } 447 } 448 449 public static final class UnboundNestMembersAttribute 450 extends UnboundAttribute<NestMembersAttribute> 451 implements NestMembersAttribute { 452 private final List<ClassEntry> memberEntries; 453 454 public UnboundNestMembersAttribute(List<ClassEntry> memberEntries) { 455 super(Attributes.nestMembers()); 456 this.memberEntries = List.copyOf(memberEntries); 457 } 458 459 @Override 460 public List<ClassEntry> nestMembers() { 461 return memberEntries; 462 } 463 } 464 465 public static final class UnboundNestHostAttribute 466 extends UnboundAttribute<NestHostAttribute> 467 implements NestHostAttribute { 468 private final ClassEntry hostEntry; 469 470 public UnboundNestHostAttribute(ClassEntry hostEntry) { 471 super(Attributes.nestHost()); 472 this.hostEntry = hostEntry; 473 } 474 475 @Override 476 public ClassEntry nestHost() { 477 return hostEntry; 478 } 479 } 480 481 public static final class UnboundCompilationIDAttribute 482 extends UnboundAttribute<CompilationIDAttribute> 483 implements CompilationIDAttribute { 484 private final Utf8Entry idEntry; 485 486 public UnboundCompilationIDAttribute(Utf8Entry idEntry) { 487 super(Attributes.compilationId()); 488 this.idEntry = idEntry; 489 } 490 491 @Override 492 public Utf8Entry compilationId() { 493 return idEntry; 494 } 495 } 496 497 public static final class UnboundSourceIDAttribute 498 extends UnboundAttribute<SourceIDAttribute> 499 implements SourceIDAttribute { 500 private final Utf8Entry idEntry; 501 502 public UnboundSourceIDAttribute(Utf8Entry idEntry) { 503 super(Attributes.sourceId()); 504 this.idEntry = idEntry; 505 } 506 507 @Override 508 public Utf8Entry sourceId() { 509 return idEntry; 510 } 511 } 512 513 public static final class UnboundSourceDebugExtensionAttribute 514 extends UnboundAttribute<SourceDebugExtensionAttribute> 515 implements SourceDebugExtensionAttribute { 516 private final byte[] contents; 517 518 public UnboundSourceDebugExtensionAttribute(byte[] contents) { 519 super(Attributes.sourceDebugExtension()); 520 this.contents = contents; 521 } 522 523 @Override 524 public byte[] contents() { 525 return contents; 526 } 527 } 528 529 public static final class UnboundCharacterRangeTableAttribute 530 extends UnboundAttribute<CharacterRangeTableAttribute> 531 implements CharacterRangeTableAttribute { 532 private final List<CharacterRangeInfo> ranges; 533 534 public UnboundCharacterRangeTableAttribute(List<CharacterRangeInfo> ranges) { 535 super(Attributes.characterRangeTable()); 536 this.ranges = List.copyOf(ranges); 537 } 538 539 @Override 540 public List<CharacterRangeInfo> characterRangeTable() { 541 return ranges; 542 } 543 } 544 545 public static final class UnboundLineNumberTableAttribute 546 extends UnboundAttribute<LineNumberTableAttribute> 547 implements LineNumberTableAttribute { 548 private final List<LineNumberInfo> lines; 549 550 public UnboundLineNumberTableAttribute(List<LineNumberInfo> lines) { 551 super(Attributes.lineNumberTable()); 552 this.lines = List.copyOf(lines); 553 } 554 555 @Override 556 public List<LineNumberInfo> lineNumbers() { 557 return lines; 558 } 559 } 560 561 public static final class UnboundLocalVariableTableAttribute 562 extends UnboundAttribute<LocalVariableTableAttribute> 563 implements LocalVariableTableAttribute { 564 private final List<LocalVariableInfo> locals; 565 566 public UnboundLocalVariableTableAttribute(List<LocalVariableInfo> locals) { 567 super(Attributes.localVariableTable()); 568 this.locals = List.copyOf(locals); 569 } 570 571 @Override 572 public List<LocalVariableInfo> localVariables() { 573 return locals; 574 } 575 } 576 577 public static final class UnboundLocalVariableTypeTableAttribute 578 extends UnboundAttribute<LocalVariableTypeTableAttribute> 579 implements LocalVariableTypeTableAttribute { 580 private final List<LocalVariableTypeInfo> locals; 581 582 public UnboundLocalVariableTypeTableAttribute(List<LocalVariableTypeInfo> locals) { 583 super(Attributes.localVariableTypeTable()); 584 this.locals = List.copyOf(locals); 585 } 586 587 @Override 588 public List<LocalVariableTypeInfo> localVariableTypes() { 589 return locals; 590 } 591 } 592 593 public static final class UnboundRuntimeVisibleAnnotationsAttribute 594 extends UnboundAttribute<RuntimeVisibleAnnotationsAttribute> 595 implements RuntimeVisibleAnnotationsAttribute { 596 private final List<Annotation> elements; 597 598 public UnboundRuntimeVisibleAnnotationsAttribute(List<Annotation> elements) { 599 super(Attributes.runtimeVisibleAnnotations()); 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 UnboundRuntimeInvisibleAnnotationsAttribute 610 extends UnboundAttribute<RuntimeInvisibleAnnotationsAttribute> 611 implements RuntimeInvisibleAnnotationsAttribute { 612 private final List<Annotation> elements; 613 614 public UnboundRuntimeInvisibleAnnotationsAttribute(List<Annotation> elements) { 615 super(Attributes.runtimeInvisibleAnnotations()); 616 this.elements = List.copyOf(elements); 617 } 618 619 @Override 620 public List<Annotation> annotations() { 621 return elements; 622 } 623 } 624 625 public static final class UnboundRuntimeVisibleParameterAnnotationsAttribute 626 extends UnboundAttribute<RuntimeVisibleParameterAnnotationsAttribute> 627 implements RuntimeVisibleParameterAnnotationsAttribute { 628 private final List<List<Annotation>> elements; 629 630 public UnboundRuntimeVisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 631 super(Attributes.runtimeVisibleParameterAnnotations()); 632 this.elements = List.copyOf(elements); 633 } 634 635 @Override 636 public List<List<Annotation>> parameterAnnotations() { 637 return elements; 638 } 639 } 640 641 public static final class UnboundRuntimeInvisibleParameterAnnotationsAttribute 642 extends UnboundAttribute<RuntimeInvisibleParameterAnnotationsAttribute> 643 implements RuntimeInvisibleParameterAnnotationsAttribute { 644 private final List<List<Annotation>> elements; 645 646 public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 647 super(Attributes.runtimeInvisibleParameterAnnotations()); 648 this.elements = List.copyOf(elements); 649 } 650 651 @Override 652 public List<List<Annotation>> parameterAnnotations() { 653 return elements; 654 } 655 } 656 657 public static final class UnboundRuntimeVisibleTypeAnnotationsAttribute 658 extends UnboundAttribute<RuntimeVisibleTypeAnnotationsAttribute> 659 implements RuntimeVisibleTypeAnnotationsAttribute { 660 private final List<TypeAnnotation> elements; 661 662 public UnboundRuntimeVisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 663 super(Attributes.runtimeVisibleTypeAnnotations()); 664 this.elements = List.copyOf(elements); 665 } 666 667 @Override 668 public List<TypeAnnotation> annotations() { 669 return elements; 670 } 671 } 672 673 public static final class UnboundRuntimeInvisibleTypeAnnotationsAttribute 674 extends UnboundAttribute<RuntimeInvisibleTypeAnnotationsAttribute> 675 implements RuntimeInvisibleTypeAnnotationsAttribute { 676 private final List<TypeAnnotation> elements; 677 678 public UnboundRuntimeInvisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 679 super(Attributes.runtimeInvisibleTypeAnnotations()); 680 this.elements = List.copyOf(elements); 681 } 682 683 @Override 684 public List<TypeAnnotation> annotations() { 685 return elements; 686 } 687 } 688 689 public record UnboundCharacterRangeInfo(int startPc, int endPc, 690 int characterRangeStart, 691 int characterRangeEnd, 692 int flags) 693 implements CharacterRangeInfo { } 694 695 public record UnboundInnerClassInfo(ClassEntry innerClass, 696 Optional<ClassEntry> outerClass, 697 Optional<Utf8Entry> innerName, 698 int flagsMask) 699 implements InnerClassInfo {} 700 701 public record UnboundLineNumberInfo(int startPc, int lineNumber) 702 implements LineNumberInfo { } 703 704 public record UnboundLocalVariableInfo(int startPc, int length, 705 Utf8Entry name, 706 Utf8Entry type, 707 int slot) 708 implements LocalVariableInfo { } 709 710 public record UnboundLocalVariableTypeInfo(int startPc, int length, 711 Utf8Entry name, 712 Utf8Entry signature, 713 int slot) 714 implements LocalVariableTypeInfo { } 715 716 public record UnboundMethodParameterInfo(Optional<Utf8Entry> name, int flagsMask) 717 implements MethodParameterInfo {} 718 719 public record UnboundModuleExportInfo(PackageEntry exportedPackage, 720 int exportsFlagsMask, 721 List<ModuleEntry> exportsTo) 722 implements ModuleExportInfo { 723 public UnboundModuleExportInfo(PackageEntry exportedPackage, int exportsFlagsMask, 724 List<ModuleEntry> exportsTo) { 725 this.exportedPackage = exportedPackage; 726 this.exportsFlagsMask = exportsFlagsMask; 727 this.exportsTo = List.copyOf(exportsTo); 728 } 729 } 730 731 public record UnboundModuleHashInfo(ModuleEntry moduleName, 732 byte[] hash) implements ModuleHashInfo { } 733 734 public record UnboundModuleOpenInfo(PackageEntry openedPackage, int opensFlagsMask, 735 List<ModuleEntry> opensTo) 736 implements ModuleOpenInfo { 737 public UnboundModuleOpenInfo(PackageEntry openedPackage, int opensFlagsMask, 738 List<ModuleEntry> opensTo) { 739 this.openedPackage = openedPackage; 740 this.opensFlagsMask = opensFlagsMask; 741 this.opensTo = List.copyOf(opensTo); 742 } 743 } 744 745 public record UnboundModuleProvideInfo(ClassEntry provides, 746 List<ClassEntry> providesWith) 747 implements ModuleProvideInfo { 748 public UnboundModuleProvideInfo(ClassEntry provides, List<ClassEntry> providesWith) { 749 this.provides = provides; 750 this.providesWith = List.copyOf(providesWith); 751 } 752 } 753 754 public record UnboundModuleRequiresInfo(ModuleEntry requires, int requiresFlagsMask, 755 Optional<Utf8Entry> requiresVersion) 756 implements ModuleRequireInfo {} 757 758 public record UnboundRecordComponentInfo(Utf8Entry name, 759 Utf8Entry descriptor, 760 List<Attribute<?>> attributes) 761 implements RecordComponentInfo { 762 public UnboundRecordComponentInfo(Utf8Entry name, Utf8Entry descriptor, List<Attribute<?>> attributes) { 763 this.name = name; 764 this.descriptor = descriptor; 765 this.attributes = List.copyOf(attributes); 766 } 767 } 768 769 public record UnboundTypeAnnotation(TargetInfo targetInfo, 770 List<TypePathComponent> targetPath, 771 Utf8Entry className, 772 List<AnnotationElement> elements) implements TypeAnnotation { 773 774 public UnboundTypeAnnotation(TargetInfo targetInfo, List<TypePathComponent> targetPath, 775 Utf8Entry className, List<AnnotationElement> elements) { 776 this.targetInfo = targetInfo; 777 this.targetPath = List.copyOf(targetPath); 778 this.className = className; 779 this.elements = List.copyOf(elements); 780 } 781 782 private int labelToBci(LabelContext lr, Label label) { 783 //helper method to avoid NPE 784 if (lr == null) throw new IllegalArgumentException("Illegal targetType '%s' in TypeAnnotation outside of Code attribute".formatted(targetInfo.targetType())); 785 return lr.labelToBci(label); 786 } 787 788 @Override 789 public void writeTo(BufWriter buf) { 790 LabelContext lr = ((BufWriterImpl) buf).labelContext(); 791 // target_type 792 buf.writeU1(targetInfo.targetType().targetTypeValue()); 793 794 // target_info 795 switch (targetInfo) { 796 case TypeParameterTarget tpt -> buf.writeU1(tpt.typeParameterIndex()); 797 case SupertypeTarget st -> buf.writeU2(st.supertypeIndex()); 798 case TypeParameterBoundTarget tpbt -> { 799 buf.writeU1(tpbt.typeParameterIndex()); 800 buf.writeU1(tpbt.boundIndex()); 801 } 802 case EmptyTarget et -> { 803 // nothing to write 804 } 805 case FormalParameterTarget fpt -> buf.writeU1(fpt.formalParameterIndex()); 806 case ThrowsTarget tt -> buf.writeU2(tt.throwsTargetIndex()); 807 case LocalVarTarget lvt -> { 808 buf.writeU2(lvt.table().size()); 809 for (var e : lvt.table()) { 810 int startPc = labelToBci(lr, e.startLabel()); 811 buf.writeU2(startPc); 812 buf.writeU2(labelToBci(lr, e.endLabel()) - startPc); 813 buf.writeU2(e.index()); 814 } 815 } 816 case CatchTarget ct -> buf.writeU2(ct.exceptionTableIndex()); 817 case OffsetTarget ot -> buf.writeU2(labelToBci(lr, ot.target())); 818 case TypeArgumentTarget tat -> { 819 buf.writeU2(labelToBci(lr, tat.target())); 820 buf.writeU1(tat.typeArgumentIndex()); 821 } 822 } 823 824 // target_path 825 buf.writeU1(targetPath().size()); 826 for (TypePathComponent component : targetPath()) { 827 buf.writeU1(component.typePathKind().tag()); 828 buf.writeU1(component.typeArgumentIndex()); 829 } 830 831 // type_index 832 buf.writeIndex(className); 833 834 // element_value_pairs 835 buf.writeU2(elements.size()); 836 for (AnnotationElement pair : elements()) { 837 buf.writeIndex(pair.name()); 838 pair.value().writeTo(buf); 839 } 840 } 841 } 842 843 public record TypePathComponentImpl(TypeAnnotation.TypePathComponent.Kind typePathKind, int typeArgumentIndex) 844 implements TypeAnnotation.TypePathComponent {} 845 846 public static final class UnboundModuleAttribute extends UnboundAttribute<ModuleAttribute> implements ModuleAttribute { 847 private final ModuleEntry moduleName; 848 private final int moduleFlags; 849 private final Utf8Entry moduleVersion; 850 private final List<ModuleRequireInfo> requires; 851 private final List<ModuleExportInfo> exports; 852 private final List<ModuleOpenInfo> opens; 853 private final List<ClassEntry> uses; 854 private final List<ModuleProvideInfo> provides; 855 856 public UnboundModuleAttribute(ModuleEntry moduleName, 857 int moduleFlags, 858 Utf8Entry moduleVersion, 859 Collection<ModuleRequireInfo> requires, 860 Collection<ModuleExportInfo> exports, 861 Collection<ModuleOpenInfo> opens, 862 Collection<ClassEntry> uses, 863 Collection<ModuleProvideInfo> provides) 864 { 865 super(Attributes.module()); 866 this.moduleName = moduleName; 867 this.moduleFlags = moduleFlags; 868 this.moduleVersion = moduleVersion; 869 this.requires = List.copyOf(requires); 870 this.exports = List.copyOf(exports); 871 this.opens = List.copyOf(opens); 872 this.uses = List.copyOf(uses); 873 this.provides = List.copyOf(provides); 874 } 875 876 @Override 877 public ModuleEntry moduleName() { 878 return moduleName; 879 } 880 881 @Override 882 public int moduleFlagsMask() { 883 return moduleFlags; 884 } 885 886 @Override 887 public Optional<Utf8Entry> moduleVersion() { 888 return Optional.ofNullable(moduleVersion); 889 } 890 891 @Override 892 public List<ModuleRequireInfo> requires() { 893 return requires; 894 } 895 896 @Override 897 public List<ModuleExportInfo> exports() { 898 return exports; 899 } 900 901 @Override 902 public List<ModuleOpenInfo> opens() { 903 return opens; 904 } 905 906 @Override 907 public List<ClassEntry> uses() { 908 return uses; 909 } 910 911 @Override 912 public List<ModuleProvideInfo> provides() { 913 return provides; 914 } 915 } 916 917 public abstract static non-sealed class AdHocAttribute<T extends Attribute<T>> 918 extends UnboundAttribute<T> { 919 920 public AdHocAttribute(AttributeMapper<T> mapper) { 921 super(mapper); 922 } 923 924 public abstract void writeBody(BufWriter b); 925 926 @Override 927 public void writeTo(BufWriter b) { 928 b.writeIndex(b.constantPool().utf8Entry(mapper.name())); 929 b.writeInt(0); 930 int start = b.size(); 931 writeBody(b); 932 int written = b.size() - start; 933 b.patchInt(start - 4, 4, written); 934 } 935 } 936 937 public static final class EmptyBootstrapAttribute 938 extends UnboundAttribute<BootstrapMethodsAttribute> 939 implements BootstrapMethodsAttribute { 940 public EmptyBootstrapAttribute() { 941 super(Attributes.bootstrapMethods()); 942 } 943 944 @Override 945 public int bootstrapMethodsSize() { 946 return 0; 947 } 948 949 @Override 950 public List<BootstrapMethodEntry> bootstrapMethods() { 951 return List.of(); 952 } 953 } 954 }