Example #1
0
        private ValueExpression Evaluate(IParserContext 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(TokenPosition, null, targetType));
                }
            }

            if (targetObject is IDynamicObject)
            {
                object value;
                Type   type;

                if (((IDynamicObject)targetObject).TryGetValue(_member, out value, out type))
                {
                    return(new ValueExpression(TokenPosition, value, type));
                }
            }

            MemberInfo[] members = targetType.GetMember(_member);

            if (members.Length == 0)
            {
                PropertyInfo indexerPropInfo = targetType.GetProperty("Item", new[] { typeof(string) });

                if (indexerPropInfo != null)
                {
                    return(new ValueExpression(TokenPosition, indexerPropInfo.GetValue(targetObject, new object[] { _member }), indexerPropInfo.PropertyType));
                }

                throw new UnknownPropertyException("Unknown property " + _member + " for object " + _target + " (type " + targetType.Name + ")", this);
            }

            if (members.Length >= 1 && members[0] is MethodInfo)
            {
                if (targetObject == null)
                {
                    return(Exp.Value(TokenPosition, new StaticMethod(targetType, _member)));
                }
                else
                {
                    return(Exp.Value(TokenPosition, 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(TokenPosition, ((FieldInfo)member).GetValue(targetObject), ((FieldInfo)member).FieldType));
            }

            if (member is PropertyInfo)
            {
                return(new ValueExpression(TokenPosition, ((PropertyInfo)member).GetValue(targetObject, null), ((PropertyInfo)member).PropertyType));
            }

            throw new ExpressionEvaluationException(_member + " is not a field or property", this);
        }