public object GetValue(IMemberExpression expression, object origin, Action <MemberContext> evaluate = null) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var result = origin; MemberContext context = new MemberContext(0, origin, origin, expression); while (context != null) { context.Member = this.GetMember(context); evaluate?.Invoke(context); if (!context.HasValue) { context.Value = this.GetMemberValue(context); } result = context.Value; context = context.Next(); } return(result); }
public static void VisitMemberExpressionChildren<TExpression>( IMemberExpression<TExpression> memberExpression, IGenericExpressionVisitor visitor) where TExpression : IExpression { GenericExpressionChildVisitor.VisitMemberExpressionChildren<IMemberExpression<TExpression>, TExpression, IGenericExpressionVisitor>(memberExpression, visitor); }
public void SetValue(IMemberExpression expression, object origin, Func <MemberContext, object> valueFactory, Action <MemberContext> evaluate = null) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (valueFactory == null) { throw new ArgumentNullException(nameof(valueFactory)); } var context = new MemberContext(0, origin, origin, expression); while (context.HasNext) { context.Member = this.GetMember(context); evaluate?.Invoke(context); if (!context.HasValue) { context.Value = this.GetMemberValue(context); } context = context.Next(); } context.Member = this.GetMember(context); evaluate?.Invoke(context); context.Value = valueFactory(context); this.SetMemberValue(context); }
public override void VisitMemberExpression <TExpression>(IMemberExpression <TExpression> memberExpression) { Value = new Expression() { MemberExpression = new MemberExpressionFactory(memberExpression).Value }; }
public void AppendParameterConstant(IMemberExpression owner) { if (owner == null) { throw new InvalidOperationException(EXCEPTION_UNKNOWN_MESSAGE); } void Add(ICollection <IMemberExpression> parameters, string content, TypeCode type) { parameters.Add(MemberExpression.Constant(content, type)); }; if (owner is IndexerExpression indexer) { Add(indexer.Arguments, GetBufferContent(), Flags.GetConstantType()); } else if (owner is MethodExpression method) { Add(method.Arguments, GetBufferContent(), Flags.GetConstantType()); } else { throw new InvalidOperationException(EXCEPTION_UNKNOWN_MESSAGE); } }
public MemberContext(int index, object origin, object target, IMemberExpression expression) { this.Depth = 0; this.Index = index; this.Origin = origin; this.Owner = target; this.Expression = expression; this.Member = null; this.Parameters = null; }
public T Prepend <T>(T expression) where T : MemberExpression { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } _previous = expression; expression._next = this; return(expression); }
public HierarchicalExpression(PathAnchor anchor, string[] segments, IMemberExpression accessor) { this.Anchor = anchor; this.Accessor = accessor; this.Segments = segments ?? Array.Empty <string>(); switch (anchor) { case PathAnchor.Root: if (segments == null || segments.Length == 0) { this.Path = HierarchicalNode.PathSeparatorChar.ToString(); } else { this.Path = HierarchicalNode.PathSeparatorChar + string.Join(HierarchicalNode.PathSeparatorChar, segments); } break; case PathAnchor.Current: if (segments == null || segments.Length == 0) { this.Path = "."; } else { this.Path = "." + HierarchicalNode.PathSeparatorChar + string.Join(HierarchicalNode.PathSeparatorChar, segments); } break; case PathAnchor.Parent: if (segments == null || segments.Length == 0) { this.Path = ".."; } else { this.Path = ".." + HierarchicalNode.PathSeparatorChar + string.Join(HierarchicalNode.PathSeparatorChar, segments); } break; default: if (segments == null || segments.Length == 0) { this.Path = string.Empty; } else { this.Path = string.Join(HierarchicalNode.PathSeparatorChar, Segments); } break; } }
public IdentifierExpression AppendIdentifier(IMemberExpression owner) { var current = MemberExpression.Identifier(GetBufferContent()); if (owner == null) { if (Head == null) { Head = current; } else { Head = Head.Append(current); } return(current); } if (owner is IndexerExpression indexer) { if (Flags.IsAttaching()) { if (indexer.Arguments.Count == 0 || indexer.Arguments[indexer.Arguments.Count - 1].ExpressionType != MemberExpressionType.Identifier) { throw new InvalidOperationException(EXCEPTION_UNKNOWN_MESSAGE); } return(((MemberExpression)((IdentifierExpression)indexer.Arguments[indexer.Arguments.Count - 1]).Last()).Append(current)); } indexer.Arguments.Add(current); return(current); } else if (owner is MethodExpression method) { if (Flags.IsAttaching()) { if (method.Arguments.Count == 0 || method.Arguments[method.Arguments.Count - 1].ExpressionType != MemberExpressionType.Identifier) { throw new InvalidOperationException(EXCEPTION_UNKNOWN_MESSAGE); } return(((MemberExpression)((IdentifierExpression)method.Arguments[method.Arguments.Count - 1]).Last()).Append(current)); } method.Arguments.Add(current); return(current); } throw new InvalidOperationException(EXCEPTION_UNKNOWN_MESSAGE); }
/// <summary> /// 查找指定表达式节点位于表达式中的最末节点元素。 /// </summary> /// <param name="expression">指定的要查找的表达式节点。</param> /// <returns>返回的最末表达式元素。</returns> public static IMemberExpression Last(this IMemberExpression expression) { if (expression == null) { return(null); } while (expression.Next != null) { expression = expression.Next; } return(expression); }
/// <summary> /// 查找指定表达式节点位于表达式中的首个节点元素。 /// </summary> /// <param name="expression">指定的要查找的表达式节点。</param> /// <returns>返回的首个表达式元素。</returns> public static IMemberExpression First(this IMemberExpression expression) { if (expression == null) { return(null); } while (expression.Previous != null) { expression = expression.Previous; } return(expression); }
public static bool TryParse(string text, int start, int count, out IMemberExpression expression) { return((expression = Parse(text, start, count, null)) != null); }
public virtual void VisitMemberExpression <TExpression>(IMemberExpression <TExpression> memberExpression) where TExpression : IExpression { Visit(memberExpression); }
public void SetValue(IMemberExpression expression, object origin, object value, Action <MemberContext> evaluate = null) { this.SetValue(expression, origin, _ => value, evaluate); }
public override void VisitMemberExpression <TExpression>(IMemberExpression <TExpression> memberExpression) { Steps.Add(new WriteExpression <TExpression>(memberExpression.ObjectExpression)); Steps.Add(new WriteDot()); Steps.Add(new WriteName(memberExpression.MemberName)); }
public static bool TryParse(string text, out IMemberExpression expression) { return((expression = Parse(text, 0, 0, null)) != null); }
internal static Type GetMemberType(IMemberExpression expression, Type originType) { if (originType == null) { throw new ArgumentNullException(nameof(originType)); } if (expression == null) { return(originType); } var element = expression; var elementType = originType; while (element != null) { switch (element.ExpressionType) { case MemberExpressionType.Constant: elementType = ((ConstantExpression)element).Value?.GetType(); break; case MemberExpressionType.Identifier: var identifier = (IdentifierExpression)element; elementType = elementType.GetProperty(identifier.Name)?.PropertyType ?? elementType.GetField(identifier.Name)?.FieldType; break; case MemberExpressionType.Indexer: var memberName = elementType.GetCustomAttribute <DefaultMemberAttribute>()?.MemberName; if (string.IsNullOrEmpty(memberName)) { throw new InvalidOperationException(""); } elementType = elementType.GetProperty(memberName)?.PropertyType; break; case MemberExpressionType.Method: var method = (MethodExpression)element; if (method.HasArguments) { var parameterTypes = new Type[method.Arguments.Count]; for (var i = 0; i < method.Arguments.Count; i++) { parameterTypes[i] = GetMemberType(method.Arguments[i], originType); } elementType = elementType.GetMethod(method.Name, parameterTypes)?.ReturnType; } else { elementType = elementType.GetMethod(method.Name)?.ReturnType; } break; } element = element.Next; } return(elementType); }