diff --git a/src/lib.rs b/src/lib.rs index f18b005..13cf038 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -163,7 +163,7 @@ fn read_field(index: &mut usize, bytecode: &Vec) -> Field { fn read_method(constant_pool: Rc>, index: &mut usize, bytecode: &Vec) -> Method { let access_flags = get_u16(bytecode, *index); let name_index = get_u16(bytecode, *index + 2) as usize; - let descriptor_index = get_u16(bytecode, *index + 4); + let descriptor_index = get_u16(bytecode, *index + 4) as usize; let attributes_count = get_u16(bytecode, *index + 6); *index += 8; let mut attributes = vec![]; diff --git a/src/types.rs b/src/types.rs index 1332a93..c8ced20 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,3 +1,4 @@ +use std::borrow::ToOwned; use std::rc::Rc; use crate::types::CpEntry::*; @@ -62,16 +63,44 @@ pub struct Method { pub constant_pool: Rc>, pub access_flags: u16, pub name_index: usize, - pub descriptor_index: u16, + pub descriptor_index: usize, pub attributes_count: u16, pub attributes: Vec, } impl Method { - pub fn name(&self) -> &str { - if let Utf8(s) = &self.constant_pool[self.name_index - 1] { - return &s; + pub fn name(&self) -> String { + let mut full_name = get_modifier(self.access_flags); + if let Utf8(s) = &self.constant_pool[&self.name_index - 1] { + full_name.push_str(s); } - panic!() // name must be utf8 + if let Utf8(s) = &self.constant_pool[&self.descriptor_index - 1] { + full_name.push_str(s); + } + + + full_name } -} \ No newline at end of file +} + +const MODIFIERS: [(u16, &'static str); 12] = [ + (0x0001, "public "), + (0x0002, "private "), + (0x0004, "protected "), + (0x0008, "static "), + (0x0010, "final "), + (0x0020, "synchronized "), + (0x0040, "volatile "), + (0x0080, "transient "), + (0x0100, "native "), + (0x0200, "interface "), + (0x0400, "interface "), + (0x0800, "strict ")]; + +pub fn get_modifier (value: u16) -> String { + let mut output = String::new(); + for m in MODIFIERS { + if value & m.0 == m.0 { output.push_str(&m.1) } + } + output +} diff --git a/tests/class_tests.rs b/tests/class_tests.rs index 312f387..9c6529d 100644 --- a/tests/class_tests.rs +++ b/tests/class_tests.rs @@ -1,87 +1,89 @@ -use std::rc::Rc; -use classfile_reader::types::{Attribute, Class, Field, Method}; -use classfile_reader::types::CpEntry::*; +mod test { + use std::rc::Rc; + use classfile_reader::types::{Attribute, Class, Field, Method}; + use classfile_reader::types::CpEntry::*; -#[test] -fn get_version() { - assert_eq!((55, 0), get_class().get_version()); -} - -#[test] -fn get_methods() { - for m in get_class().get_methods() { - println!("{}", m.name()); + #[test] + fn get_version() { + assert_eq!((55, 0), get_class().get_version()); } -} -fn get_class() -> Class { - let cp = Rc::new(vec![MethodRef(2, 3), - ClassRef(4), - NameAndType(5, 6), - Utf8("java/lang/Object".to_owned()), - Utf8("".to_owned()), - Utf8("()V".to_owned()), - Fieldref(8, 9), - ClassRef(10), - NameAndType(11, 12), - Utf8("com/github/shautvast/reflective/MetaField".to_owned()), - Utf8("name".to_owned()), - Utf8("Ljava/lang/String;".to_owned()), - Fieldref(8, 14), - NameAndType(15, 16), - Utf8("modifiers".to_owned()), - Utf8("I".to_owned()), - Utf8("(Ljava/lang/String;I)V".to_owned()), - Utf8("Code".to_owned()), - Utf8("LineNumberTable".to_owned()), - Utf8("LocalVariableTable".to_owned()), - Utf8("this".to_owned()), - Utf8("Lcom/github/shautvast/reflective/MetaField;".to_owned()), - Utf8("getName".to_owned()), - Utf8("()Ljava/lang/String;".to_owned()), - Utf8("getModifiers".to_owned()), - Utf8("()I".to_owned()), - Utf8("SourceFile".to_owned()), - Utf8("MetaField.java".to_owned())]); + #[test] + fn get_methods() { + for m in get_class().get_methods() { + println!("{}", m.name()); + } + } - Class { - minor_version: 0, - major_version: 55, - constant_pool: cp.clone(), - interfaces: vec![], - super_class: 2, - access_flags: 33, - this_class: 8, - methods: vec![ - Method { - constant_pool: cp.clone(), - access_flags: 1, - name_index: 5, - descriptor_index: 17, - attributes_count: 1, - attributes: vec![Attribute { - attribute_name_index: 18, - info: vec![0, 2, 0, 3, 0, 0, 0, 15, 42, 183, 0, 1, 42, 43, 181, 0, 7, 42, 28, - 181, 0, 13, 177, 0, 0, 0, 2, 0, 19, 0, 0, 0, - 18, 0, 4, 0, 0, 0, 8, 0, 4, 0, 9, 0, 9, 0, 10, 0, 14, 0, 11, 0, 20, 0, 0, - 0, 32, 0, 3, 0, 0, 0, 15, 0, 21, 0, 22, 0, 0, 0, 0, 0, 15, 0, 11, - 0, 12, 0, 1, 0, 0, 0, 15, 0, 15, 0, 16, 0, 2], + fn get_class() -> Class { + let cp = Rc::new(vec![MethodRef(2, 3), + ClassRef(4), + NameAndType(5, 6), + Utf8("java/lang/Object".to_owned()), + Utf8("".to_owned()), + Utf8("()V".to_owned()), + Fieldref(8, 9), + ClassRef(10), + NameAndType(11, 12), + Utf8("com/github/shautvast/reflective/MetaField".to_owned()), + Utf8("name".to_owned()), + Utf8("Ljava/lang/String;".to_owned()), + Fieldref(8, 14), + NameAndType(15, 16), + Utf8("modifiers".to_owned()), + Utf8("I".to_owned()), + Utf8("(Ljava/lang/String;I)V".to_owned()), + Utf8("Code".to_owned()), + Utf8("LineNumberTable".to_owned()), + Utf8("LocalVariableTable".to_owned()), + Utf8("this".to_owned()), + Utf8("Lcom/github/shautvast/reflective/MetaField;".to_owned()), + Utf8("getName".to_owned()), + Utf8("()Ljava/lang/String;".to_owned()), + Utf8("getModifiers".to_owned()), + Utf8("()I".to_owned()), + Utf8("SourceFile".to_owned()), + Utf8("MetaField.java".to_owned())]); + + Class { + minor_version: 0, + major_version: 55, + constant_pool: cp.clone(), + interfaces: vec![], + super_class: 2, + access_flags: 33, + this_class: 8, + methods: vec![ + Method { + constant_pool: cp.clone(), + access_flags: 1, + name_index: 5, + descriptor_index: 17, + attributes_count: 1, + attributes: vec![Attribute { + attribute_name_index: 18, + info: vec![0, 2, 0, 3, 0, 0, 0, 15, 42, 183, 0, 1, 42, 43, 181, 0, 7, 42, 28, + 181, 0, 13, 177, 0, 0, 0, 2, 0, 19, 0, 0, 0, + 18, 0, 4, 0, 0, 0, 8, 0, 4, 0, 9, 0, 9, 0, 10, 0, 14, 0, 11, 0, 20, 0, 0, + 0, 32, 0, 3, 0, 0, 0, 15, 0, 21, 0, 22, 0, 0, 0, 0, 0, 15, 0, 11, + 0, 12, 0, 1, 0, 0, 0, 15, 0, 15, 0, 16, 0, 2], + }], + }, + Method { + constant_pool: cp, + access_flags: 1, + name_index: 23, + descriptor_index: 24, + attributes_count: 1, + attributes: vec![Attribute { + attribute_name_index: 18, + info: vec![0, 1, 0, 1, 0, 0, 0, 5, 42, 180, 0, 7, 176, 0, 0, 0, 2, 0, 19, 0, 0, 0, 6, 0, + 1, 0, 0, 0, 14, 0, 20, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 21, 0, 22, 0, 0], + }], }], - }, - Method { - constant_pool: cp, - access_flags: 1, - name_index: 23, - descriptor_index: 24, - attributes_count: 1, - attributes: vec![Attribute { - attribute_name_index: 18, - info: vec![0, 1, 0, 1, 0, 0, 0, 5, 42, 180, 0, 7, 176, 0, 0, 0, 2, 0, 19, 0, 0, 0, 6, 0, - 1, 0, 0, 0, 14, 0, 20, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 21, 0, 22, 0, 0], - }], - }], - fields: vec![Field { access_flags: 18, name_index: 11, descriptor_index: 12, attributes_count: 0, attributes: vec![] }, - Field { access_flags: 18, name_index: 15, descriptor_index: 16, attributes_count: 0, attributes: vec![] }], - attributes: vec![Attribute { attribute_name_index: 27, info: vec![0, 28] }], + fields: vec![Field { access_flags: 18, name_index: 11, descriptor_index: 12, attributes_count: 0, attributes: vec![] }, + Field { access_flags: 18, name_index: 15, descriptor_index: 16, attributes_count: 0, attributes: vec![] }], + attributes: vec![Attribute { attribute_name_index: 27, info: vec![0, 28] }], + } } } \ No newline at end of file