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