void SetProperty(IProperty property, Expression reference, Expression value, bool leaveValueOnStack)
{
OpCode callOpCode = OpCodes.Call;
MethodInfo setMethod = GetMethodInfo(property.GetSetMethod());
IType targetType = null;
if (null != reference)
{
if (!setMethod.IsStatic)
{
Expression target = ((MemberReferenceExpression)reference).Target;
targetType = target.ExpressionType;
if (setMethod.DeclaringType.IsValueType || targetType is IGenericParameter)
LoadAddress(target);
else
{
callOpCode = GetCallOpCode(target, property.GetSetMethod());
target.Accept(this);
PopType();
}
}
}
LoadExpressionWithType(property.Type, value);
LocalBuilder local = null;
if (leaveValueOnStack)
{
Dup();
local = _il.DeclareLocal(GetSystemType(property.Type));
_il.Emit(OpCodes.Stloc, local);
}
if (targetType is IGenericParameter)
{
_il.Emit(OpCodes.Constrained, GetSystemType(targetType));
callOpCode = OpCodes.Callvirt;
}
_il.EmitCall(callOpCode, setMethod, null);
if (leaveValueOnStack)
{
_il.Emit(OpCodes.Ldloc, local);
PushType(property.Type);
}
}