annotate Source/Linq/ExpressionHelper.cs @ 3:1ef98bd70424

!bug 100 +3h Исправление проблемы BLToolkit + mono 3.4
author cin
date Fri, 22 Aug 2014 17:34:46 +0400
parents f990fcb411a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Collections.Generic;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4 using System.Linq.Expressions;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5 using System.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 using BLToolkit.Data.Linq.Builder;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 // ReSharper disable ConditionIsAlwaysTrueOrFalse
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10 // ReSharper disable HeuristicUnreachableCode
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12 namespace BLToolkit.Linq
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 using Data.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 using Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17 public static class ExpressionHelper
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19 #region IsConstant
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21 public static bool IsConstant(Type type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 if (type.IsEnum)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26 switch (Type.GetTypeCode(type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 case TypeCode.Int16 :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29 case TypeCode.Int32 :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 case TypeCode.Int64 :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31 case TypeCode.UInt16 :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32 case TypeCode.UInt32 :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 case TypeCode.UInt64 :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 case TypeCode.SByte :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35 case TypeCode.Byte :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 case TypeCode.Decimal :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37 case TypeCode.Double :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38 case TypeCode.Single :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 case TypeCode.Boolean :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 case TypeCode.String :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41 case TypeCode.Char : return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 if (TypeHelper.IsNullableType(type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45 return IsConstant(type.GetGenericArguments()[0]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52 #region Compare
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 internal static bool Compare(Expression expr1, Expression expr2, Dictionary<Expression,QueryableAccessor> queryableAccessorDic)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56 return Compare(expr1, expr2, new HashSet<Expression>(), queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59 static bool Compare(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60 Expression expr1,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61 Expression expr2,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 HashSet<Expression> visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 Dictionary<Expression,QueryableAccessor> queryableAccessorDic)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 if (expr1 == expr2)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 if (expr1 == null || expr2 == null || expr1.NodeType != expr2.NodeType || expr1.Type != expr2.Type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71 switch (expr1.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101 var e1 = (BinaryExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102 var e2 = (BinaryExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 e1.Method == e2.Method &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105 Compare(e1.Conversion, e2.Conversion, visited, queryableAccessorDic) &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 Compare(e1.Left, e2.Left, visited, queryableAccessorDic) &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 Compare(e1.Right, e2.Right, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 var e1 = (UnaryExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121 var e2 = (UnaryExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 return e1.Method == e2.Method && Compare(e1.Operand, e2.Operand, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 var e1 = (MethodCallExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128 var e2 = (MethodCallExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 if (e1.Arguments.Count != e2.Arguments.Count || e1.Method != e2.Method)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 if (queryableAccessorDic.Count > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135 QueryableAccessor qa;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137 if (queryableAccessorDic.TryGetValue(expr1, out qa))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 return Compare(qa.Queryable.Expression, qa.Accessor(expr2).Expression, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 if (!Compare(e1.Object, e2.Object, visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144 for (var i = 0; i < e1.Arguments.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145 if (!Compare(e1.Arguments[i], e2.Arguments[i], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153 var e1 = (ConditionalExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 var e2 = (ConditionalExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156 Compare(e1.Test, e2.Test, visited, queryableAccessorDic) &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157 Compare(e1.IfTrue, e2.IfTrue, visited, queryableAccessorDic) &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 Compare(e1.IfFalse, e2.IfFalse, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161 case ExpressionType.Constant:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163 var e1 = (ConstantExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164 var e2 = (ConstantExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166 if (e1.Value == null && e2.Value == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 if (IsConstant(e1.Type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 return Equals(e1.Value, e2.Value);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172 if (e1.Value == null || e2.Value == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175 if (e1.Value is IQueryable)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177 var eq1 = ((IQueryable)e1.Value).Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178 var eq2 = ((IQueryable)e2.Value).Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180 if (visited.Add(eq1))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181 return Compare(eq1, eq2, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189 var e1 = (InvocationExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 var e2 = (InvocationExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 if (e1.Arguments.Count != e2.Arguments.Count || !Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 for (var i = 0; i < e1.Arguments.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196 if (!Compare(e1.Arguments[i], e2.Arguments[i], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 var e1 = (LambdaExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205 var e2 = (LambdaExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207 if (e1.Parameters.Count != e2.Parameters.Count || !Compare(e1.Body, e2.Body, visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 for (var i = 0; i < e1.Parameters.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211 if (!Compare(e1.Parameters[i], e2.Parameters[i], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 var e1 = (ListInitExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220 var e2 = (ListInitExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222 if (e1.Initializers.Count != e2.Initializers.Count || !Compare(e1.NewExpression, e2.NewExpression, visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225 for (var i = 0; i < e1.Initializers.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227 var i1 = e1.Initializers[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228 var i2 = e2.Initializers[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230 if (i1.Arguments.Count != i2.Arguments.Count || i1.AddMethod != i2.AddMethod)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 for (var j = 0; j < i1.Arguments.Count; j++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234 if (!Compare(i1.Arguments[j], i2.Arguments[j], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 var e1 = (MemberExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244 var e2 = (MemberExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 if (e1.Member == e2.Member)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248 if (e1.Expression == e2.Expression || e1.Expression.Type == e2.Expression.Type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250 if (queryableAccessorDic.Count > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252 QueryableAccessor qa;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254 if (queryableAccessorDic.TryGetValue(expr1, out qa))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256 Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic) &&
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257 Compare(qa.Queryable.Expression, qa.Accessor(expr2).Expression, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261 return Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269 var e1 = (MemberInitExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270 var e2 = (MemberInitExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272 if (e1.Bindings.Count != e2.Bindings.Count || !Compare(e1.NewExpression, e2.NewExpression, visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
275 Func<MemberBinding,MemberBinding,bool> compareBindings = null; compareBindings = (b1,b2) =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
276 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
277 if (b1 == b2)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
278 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
279
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
280 if (b1 == null || b2 == null || b1.BindingType != b2.BindingType || b1.Member != b2.Member)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
281 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
282
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
283 switch (b1.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
284 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
285 case MemberBindingType.Assignment:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
286 return Compare(((MemberAssignment)b1).Expression, ((MemberAssignment)b2).Expression, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
287
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
288 case MemberBindingType.ListBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
289 var ml1 = (MemberListBinding)b1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
290 var ml2 = (MemberListBinding)b2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
291
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
292 if (ml1.Initializers.Count != ml2.Initializers.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
293 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
294
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
295 for (var i = 0; i < ml1.Initializers.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
296 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
297 var ei1 = ml1.Initializers[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
298 var ei2 = ml2.Initializers[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
299
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
300 if (ei1.AddMethod != ei2.AddMethod || ei1.Arguments.Count != ei2.Arguments.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
301 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
302
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
303 for (var j = 0; j < ei1.Arguments.Count; j++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
304 if (!Compare(ei1.Arguments[j], ei2.Arguments[j], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
305 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
306 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
307
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
308 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
309
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
310 case MemberBindingType.MemberBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
311 var mm1 = (MemberMemberBinding)b1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
312 var mm2 = (MemberMemberBinding)b2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
313
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
314 if (mm1.Bindings.Count != mm2.Bindings.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
315 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
316
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
317 for (var i = 0; i < mm1.Bindings.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
318 if (!compareBindings(mm1.Bindings[i], mm2.Bindings[i]))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
319 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
320
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
321 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
322 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
323
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
324 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
325 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
326
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
327 for (var i = 0; i < e1.Bindings.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
328 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
329 var b1 = e1.Bindings[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
330 var b2 = e2.Bindings[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
331
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
332 if (!compareBindings(b1, b2))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
333 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
334 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
335
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
336 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
337 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
338
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
339 case ExpressionType.New:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
340 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
341 var e1 = (NewExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
342 var e2 = (NewExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
343
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
344 if (e1.Arguments.Count != e2.Arguments.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
345 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
346
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
347 if (e1.Members == null && e2.Members != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
348 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
349
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
350 if (e1.Members != null && e2.Members == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
351 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
352
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
353 if (e1.Constructor != e2.Constructor)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
354 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
355
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
356 if (e1.Members != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
357 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
358 if (e1.Members.Count != e2.Members.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
359 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
360
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
361 for (var i = 0; i < e1.Members.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
362 if (e1.Members[i] != e2.Members[i])
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
363 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
364 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
365
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
366 for (var i = 0; i < e1.Arguments.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
367 if (!Compare(e1.Arguments[i], e2.Arguments[i], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
368 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
369
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
370 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
371 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
372
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
373 case ExpressionType.NewArrayBounds:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
374 case ExpressionType.NewArrayInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
375 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
376 var e1 = (NewArrayExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
377 var e2 = (NewArrayExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
378
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
379 if (e1.Expressions.Count != e2.Expressions.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
380 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
381
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
382 for (var i = 0; i < e1.Expressions.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
383 if (!Compare(e1.Expressions[i], e2.Expressions[i], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
384 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
385
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
386 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
387 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
388
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
389 case ExpressionType.Parameter:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
390 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
391 var e1 = (ParameterExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
392 var e2 = (ParameterExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
393 return e1.Name == e2.Name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
394 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
395
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
396 case ExpressionType.TypeIs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
397 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
398 var e1 = (TypeBinaryExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
399 var e2 = (TypeBinaryExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
400 return e1.TypeOperand == e2.TypeOperand && Compare(e1.Expression, e2.Expression, visited, queryableAccessorDic);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
401 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
402
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
403 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
404
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
405 case ExpressionType.Block:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
406 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
407 var e1 = (BlockExpression)expr1;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
408 var e2 = (BlockExpression)expr2;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
409
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
410 for (var i = 0; i < e1.Expressions.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
411 if (!Compare(e1.Expressions[i], e2.Expressions[i], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
412 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
413
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
414 for (var i = 0; i < e1.Variables.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
415 if (!Compare(e1.Variables[i], e2.Variables[i], visited, queryableAccessorDic))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
416 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
417
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
418 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
419 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
420
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
421 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
422 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
423
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
424 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
425 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
426
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
427 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
428
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
429 #region Path
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
430
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
431 static Expression ConvertTo(Expression expr, Type type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
432 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
433 return Expression.Convert(expr, type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
434 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
435
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
436 static void Path<T>(IEnumerable<T> source, HashSet<Expression> visited, Expression path, MethodInfo property, Action<T,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
437 where T : class
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
438 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
439 var prop = Expression.Property(path, property);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
440 var i = 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
441 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
442 func(item, Expression.Call(prop, ReflectionHelper.IndexExpressor<T>.Item, new Expression[] { Expression.Constant(i++) }));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
443 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
444
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
445 static void Path<T>(IEnumerable<T> source, HashSet<Expression> visited, Expression path, MethodInfo property, Action<Expression,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
446 where T : Expression
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
447 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
448 var prop = Expression.Property(path, property);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
449 var i = 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
450 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
451 Path(item, visited, Expression.Call(prop, ReflectionHelper.IndexExpressor<T>.Item, new Expression[] { Expression.Constant(i++) }), func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
452 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
453
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
454 static void Path(Expression expr, HashSet<Expression> visited, Expression path, MethodInfo property, Action<Expression,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
455 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
456 Path(expr, visited, Expression.Property(path, property), func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
457 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
458
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
459 public static void Path(this Expression expr, Expression path, Action<Expression,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
460 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
461 Path(expr, new HashSet<Expression>(), path, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
462 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
463
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
464 static void Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
465 this Expression expr,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
466 HashSet<Expression> visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
467 Expression path,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
468 Action<Expression,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
469 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
470 if (expr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
471 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
472
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
473 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
474 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
475 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
476 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
477 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
478 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
479 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
480 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
481 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
482 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
483 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
484 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
485 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
486 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
487 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
488 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
489 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
490 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
491 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
492 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
493 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
494 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
495 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
496 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
497 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
498 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
499 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
500 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
501 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
502 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
503 path = ConvertTo(path, typeof(BinaryExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
504 var e = (BinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
505
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
506 Path(e.Conversion, visited, path, ReflectionHelper.Binary.Conversion, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
507 Path(e.Left, visited, path, ReflectionHelper.Binary.Left, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
508 Path(e.Right, visited, path, ReflectionHelper.Binary.Right, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
509
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
510 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
511 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
512
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
513 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
514 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
515 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
516 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
517 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
518 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
519 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
520 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
521 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
522 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
523 ((UnaryExpression)expr).Operand,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
524 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
525 path = ConvertTo(path, typeof(UnaryExpression)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
526 ReflectionHelper.Unary.Operand,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
527 func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
528 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
529
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
530 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
531 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
532 path = ConvertTo(path, typeof(MethodCallExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
533 var e = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
534
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
535 Path(e.Object, visited, path, ReflectionHelper.MethodCall.Object, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
536 Path(e.Arguments, visited, path, ReflectionHelper.MethodCall.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
537
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
538 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
539 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
540
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
541 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
542 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
543 path = ConvertTo(path, typeof(ConditionalExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
544 var e = (ConditionalExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
545
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
546 Path(e.Test, visited, path, ReflectionHelper.Conditional.Test, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
547 Path(e.IfTrue, visited, path, ReflectionHelper.Conditional.IfTrue, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
548 Path(e.IfFalse, visited, path, ReflectionHelper.Conditional.IfFalse, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
549
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
550 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
551 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
552
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
553 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
554 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
555 path = ConvertTo(path, typeof(InvocationExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
556 var e = (InvocationExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
557
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
558 Path(e.Expression, visited, path, ReflectionHelper.Invocation.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
559 Path(e.Arguments, visited, path, ReflectionHelper.Invocation.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
560
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
561 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
562 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
563
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
564 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
565 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
566 path = ConvertTo(path, typeof(LambdaExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
567 var e = (LambdaExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
568
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
569 Path(e.Body, visited, path, ReflectionHelper.LambdaExpr.Body, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
570 Path(e.Parameters, visited, path, ReflectionHelper.LambdaExpr.Parameters, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
571
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
572 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
573 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
574
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
575 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
576 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
577 path = ConvertTo(path, typeof(ListInitExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
578 var e = (ListInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
579
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
580 Path(e.NewExpression, visited, path, ReflectionHelper.ListInit.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
581 Path(e.Initializers, visited, path, ReflectionHelper.ListInit.Initializers,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
582 (ex,p) => Path(ex.Arguments, visited, p, ReflectionHelper.ElementInit.Arguments, func));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
583
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
584 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
585 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
586
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
587 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
588 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
589 ((MemberExpression)expr).Expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
590 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
591 path = ConvertTo(path, typeof(MemberExpression)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
592 ReflectionHelper.Member.Expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
593 func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
594 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
595
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
596 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
597 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
598 Action<MemberBinding,Expression> modify = null; modify = (b,pinf) =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
599 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
600 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
601 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
602 case MemberBindingType.Assignment:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
603 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
604 ((MemberAssignment)b).Expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
605 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
606 ConvertTo(pinf, typeof(MemberAssignment)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
607 ReflectionHelper.MemberAssignmentBind.Expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
608 func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
609 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
610
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
611 case MemberBindingType.ListBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
612 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
613 ((MemberListBinding)b).Initializers,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
614 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
615 ConvertTo(pinf, typeof(MemberListBinding)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
616 ReflectionHelper.MemberListBind.Initializers,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
617 (p,psi) => Path(p.Arguments, visited, psi, ReflectionHelper.ElementInit.Arguments, func));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
618 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
619
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
620 case MemberBindingType.MemberBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
621 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
622 ((MemberMemberBinding)b).Bindings,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
623 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
624 ConvertTo(pinf, typeof(MemberMemberBinding)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
625 ReflectionHelper.MemberMemberBind.Bindings,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
626 modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
627 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
628 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
629 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
630
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
631 path = ConvertTo(path, typeof(MemberInitExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
632 var e = (MemberInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
633
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
634 Path(e.NewExpression, visited, path, ReflectionHelper.MemberInit.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
635 Path(e.Bindings, visited, path, ReflectionHelper.MemberInit.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
636
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
637 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
638 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
639
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
640 case ExpressionType.New:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
641 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
642 ((NewExpression)expr).Arguments,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
643 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
644 path = ConvertTo(path, typeof(NewExpression)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
645 ReflectionHelper.New.Arguments,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
646 func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
647 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
648
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
649 case ExpressionType.NewArrayBounds:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
650 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
651 ((NewArrayExpression)expr).Expressions,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
652 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
653 path = ConvertTo(path, typeof(NewArrayExpression)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
654 ReflectionHelper.NewArray.Expressions,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
655 func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
656 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
657
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
658 case ExpressionType.NewArrayInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
659 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
660 ((NewArrayExpression)expr).Expressions,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
661 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
662 path = ConvertTo(path, typeof(NewArrayExpression)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
663 ReflectionHelper.NewArray.Expressions,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
664 func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
665 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
666
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
667 case ExpressionType.TypeIs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
668 Path(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
669 ((TypeBinaryExpression)expr).Expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
670 visited,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
671 path = ConvertTo(path, typeof(TypeBinaryExpression)),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
672 ReflectionHelper.TypeBinary.Expression,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
673 func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
674 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
675
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
676 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
677
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
678 case ExpressionType.Block:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
679 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
680 path = ConvertTo(path, typeof(BlockExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
681 var e = (BlockExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
682
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
683 Path(e.Expressions, visited, path, ReflectionHelper.Block.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
684 Path(e.Variables, visited, path, ReflectionHelper.Block.Variables, func); // ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
685
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
686 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
687 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
688
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
689 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
690
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
691 case ExpressionType.Constant :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
692 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
693 path = ConvertTo(path, typeof(ConstantExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
694 var e = (ConstantExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
695 var iq = e.Value as IQueryable;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
696
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
697 if (iq != null && !visited.Contains(iq.Expression))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
698 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
699 visited.Add(iq.Expression);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
700
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
701 Expression p = Expression.Property(path, ReflectionHelper.Constant.Value);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
702 p = ConvertTo(p, typeof(IQueryable));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
703 Path(iq.Expression, visited, p, ReflectionHelper.QueryableInt.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
704 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
705
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
706 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
707 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
708
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
709 case ExpressionType.Parameter: path = ConvertTo(path, typeof(ParameterExpression)); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
710 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
711
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
712 func(expr, path);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
713 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
714
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
715 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
716
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
717 #region Visit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
718
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
719 static void Visit<T>(IEnumerable<T> source, Action<T> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
720 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
721 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
722 func(item);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
723 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
724
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
725 static void Visit<T>(IEnumerable<T> source, Action<Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
726 where T : Expression
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
727 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
728 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
729 Visit(item, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
730 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
731
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
732 public static void Visit(this Expression expr, Action<Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
733 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
734 if (expr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
735 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
736
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
737 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
738 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
739 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
740 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
741 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
742 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
743 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
744 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
745 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
746 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
747 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
748 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
749 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
750 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
751 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
752 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
753 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
754 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
755 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
756 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
757 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
758 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
759 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
760 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
761 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
762 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
763 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
764 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
765 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
766 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
767 var e = (BinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
768
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
769 Visit(e.Conversion, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
770 Visit(e.Left, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
771 Visit(e.Right, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
772
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
773 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
774 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
775
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
776 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
777 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
778 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
779 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
780 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
781 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
782 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
783 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
784 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
785 Visit(((UnaryExpression)expr).Operand, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
786 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
787
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
788 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
789 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
790 var e = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
791
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
792 Visit(e.Object, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
793 Visit(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
794
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
795 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
796 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
797
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
798 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
799 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
800 var e = (ConditionalExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
801
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
802 Visit(e.Test, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
803 Visit(e.IfTrue, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
804 Visit(e.IfFalse, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
805
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
806 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
807 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
808
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
809 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
810 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
811 var e = (InvocationExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
812
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
813 Visit(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
814 Visit(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
815
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
816 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
817 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
818
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
819 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
820 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
821 var e = (LambdaExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
822
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
823 Visit(e.Body, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
824 Visit(e.Parameters, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
825
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
826 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
827 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
828
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
829 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
830 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
831 var e = (ListInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
832
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
833 Visit(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
834 Visit(e.Initializers, ex => Visit(ex.Arguments, func));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
835
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
836 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
837 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
838
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
839 case ExpressionType.MemberAccess: Visit(((MemberExpression)expr).Expression, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
840
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
841 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
842 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
843 Action<MemberBinding> modify = null; modify = b =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
844 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
845 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
846 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
847 case MemberBindingType.Assignment : Visit(((MemberAssignment)b). Expression, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
848 case MemberBindingType.ListBinding : Visit(((MemberListBinding)b).Initializers, p => Visit(p.Arguments, func)); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
849 case MemberBindingType.MemberBinding : Visit(((MemberMemberBinding)b).Bindings, modify); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
850 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
851 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
852
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
853 var e = (MemberInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
854
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
855 Visit(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
856 Visit(e.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
857
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
858 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
859 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
860
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
861 case ExpressionType.New : Visit(((NewExpression) expr).Arguments, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
862 case ExpressionType.NewArrayBounds : Visit(((NewArrayExpression) expr).Expressions, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
863 case ExpressionType.NewArrayInit : Visit(((NewArrayExpression) expr).Expressions, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
864 case ExpressionType.TypeIs : Visit(((TypeBinaryExpression)expr).Expression, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
865
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
866 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
867
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
868 case ExpressionType.Block:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
869 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
870 var e = (BlockExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
871
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
872 Visit(e.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
873 Visit(e.Variables, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
874
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
875 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
876 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
877
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
878 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
879
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
880 case (ExpressionType)ChangeTypeExpression.ChangeTypeType :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
881 Visit(((ChangeTypeExpression)expr).Expression, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
882 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
883
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
884 func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
885 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
886
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
887 static void Visit<T>(IEnumerable<T> source, Func<T,bool> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
888 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
889 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
890 func(item);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
891 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
892
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
893 static void Visit<T>(IEnumerable<T> source, Func<Expression,bool> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
894 where T : Expression
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
895 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
896 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
897 Visit(item, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
898 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
899
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
900 public static void Visit(this Expression expr, Func<Expression,bool> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
901 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
902 if (expr == null || !func(expr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
903 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
904
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
905 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
906 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
907 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
908 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
909 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
910 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
911 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
912 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
913 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
914 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
915 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
916 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
917 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
918 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
919 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
920 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
921 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
922 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
923 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
924 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
925 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
926 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
927 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
928 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
929 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
930 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
931 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
932 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
933 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
934 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
935 var e = (BinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
936
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
937 Visit(e.Conversion, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
938 Visit(e.Left, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
939 Visit(e.Right, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
940
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
941 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
942 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
943
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
944 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
945 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
946 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
947 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
948 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
949 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
950 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
951 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
952 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
953 Visit(((UnaryExpression)expr).Operand, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
954 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
955
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
956 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
957 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
958 var e = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
959
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
960 Visit(e.Object, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
961 Visit(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
962
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
963 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
964 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
965
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
966 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
967 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
968 var e = (ConditionalExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
969
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
970 Visit(e.Test, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
971 Visit(e.IfTrue, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
972 Visit(e.IfFalse, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
973
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
974 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
975 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
976
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
977 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
978 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
979 var e = (InvocationExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
980
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
981 Visit(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
982 Visit(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
983
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
984 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
985 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
986
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
987 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
988 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
989 var e = (LambdaExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
990
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
991 Visit(e.Body, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
992 Visit(e.Parameters, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
993
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
994 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
995 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
996
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
997 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
998 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
999 var e = (ListInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1000
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1001 Visit(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1002 Visit(e.Initializers, ex => Visit(ex.Arguments, func));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1003
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1004 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1005 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1006
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1007 case ExpressionType.MemberAccess: Visit(((MemberExpression)expr).Expression, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1008
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1009 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1010 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1011 Func<MemberBinding,bool> modify = null; modify = b =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1012 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1013 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1014 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1015 case MemberBindingType.Assignment : Visit(((MemberAssignment)b). Expression, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1016 case MemberBindingType.ListBinding : Visit(((MemberListBinding)b).Initializers, p => Visit(p.Arguments, func)); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1017 case MemberBindingType.MemberBinding : Visit(((MemberMemberBinding)b).Bindings, modify); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1018 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1019
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1020 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1021 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1022
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1023 var e = (MemberInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1024
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1025 Visit(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1026 Visit(e.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1027
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1028 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1029 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1030
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1031 case ExpressionType.New : Visit(((NewExpression) expr).Arguments, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1032 case ExpressionType.NewArrayBounds : Visit(((NewArrayExpression) expr).Expressions, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1033 case ExpressionType.NewArrayInit : Visit(((NewArrayExpression) expr).Expressions, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1034 case ExpressionType.TypeIs : Visit(((TypeBinaryExpression)expr).Expression, func); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1035
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1036 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1037
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1038 case ExpressionType.Block:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1039 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1040 var e = (BlockExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1041
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1042 Visit(e.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1043 Visit(e.Variables, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1044
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1045 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1046 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1047
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1048 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1049
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1050 case (ExpressionType)ChangeTypeExpression.ChangeTypeType :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1051 Visit(((ChangeTypeExpression)expr).Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1052 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1053 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1054 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1055
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1056 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1057
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1058 #region Find
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1059
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1060 static Expression Find<T>(IEnumerable<T> source, Func<T,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1061 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1062 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1063 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1064 var ex = func(item);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1065 if (ex != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1066 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1067 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1068
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1069 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1070 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1071
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1072 static Expression Find<T>(IEnumerable<T> source, Func<Expression,bool> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1073 where T : Expression
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1074 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1075 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1076 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1077 var f = Find(item, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1078 if (f != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1079 return f;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1080 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1081
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1082 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1083 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1084
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1085 public static Expression Find(this Expression expr, Func<Expression,bool> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1086 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1087 if (expr == null || func(expr))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1088 return expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1089
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1090 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1091 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1092 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1093 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1094 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1095 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1096 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1097 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1098 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1099 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1100 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1101 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1102 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1103 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1104 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1105 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1106 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1107 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1108 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1109 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1110 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1111 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1112 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1113 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1114 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1115 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1116 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1117 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1118 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1119 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1120 var e = (BinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1121
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1122 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1123 Find(e.Conversion, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1124 Find(e.Left, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1125 Find(e.Right, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1126 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1127
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1128 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1129 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1130 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1131 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1132 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1133 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1134 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1135 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1136 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1137 return Find(((UnaryExpression)expr).Operand, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1138
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1139 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1140 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1141 var e = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1142
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1143 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1144 Find(e.Object, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1145 Find(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1146 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1147
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1148 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1149 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1150 var e = (ConditionalExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1151
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1152 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1153 Find(e.Test, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1154 Find(e.IfTrue, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1155 Find(e.IfFalse, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1156 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1157
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1158 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1159 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1160 var e = (InvocationExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1161
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1162 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1163 Find(e.Expression, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1164 Find(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1165 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1166
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1167 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1168 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1169 var e = (LambdaExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1170
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1171 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1172 Find(e.Body, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1173 Find(e.Parameters, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1174 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1175
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1176 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1177 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1178 var e = (ListInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1179
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1180 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1181 Find(e.NewExpression, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1182 Find(e.Initializers, ex => Find(ex.Arguments, func));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1183 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1184
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1185 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1186 return Find(((MemberExpression)expr).Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1187
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1188 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1189 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1190 Func<MemberBinding,Expression> modify = null; modify = b =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1191 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1192 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1193 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1194 case MemberBindingType.Assignment : return Find(((MemberAssignment)b). Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1195 case MemberBindingType.ListBinding : return Find(((MemberListBinding)b). Initializers, p => Find(p.Arguments, func));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1196 case MemberBindingType.MemberBinding : return Find(((MemberMemberBinding)b).Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1197 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1198
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1199 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1200 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1201
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1202 var e = (MemberInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1203
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1204 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1205 Find(e.NewExpression, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1206 Find(e.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1207 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1208
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1209 case ExpressionType.New : return Find(((NewExpression) expr).Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1210 case ExpressionType.NewArrayBounds : return Find(((NewArrayExpression) expr).Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1211 case ExpressionType.NewArrayInit : return Find(((NewArrayExpression) expr).Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1212 case ExpressionType.TypeIs : return Find(((TypeBinaryExpression)expr).Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1213
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1214 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1215
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1216 case ExpressionType.Block:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1217 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1218 var e = (BlockExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1219
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1220 return
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1221 Find(e.Expressions, func) ??
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1222 Find(e.Variables, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1223 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1224
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1225 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1226
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1227 case (ExpressionType)ChangeTypeExpression.ChangeTypeType :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1228 return Find(((ChangeTypeExpression)expr).Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1229 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1230
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1231 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1232 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1233
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1234 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1235
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1236 #region Convert
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1237
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1238 static IEnumerable<T> Convert<T>(IEnumerable<T> source, Func<T,T> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1239 where T : class
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1240 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1241 var modified = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1242 var list = new List<T>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1243
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1244 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1245 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1246 var e = func(item);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1247 list.Add(e);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1248 modified = modified || e != item;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1249 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1250
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1251 return modified ? list : source;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1252 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1253
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1254 static IEnumerable<T> Convert<T>(IEnumerable<T> source, Func<Expression,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1255 where T : Expression
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1256 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1257 var modified = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1258 var list = new List<T>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1259
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1260 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1261 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1262 var e = Convert(item, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1263 list.Add((T)e);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1264 modified = modified || e != item;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1265 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1266
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1267 return modified? list: source;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1268 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1269
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1270 public static Expression Convert(this Expression expr, Func<Expression,Expression> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1271 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1272 if (expr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1273 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1274
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1275 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1276 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1277 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1278 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1279 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1280 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1281 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1282 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1283 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1284 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1285 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1286 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1287 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1288 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1289 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1290 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1291 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1292 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1293 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1294 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1295 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1296 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1297 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1298 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1299 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1300 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1301 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1302 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1303 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1304 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1305 var ex = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1306 if (ex != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1307 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1308
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1309 var e = (BinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1310 var c = Convert(e.Conversion, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1311 var l = Convert(e.Left, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1312 var r = Convert(e.Right, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1313
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1314 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1315 return c != e.Conversion || l != e.Left || r != e.Right ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1316 Expression.MakeBinary(expr.NodeType, l, r, e.IsLiftedToNull, e.Method, (LambdaExpression)c):
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1317 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1318 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1319 return e.Update(l, (LambdaExpression)c, r);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1320 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1321 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1322
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1323 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1324 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1325 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1326 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1327 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1328 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1329 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1330 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1331 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1332 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1333 var ex = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1334 if (ex != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1335 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1336
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1337 var e = (UnaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1338 var o = Convert(e.Operand, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1339
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1340 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1341 return o != e.Operand ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1342 Expression.MakeUnary(expr.NodeType, o, e.Type, e.Method) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1343 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1344 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1345 return e.Update(o);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1346 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1347 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1348
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1349 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1350 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1351 var ex = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1352 if (ex != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1353 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1354
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1355 var e = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1356 var o = Convert(e.Object, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1357 var a = Convert(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1358
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1359 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1360 return o != e.Object || a != e.Arguments ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1361 Expression.Call(o, e.Method, a) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1362 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1363 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1364 return e.Update(o, a);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1365 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1366 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1367
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1368 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1369 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1370 var ex = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1371 if (ex != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1372 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1373
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1374 var e = (ConditionalExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1375 var s = Convert(e.Test, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1376 var t = Convert(e.IfTrue, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1377 var f = Convert(e.IfFalse, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1378
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1379 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1380 return s != e.Test || t != e.IfTrue || f != e.IfFalse ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1381 Expression.Condition(s, t, f) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1382 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1383 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1384 return e.Update(s, t, f);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1385 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1386 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1387
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1388 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1389 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1390 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1391 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1392 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1393
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1394 var e = (InvocationExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1395 var ex = Convert(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1396 var a = Convert(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1397
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1398 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1399 return ex != e.Expression || a != e.Arguments ? Expression.Invoke(ex, a) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1400 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1401 return e.Update(ex, a);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1402 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1403 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1404
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1405 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1406 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1407 var ex = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1408 if (ex != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1409 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1410
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1411 var e = (LambdaExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1412 var b = Convert(e.Body, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1413 var p = Convert(e.Parameters, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1414
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1415 return b != e.Body || p != e.Parameters ? Expression.Lambda(ex.Type, b, p.ToArray()) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1416 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1417
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1418 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1419 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1420 var ex = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1421 if (ex != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1422 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1423
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1424 var e = (ListInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1425 var n = Convert(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1426 var i = Convert(e.Initializers, p =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1427 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1428 var args = Convert(p.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1429 return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1430 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1431
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1432 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1433 return n != e.NewExpression || i != e.Initializers ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1434 Expression.ListInit((NewExpression)n, i) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1435 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1436 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1437 return e.Update((NewExpression)n, i);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1438 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1439 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1440
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1441 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1442 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1443 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1444 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1445 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1446
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1447 var e = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1448 var ex = Convert(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1449
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1450 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1451 return ex != e.Expression ? Expression.MakeMemberAccess(ex, e.Member) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1452 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1453 return e.Update(ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1454 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1455 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1456
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1457 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1458 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1459 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1460 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1461 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1462
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1463 Func<MemberBinding,MemberBinding> modify = null; modify = b =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1464 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1465 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1466 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1467 case MemberBindingType.Assignment:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1468 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1469 var ma = (MemberAssignment)b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1470 var ex = Convert(ma.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1471
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1472 if (ex != ma.Expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1473 ma = Expression.Bind(ma.Member, ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1474
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1475 return ma;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1476 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1477
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1478 case MemberBindingType.ListBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1479 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1480 var ml = (MemberListBinding)b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1481 var i = Convert(ml.Initializers, p =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1482 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1483 var args = Convert(p.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1484 return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1485 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1486
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1487 if (i != ml.Initializers)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1488 ml = Expression.ListBind(ml.Member, i);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1489
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1490 return ml;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1491 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1492
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1493 case MemberBindingType.MemberBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1494 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1495 var mm = (MemberMemberBinding)b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1496 var bs = Convert(mm.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1497
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1498 if (bs != mm.Bindings)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1499 mm = Expression.MemberBind(mm.Member);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1500
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1501 return mm;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1502 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1503 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1504
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1505 return b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1506 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1507
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1508 var e = (MemberInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1509 var ne = Convert(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1510 var bb = Convert(e.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1511
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1512 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1513 return ne != e.NewExpression || bb != e.Bindings ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1514 Expression.MemberInit((NewExpression)ne, bb) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1515 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1516 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1517 return e.Update((NewExpression)ne, bb);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1518 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1519 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1520
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1521 case ExpressionType.New:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1522 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1523 var ex = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1524 if (ex != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1525 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1526
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1527 var e = (NewExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1528 var a = Convert(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1529
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1530 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1531 return a != e.Arguments ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1532 e.Members == null ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1533 Expression.New(e.Constructor, a) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1534 Expression.New(e.Constructor, a, e.Members) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1535 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1536 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1537 return e.Update(a);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1538 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1539 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1540
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1541 case ExpressionType.NewArrayBounds:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1542 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1543 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1544 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1545 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1546
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1547 var e = (NewArrayExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1548 var ex = Convert(e.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1549
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1550 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1551 return ex != e.Expressions ? Expression.NewArrayBounds(e.Type, ex) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1552 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1553 return e.Update(ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1554 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1555 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1556
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1557 case ExpressionType.NewArrayInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1558 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1559 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1560 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1561 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1562
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1563 var e = (NewArrayExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1564 var ex = Convert(e.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1565
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1566 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1567 return ex != e.Expressions ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1568 Expression.NewArrayInit(e.Type.GetElementType(), ex) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1569 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1570 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1571 return e.Update(ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1572
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1573 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1574 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1575
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1576 case ExpressionType.TypeIs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1577 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1578 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1579 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1580 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1581
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1582 var e = (TypeBinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1583 var ex = Convert(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1584
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1585 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1586 return ex != e.Expression ? Expression.TypeIs(ex, e.Type) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1587 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1588 return e.Update(ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1589 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1590 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1591
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1592 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1593
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1594 case ExpressionType.Block:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1595 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1596 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1597 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1598 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1599
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1600 var e = (BlockExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1601 var ex = Convert(e.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1602 var v = Convert(e.Variables, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1603
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1604 return e.Update(v, ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1605 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1606
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1607 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1608
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1609 case ExpressionType.Constant : return func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1610 case ExpressionType.Parameter: return func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1611
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1612 case (ExpressionType)ChangeTypeExpression.ChangeTypeType :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1613 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1614 var exp = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1615 if (exp != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1616 return exp;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1617
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1618 var e = expr as ChangeTypeExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1619 var ex = Convert(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1620
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1621 if (ex == e.Expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1622 return expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1623
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1624 if (ex.Type == e.Type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1625 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1626
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1627 return new ChangeTypeExpression(ex, e.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1628 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1629 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1630
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1631 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1632 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1633
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1634 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1635
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1636 #region Convert2
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1637
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1638 public struct ConvertInfo
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1639 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1640 public ConvertInfo(Expression expression, bool stop)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1641 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1642 Expression = expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1643 Stop = stop;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1644 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1645
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1646 public ConvertInfo(Expression expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1647 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1648 Expression = expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1649 Stop = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1650 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1651
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1652 public Expression Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1653 public bool Stop;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1654 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1655
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1656 static IEnumerable<T> Convert2<T>(IEnumerable<T> source, Func<T,T> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1657 where T : class
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1658 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1659 var modified = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1660 var list = new List<T>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1661
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1662 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1663 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1664 var e = func(item);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1665 list.Add(e);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1666 modified = modified || e != item;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1667 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1668
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1669 return modified ? list : source;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1670 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1671
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1672 static IEnumerable<T> Convert2<T>(IEnumerable<T> source, Func<Expression,ConvertInfo> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1673 where T : Expression
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1674 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1675 var modified = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1676 var list = new List<T>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1677
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1678 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1679 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1680 var e = Convert2(item, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1681 list.Add((T)e);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1682 modified = modified || e != item;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1683 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1684
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1685 return modified ? list : source;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1686 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1687
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1688 #if FW3
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1689 static IEnumerable<Expression> ConvertMethodArguments(IEnumerable<Expression> source, MethodBase method)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1690 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1691 return ConvertMethodArguments(source, method, null);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1692 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1693
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1694 static IEnumerable<Expression> ConvertMethodArguments(IEnumerable<Expression> source, MethodBase method, IList<MemberInfo> initMembers)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1695 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1696 static IEnumerable<Expression> ConvertMethodArguments(IEnumerable<Expression> source, MethodBase method, IList<MemberInfo> initMembers = null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1697 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1698 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1699 var list = new List<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1700
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1701 var targetTypes = new List<Type>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1702 foreach (var param in method.GetParameters())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1703 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1704 targetTypes.Add(param.ParameterType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1705 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1706 if (initMembers != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1707 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1708 foreach (var mi in initMembers)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1709 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1710 if (mi is PropertyInfo)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1711 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1712 targetTypes.Add(((PropertyInfo)mi).PropertyType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1713 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1714 else if (mi is FieldInfo)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1715 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1716 targetTypes.Add(((FieldInfo)mi).FieldType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1717 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1718 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1719 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1720
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1721 var idx = 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1722 foreach (var item in source)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1723 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1724 var targetType = targetTypes[idx];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1725 if (item.Type != targetType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1726 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1727 list.Add(Expression.Convert(item, targetType));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1728 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1729 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1730 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1731 list.Add(item);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1732 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1733 idx++;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1734 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1735
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1736 return list;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1737 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1738
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1739 public static Expression Convert2(this Expression expr, Func<Expression,ConvertInfo> func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1740 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1741 if (expr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1742 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1743
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1744 ConvertInfo ci;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1745
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1746 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1747 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1748 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1749 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1750 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1751 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1752 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1753 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1754 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1755 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1756 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1757 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1758 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1759 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1760 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1761 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1762 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1763 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1764 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1765 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1766 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1767 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1768 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1769 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1770 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1771 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1772 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1773 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1774 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1775 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1776 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1777 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1778 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1779
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1780 var e = expr as BinaryExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1781 var c = Convert2(e.Conversion, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1782 var l = Convert2(e.Left, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1783 var r = Convert2(e.Right, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1784
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1785 return c != e.Conversion || l != e.Left || r != e.Right ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1786 Expression.MakeBinary(expr.NodeType, l, r, e.IsLiftedToNull, e.Method, (LambdaExpression)c):
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1787 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1788 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1789
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1790 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1791 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1792 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1793 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1794 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1795 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1796 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1797 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1798 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1799 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1800 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1801 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1802 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1803
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1804 var e = expr as UnaryExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1805 var o = Convert2(e.Operand, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1806
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1807 return o != e.Operand ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1808 Expression.MakeUnary(expr.NodeType, o, e.Type, e.Method) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1809 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1810 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1811
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1812 case ExpressionType.Call:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1813 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1814 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1815 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1816 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1817
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1818 var e = expr as MethodCallExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1819 var o = Convert2(e.Object, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1820 var a = Convert2(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1821
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1822 return o != e.Object || a != e.Arguments ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1823 Expression.Call(o, e.Method, ConvertMethodArguments(a, e.Method)) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1824 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1825 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1826
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1827 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1828 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1829 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1830 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1831 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1832
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1833 var e = expr as ConditionalExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1834 var s = Convert2(e.Test, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1835 var t = Convert2(e.IfTrue, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1836 var f = Convert2(e.IfFalse, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1837
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1838 return s != e.Test || t != e.IfTrue || f != e.IfFalse ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1839 Expression.Condition(s, t, f) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1840 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1841 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1842
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1843 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1844 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1845 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1846 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1847 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1848
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1849 var e = expr as InvocationExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1850 var ex = Convert2(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1851 var a = Convert2(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1852
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1853 return ex != e.Expression || a != e.Arguments ? Expression.Invoke(ex, a) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1854 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1855
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1856 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1857 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1858 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1859 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1860 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1861
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1862 var e = expr as LambdaExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1863 var b = Convert2(e.Body, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1864 var p = Convert2(e.Parameters, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1865
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1866 return b != e.Body || p != e.Parameters ? Expression.Lambda(ci.Expression.Type, b, p.ToArray()) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1867 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1868
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1869 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1870 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1871 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1872 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1873 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1874
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1875 var e = expr as ListInitExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1876 var n = Convert2(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1877 var i = Convert2(e.Initializers, p =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1878 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1879 var args = Convert2(p.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1880 return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1881 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1882
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1883 return n != e.NewExpression || i != e.Initializers ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1884 Expression.ListInit((NewExpression)n, i) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1885 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1886 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1887
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1888 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1889 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1890 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1891 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1892 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1893
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1894 var e = expr as MemberExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1895 var ex = Convert2(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1896
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1897 return ex != e.Expression ? Expression.MakeMemberAccess(ex, e.Member) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1898 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1899
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1900 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1901 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1902 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1903 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1904 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1905
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1906 Func<MemberBinding,MemberBinding> modify = null; modify = b =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1907 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1908 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1909 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1910 case MemberBindingType.Assignment:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1911 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1912 var ma = (MemberAssignment)b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1913 var ex = Convert2(ma.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1914
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1915 if (ex != ma.Expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1916 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1917 if (ex.Type != ma.Expression.Type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1918 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1919 ex = Expression.Convert(ex, ma.Expression.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1920 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1921 ma = Expression.Bind(ma.Member, ex);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1922 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1923
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1924 return ma;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1925 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1926
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1927 case MemberBindingType.ListBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1928 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1929 var ml = (MemberListBinding)b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1930 var i = Convert(ml.Initializers, p =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1931 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1932 var args = Convert2(p.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1933 return args != p.Arguments? Expression.ElementInit(p.AddMethod, args): p;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1934 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1935
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1936 if (i != ml.Initializers)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1937 ml = Expression.ListBind(ml.Member, i);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1938
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1939 return ml;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1940 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1941
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1942 case MemberBindingType.MemberBinding:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1943 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1944 var mm = (MemberMemberBinding)b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1945 var bs = Convert(mm.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1946
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1947 if (bs != mm.Bindings)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1948 mm = Expression.MemberBind(mm.Member);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1949
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1950 return mm;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1951 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1952 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1953
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1954 return b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1955 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1956
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1957 var e = expr as MemberInitExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1958 var ne = Convert2(e.NewExpression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1959 var bb = Convert2(e.Bindings, modify);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1960
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1961 return ne != e.NewExpression || bb != e.Bindings ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1962 Expression.MemberInit((NewExpression)ne, bb) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1963 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1964 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1965
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1966 case ExpressionType.New:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1967 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1968 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1969 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1970 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1971
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1972 var e = expr as NewExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1973 var a = Convert2(e.Arguments, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1974
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1975 return a != e.Arguments ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1976 e.Members == null ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1977 Expression.New(e.Constructor, ConvertMethodArguments(a, e.Constructor)) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1978 Expression.New(e.Constructor, ConvertMethodArguments(a, e.Constructor, e.Members), e.Members) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1979 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1980 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1981
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1982 case ExpressionType.NewArrayBounds:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1983 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1984 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1985 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1986 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1987
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1988 var e = expr as NewArrayExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1989 var ex = Convert2(e.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1990
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1991 return ex != e.Expressions ? Expression.NewArrayBounds(e.Type, ex) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1992 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1993
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1994 case ExpressionType.NewArrayInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1995 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1996 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1997 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1998 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1999
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2000 var e = expr as NewArrayExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2001 var et = e.Type.GetElementType();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2002 var ex = Convert2(e.Expressions, func)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2003 .Select(ee => et == typeof(object) && ee.Type.IsValueType ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2004 Expression.Convert(ee, typeof(object)) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2005 ee);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2006
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2007 return ex != e.Expressions ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2008 Expression.NewArrayInit(et, ex) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2009 expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2010 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2011
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2012 case ExpressionType.TypeIs :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2013 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2014 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2015 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2016 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2017
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2018 var e = expr as TypeBinaryExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2019 var ex = Convert2(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2020
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2021 return ex != e.Expression ? Expression.TypeIs(ex, e.Type) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2022 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2023
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2024 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2025
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2026 case ExpressionType.Block :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2027 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2028 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2029 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2030 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2031
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2032 var e = expr as BlockExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2033 var ex = Convert2(e.Expressions, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2034 var v = Convert2(e.Variables, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2035
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2036 return ex != e.Expressions || v != e.Variables ? Expression.Block(e.Type, v, ex) : expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2037 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2038
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2039 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2040
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2041 case ExpressionType.Constant : return func(expr).Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2042 case ExpressionType.Parameter: return func(expr).Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2043
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2044 case (ExpressionType)ChangeTypeExpression.ChangeTypeType :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2045 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2046 ci = func(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2047 if (ci.Stop || ci.Expression != expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2048 return ci.Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2049
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2050 var e = expr as ChangeTypeExpression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2051 var ex = Convert2(e.Expression, func);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2052
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2053 if (ex == e.Expression)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2054 return expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2055
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2056 if (ex.Type == e.Type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2057 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2058
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2059 return new ChangeTypeExpression(ex, e.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2060 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2061 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2062
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2063 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2064 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2065
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2066 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2067
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2068 #region Helpers
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2069
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2070 static public Expression Unwrap(this Expression ex)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2071 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2072 if (ex == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2073 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2074
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2075 switch (ex.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2076 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2077 case ExpressionType.Quote : return ((UnaryExpression)ex).Operand.Unwrap();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2078 case ExpressionType.ConvertChecked :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2079 case ExpressionType.Convert :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2080 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2081 var ue = (UnaryExpression)ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2082
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2083 if (!ue.Operand.Type.IsEnum)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2084 return ue.Operand.Unwrap();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2085
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2086 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2087 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2088 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2089
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2090 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2091 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2092
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2093 static public Dictionary<Expression,Expression> GetExpressionAccessors(this Expression expression, Expression path)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2094 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2095 var accessors = new Dictionary<Expression,Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2096
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2097 expression.Path(path, (e,p) =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2098 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2099 switch (e.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2100 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2101 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2102 case ExpressionType.MemberAccess :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2103 case ExpressionType.New :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2104 if (!accessors.ContainsKey(e))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2105 accessors.Add(e, p);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2106 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2107
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2108 case ExpressionType.Constant :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2109 if (!accessors.ContainsKey(e))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2110 accessors.Add(e, Expression.Property(p, ReflectionHelper.Constant.Value));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2111 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2112
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2113 case ExpressionType.ConvertChecked :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2114 case ExpressionType.Convert :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2115 if (!accessors.ContainsKey(e))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2116 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2117 var ue = (UnaryExpression)e;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2118
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2119 switch (ue.Operand.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2120 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2121 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2122 case ExpressionType.MemberAccess :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2123 case ExpressionType.New :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2124 case ExpressionType.Constant :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2125
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2126 accessors.Add(e, p);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2127 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2128 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2129 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2130
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2131 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2132 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2133 });
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2134
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2135 return accessors;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2136 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2137
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2138 static public Expression GetRootObject(this Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2139 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2140 if (expr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2141 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2142
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2143 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2144 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2145 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2146 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2147 var e = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2148
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2149 if (e.Object != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2150 return GetRootObject(e.Object);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2151
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2152 if (e.Arguments != null && e.Arguments.Count > 0 && e.IsQueryable())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2153 return GetRootObject(e.Arguments[0]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2154
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2155 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2156 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2157
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2158 case ExpressionType.MemberAccess :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2159 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2160 var e = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2161
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2162 if (e.Expression != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2163 return GetRootObject(e.Expression.Unwrap());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2164
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2165 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2166 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2167 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2168
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2169 return expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2170 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2171
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2172 static public List<Expression> GetMembers(this Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2173 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2174 if (expr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2175 return new List<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2176
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2177 List<Expression> list;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2178
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2179 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2180 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2181 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2182 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2183 var e = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2184
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2185 if (e.Object != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2186 list = GetMembers(e.Object);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2187 else if (e.Arguments != null && e.Arguments.Count > 0 && e.IsQueryable())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2188 list = GetMembers(e.Arguments[0]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2189 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2190 list = new List<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2191
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2192 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2193 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2194
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2195 case ExpressionType.MemberAccess :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2196 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2197 var e = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2198
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2199 if (e.Expression != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2200 list = GetMembers(e.Expression.Unwrap());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2201 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2202 list = new List<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2203
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2204 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2205 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2206
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2207 default :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2208 list = new List<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2209 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2210 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2211
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2212 list.Add(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2213
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2214 return list;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2215 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2216
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2217 static public bool IsQueryable(this MethodCallExpression method)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2218 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2219 var type = method.Method.DeclaringType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2220
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2221 return type == typeof(Queryable) || type == typeof(Enumerable) || type == typeof(LinqExtensions);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2222 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2223
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2224 static public bool IsQueryable(this MethodCallExpression method, string name)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2225 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2226 return method.Method.Name == name && method.IsQueryable();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2227 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2228
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2229 static public bool IsQueryable(this MethodCallExpression method, params string[] names)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2230 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2231 if (method.IsQueryable())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2232 foreach (var name in names)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2233 if (method.Method.Name == name)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2234 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2235
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2236 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2237 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2238
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2239 static Expression FindLevel(Expression expression, int level, ref int current)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2240 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2241 switch (expression.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2242 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2243 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2244 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2245 var call = (MethodCallExpression)expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2246 var expr = call.Object;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2247
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2248 if (expr == null && call.IsQueryable() && call.Arguments.Count > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2249 expr = call.Arguments[0];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2250
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2251 if (expr != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2252 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2253 var ex = FindLevel(expr, level, ref current);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2254
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2255 if (level == current)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2256 return ex;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2257
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2258 current++;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2259 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2260
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2261 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2262 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2263
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2264 case ExpressionType.MemberAccess:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2265 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2266 var e = ((MemberExpression)expression);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2267
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2268 if (e.Expression != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2269 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2270 var expr = FindLevel(e.Expression.Unwrap(), level, ref current);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2271
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2272 if (level == current)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2273 return expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2274
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2275 current++;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2276 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2277
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2278 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2279 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2280 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2281
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2282 return expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2283 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2284
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2285 static public Expression GetLevelExpression(this Expression expression, int level)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2286 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2287 var current = 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2288 var expr = FindLevel(expression, level, ref current);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2289
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2290 if (expr == null || current != level)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2291 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2292
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2293 return expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2294 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2295
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2296 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2297 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2298 }