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