private ValueExpression Evaluate(ITemplateContext context, object newValue) { ValueExpression targetValue = _target.Evaluate(context); object targetObject; Type targetType; if (targetValue.Value is ClassName) { targetType = ((ClassName)targetValue.Value).Type; targetObject = null; } else { targetType = targetValue.Type; targetObject = targetValue.Value; if (targetObject == null) { return(new ValueExpression(null, targetType)); } } //if (targetObject is IDynamicObject) //{ // object value; // Type type; // if (((IDynamicObject)targetObject).TryGetValue(_member, out value, out type)) // return new ValueExpression(value, type); //} MemberInfo[] members = targetType.GetMember(_member); if (members.Length == 0) { PropertyInfo indexerPropInfo = targetType.GetProperty("Item", new Type[] { typeof(string) }); if (indexerPropInfo != null) { return(new ValueExpression(indexerPropInfo.GetValue(targetObject, new object[] { _member }), indexerPropInfo.PropertyType)); } if (_missingFieldHandler != null) { foreach (MissingFieldHandler handler in _missingFieldHandler.GetInvocationList()) { object value; Type type; if (handler(targetObject, targetType, _member, out value, out type)) { return(new ValueExpression(value, type)); } } } throw new MissingFieldException(targetType.Name, _member); } if (members.Length >= 1 && members[0] is MethodInfo) { if (targetObject == null) { return(Expression.Value(new StaticMethod(targetType, _member))); } else { return(Expression.Value(new InstanceMethod(targetType, _member, targetObject))); } } MemberInfo member = members[0]; if (members.Length > 1 && targetObject != null) // CoolStorage, ActiveRecord and Dynamic Proxy frameworks sometimes return > 1 member { foreach (MemberInfo mi in members) { if (mi.DeclaringType == targetObject.GetType()) { member = mi; } } } if (newValue != null) { if (member is FieldInfo) { ((FieldInfo)member).SetValue(targetObject, newValue); } if (member is PropertyInfo) { ((PropertyInfo)member).SetValue(targetObject, newValue, null); } // Fall through to get the new property/field value below } if (member is FieldInfo) { return(new ValueExpression(((FieldInfo)member).GetValue(targetObject), ((FieldInfo)member).FieldType)); } if (member is PropertyInfo) { return(new ValueExpression(((PropertyInfo)member).GetValue(targetObject, null), ((PropertyInfo)member).PropertyType)); } throw new InvalidExpressionException(); }
public override ValueExpression Evaluate(ITemplateContext context) { ValueExpression[] values = new ValueExpression[] { Left.Evaluate(context), Right.Evaluate(context) }; Type type1 = values[0].Type; Type type2 = values[1].Type; bool nullable1 = type1.IsGenericType && type1.GetGenericTypeDefinition() == typeof(Nullable <>); bool nullable2 = type2.IsGenericType && type2.GetGenericTypeDefinition() == typeof(Nullable <>); type1 = Nullable.GetUnderlyingType(type1) ?? type1; type2 = Nullable.GetUnderlyingType(type2) ?? type2; bool isNullable = (nullable1 || nullable2); OperatorMethod operatorMethod = FindOperatorMethod(type1, type2); if (operatorMethod == null) { Type promotionType = null; if (type1 == typeof(decimal) || type2 == typeof(decimal)) { promotionType = typeof(decimal); } else if (type1 == typeof(double) || type2 == typeof(double)) { promotionType = typeof(double); } else if (type1 == typeof(float) || type2 == typeof(float)) { promotionType = typeof(float); } else if (type1 == typeof(ulong) || type2 == typeof(ulong)) { promotionType = typeof(ulong); } else if (type1 == typeof(long) || type2 == typeof(long)) { promotionType = typeof(long); } else if (type1 == typeof(uint) || type2 == typeof(uint) && (type1 == typeof(sbyte) || type2 == typeof(sbyte) || type1 == typeof(short) || type2 == typeof(short) || type1 == typeof(int) || type2 == typeof(int))) { promotionType = typeof(long); } else if (type1 == typeof(uint) || type2 == typeof(uint)) { promotionType = typeof(uint); } else if (type1.IsPrimitive && type2.IsPrimitive && type1 != typeof(bool) && type2 != typeof(bool)) { promotionType = typeof(int); } if (promotionType != null) { type1 = promotionType; type2 = promotionType; } operatorMethod = FindOperatorMethod(type1, type2); } if (operatorMethod == null) { if (_operator == "==" || _operator == "!=") { return(new ValueExpression(BEH.CalcObject(_operator, values[0].Value, values[1].Value), typeof(bool))); } throw new ArithmeticException(); } Type returnType = operatorMethod.ReturnType; if (isNullable) { returnType = typeof(Nullable <>).MakeGenericType(returnType); //TODO: check specs for bool? values if (values[0].Value == null || values[1].Value == null) { return(new ValueExpression(null, returnType)); } } object value1 = Convert.ChangeType(values[0].Value, operatorMethod.Type1); object value2 = Convert.ChangeType(values[1].Value, operatorMethod.Type2); return(new ValueExpression(operatorMethod.Function(_operator, value1, value2), returnType)); }