• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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