use dotnetdll::prelude::*;
#[macro_use]
mod common;
#[test]
pub fn read() {
common::read_fixture(
"fields_props",
r#"
.class public Program extends [mscorlib]System.Object {
.field private static int32 static_field
.field private uint32 instance_field
.property int32 StaticProperty() {
.get int32 Program::get_StaticProperty()
.set void Program::set_StaticProperty(int32)
}
.method public static int32 get_StaticProperty() { }
.method public static void set_StaticProperty(int32) { }
.property instance uint32 InstanceProperty() {
.get instance uint32 Program::get_InstanceProperty()
.set instance void Program::set_InstanceProperty(uint32)
}
.method public instance uint32 get_InstanceProperty() { }
.method public void set_InstanceProperty(uint32) { }
}
"#,
|res| {
let program = &res.type_definitions[1];
assert_inner_eq!(program.fields[0], {
name: "static_field",
return_type: ctype! { int },
static_member => true
});
assert_inner_eq!(program.fields[1], {
name: "instance_field",
return_type: ctype! { uint },
static_member => false
});
assert_inner_eq!(program.properties[0], {
name: "StaticProperty",
property_type: Parameter::value(ctype! { int }),
static_member => true,
getter => Some(Method { ref name, .. }) if name == "get_StaticProperty",
setter => Some(Method { ref name, .. }) if name == "set_StaticProperty"
});
assert_inner_eq!(program.properties[1], {
name: "InstanceProperty",
property_type: Parameter::value(ctype! { uint }),
static_member => false,
getter => Some(Method { ref name, .. }) if name == "get_InstanceProperty",
setter => Some(Method { ref name, .. }) if name == "set_InstanceProperty"
});
},
)
.unwrap();
}
#[test]
pub fn write() {
common::write_fixture(
"fields_props",
|ctx| {
let console_type = BaseType::class(ctx.console).into();
let write_line = ctx
.resolution
.push_method_reference(method_ref! { static void #console_type::WriteLine(string, object, object) });
let static_field = ctx.resolution.push_field(
ctx.class,
Field::static_member(Accessibility::Private, "static_field", ctype! { int }),
);
let instance_field = ctx.resolution.push_field(
ctx.class,
Field::instance(Accessibility::Private, "instance_field", ctype! { uint }),
);
let static_type = ctx.resolution[static_field].return_type.clone();
let static_prop = ctx.resolution.push_property(
ctx.class,
Property::new(false, "StaticProperty", Parameter::value(static_type.clone())),
);
let static_type: MethodType = static_type.into();
let static_getter = ctx.resolution.set_property_getter(
static_prop,
Method::new(
Accessibility::Public,
msig! { static @static_type () },
"get_StaticProperty",
Some(body::Method::new(asm! {
load_static_field static_field;
Return;
})),
),
);
let static_setter = ctx.resolution.set_property_setter(
static_prop,
Method::new(
Accessibility::Public,
msig! { static void (@static_type) },
"set_StaticProperty",
Some(body::Method::new(asm! {
LoadArgument 0;
store_static_field static_field;
Return;
})),
),
);
let instance_type = ctx.resolution[instance_field].return_type.clone();
let instance_prop = ctx.resolution.push_property(
ctx.class,
Property::new(false, "InstanceProperty", Parameter::value(instance_type.clone())),
);
let instance_type: MethodType = instance_type.into();
let instance_getter = ctx.resolution.set_property_getter(
instance_prop,
Method::new(
Accessibility::Public,
msig! { @instance_type () },
"get_InstanceProperty",
Some(body::Method::new(asm! {
LoadArgument 0;
load_field instance_field;
Return;
})),
),
);
let instance_setter = ctx.resolution.set_property_setter(
instance_prop,
Method::new(
Accessibility::Public,
msig! { void (@instance_type) },
"set_InstanceProperty",
Some(body::Method::new(asm! {
LoadArgument 0;
LoadArgument 1;
store_field instance_field;
Return;
})),
),
);
common::MainMethod::WithVariables {
locals: vec![LocalVariable::new(BaseType::class(ctx.class).into())],
body: asm! {
LoadConstantInt32 -1;
call static_setter;
new_object ctx.default_ctor;
Duplicate;
StoreLocal 0;
LoadConstantInt32 1;
call instance_setter;
call static_getter;
LoadConstantInt32 1;
Add;
call static_setter;
LoadLocal 0;
Duplicate;
call instance_getter;
LoadConstantInt32 1;
Add;
call instance_setter;
load_string "{0}, {1}";
call static_getter;
box_value static_type;
LoadLocal 0;
call instance_getter;
box_value instance_type;
call write_line;
Return;
},
}
},
b"0, 2\n",
)
.unwrap();
}