1use bitflags::bitflags;
2
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[derive(Debug, Clone)]
6pub struct ClassFile {
7 pub minor_version: u16,
8 pub major_version: u16,
9 pub constant_pool: Vec<ConstantPoolEntry>,
10 pub access_flags: ClassAccessFlags,
11 pub this_class: u16,
12 pub super_class: u16,
13 pub interfaces: Vec<u16>,
14 pub fields: Vec<FieldInfo>,
15 pub methods: Vec<MethodInfo>,
16 pub attributes: Vec<AttributeInfo>,
17}
18
19bitflags! {
20 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22 pub struct ClassAccessFlags: u16 {
23 const PUBLIC = 0x0001;
24 const FINAL = 0x0010;
25 const SUPER = 0x0020;
26 const INTERFACE = 0x0200;
27 const ABSTRACT = 0x0400;
28 const SYNTHETIC = 0x1000;
29 const ANNOTATION = 0x2000;
30 const ENUM = 0x4000;
31 const MODULE = 0x8000;
32 }
33}
34
35bitflags! {
36 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
37 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38 pub struct FieldAccessFlags: u16 {
39 const PUBLIC = 0x0001;
40 const PRIVATE = 0x0002;
41 const PROTECTED = 0x0004;
42 const STATIC = 0x0008;
43 const FINAL = 0x0010;
44 const VOLATILE = 0x0040;
45 const TRANSIENT = 0x0080;
46 const SYNTHETIC = 0x1000;
47 const ENUM = 0x4000;
48 }
49}
50
51bitflags! {
52 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54 pub struct MethodAccessFlags: u16 {
55 const PUBLIC = 0x0001;
56 const PRIVATE = 0x0002;
57 const PROTECTED = 0x0004;
58 const STATIC = 0x0008;
59 const FINAL = 0x0010;
60 const SYNCHRONIZED = 0x0020;
61 const BRIDGE = 0x0040;
62 const VARARGS = 0x0080;
63 const NATIVE = 0x0100;
64 const ABSTRACT = 0x0400;
65 const STRICT = 0x0800;
66 const SYNTHETIC = 0x1000;
67 }
68}
69
70pub mod cp_tag {
72 pub const UTF8: u8 = 1;
73 pub const INTEGER: u8 = 3;
74 pub const FLOAT: u8 = 4;
75 pub const LONG: u8 = 5;
76 pub const DOUBLE: u8 = 6;
77 pub const CLASS: u8 = 7;
78 pub const STRING: u8 = 8;
79 pub const FIELDREF: u8 = 9;
80 pub const METHODREF: u8 = 10;
81 pub const INTERFACE_METHODREF: u8 = 11;
82 pub const NAME_AND_TYPE: u8 = 12;
83 pub const METHOD_HANDLE: u8 = 15;
84 pub const METHOD_TYPE: u8 = 16;
85 pub const DYNAMIC: u8 = 17;
86 pub const INVOKE_DYNAMIC: u8 = 18;
87 pub const MODULE: u8 = 19;
88 pub const PACKAGE: u8 = 20;
89}
90
91pub mod ref_kind {
93 pub const GETFIELD: u8 = 1;
94 pub const GETSTATIC: u8 = 2;
95 pub const PUTFIELD: u8 = 3;
96 pub const PUTSTATIC: u8 = 4;
97 pub const INVOKEVIRTUAL: u8 = 5;
98 pub const INVOKESTATIC: u8 = 6;
99 pub const INVOKESPECIAL: u8 = 7;
100 pub const NEWINVOKESPECIAL: u8 = 8;
101 pub const INVOKEINTERFACE: u8 = 9;
102}
103
104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
107#[derive(Debug, Clone)]
108pub enum ConstantPoolEntry {
109 Utf8(Utf8Info),
110 Integer(IntegerInfo),
111 Float(FloatInfo),
112 Long(LongInfo),
113 Double(DoubleInfo),
114 Class(ClassInfo),
115 String(StringInfo),
116 Fieldref(FieldrefInfo),
117 Methodref(MethodrefInfo),
118 InterfaceMethodref(InterfaceMethodrefInfo),
119 NameAndType(NameAndTypeInfo),
120 MethodHandle(MethodHandleInfo),
121 MethodType(MethodTypeInfo),
122 Dynamic(DynamicInfo),
123 InvokeDynamic(InvokeDynamicInfo),
124 Module(ModuleInfo),
125 Package(PackageInfo),
126}
127
128#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
129#[derive(Debug, Clone)]
130pub struct Utf8Info {
131 pub value: String,
132}
133
134#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
135#[derive(Debug, Clone)]
136pub struct IntegerInfo {
137 pub value: i32,
138}
139
140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141#[derive(Debug, Clone)]
142pub struct FloatInfo {
143 pub value: f32,
144}
145
146#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
147#[derive(Debug, Clone)]
148pub struct LongInfo {
149 pub value: i64,
150}
151
152#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
153#[derive(Debug, Clone)]
154pub struct DoubleInfo {
155 pub value: f64,
156}
157
158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159#[derive(Debug, Clone)]
160pub struct ClassInfo {
161 pub name_index: u16,
162}
163
164#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
165#[derive(Debug, Clone)]
166pub struct StringInfo {
167 pub string_index: u16,
168}
169
170#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
171#[derive(Debug, Clone)]
172pub struct FieldrefInfo {
173 pub class_index: u16,
174 pub name_and_type_index: u16,
175}
176
177#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
178#[derive(Debug, Clone)]
179pub struct MethodrefInfo {
180 pub class_index: u16,
181 pub name_and_type_index: u16,
182}
183
184#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
185#[derive(Debug, Clone)]
186pub struct InterfaceMethodrefInfo {
187 pub class_index: u16,
188 pub name_and_type_index: u16,
189}
190
191#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
192#[derive(Debug, Clone)]
193pub struct NameAndTypeInfo {
194 pub name_index: u16,
195 pub descriptor_index: u16,
196}
197
198#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
199#[derive(Debug, Clone)]
200pub struct MethodHandleInfo {
201 pub reference_kind: u8,
202 pub reference_index: u16,
203}
204
205#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
206#[derive(Debug, Clone)]
207pub struct MethodTypeInfo {
208 pub descriptor_index: u16,
209}
210
211#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
212#[derive(Debug, Clone)]
213pub struct DynamicInfo {
214 pub bootstrap_method_attr_index: u16,
215 pub name_and_type_index: u16,
216}
217
218#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
219#[derive(Debug, Clone)]
220pub struct InvokeDynamicInfo {
221 pub bootstrap_method_attr_index: u16,
222 pub name_and_type_index: u16,
223}
224
225#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
226#[derive(Debug, Clone)]
227pub struct ModuleInfo {
228 pub name_index: u16,
229}
230
231#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
232#[derive(Debug, Clone)]
233pub struct PackageInfo {
234 pub name_index: u16,
235}
236
237#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
238#[derive(Debug, Clone)]
239pub struct FieldInfo {
240 pub access_flags: FieldAccessFlags,
241 pub name_index: u16,
242 pub descriptor_index: u16,
243 pub attributes: Vec<AttributeInfo>,
244}
245
246#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
247#[derive(Debug, Clone)]
248pub struct MethodInfo {
249 pub access_flags: MethodAccessFlags,
250 pub name_index: u16,
251 pub descriptor_index: u16,
252 pub attributes: Vec<AttributeInfo>,
253}
254
255#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
257#[derive(Debug, Clone)]
258pub struct AttributeInfo {
259 pub attribute_name_index: u16,
260 pub info: Vec<u8>,
261}
262
263#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
266#[derive(Debug, Clone)]
267pub struct CodeAttribute {
268 pub max_stack: u16,
269 pub max_locals: u16,
270 pub code: Vec<u8>,
271 pub exception_table: Vec<ExceptionTableEntry>,
272 pub attributes: Vec<AttributeInfo>,
273}
274
275#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
276#[derive(Debug, Clone)]
277pub struct ExceptionTableEntry {
278 pub start_pc: u16,
279 pub end_pc: u16,
280 pub handler_pc: u16,
281 pub catch_type: u16,
282}
283
284#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
285#[derive(Debug, Clone)]
286pub struct ConstantValueAttribute {
287 pub constantvalue_index: u16,
288}
289
290#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
291#[derive(Debug, Clone)]
292pub struct ExceptionsAttribute {
293 pub exception_index_table: Vec<u16>,
294}
295
296#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
297#[derive(Debug, Clone)]
298pub struct BootstrapMethodsAttribute {
299 pub bootstrap_methods: Vec<BootstrapMethodEntry>,
300}
301
302#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
303#[derive(Debug, Clone)]
304pub struct BootstrapMethodEntry {
305 pub bootstrap_method_ref: u16,
306 pub bootstrap_arguments: Vec<u16>,
307}
308
309#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
310#[derive(Debug, Clone)]
311pub struct StackMapTableAttribute {
312 pub entries: Vec<StackMapFrame>,
313}
314
315#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
316#[derive(Debug, Clone)]
317pub enum StackMapFrame {
318 SameFrame {
319 frame_type: u8,
320 },
321 SameLocals1StackItemFrame {
322 frame_type: u8,
323 stack: VerificationTypeInfo,
324 },
325 SameLocals1StackItemFrameExtended {
326 offset_delta: u16,
327 stack: VerificationTypeInfo,
328 },
329 ChopFrame {
330 frame_type: u8,
331 offset_delta: u16,
332 },
333 SameFrameExtended {
334 offset_delta: u16,
335 },
336 AppendFrame {
337 frame_type: u8,
338 offset_delta: u16,
339 locals: Vec<VerificationTypeInfo>,
340 },
341 FullFrame {
342 offset_delta: u16,
343 locals: Vec<VerificationTypeInfo>,
344 stack: Vec<VerificationTypeInfo>,
345 },
346}
347
348#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
349#[derive(Debug, Clone)]
350pub enum VerificationTypeInfo {
351 Top,
352 Integer,
353 Float,
354 Double,
355 Long,
356 Null,
357 UninitializedThis,
358 Object { cpool_index: u16 },
359 Uninitialized { offset: u16 },
360}
361
362#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
363#[derive(Debug, Clone)]
364pub struct InnerClass {
365 pub inner_class_info_index: u16,
366 pub outer_class_info_index: u16,
367 pub inner_name_index: u16,
368 pub inner_class_access_flags: ClassAccessFlags,
369}
370
371#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
372#[derive(Debug, Clone)]
373pub struct InnerClassesAttribute {
374 pub classes: Vec<InnerClass>,
375}
376
377#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
378#[derive(Debug, Clone)]
379pub struct SourceFileAttribute {
380 pub sourcefile_index: u16,
381}
382
383#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
384#[derive(Debug, Clone)]
385pub struct LineNumberTableAttribute {
386 pub line_number_table: Vec<LineNumberEntry>,
387}
388
389#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
390#[derive(Debug, Clone)]
391pub struct LineNumberEntry {
392 pub start_pc: u16,
393 pub line_number: u16,
394}
395
396#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
397#[derive(Debug, Clone)]
398pub struct LocalVariableTableAttribute {
399 pub local_variable_table: Vec<LocalVariableEntry>,
400}
401
402#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
403#[derive(Debug, Clone)]
404pub struct LocalVariableEntry {
405 pub start_pc: u16,
406 pub length: u16,
407 pub name_index: u16,
408 pub descriptor_index: u16,
409 pub index: u16,
410}
411
412#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
413#[derive(Debug, Clone)]
414pub struct LocalVariableTypeTableAttribute {
415 pub local_variable_type_table: Vec<LocalVariableTypeEntry>,
416}
417
418#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
419#[derive(Debug, Clone)]
420pub struct LocalVariableTypeEntry {
421 pub start_pc: u16,
422 pub length: u16,
423 pub name_index: u16,
424 pub signature_index: u16,
425 pub index: u16,
426}
427
428#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
429#[derive(Debug, Clone)]
430pub struct Annotation {
431 pub type_index: u16,
432 pub element_value_pairs: Vec<(u16, ElementValue)>,
433}
434
435#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
436#[derive(Debug, Clone)]
437pub enum ElementValue {
438 Byte {
439 const_value_index: u16,
440 },
441 Char {
442 const_value_index: u16,
443 },
444 Double {
445 const_value_index: u16,
446 },
447 Float {
448 const_value_index: u16,
449 },
450 Int {
451 const_value_index: u16,
452 },
453 Long {
454 const_value_index: u16,
455 },
456 Short {
457 const_value_index: u16,
458 },
459 Boolean {
460 const_value_index: u16,
461 },
462 String {
463 const_value_index: u16,
464 },
465 Enum {
466 type_name_index: u16,
467 const_name_index: u16,
468 },
469 Class {
470 class_info_index: u16,
471 },
472 AnnotationType {
473 annotation: Annotation,
474 },
475 Array {
476 values: Vec<ElementValue>,
477 },
478}
479
480#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
481#[derive(Debug, Clone)]
482pub struct RuntimeAnnotationsAttribute {
483 pub annotations: Vec<Annotation>,
484}
485
486#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
487#[derive(Debug, Clone)]
488pub struct ParameterAnnotation {
489 pub annotations: Vec<Annotation>,
490}
491
492#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
493#[derive(Debug, Clone)]
494pub struct RuntimeParameterAnnotationsAttribute {
495 pub parameter_annotations: Vec<ParameterAnnotation>,
496}
497
498#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
500#[derive(Debug, Clone)]
501pub enum TypeAnnotationTarget {
502 TypeParameter {
503 type_parameter_index: u8,
504 },
505 SuperType {
506 super_type_index: u16,
507 },
508 TypeParameterBound {
509 type_parameter_index: u8,
510 bound_index: u8,
511 },
512 Empty,
513 FormalParameter {
514 formal_parameter_index: u8,
515 },
516 Throws {
517 throws_type_index: u16,
518 },
519 LocalVar {
520 table: Vec<LocalVarTargetEntry>,
521 },
522 Catch {
523 exception_table_index: u16,
524 },
525 Offset {
526 offset: u16,
527 },
528 TypeArgument {
529 offset: u16,
530 type_argument_index: u8,
531 },
532}
533
534#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
535#[derive(Debug, Clone)]
536pub struct LocalVarTargetEntry {
537 pub start_pc: u16,
538 pub length: u16,
539 pub index: u16,
540}
541
542#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
544#[derive(Debug, Clone)]
545pub struct TypeAnnotation {
546 pub target: TypeAnnotationTarget,
547 pub target_path: Vec<TypePathEntry>,
548 pub type_index: u16,
549 pub element_value_pairs: Vec<(u16, ElementValue)>,
550}
551
552#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
554#[derive(Debug, Clone)]
555pub struct TypePathEntry {
556 pub type_path_kind: u8,
557 pub type_argument_index: u8,
558}
559
560#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
561#[derive(Debug, Clone)]
562pub struct RuntimeTypeAnnotationsAttribute {
563 pub annotations: Vec<TypeAnnotation>,
564}
565
566#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
567#[derive(Debug, Clone)]
568pub struct NestHostAttribute {
569 pub host_class_index: u16,
570}
571
572#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
573#[derive(Debug, Clone)]
574pub struct NestMembersAttribute {
575 pub classes: Vec<u16>,
576}
577
578#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
579#[derive(Debug, Clone)]
580pub struct RecordAttribute {
581 pub components: Vec<RecordComponentInfo>,
582}
583
584#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
585#[derive(Debug, Clone)]
586pub struct RecordComponentInfo {
587 pub name_index: u16,
588 pub descriptor_index: u16,
589 pub attributes: Vec<AttributeInfo>,
590}
591
592#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
593#[derive(Debug, Clone)]
594pub struct PermittedSubclassesAttribute {
595 pub classes: Vec<u16>,
596}
597
598#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
600#[derive(Debug, Clone)]
601pub enum ParsedAttribute {
602 Code(CodeAttribute),
603 ConstantValue(ConstantValueAttribute),
604 Exceptions(ExceptionsAttribute),
605 BootstrapMethods(BootstrapMethodsAttribute),
606 StackMapTable(StackMapTableAttribute),
607 InnerClasses(InnerClassesAttribute),
608 SourceFile(SourceFileAttribute),
609 LineNumberTable(LineNumberTableAttribute),
610 LocalVariableTable(LocalVariableTableAttribute),
611 LocalVariableTypeTable(LocalVariableTypeTableAttribute),
612 RuntimeVisibleAnnotations(RuntimeAnnotationsAttribute),
613 RuntimeInvisibleAnnotations(RuntimeAnnotationsAttribute),
614 RuntimeVisibleParameterAnnotations(RuntimeParameterAnnotationsAttribute),
615 RuntimeInvisibleParameterAnnotations(RuntimeParameterAnnotationsAttribute),
616 RuntimeVisibleTypeAnnotations(RuntimeTypeAnnotationsAttribute),
617 RuntimeInvisibleTypeAnnotations(RuntimeTypeAnnotationsAttribute),
618 NestHost(NestHostAttribute),
619 NestMembers(NestMembersAttribute),
620 Record(RecordAttribute),
621 PermittedSubclasses(PermittedSubclassesAttribute),
622 Deprecated,
623 Synthetic,
624 Signature { signature_index: u16 },
625 Unknown(AttributeInfo),
626}
627
628impl ConstantPoolEntry {
629 pub fn tag(&self) -> u8 {
631 match self {
632 ConstantPoolEntry::Utf8(_) => cp_tag::UTF8,
633 ConstantPoolEntry::Integer(_) => cp_tag::INTEGER,
634 ConstantPoolEntry::Float(_) => cp_tag::FLOAT,
635 ConstantPoolEntry::Long(_) => cp_tag::LONG,
636 ConstantPoolEntry::Double(_) => cp_tag::DOUBLE,
637 ConstantPoolEntry::Class(_) => cp_tag::CLASS,
638 ConstantPoolEntry::String(_) => cp_tag::STRING,
639 ConstantPoolEntry::Fieldref(_) => cp_tag::FIELDREF,
640 ConstantPoolEntry::Methodref(_) => cp_tag::METHODREF,
641 ConstantPoolEntry::InterfaceMethodref(_) => cp_tag::INTERFACE_METHODREF,
642 ConstantPoolEntry::NameAndType(_) => cp_tag::NAME_AND_TYPE,
643 ConstantPoolEntry::MethodHandle(_) => cp_tag::METHOD_HANDLE,
644 ConstantPoolEntry::MethodType(_) => cp_tag::METHOD_TYPE,
645 ConstantPoolEntry::Dynamic(_) => cp_tag::DYNAMIC,
646 ConstantPoolEntry::InvokeDynamic(_) => cp_tag::INVOKE_DYNAMIC,
647 ConstantPoolEntry::Module(_) => cp_tag::MODULE,
648 ConstantPoolEntry::Package(_) => cp_tag::PACKAGE,
649 }
650 }
651
652 pub fn takes_two_slots(&self) -> bool {
654 matches!(
655 self,
656 ConstantPoolEntry::Long(_) | ConstantPoolEntry::Double(_)
657 )
658 }
659}
660
661impl ClassFile {
662 pub fn this_class_name(&self) -> Option<&str> {
664 crate::constant_pool::get_utf8(&self.constant_pool, self.this_class)
665 }
666
667 pub fn super_class_name(&self) -> Option<&str> {
669 if self.super_class == 0 {
670 return None;
671 }
672 crate::constant_pool::get_utf8(&self.constant_pool, self.super_class)
673 }
674
675 pub fn method_name(&self, method: &MethodInfo) -> Option<&str> {
677 crate::constant_pool::get_utf8(&self.constant_pool, method.name_index)
678 }
679
680 pub fn method_descriptor(&self, method: &MethodInfo) -> Option<&str> {
682 crate::constant_pool::get_utf8(&self.constant_pool, method.descriptor_index)
683 }
684
685 pub fn field_name(&self, field: &FieldInfo) -> Option<&str> {
687 crate::constant_pool::get_utf8(&self.constant_pool, field.name_index)
688 }
689
690 pub fn field_descriptor(&self, field: &FieldInfo) -> Option<&str> {
692 crate::constant_pool::get_utf8(&self.constant_pool, field.descriptor_index)
693 }
694
695 pub fn version(&self) -> (u16, u16) {
697 (self.major_version, self.minor_version)
698 }
699}