1 /* 2 * Copyright 2016 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.turbine.bytecode; 18 19 import static java.util.Objects.requireNonNull; 20 21 import com.google.auto.value.AutoValue; 22 import com.google.common.collect.ImmutableList; 23 import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue; 24 import com.google.turbine.model.Const; 25 import com.google.turbine.model.Const.Value; 26 import java.util.ArrayDeque; 27 import java.util.Deque; 28 import java.util.List; 29 import java.util.Map; 30 import org.jspecify.annotations.Nullable; 31 32 /** A JVMS §4.1 ClassFile. */ 33 public class ClassFile { 34 35 private final int access; 36 private final int majorVersion; 37 private final String name; 38 private final @Nullable String signature; 39 private final @Nullable String superClass; 40 private final List<String> interfaces; 41 private final List<String> permits; 42 private final List<MethodInfo> methods; 43 private final List<FieldInfo> fields; 44 private final List<AnnotationInfo> annotations; 45 private final List<InnerClass> innerClasses; 46 private final ImmutableList<TypeAnnotationInfo> typeAnnotations; 47 private final @Nullable ModuleInfo module; 48 private final @Nullable String nestHost; 49 private final ImmutableList<String> nestMembers; 50 private final @Nullable RecordInfo record; 51 private final @Nullable String transitiveJar; 52 ClassFile( int access, int majorVersion, String name, @Nullable String signature, @Nullable String superClass, List<String> interfaces, List<String> permits, List<MethodInfo> methods, List<FieldInfo> fields, List<AnnotationInfo> annotations, List<InnerClass> innerClasses, ImmutableList<TypeAnnotationInfo> typeAnnotations, @Nullable ModuleInfo module, @Nullable String nestHost, ImmutableList<String> nestMembers, @Nullable RecordInfo record, @Nullable String transitiveJar)53 public ClassFile( 54 int access, 55 int majorVersion, 56 String name, 57 @Nullable String signature, 58 @Nullable String superClass, 59 List<String> interfaces, 60 List<String> permits, 61 List<MethodInfo> methods, 62 List<FieldInfo> fields, 63 List<AnnotationInfo> annotations, 64 List<InnerClass> innerClasses, 65 ImmutableList<TypeAnnotationInfo> typeAnnotations, 66 @Nullable ModuleInfo module, 67 @Nullable String nestHost, 68 ImmutableList<String> nestMembers, 69 @Nullable RecordInfo record, 70 @Nullable String transitiveJar) { 71 this.access = access; 72 this.majorVersion = majorVersion; 73 this.name = name; 74 this.signature = signature; 75 this.superClass = superClass; 76 this.interfaces = interfaces; 77 this.permits = permits; 78 this.methods = methods; 79 this.fields = fields; 80 this.annotations = annotations; 81 this.innerClasses = innerClasses; 82 this.typeAnnotations = typeAnnotations; 83 this.module = module; 84 this.nestHost = nestHost; 85 this.nestMembers = nestMembers; 86 this.record = record; 87 this.transitiveJar = transitiveJar; 88 } 89 90 /** Class access and property flags. */ access()91 public int access() { 92 return access; 93 } 94 95 /** Class file major version. */ majorVersion()96 public int majorVersion() { 97 return majorVersion; 98 } 99 100 /** The name of the class or interface. */ name()101 public String name() { 102 return name; 103 } 104 105 /** The value of the Signature attribute. */ signature()106 public @Nullable String signature() { 107 return signature; 108 } 109 110 /** The super class. */ superName()111 public @Nullable String superName() { 112 return superClass; 113 } 114 115 /** The direct superinterfaces. */ interfaces()116 public List<String> interfaces() { 117 return interfaces; 118 } 119 120 /** The permitted direct subclasses. */ permits()121 public List<String> permits() { 122 return permits; 123 } 124 125 /** Methods declared by this class or interfaces type. */ methods()126 public List<MethodInfo> methods() { 127 return methods; 128 } 129 130 /** Fields declared by this class or interfaces type. */ fields()131 public List<FieldInfo> fields() { 132 return fields; 133 } 134 135 /** Declaration annotations of the class. */ annotations()136 public List<AnnotationInfo> annotations() { 137 return annotations; 138 } 139 140 /** Inner class information. */ innerClasses()141 public List<InnerClass> innerClasses() { 142 return innerClasses; 143 } 144 145 /** Type annotations. */ typeAnnotations()146 public ImmutableList<TypeAnnotationInfo> typeAnnotations() { 147 return typeAnnotations; 148 } 149 150 /** A module attribute. */ module()151 public @Nullable ModuleInfo module() { 152 return module; 153 } 154 nestHost()155 public @Nullable String nestHost() { 156 return nestHost; 157 } 158 nestMembers()159 public ImmutableList<String> nestMembers() { 160 return nestMembers; 161 } 162 record()163 public @Nullable RecordInfo record() { 164 return record; 165 } 166 167 /** The original jar of a repackaged transitive class. */ transitiveJar()168 public @Nullable String transitiveJar() { 169 return transitiveJar; 170 } 171 172 /** The contents of a JVMS §4.5 field_info structure. */ 173 public static class FieldInfo { 174 175 private final int access; 176 private final String name; 177 private final String descriptor; 178 private final @Nullable String signature; 179 private final @Nullable Value value; 180 private final List<AnnotationInfo> annotations; 181 private final ImmutableList<TypeAnnotationInfo> typeAnnotations; 182 FieldInfo( int access, String name, String descriptor, @Nullable String signature, @Nullable Value value, List<AnnotationInfo> annotations, ImmutableList<TypeAnnotationInfo> typeAnnotations)183 public FieldInfo( 184 int access, 185 String name, 186 String descriptor, 187 @Nullable String signature, 188 @Nullable Value value, 189 List<AnnotationInfo> annotations, 190 ImmutableList<TypeAnnotationInfo> typeAnnotations) { 191 this.access = access; 192 this.name = name; 193 this.descriptor = descriptor; 194 this.signature = signature; 195 this.value = value; 196 this.annotations = annotations; 197 this.typeAnnotations = typeAnnotations; 198 } 199 200 /** Field access and property flags. */ access()201 public int access() { 202 return access; 203 } 204 205 /** The name of the field. */ name()206 public String name() { 207 return name; 208 } 209 210 /** The descriptor. */ descriptor()211 public String descriptor() { 212 return descriptor; 213 } 214 215 /** The value of Signature attribute. */ signature()216 public @Nullable String signature() { 217 return signature; 218 } 219 220 /** The compile-time constant value. */ value()221 public Const.@Nullable Value value() { 222 return value; 223 } 224 225 /** Declaration annotations of the field. */ annotations()226 public List<AnnotationInfo> annotations() { 227 return annotations; 228 } 229 230 /** Type annotations. */ typeAnnotations()231 public ImmutableList<TypeAnnotationInfo> typeAnnotations() { 232 return typeAnnotations; 233 } 234 } 235 236 /** A JVMS §4.7.6 InnerClasses attribute. */ 237 public static class InnerClass { 238 239 private final String innerClass; 240 private final String outerClass; 241 private final String innerName; 242 private final int access; 243 InnerClass(String innerClass, String outerClass, String innerName, int access)244 public InnerClass(String innerClass, String outerClass, String innerName, int access) { 245 this.innerClass = requireNonNull(innerClass); 246 this.outerClass = requireNonNull(outerClass); 247 this.innerName = requireNonNull(innerName); 248 this.access = access; 249 } 250 251 /** The binary name of the inner class. */ innerClass()252 public String innerClass() { 253 return innerClass; 254 } 255 256 /** The binary name of the enclosing class. */ outerClass()257 public String outerClass() { 258 return outerClass; 259 } 260 261 /** The simple name of the inner class. */ innerName()262 public String innerName() { 263 return innerName; 264 } 265 266 /** Access and property flags of the inner class; see JVMS table 4.8. */ access()267 public int access() { 268 return access; 269 } 270 } 271 272 /** The contents of a JVMS §4.6 method_info structure. */ 273 public static class MethodInfo { 274 275 private final int access; 276 private final String name; 277 private final String descriptor; 278 private final @Nullable String signature; 279 private final List<String> exceptions; 280 private final AnnotationInfo.@Nullable ElementValue defaultValue; 281 private final List<AnnotationInfo> annotations; 282 private final ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations; 283 private final ImmutableList<TypeAnnotationInfo> typeAnnotations; 284 private final ImmutableList<ParameterInfo> parameters; 285 MethodInfo( int access, String name, String descriptor, @Nullable String signature, List<String> exceptions, @Nullable ElementValue defaultValue, List<AnnotationInfo> annotations, ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations, ImmutableList<TypeAnnotationInfo> typeAnnotations, ImmutableList<ParameterInfo> parameters)286 public MethodInfo( 287 int access, 288 String name, 289 String descriptor, 290 @Nullable String signature, 291 List<String> exceptions, 292 @Nullable ElementValue defaultValue, 293 List<AnnotationInfo> annotations, 294 ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations, 295 ImmutableList<TypeAnnotationInfo> typeAnnotations, 296 ImmutableList<ParameterInfo> parameters) { 297 this.access = access; 298 this.name = name; 299 this.descriptor = descriptor; 300 this.signature = signature; 301 this.exceptions = exceptions; 302 this.defaultValue = defaultValue; 303 this.annotations = annotations; 304 this.parameterAnnotations = parameterAnnotations; 305 this.typeAnnotations = typeAnnotations; 306 this.parameters = parameters; 307 } 308 309 /** Method access and property flags. */ access()310 public int access() { 311 return access; 312 } 313 314 /** The name of the method. */ name()315 public String name() { 316 return name; 317 } 318 319 /** The descriptor. */ descriptor()320 public String descriptor() { 321 return descriptor; 322 } 323 324 /** The value of Signature attribute. */ signature()325 public @Nullable String signature() { 326 return signature; 327 } 328 329 /** The value of Exceptions attribute. */ exceptions()330 public List<String> exceptions() { 331 return exceptions; 332 } 333 334 /** The value of the AnnotationDefault attribute. */ defaultValue()335 public AnnotationInfo.@Nullable ElementValue defaultValue() { 336 return defaultValue; 337 } 338 339 /** Declaration annotations of the method. */ annotations()340 public List<AnnotationInfo> annotations() { 341 return annotations; 342 } 343 344 /** Declaration annotations of the formal parameters. */ parameterAnnotations()345 public ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations() { 346 return parameterAnnotations; 347 } 348 349 /** Type annotations. */ typeAnnotations()350 public ImmutableList<TypeAnnotationInfo> typeAnnotations() { 351 return typeAnnotations; 352 } 353 354 /** Formal parameters. */ parameters()355 public ImmutableList<ParameterInfo> parameters() { 356 return parameters; 357 } 358 359 /** A formal parameter. */ 360 public static class ParameterInfo { 361 private final String name; 362 private final int access; 363 ParameterInfo(String name, int access)364 public ParameterInfo(String name, int access) { 365 this.name = name; 366 this.access = access; 367 } 368 369 /** Returns the parameter's name. */ name()370 public String name() { 371 return name; 372 } 373 374 /** Returns the parameter's modifiers. */ access()375 public int access() { 376 return access; 377 } 378 } 379 } 380 381 /** The contents of a JVMS §4.7.16 annotation structure. */ 382 public static class AnnotationInfo { 383 384 /** Whether the annotation is visible at runtime. */ 385 public enum RuntimeVisibility { 386 VISIBLE, 387 INVISIBLE 388 } 389 390 private final String typeName; 391 private final RuntimeVisibility runtimeVisibility; 392 private final Map<String, ElementValue> elementValuePairs; 393 AnnotationInfo( String typeName, RuntimeVisibility runtimeVisibility, Map<String, ElementValue> elementValuePairs)394 public AnnotationInfo( 395 String typeName, 396 RuntimeVisibility runtimeVisibility, 397 Map<String, ElementValue> elementValuePairs) { 398 this.typeName = typeName; 399 this.runtimeVisibility = runtimeVisibility; 400 this.elementValuePairs = elementValuePairs; 401 } 402 403 /** The JVMS §4.3.2 field descriptor for the type of the annotation. */ typeName()404 public String typeName() { 405 return typeName; 406 } 407 408 /** Returns true if the annotation is visible at runtime. */ isRuntimeVisible()409 public boolean isRuntimeVisible() { 410 return runtimeVisibility == RuntimeVisibility.VISIBLE; 411 } 412 413 /** The element-value pairs of the annotation. */ elementValuePairs()414 public Map<String, ElementValue> elementValuePairs() { 415 return elementValuePairs; 416 } 417 418 /** A value of a JVMS §4.7.16.1 element-value pair. */ 419 public interface ElementValue { 420 421 /** The value kind. */ kind()422 ElementValue.Kind kind(); 423 424 /** Element value kinds. */ 425 enum Kind { 426 ENUM, 427 CONST, 428 ARRAY, 429 CLASS, 430 ANNOTATION 431 } 432 433 /** An enum constant value. */ 434 class EnumConstValue implements ElementValue { 435 436 private final String typeName; 437 private final String constName; 438 EnumConstValue(String typeName, String constName)439 public EnumConstValue(String typeName, String constName) { 440 this.typeName = typeName; 441 this.constName = constName; 442 } 443 444 @Override kind()445 public ElementValue.Kind kind() { 446 return ElementValue.Kind.ENUM; 447 } 448 449 /** The type of the enum. */ typeName()450 public String typeName() { 451 return typeName; 452 } 453 454 /** The name of the enum constant. */ constName()455 public String constName() { 456 return constName; 457 } 458 } 459 460 /** A primitive or string constant value. */ 461 class ConstValue implements ElementValue { 462 463 private final Const.Value value; 464 ConstValue(Const.Value value)465 public ConstValue(Const.Value value) { 466 467 this.value = value; 468 } 469 470 @Override kind()471 public ElementValue.Kind kind() { 472 return ElementValue.Kind.CONST; 473 } 474 475 /** The constant value. */ value()476 public Const.Value value() { 477 return value; 478 } 479 } 480 481 /** A constant array value. */ 482 class ArrayValue implements ElementValue { 483 484 private final List<ElementValue> elements; 485 ArrayValue(List<ElementValue> elements)486 public ArrayValue(List<ElementValue> elements) { 487 this.elements = elements; 488 } 489 490 @Override kind()491 public ElementValue.Kind kind() { 492 return ElementValue.Kind.ARRAY; 493 } 494 495 /** The elements of the array. */ elements()496 public List<ElementValue> elements() { 497 return elements; 498 } 499 } 500 501 /** A constant class literal value. */ 502 class ConstTurbineClassValue implements ElementValue { 503 504 private final String className; 505 ConstTurbineClassValue(String className)506 public ConstTurbineClassValue(String className) { 507 this.className = className; 508 } 509 510 @Override kind()511 public ElementValue.Kind kind() { 512 return ElementValue.Kind.CLASS; 513 } 514 515 /** The class name. */ className()516 public String className() { 517 return className; 518 } 519 } 520 521 /** A nested annotation value. */ 522 class ConstTurbineAnnotationValue implements ElementValue { 523 524 private final AnnotationInfo annotation; 525 ConstTurbineAnnotationValue(AnnotationInfo annotation)526 public ConstTurbineAnnotationValue(AnnotationInfo annotation) { 527 this.annotation = annotation; 528 } 529 530 @Override kind()531 public ElementValue.Kind kind() { 532 return ElementValue.Kind.ANNOTATION; 533 } 534 535 /** The annotation. */ annotation()536 public AnnotationInfo annotation() { 537 return annotation; 538 } 539 } 540 } 541 } 542 543 /** The contents of a JVMS §4.7.20 type annotation structure. */ 544 public static class TypeAnnotationInfo { 545 private final TargetType targetType; 546 private final Target target; 547 private final TypePath path; 548 private final AnnotationInfo anno; 549 TypeAnnotationInfo( TargetType targetType, Target target, TypePath path, AnnotationInfo anno)550 public TypeAnnotationInfo( 551 TargetType targetType, Target target, TypePath path, AnnotationInfo anno) { 552 this.targetType = targetType; 553 this.target = target; 554 this.path = path; 555 this.anno = anno; 556 } 557 558 /** 559 * The underlying annotation info (type, visibility, element-value pairs); shared with 560 * declaration annotations. 561 */ anno()562 public AnnotationInfo anno() { 563 return anno; 564 } 565 566 /** A JVMS 4.7.20 target_type kind, denotes the type context where the annotation appears. */ targetType()567 public TargetType targetType() { 568 return targetType; 569 } 570 571 /** A JVMS 4.7.20 target_info structure. */ target()572 public Target target() { 573 return target; 574 } 575 576 /** 577 * A JVMS 4.7.20 type_path structure, denotes which part of the type the annotation applies to. 578 */ path()579 public TypePath path() { 580 return path; 581 } 582 583 /** A JVMS 4.7.20-A target_type kind. */ 584 public enum TargetType { 585 CLASS_TYPE_PARAMETER(0x00), 586 METHOD_TYPE_PARAMETER(0x01), 587 SUPERTYPE(0x10), 588 CLASS_TYPE_PARAMETER_BOUND(0x11), 589 METHOD_TYPE_PARAMETER_BOUND(0x12), 590 FIELD(0x13), 591 METHOD_RETURN(0x14), 592 METHOD_RECEIVER_PARAMETER(0x15), 593 METHOD_FORMAL_PARAMETER(0x16), 594 METHOD_THROWS(0x17); 595 596 private final int tag; 597 TargetType(int tag)598 TargetType(int tag) { 599 this.tag = tag; 600 } 601 tag()602 public int tag() { 603 return tag; 604 } 605 606 /** 607 * Returns the {@link TargetType} for the given JVMS 4.7.20-A target_type value, and {@code 608 * null} for target_type values that do not correspond to API elements (see JVMS 4.7.20-B). 609 */ forTag(int targetType)610 static @Nullable TargetType forTag(int targetType) { 611 switch (targetType) { 612 case 0x00: 613 return CLASS_TYPE_PARAMETER; 614 case 0x01: 615 return METHOD_TYPE_PARAMETER; 616 case 0x10: 617 return SUPERTYPE; 618 case 0x11: 619 return CLASS_TYPE_PARAMETER_BOUND; 620 case 0x12: 621 return METHOD_TYPE_PARAMETER_BOUND; 622 case 0x13: 623 return FIELD; 624 case 0x14: 625 return METHOD_RETURN; 626 case 0x15: 627 return METHOD_RECEIVER_PARAMETER; 628 case 0x16: 629 return METHOD_FORMAL_PARAMETER; 630 case 0x17: 631 return METHOD_THROWS; 632 default: 633 return null; 634 } 635 } 636 } 637 638 /** A JVMS 4.7.20 target_info. */ 639 public abstract static class Target { 640 /** Target info kind. */ 641 public enum Kind { 642 TYPE_PARAMETER, 643 SUPERTYPE, 644 TYPE_PARAMETER_BOUND, 645 EMPTY, 646 FORMAL_PARAMETER, 647 THROWS; 648 } 649 650 /** Returns the target info kind. */ kind()651 public abstract Target.Kind kind(); 652 } 653 654 /** A JVMS 4.7.20.1 type_parameter_target. */ 655 @AutoValue 656 public abstract static class TypeParameterTarget extends Target { create(int index)657 public static TypeParameterTarget create(int index) { 658 return new AutoValue_ClassFile_TypeAnnotationInfo_TypeParameterTarget(index); 659 } 660 index()661 public abstract int index(); 662 663 @Override kind()664 public Target.Kind kind() { 665 return Target.Kind.TYPE_PARAMETER; 666 } 667 } 668 669 /** A JVMS 4.7.20.1 supertype_target. */ 670 @AutoValue 671 public abstract static class SuperTypeTarget extends Target { create(int index)672 public static SuperTypeTarget create(int index) { 673 return new AutoValue_ClassFile_TypeAnnotationInfo_SuperTypeTarget(index); 674 } 675 676 @Override kind()677 public Target.Kind kind() { 678 return Target.Kind.SUPERTYPE; 679 } 680 index()681 public abstract int index(); 682 } 683 684 /** A JVMS 4.7.20.1 type_parameter_bound_target. */ 685 @AutoValue 686 public abstract static class TypeParameterBoundTarget extends Target { create(int typeParameterIndex, int boundIndex)687 public static TypeParameterBoundTarget create(int typeParameterIndex, int boundIndex) { 688 return new AutoValue_ClassFile_TypeAnnotationInfo_TypeParameterBoundTarget( 689 typeParameterIndex, boundIndex); 690 } 691 692 @Override kind()693 public Target.Kind kind() { 694 return Target.Kind.TYPE_PARAMETER_BOUND; 695 } 696 typeParameterIndex()697 public abstract int typeParameterIndex(); 698 boundIndex()699 public abstract int boundIndex(); 700 } 701 702 /** A JVMS 4.7.20.1 empty_target. */ 703 public static final Target EMPTY_TARGET = 704 new Target() { 705 @Override 706 public Target.Kind kind() { 707 return Target.Kind.EMPTY; 708 } 709 }; 710 711 /** A JVMS 4.7.20.1 formal_parameter_target. */ 712 @AutoValue 713 public abstract static class FormalParameterTarget extends Target { 714 create(int index)715 public static FormalParameterTarget create(int index) { 716 return new AutoValue_ClassFile_TypeAnnotationInfo_FormalParameterTarget(index); 717 } 718 719 @Override kind()720 public Target.Kind kind() { 721 return Target.Kind.FORMAL_PARAMETER; 722 } 723 index()724 public abstract int index(); 725 } 726 727 /** A JVMS 4.7.20.1 throws_target. */ 728 @AutoValue 729 public abstract static class ThrowsTarget extends Target { 730 create(int index)731 public static ThrowsTarget create(int index) { 732 return new AutoValue_ClassFile_TypeAnnotationInfo_ThrowsTarget(index); 733 } 734 735 @Override kind()736 public Target.Kind kind() { 737 return Target.Kind.THROWS; 738 } 739 index()740 public abstract int index(); 741 } 742 743 /** 744 * A JVMS 4.7.20.2 type_path. 745 * 746 * <p>Represented as an immutable linked-list of nodes, which is built out by {@code Lower} 747 * while recursively searching for type annotations to process. 748 */ 749 @AutoValue 750 public abstract static class TypePath { 751 752 /** The root type_path_kind, used for initialization. */ root()753 public static TypePath root() { 754 return create(null, null); 755 } 756 757 /** Adds an array type_path_kind entry. */ array()758 public TypePath array() { 759 return create(TypePath.Kind.ARRAY, this); 760 } 761 762 /** Adds a nested type type_path_kind entry. */ nested()763 public TypePath nested() { 764 return create(TypePath.Kind.NESTED, this); 765 } 766 767 /** Adds a wildcard bound type_path_kind entry. */ wild()768 public TypePath wild() { 769 return create(TypePath.Kind.WILDCARD_BOUND, this); 770 } 771 772 /** Adds a type argument type_path_kind entry. */ typeArgument(int idx)773 public TypePath typeArgument(int idx) { 774 return create(idx, TypePath.Kind.TYPE_ARGUMENT, this); 775 } 776 777 /** A type_path_kind. */ 778 public enum Kind { 779 ARRAY(0), 780 NESTED(1), 781 WILDCARD_BOUND(2), 782 TYPE_ARGUMENT(3); 783 784 final int tag; 785 Kind(int tag)786 Kind(int tag) { 787 this.tag = tag; 788 } 789 } 790 791 /** The type argument index; set only if the kind is {@code TYPE_ARGUMENT}. */ typeArgumentIndex()792 public abstract int typeArgumentIndex(); 793 kind()794 public abstract @Nullable Kind kind(); 795 parent()796 public abstract @Nullable TypePath parent(); 797 create(TypePath.@ullable Kind kind, @Nullable TypePath parent)798 private static TypePath create(TypePath.@Nullable Kind kind, @Nullable TypePath parent) { 799 // JVMS 4.7.20.2: type_argument_index is 0 if the bound kind is not TYPE_ARGUMENT 800 return create(0, kind, parent); 801 } 802 create( int index, TypePath.@Nullable Kind kind, @Nullable TypePath parent)803 private static TypePath create( 804 int index, TypePath.@Nullable Kind kind, @Nullable TypePath parent) { 805 return new AutoValue_ClassFile_TypeAnnotationInfo_TypePath(index, kind, parent); 806 } 807 808 /** The JVMS 4.7.20.2-A serialized value of the type_path_kind. */ tag()809 public byte tag() { 810 return (byte) requireNonNull(kind()).tag; 811 } 812 813 /** Returns a flattened view of the type path. */ flatten()814 public ImmutableList<TypePath> flatten() { 815 Deque<TypePath> flat = new ArrayDeque<>(); 816 for (TypePath curr = this; requireNonNull(curr).kind() != null; curr = curr.parent()) { 817 flat.addFirst(curr); 818 } 819 return ImmutableList.copyOf(flat); 820 } 821 } 822 } 823 824 /** A JVMS 4.7.25 module attribute. */ 825 public static class ModuleInfo { 826 827 private final String name; 828 private final @Nullable String version; 829 private final int flags; 830 private final ImmutableList<RequireInfo> requires; 831 private final ImmutableList<ExportInfo> exports; 832 private final ImmutableList<OpenInfo> opens; 833 private final ImmutableList<UseInfo> uses; 834 private final ImmutableList<ProvideInfo> provides; 835 ModuleInfo( String name, int flags, @Nullable String version, ImmutableList<RequireInfo> requires, ImmutableList<ExportInfo> exports, ImmutableList<OpenInfo> opens, ImmutableList<UseInfo> uses, ImmutableList<ProvideInfo> provides)836 public ModuleInfo( 837 String name, 838 int flags, 839 @Nullable String version, 840 ImmutableList<RequireInfo> requires, 841 ImmutableList<ExportInfo> exports, 842 ImmutableList<OpenInfo> opens, 843 ImmutableList<UseInfo> uses, 844 ImmutableList<ProvideInfo> provides) { 845 this.name = name; 846 this.flags = flags; 847 this.version = version; 848 this.requires = requires; 849 this.exports = exports; 850 this.opens = opens; 851 this.uses = uses; 852 this.provides = provides; 853 } 854 name()855 public String name() { 856 return name; 857 } 858 flags()859 public int flags() { 860 return flags; 861 } 862 version()863 public @Nullable String version() { 864 return version; 865 } 866 requires()867 public ImmutableList<RequireInfo> requires() { 868 return requires; 869 } 870 exports()871 public ImmutableList<ExportInfo> exports() { 872 return exports; 873 } 874 opens()875 public ImmutableList<OpenInfo> opens() { 876 return opens; 877 } 878 uses()879 public ImmutableList<UseInfo> uses() { 880 return uses; 881 } 882 provides()883 public ImmutableList<ProvideInfo> provides() { 884 return provides; 885 } 886 887 /** A JVMS 4.7.25 module requires directive. */ 888 public static class RequireInfo { 889 890 private final String moduleName; 891 private final int flags; 892 private final @Nullable String version; 893 RequireInfo(String moduleName, int flags, @Nullable String version)894 public RequireInfo(String moduleName, int flags, @Nullable String version) { 895 this.moduleName = moduleName; 896 this.flags = flags; 897 this.version = version; 898 } 899 moduleName()900 public String moduleName() { 901 return moduleName; 902 } 903 flags()904 public int flags() { 905 return flags; 906 } 907 version()908 public @Nullable String version() { 909 return version; 910 } 911 } 912 913 /** A JVMS 4.7.25 module exports directive. */ 914 public static class ExportInfo { 915 916 private final String moduleName; 917 private final int flags; 918 private final ImmutableList<String> modules; 919 ExportInfo(String moduleName, int flags, ImmutableList<String> modules)920 public ExportInfo(String moduleName, int flags, ImmutableList<String> modules) { 921 this.moduleName = moduleName; 922 this.flags = flags; 923 this.modules = modules; 924 } 925 moduleName()926 public String moduleName() { 927 return moduleName; 928 } 929 flags()930 public int flags() { 931 return flags; 932 } 933 modules()934 public ImmutableList<String> modules() { 935 return modules; 936 } 937 } 938 939 /** A JVMS 4.7.25 module opens directive. */ 940 public static class OpenInfo { 941 942 private final String moduleName; 943 private final int flags; 944 private final ImmutableList<String> modules; 945 OpenInfo(String moduleName, int flags, ImmutableList<String> modules)946 public OpenInfo(String moduleName, int flags, ImmutableList<String> modules) { 947 this.moduleName = moduleName; 948 this.flags = flags; 949 this.modules = modules; 950 } 951 moduleName()952 public String moduleName() { 953 return moduleName; 954 } 955 flags()956 public int flags() { 957 return flags; 958 } 959 modules()960 public ImmutableList<String> modules() { 961 return modules; 962 } 963 } 964 965 /** A JVMS 4.7.25 module uses directive. */ 966 public static class UseInfo { 967 968 private final String descriptor; 969 UseInfo(String descriptor)970 public UseInfo(String descriptor) { 971 this.descriptor = descriptor; 972 } 973 descriptor()974 public String descriptor() { 975 return descriptor; 976 } 977 } 978 979 /** A JVMS 4.7.25 module provides directive. */ 980 public static class ProvideInfo { 981 982 private final String descriptor; 983 private final ImmutableList<String> implDescriptors; 984 ProvideInfo(String descriptor, ImmutableList<String> implDescriptors)985 public ProvideInfo(String descriptor, ImmutableList<String> implDescriptors) { 986 this.descriptor = descriptor; 987 this.implDescriptors = implDescriptors; 988 } 989 descriptor()990 public String descriptor() { 991 return descriptor; 992 } 993 implDescriptors()994 public ImmutableList<String> implDescriptors() { 995 return implDescriptors; 996 } 997 } 998 } 999 1000 /** A JVMS §4.7.30 Record attribute. */ 1001 public static class RecordInfo { 1002 1003 /** A JVMS §4.7.30 Record component attribute. */ 1004 public static class RecordComponentInfo { 1005 1006 private final String name; 1007 private final String descriptor; 1008 private final @Nullable String signature; 1009 private final ImmutableList<AnnotationInfo> annotations; 1010 private final ImmutableList<TypeAnnotationInfo> typeAnnotations; 1011 RecordComponentInfo( String name, String descriptor, @Nullable String signature, ImmutableList<AnnotationInfo> annotations, ImmutableList<TypeAnnotationInfo> typeAnnotations)1012 public RecordComponentInfo( 1013 String name, 1014 String descriptor, 1015 @Nullable String signature, 1016 ImmutableList<AnnotationInfo> annotations, 1017 ImmutableList<TypeAnnotationInfo> typeAnnotations) { 1018 this.name = name; 1019 this.descriptor = descriptor; 1020 this.signature = signature; 1021 this.annotations = annotations; 1022 this.typeAnnotations = typeAnnotations; 1023 } 1024 name()1025 public String name() { 1026 return name; 1027 } 1028 descriptor()1029 public String descriptor() { 1030 return descriptor; 1031 } 1032 signature()1033 public @Nullable String signature() { 1034 return signature; 1035 } 1036 annotations()1037 public ImmutableList<AnnotationInfo> annotations() { 1038 return annotations; 1039 } 1040 typeAnnotations()1041 public ImmutableList<TypeAnnotationInfo> typeAnnotations() { 1042 return typeAnnotations; 1043 } 1044 } 1045 RecordInfo(ImmutableList<RecordComponentInfo> recordComponents)1046 public RecordInfo(ImmutableList<RecordComponentInfo> recordComponents) { 1047 this.recordComponents = recordComponents; 1048 } 1049 1050 private final ImmutableList<RecordComponentInfo> recordComponents; 1051 recordComponents()1052 public ImmutableList<RecordComponentInfo> recordComponents() { 1053 return recordComponents; 1054 } 1055 } 1056 } 1057