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); }