private static IEnumerable<object> IterateBindings(ExpressionIterationNode parent, IEnumerable<MemberBinding> bindings) { foreach (var binding in bindings) { var bindingNode = new ExpressionIterationNode(parent, binding); yield return bindingNode; switch (binding.BindingType) { case MemberBindingType.Assignment: yield return ((MemberAssignment)binding).Expression.IterateInternal(bindingNode); break; case MemberBindingType.ListBinding: foreach (var initializer in ((MemberListBinding)binding).Initializers) { var initializerNode = new ExpressionIterationNode(bindingNode, initializer); yield return initializerNode; foreach (var argument in initializer.Arguments) { yield return argument.IterateInternal(initializerNode); } } break; case MemberBindingType.MemberBinding: yield return IterateBindings(bindingNode, ((MemberMemberBinding)binding).Bindings); break; default: throw new NotSupportedException("Unsupported MemberBindingType: " + binding.BindingType); } } }
private static IEnumerable <object> IterateBindings(ExpressionIterationNode parent, IEnumerable <MemberBinding> bindings) { foreach (var binding in bindings) { var bindingNode = new ExpressionIterationNode(parent, binding); yield return(bindingNode); switch (binding.BindingType) { case MemberBindingType.Assignment: yield return(((MemberAssignment)binding).Expression.IterateInternal(bindingNode)); break; case MemberBindingType.ListBinding: foreach (var initializer in ((MemberListBinding)binding).Initializers) { var initializerNode = new ExpressionIterationNode(bindingNode, initializer); yield return(initializerNode); foreach (var argument in initializer.Arguments) { yield return(argument.IterateInternal(initializerNode)); } } break; case MemberBindingType.MemberBinding: yield return(IterateBindings(bindingNode, ((MemberMemberBinding)binding).Bindings)); break; default: throw new NotSupportedException("Unsupported MemberBindingType: " + binding.BindingType); } } }
public ExpressionIterationNode(ExpressionIterationNode parentNode, object element) { ParentNode = parentNode; Element = element; }
private static IEnumerable <object> IterateInternal(this Expression expression, ExpressionIterationNode parent) { var current = new ExpressionIterationNode(parent, expression); yield return(current); if (expression == null) { yield break; } IEnumerable <ExpressionIterationNode> children; switch (expression.NodeType) { case ExpressionType.Add: case ExpressionType.AddAssign: case ExpressionType.AddAssignChecked: case ExpressionType.AddChecked: case ExpressionType.And: case ExpressionType.AndAlso: case ExpressionType.AndAssign: case ExpressionType.ArrayIndex: case ExpressionType.Assign: case ExpressionType.Coalesce: case ExpressionType.Divide: case ExpressionType.DivideAssign: case ExpressionType.Equal: case ExpressionType.ExclusiveOr: case ExpressionType.ExclusiveOrAssign: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LeftShift: case ExpressionType.LeftShiftAssign: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.Modulo: case ExpressionType.ModuloAssign: case ExpressionType.Multiply: case ExpressionType.MultiplyAssign: case ExpressionType.MultiplyAssignChecked: case ExpressionType.MultiplyChecked: case ExpressionType.NotEqual: case ExpressionType.Or: case ExpressionType.OrAssign: case ExpressionType.OrElse: case ExpressionType.Power: case ExpressionType.PowerAssign: case ExpressionType.RightShift: case ExpressionType.RightShiftAssign: case ExpressionType.Subtract: case ExpressionType.SubtractAssign: case ExpressionType.SubtractAssignChecked: case ExpressionType.SubtractChecked: { var binary = (BinaryExpression)expression; yield return(binary.Left.IterateInternal(current)); yield return(binary.Right.IterateInternal(current)); } break; case ExpressionType.ArrayLength: case ExpressionType.Convert: case ExpressionType.ConvertChecked: case ExpressionType.Decrement: case ExpressionType.Increment: case ExpressionType.IsFalse: case ExpressionType.IsTrue: case ExpressionType.Negate: case ExpressionType.NegateChecked: case ExpressionType.Not: case ExpressionType.OnesComplement: case ExpressionType.PostDecrementAssign: case ExpressionType.PostIncrementAssign: case ExpressionType.PreDecrementAssign: case ExpressionType.PreIncrementAssign: case ExpressionType.Quote: case ExpressionType.Throw: case ExpressionType.TypeAs: case ExpressionType.UnaryPlus: case ExpressionType.Unbox: { var unary = (UnaryExpression)expression; yield return(unary.Operand.IterateInternal(current)); } break; case ExpressionType.Call: { var call = (MethodCallExpression)expression; yield return(call.Object.IterateInternal(current)); foreach (var argument in call.Arguments) { yield return(argument.IterateInternal(current)); } } break; case ExpressionType.Conditional: { var conditional = (ConditionalExpression)expression; yield return(conditional.Test.IterateInternal(current)); yield return(conditional.IfTrue.IterateInternal(current)); yield return(conditional.IfFalse.IterateInternal(current)); } break; case ExpressionType.Invoke: { var invocation = (InvocationExpression)expression; yield return(invocation.Expression.IterateInternal(current)); foreach (var argument in invocation.Arguments) { yield return(argument.IterateInternal(current)); } } break; case ExpressionType.Lambda: { var lambda = (LambdaExpression)expression; foreach (var parameter in lambda.Parameters) { yield return(parameter.IterateInternal(current)); } yield return(lambda.Body.IterateInternal(current)); } break; case ExpressionType.ListInit: { var listInit = (ListInitExpression)expression; yield return(listInit.NewExpression.IterateInternal(current)); foreach (var initializer in listInit.Initializers) { var initializerNode = new ExpressionIterationNode(current, initializer); yield return(initializerNode); foreach (var argument in initializer.Arguments) { yield return(argument.IterateInternal(initializerNode)); } } } break; case ExpressionType.MemberAccess: { var memberAccess = (MemberExpression)expression; yield return(memberAccess.Expression.IterateInternal(current)); } break; case ExpressionType.MemberInit: { var memberInit = (MemberInitExpression)expression; yield return(memberInit.NewExpression.IterateInternal(current)); yield return(IterateBindings(current, memberInit.Bindings)); } break; case ExpressionType.New: { var newExpr = (NewExpression)expression; foreach (var argument in newExpr.Arguments) { yield return(argument.IterateInternal(current)); } } break; case ExpressionType.NewArrayInit: case ExpressionType.NewArrayBounds: { var newArray = (NewArrayExpression)expression; foreach (var expr in newArray.Expressions) { yield return(expr.IterateInternal(current)); } } break; case ExpressionType.TypeEqual: case ExpressionType.TypeIs: { var typeBinary = (TypeBinaryExpression)expression; yield return(typeBinary.Expression.IterateInternal(current)); } break; case ExpressionType.Block: { var block = (BlockExpression)expression; // TODO: Variables foreach (var expr in block.Expressions) { yield return(expr.IterateInternal(current)); } } break; case ExpressionType.Dynamic: { var dyn = (DynamicExpression)expression; foreach (var argument in dyn.Arguments) { yield return(argument.IterateInternal(current)); } } break; case ExpressionType.Index: { var index = (IndexExpression)expression; yield return(index.Object.IterateInternal(current)); foreach (var argument in index.Arguments) { yield return(argument.IterateInternal(current)); } } break; case ExpressionType.Default: case ExpressionType.DebugInfo: case ExpressionType.Parameter: case ExpressionType.Constant: case ExpressionType.RuntimeVariables: // Do nothing yield break; case ExpressionType.Loop: case ExpressionType.Switch: case ExpressionType.Try: case ExpressionType.Label: case ExpressionType.Goto: case ExpressionType.Extension: throw new NotSupportedException("Unsupported expression type: " + expression.NodeType); default: throw new ArgumentOutOfRangeException("expression", expression.NodeType, "Invalid expression type"); } yield break; }
private static IEnumerable<object> IterateInternal(this Expression expression, ExpressionIterationNode parent) { var current = new ExpressionIterationNode(parent, expression); yield return current; if (expression == null) { yield break; } IEnumerable<ExpressionIterationNode> children; switch (expression.NodeType) { case ExpressionType.Add: case ExpressionType.AddAssign: case ExpressionType.AddAssignChecked: case ExpressionType.AddChecked: case ExpressionType.And: case ExpressionType.AndAlso: case ExpressionType.AndAssign: case ExpressionType.ArrayIndex: case ExpressionType.Assign: case ExpressionType.Coalesce: case ExpressionType.Divide: case ExpressionType.DivideAssign: case ExpressionType.Equal: case ExpressionType.ExclusiveOr: case ExpressionType.ExclusiveOrAssign: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LeftShift: case ExpressionType.LeftShiftAssign: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.Modulo: case ExpressionType.ModuloAssign: case ExpressionType.Multiply: case ExpressionType.MultiplyAssign: case ExpressionType.MultiplyAssignChecked: case ExpressionType.MultiplyChecked: case ExpressionType.NotEqual: case ExpressionType.Or: case ExpressionType.OrAssign: case ExpressionType.OrElse: case ExpressionType.Power: case ExpressionType.PowerAssign: case ExpressionType.RightShift: case ExpressionType.RightShiftAssign: case ExpressionType.Subtract: case ExpressionType.SubtractAssign: case ExpressionType.SubtractAssignChecked: case ExpressionType.SubtractChecked: { var binary = (BinaryExpression)expression; yield return binary.Left.IterateInternal(current); yield return binary.Right.IterateInternal(current); } break; case ExpressionType.ArrayLength: case ExpressionType.Convert: case ExpressionType.ConvertChecked: case ExpressionType.Decrement: case ExpressionType.Increment: case ExpressionType.IsFalse: case ExpressionType.IsTrue: case ExpressionType.Negate: case ExpressionType.NegateChecked: case ExpressionType.Not: case ExpressionType.OnesComplement: case ExpressionType.PostDecrementAssign: case ExpressionType.PostIncrementAssign: case ExpressionType.PreDecrementAssign: case ExpressionType.PreIncrementAssign: case ExpressionType.Quote: case ExpressionType.Throw: case ExpressionType.TypeAs: case ExpressionType.UnaryPlus: case ExpressionType.Unbox: { var unary = (UnaryExpression)expression; yield return unary.Operand.IterateInternal(current); } break; case ExpressionType.Call: { var call = (MethodCallExpression)expression; yield return call.Object.IterateInternal(current); foreach (var argument in call.Arguments) { yield return argument.IterateInternal(current); } } break; case ExpressionType.Conditional: { var conditional = (ConditionalExpression)expression; yield return conditional.Test.IterateInternal(current); yield return conditional.IfTrue.IterateInternal(current); yield return conditional.IfFalse.IterateInternal(current); } break; case ExpressionType.Invoke: { var invocation = (InvocationExpression)expression; yield return invocation.Expression.IterateInternal(current); foreach (var argument in invocation.Arguments) { yield return argument.IterateInternal(current); } } break; case ExpressionType.Lambda: { var lambda = (LambdaExpression)expression; foreach (var parameter in lambda.Parameters) { yield return parameter.IterateInternal(current); } yield return lambda.Body.IterateInternal(current); } break; case ExpressionType.ListInit: { var listInit = (ListInitExpression)expression; yield return listInit.NewExpression.IterateInternal(current); foreach (var initializer in listInit.Initializers) { var initializerNode = new ExpressionIterationNode(current, initializer); yield return initializerNode; foreach (var argument in initializer.Arguments) { yield return argument.IterateInternal(initializerNode); } } } break; case ExpressionType.MemberAccess: { var memberAccess = (MemberExpression)expression; yield return memberAccess.Expression.IterateInternal(current); } break; case ExpressionType.MemberInit: { var memberInit = (MemberInitExpression)expression; yield return memberInit.NewExpression.IterateInternal(current); yield return IterateBindings(current, memberInit.Bindings); } break; case ExpressionType.New: { var newExpr = (NewExpression)expression; foreach (var argument in newExpr.Arguments) { yield return argument.IterateInternal(current); } } break; case ExpressionType.NewArrayInit: case ExpressionType.NewArrayBounds: { var newArray = (NewArrayExpression)expression; foreach (var expr in newArray.Expressions) { yield return expr.IterateInternal(current); } } break; case ExpressionType.TypeEqual: case ExpressionType.TypeIs: { var typeBinary = (TypeBinaryExpression)expression; yield return typeBinary.Expression.IterateInternal(current); } break; case ExpressionType.Block: { var block = (BlockExpression)expression; // TODO: Variables foreach (var expr in block.Expressions) { yield return expr.IterateInternal(current); } } break; case ExpressionType.Dynamic: { var dyn = (DynamicExpression)expression; foreach (var argument in dyn.Arguments) { yield return argument.IterateInternal(current); } } break; case ExpressionType.Index: { var index = (IndexExpression)expression; yield return index.Object.IterateInternal(current); foreach (var argument in index.Arguments) { yield return argument.IterateInternal(current); } } break; case ExpressionType.Default: case ExpressionType.DebugInfo: case ExpressionType.Parameter: case ExpressionType.Constant: case ExpressionType.RuntimeVariables: // Do nothing yield break; case ExpressionType.Loop: case ExpressionType.Switch: case ExpressionType.Try: case ExpressionType.Label: case ExpressionType.Goto: case ExpressionType.Extension: throw new NotSupportedException("Unsupported expression type: " + expression.NodeType); default: throw new ArgumentOutOfRangeException("expression", expression.NodeType, "Invalid expression type"); } yield break; }