private object EvaluateValue(Expression expression) { var value = _item.Data; while(expression != null && value != null) { if(expression.Dollar) value = _item; var memberInfo = FindMember(expression.Member, value); if(memberInfo.Length == 0 && _item.Options != null) memberInfo = FindMember(expression.Member, value = _item.Options); if(memberInfo.Length > 0) value = InvokeBestMatch(memberInfo, expression, value); else if(_item.ValueParameter != null && _item.ValueParameter.Matches(expression.Member)) value = _item.Value; else if(_item.IndexParameter != null && _item.IndexParameter.Matches(expression.Member)) value = _item.Index; else value = EvaluateLiteral(expression); if(expression.Operator.Length > 0) return new BinaryEvaluator().Evaluate(value, EvaluateValue(expression.Next), expression.Operator); expression = expression.Next; } return value; }
private object EvaluateLiteral(Expression expression) { if(expression.Arguments.Length == 0 && expression.Indices.Length == 0 && expression.Dollar == false) { int number; if(Int32.TryParse(expression.Member, out number)) return number; bool boolean; if(Boolean.TryParse(expression.Member, out boolean)) return boolean; if((expression.Member.StartsWith("\"") && expression.Member.EndsWith("\"")) || (expression.Member.StartsWith("'") && expression.Member.EndsWith("'"))) return expression.Member.Trim('"', '\''); } return null; }
private object InvokeBestMatch(MemberInfo[] candidates, Expression expression, object target) { if(expression.Member == null) return null; foreach(var memberInfo in candidates) { var propertyInfo = memberInfo as PropertyInfo; if(propertyInfo != null) { var value = propertyInfo.GetValue(target, null); if(expression.Arguments.Length > 0 && value is Delegate) { var func = (Delegate)value; var paramValues = expression.Arguments.Select(EvaluateValue).ToArray(); return func.DynamicInvoke(paramValues); } if(expression.Indices.Length > 0) { if(value is Array) { var subIndices = expression.Indices.Select(EvaluateValue).Cast<int>().ToArray(); value = ((Array)value).GetValue(subIndices); } else if(value != null) { var indexer = value.GetType().GetProperty("Item") ?? value.GetType().GetProperty("Chars"); if(indexer != null) { var subIndices = expression.Indices.Select(EvaluateValue).ToArray(); value = indexer.GetValue(value, subIndices); } } } return value; } var fieldInfo = memberInfo as FieldInfo; if(fieldInfo != null) { if(expression.Arguments.Length > 0) continue; if(expression.Indices.Length > 0) continue; return fieldInfo.GetValue(target); } var methodInfo = memberInfo as MethodInfo; if(methodInfo != null) { var methodParameters = methodInfo.GetParameters(); if(methodParameters.Length == expression.Arguments.Length) { var paramValues = expression.Arguments.Select(EvaluateValue).ToArray(); var value = methodInfo.Invoke(target, paramValues); if(expression.Indices.Length > 0) { if(value is Array) { var indices = expression.Indices.Select(EvaluateValue).Cast<int>().ToArray(); value = ((Array)value).GetValue(indices); } else if(value != null) { var indexer = value.GetType().GetProperty("Item"); if(indexer != null) { var indices = expression.Indices.Select(EvaluateValue).ToArray(); value = indexer.GetValue(value, indices); } } } return value; } } } return null; }
public EvaluatedExpression Evaluate(Expression expression) { var value = EvaluateValue(expression); return new EvaluatedExpression(_item, value); }