Skip to content

Commit

Permalink
Merge pull request #35 from emilycares/feature/MethodParameters
Browse files Browse the repository at this point in the history
Add support for MethodParameters
  • Loading branch information
Palmr authored Aug 13, 2024
2 parents d84dda9 + 950f396 commit 1b92dfa
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ fn main() {
- [ ] RuntimeVisibleTypeAnnotations
- [ ] RuntimeInvisibleTypeAnnotations
- [ ] AnnotationDefault
- [ ] MethodParameters
- [X] MethodParameters
- [ ] Useful but not critical
- [x] SourceFile
- [ ] SourceDebugExtension
Expand Down
Binary file modified java-assets/compiled-classes/BasicClass.class
Binary file not shown.
4 changes: 4 additions & 0 deletions java-assets/src/uk/co/palmr/classfileparser/BasicClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ public static long getSize() {
public static double getLEETness() {
return 1.337;
}

public static int add(int a, int b) {
return a + b;
}
}
1 change: 1 addition & 0 deletions src/attribute_info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ pub use self::parser::bootstrap_methods_attribute_parser;
pub use self::parser::code_attribute_parser;
pub use self::parser::constant_value_attribute_parser;
pub use self::parser::exceptions_attribute_parser;
pub use self::parser::method_parameters_attribute_parser;
pub use self::parser::sourcefile_attribute_parser;
pub use self::parser::stack_map_table_attribute_parser;
26 changes: 26 additions & 0 deletions src/attribute_info/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,32 @@ pub fn code_attribute_parser(input: &[u8]) -> Result<(&[u8], CodeAttribute), Err
)
}

pub fn method_parameters_attribute_parser(
input: &[u8],
) -> Result<(&[u8], MethodParametersAttribute), Err<&[u8]>> {
do_parse!(
input,
parameters_count: be_u8
>> parameters: count!(parameters_parser, parameters_count as usize)
>> (MethodParametersAttribute {
parameters_count,
parameters,
})
)
}

pub fn parameters_parser(input: &[u8]) -> Result<(&[u8], ParameterAttribute), Err<&[u8]>> {
do_parse!(
input,
name_index: be_u16
>> access_flags: be_u16
>> (ParameterAttribute {
name_index,
access_flags
})
)
}

fn same_frame_parser(input: &[u8], frame_type: u8) -> Result<(&[u8], StackMapFrame), Err<&[u8]>> {
value!(input, SameFrame { frame_type })
}
Expand Down
12 changes: 12 additions & 0 deletions src/attribute_info/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ pub struct CodeAttribute {
pub attributes: Vec<AttributeInfo>,
}

#[derive(Clone, Debug)]
pub struct MethodParametersAttribute {
pub parameters_count: u8,
pub parameters: Vec<ParameterAttribute>,
}

#[derive(Clone, Debug)]
pub struct ParameterAttribute {
pub name_index: u16,
pub access_flags: u16,
}

#[derive(Clone, Debug)]
pub enum VerificationTypeInfo {
Top,
Expand Down
38 changes: 37 additions & 1 deletion tests/code_attribute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extern crate classfile_parser;

use classfile_parser::attribute_info::code_attribute_parser;
use classfile_parser::attribute_info::{code_attribute_parser, method_parameters_attribute_parser};
use classfile_parser::class_parser;
use classfile_parser::code_attribute::{code_parser, instruction_parser, Instruction};
use classfile_parser::method_info::MethodAccessFlags;
Expand Down Expand Up @@ -79,3 +79,39 @@ fn test_class() {
assert!(parsed.is_ok());
assert_eq!(64, parsed.unwrap().1.len());
}

fn lookup_string(c: &classfile_parser::ClassFile, index: u16) -> Option<String> {
let con = &c.const_pool[(index - 1) as usize];
match con {
classfile_parser::constant_info::ConstantInfo::Utf8(utf8) => Some(utf8.utf8_string.clone()),
_ => None,
}
}

#[test]
fn method_parameters() {
let class_bytes = include_bytes!("../java-assets/compiled-classes/BasicClass.class");
let (_, class) = class_parser(class_bytes).unwrap();
let method_info = &class.methods.iter().last().unwrap();

// The class was not compiled with "javac -parameters" this required being able to find
// MethodParameters in the class file, for example:
// javac -parameters ./java-assets/src/uk/co/palmr/classfileparser/BasicClass.java -d ./java-assets/compiled-classes ; cp ./java-assets/compiled-classes/uk/co/palmr/classfileparser/BasicClass.class ./java-assets/compiled-classes/BasicClass.class
assert_eq!(method_info.attributes.len(), 2);
let (_, method_parameters) =
method_parameters_attribute_parser(&method_info.attributes[1].info).unwrap();
assert_eq!(
lookup_string(
&class,
method_parameters.parameters.get(0).unwrap().name_index
),
Some("a".to_string())
);
assert_eq!(
lookup_string(
&class,
method_parameters.parameters.get(1).unwrap().name_index
),
Some("b".to_string())
);
}

0 comments on commit 1b92dfa

Please sign in to comment.