extern crate nom;
extern crate classfile_parser;
use classfile_parser::class_parser;
use classfile_parser::constant_info::ConstantInfo;
use classfile_parser::attribute_info::bootstrap_methods_attribute_parser;
#[test]
fn test_attribute_bootstrap_methods() {
match class_parser(include_bytes!("../java-assets/compiled-classes/BootstrapMethods.class")) {
Result::Ok((_, c)) => {
println!("Valid class file, version {},{} const_pool({}), this=const[{}], super=const[{}], interfaces({}), fields({}), methods({}), attributes({}), access({:?})", c.major_version, c.minor_version, c.const_pool_size, c.this_class, c.super_class, c.interfaces_count, c.fields_count, c.methods_count, c.attributes_count, c.access_flags);
let mut bootstrap_method_const_index = 0;
println!("Constant pool:");
for (const_index, const_item) in c.const_pool.iter().enumerate() {
println!("\t[{}] = {:?}", (const_index + 1), const_item);
match *const_item {
ConstantInfo::Utf8(ref c) => {
if c.utf8_string == "BootstrapMethods" {
if bootstrap_method_const_index != 0 {
assert!(false, "Should not find more than one BootstrapMethods constant");
}
bootstrap_method_const_index = (const_index + 1) as u16;
}
}
_ => {}
}
}
assert_ne!(bootstrap_method_const_index, 0);
println!("Bootstrap Methods constant index = {}", bootstrap_method_const_index);
for (_, attribute_item) in c.attributes.iter().enumerate() {
if attribute_item.attribute_name_index == bootstrap_method_const_index {
match bootstrap_methods_attribute_parser(&attribute_item.info) {
Result::Ok((_, bsma)) => {
assert_eq!(bsma.num_bootstrap_methods, 1);
let bsm = &bsma.bootstrap_methods[0];
assert_eq!(bsm.bootstrap_method_ref, 36);
println!("{:?}", bsm);
println!("\tmethod ref: {:?}", c.const_pool[36]);
println!("\t\tdescriptor: {:?}", c.const_pool[53]);
println!("\t\t\tclass_index: {:?}", c.const_pool[9]);
println!("\t\t\t\tname_index: {:?}", c.const_pool[51]);
println!("\t\t\t\t\tclass_index: {:?}", c.const_pool[64]);
println!("\t\t\t\t\tname_and_type_index: {:?}", c.const_pool[65]);
println!("\t\t\t\t\t\tname_index: {:?}", c.const_pool[30]);
println!("\t\t\t\t\t\tdescriptor_index: {:?}", c.const_pool[31]);
println!("\t\t\tname_and_type_index: {:?}", c.const_pool[66]);
return;
}
_ => panic!("Failed to parse bootstrap method attribute"),
}
}
}
assert!(false, "Should not get to here");
}
_ => panic!("Not a valid class file"),
}
}
#[test]
fn should_have_no_bootstrap_method_attr_if_no_invoke_dynamic() {
match class_parser(include_bytes!("../java-assets/compiled-classes/BasicClass.class")) {
Result::Ok((_, c)) => {
for (_, const_item) in c.const_pool.iter().enumerate() {
match *const_item {
ConstantInfo::Utf8(ref c) => {
if c.utf8_string == "BootstrapMethods" {
assert!(false, "Should not have found a BootstrapMethods constant in a class not requiring it")
}
}
_ => {}
}
}
}
_ => panic!("Not a valid class file"),
}
}