Beispiel #1
0
        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));
        }