Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ExpressionVisitor.cs
Go to the documentation of this file.
5
7
8public abstract class ExpressionVisitor
9{
10 [return: NotNullIfNotNull("node")]
11 public virtual Expression? Visit(Expression? node)
12 {
13 return node?.Accept(this);
14 }
15
17 {
18 ContractUtils.RequiresNotNull(nodes, "nodes");
19 Expression[] array = null;
20 int i = 0;
21 for (int count = nodes.Count; i < count; i++)
22 {
23 Expression expression = Visit(nodes[i]);
24 if (array != null)
25 {
26 array[i] = expression;
27 }
28 else if (expression != nodes[i])
29 {
30 array = new Expression[count];
31 for (int j = 0; j < i; j++)
32 {
33 array[j] = nodes[j];
34 }
35 array[i] = expression;
36 }
37 }
38 if (array == null)
39 {
40 return nodes;
41 }
43 }
44
46 {
47 return ExpressionVisitorUtils.VisitArguments(this, nodes);
48 }
49
50 private ParameterExpression[] VisitParameters(IParameterProvider nodes, string callerName)
51 {
52 return ExpressionVisitorUtils.VisitParameters(this, nodes, callerName);
53 }
54
55 public static ReadOnlyCollection<T> Visit<T>(ReadOnlyCollection<T> nodes, Func<T, T> elementVisitor)
56 {
57 ContractUtils.RequiresNotNull(nodes, "nodes");
58 ContractUtils.RequiresNotNull(elementVisitor, "elementVisitor");
59 T[] array = null;
60 int i = 0;
61 for (int count = nodes.Count; i < count; i++)
62 {
63 T val = elementVisitor(nodes[i]);
64 if (array != null)
65 {
66 array[i] = val;
67 }
68 else if ((object)val != (object)nodes[i])
69 {
70 array = new T[count];
71 for (int j = 0; j < i; j++)
72 {
73 array[j] = nodes[j];
74 }
75 array[i] = val;
76 }
77 }
78 if (array == null)
79 {
80 return nodes;
81 }
83 }
84
85 [return: NotNullIfNotNull("node")]
86 public T? VisitAndConvert<T>(T? node, string? callerName) where T : Expression
87 {
88 if (node == null)
89 {
90 return null;
91 }
92 node = Visit(node) as T;
93 if (node == null)
94 {
95 throw Error.MustRewriteToSameNode(callerName, typeof(T), callerName);
96 }
97 return node;
98 }
99
101 {
102 ContractUtils.RequiresNotNull(nodes, "nodes");
103 T[] array = null;
104 int i = 0;
105 for (int count = nodes.Count; i < count; i++)
106 {
107 if (!(Visit(nodes[i]) is T val))
108 {
109 throw Error.MustRewriteToSameNode(callerName, typeof(T), callerName);
110 }
111 if (array != null)
112 {
113 array[i] = val;
114 }
115 else if (val != nodes[i])
116 {
117 array = new T[count];
118 for (int j = 0; j < i; j++)
119 {
120 array[j] = nodes[j];
121 }
122 array[i] = val;
123 }
124 }
125 if (array == null)
126 {
127 return nodes;
128 }
130 }
131
132 protected internal virtual Expression VisitBinary(BinaryExpression node)
133 {
134 return ValidateBinary(node, node.Update(Visit(node.Left), VisitAndConvert(node.Conversion, "VisitBinary"), Visit(node.Right)));
135 }
136
137 protected internal virtual Expression VisitBlock(BlockExpression node)
138 {
140 ReadOnlyCollection<ParameterExpression> readOnlyCollection = VisitAndConvert(node.Variables, "VisitBlock");
141 if (readOnlyCollection == node.Variables && array == null)
142 {
143 return node;
144 }
145 return node.Rewrite(readOnlyCollection, array);
146 }
147
148 protected internal virtual Expression VisitConditional(ConditionalExpression node)
149 {
150 return node.Update(Visit(node.Test), Visit(node.IfTrue), Visit(node.IfFalse));
151 }
152
153 protected internal virtual Expression VisitConstant(ConstantExpression node)
154 {
155 return node;
156 }
157
158 protected internal virtual Expression VisitDebugInfo(DebugInfoExpression node)
159 {
160 return node;
161 }
162
163 protected internal virtual Expression VisitDefault(DefaultExpression node)
164 {
165 return node;
166 }
167
168 protected internal virtual Expression VisitExtension(Expression node)
169 {
170 return node.VisitChildren(this);
171 }
172
173 protected internal virtual Expression VisitGoto(GotoExpression node)
174 {
175 return node.Update(VisitLabelTarget(node.Target), Visit(node.Value));
176 }
177
178 protected internal virtual Expression VisitInvocation(InvocationExpression node)
179 {
180 Expression expression = Visit(node.Expression);
182 if (expression == node.Expression && array == null)
183 {
184 return node;
185 }
186 return node.Rewrite(expression, array);
187 }
188
189 [return: NotNullIfNotNull("node")]
190 protected virtual LabelTarget? VisitLabelTarget(LabelTarget? node)
191 {
192 return node;
193 }
194
195 protected internal virtual Expression VisitLabel(LabelExpression node)
196 {
197 return node.Update(VisitLabelTarget(node.Target), Visit(node.DefaultValue));
198 }
199
200 protected internal virtual Expression VisitLambda<T>(Expression<T> node)
201 {
202 Expression expression = Visit(node.Body);
203 ParameterExpression[] array = VisitParameters(node, "VisitLambda");
204 if (expression == node.Body && array == null)
205 {
206 return node;
207 }
208 return node.Rewrite(expression, array);
209 }
210
211 protected internal virtual Expression VisitLoop(LoopExpression node)
212 {
214 }
215
216 protected internal virtual Expression VisitMember(MemberExpression node)
217 {
218 return node.Update(Visit(node.Expression));
219 }
220
221 protected internal virtual Expression VisitIndex(IndexExpression node)
222 {
223 Expression expression = Visit(node.Object);
225 if (expression == node.Object && array == null)
226 {
227 return node;
228 }
229 return node.Rewrite(expression, array);
230 }
231
232 protected internal virtual Expression VisitMethodCall(MethodCallExpression node)
233 {
234 Expression expression = Visit(node.Object);
236 if (expression == node.Object && array == null)
237 {
238 return node;
239 }
240 return node.Rewrite(expression, array);
241 }
242
243 protected internal virtual Expression VisitNewArray(NewArrayExpression node)
244 {
245 return node.Update(Visit(node.Expressions));
246 }
247
248 protected internal virtual Expression VisitNew(NewExpression node)
249 {
251 if (array == null)
252 {
253 return node;
254 }
255 return node.Update(array);
256 }
257
258 protected internal virtual Expression VisitParameter(ParameterExpression node)
259 {
260 return node;
261 }
262
264 {
265 return node.Update(VisitAndConvert(node.Variables, "VisitRuntimeVariables"));
266 }
267
268 protected virtual SwitchCase VisitSwitchCase(SwitchCase node)
269 {
270 return node.Update(Visit(node.TestValues), Visit(node.Body));
271 }
272
273 protected internal virtual Expression VisitSwitch(SwitchExpression node)
274 {
275 return ValidateSwitch(node, node.Update(Visit(node.SwitchValue), Visit(node.Cases, VisitSwitchCase), Visit(node.DefaultBody)));
276 }
277
278 protected virtual CatchBlock VisitCatchBlock(CatchBlock node)
279 {
280 return node.Update(VisitAndConvert(node.Variable, "VisitCatchBlock"), Visit(node.Filter), Visit(node.Body));
281 }
282
283 protected internal virtual Expression VisitTry(TryExpression node)
284 {
285 return node.Update(Visit(node.Body), Visit(node.Handlers, VisitCatchBlock), Visit(node.Finally), Visit(node.Fault));
286 }
287
288 protected internal virtual Expression VisitTypeBinary(TypeBinaryExpression node)
289 {
290 return node.Update(Visit(node.Expression));
291 }
292
293 protected internal virtual Expression VisitUnary(UnaryExpression node)
294 {
295 return ValidateUnary(node, node.Update(Visit(node.Operand)));
296 }
297
298 protected internal virtual Expression VisitMemberInit(MemberInitExpression node)
299 {
300 return node.Update(VisitAndConvert(node.NewExpression, "VisitMemberInit"), Visit(node.Bindings, VisitMemberBinding));
301 }
302
303 protected internal virtual Expression VisitListInit(ListInitExpression node)
304 {
305 return node.Update(VisitAndConvert(node.NewExpression, "VisitListInit"), Visit(node.Initializers, VisitElementInit));
306 }
307
309 {
310 return node.Update(Visit(node.Arguments));
311 }
312
314 {
315 return node.BindingType switch
316 {
317 MemberBindingType.Assignment => VisitMemberAssignment((MemberAssignment)node),
318 MemberBindingType.MemberBinding => VisitMemberMemberBinding((MemberMemberBinding)node),
319 MemberBindingType.ListBinding => VisitMemberListBinding((MemberListBinding)node),
320 _ => throw Error.UnhandledBindingType(node.BindingType),
321 };
322 }
323
325 {
326 return node.Update(Visit(node.Expression));
327 }
328
330 {
331 return node.Update(Visit(node.Bindings, VisitMemberBinding));
332 }
333
335 {
336 return node.Update(Visit(node.Initializers, VisitElementInit));
337 }
338
340 {
341 if (before != after && before.Method == null)
342 {
343 if (after.Method != null)
344 {
345 throw Error.MustRewriteWithoutMethod(after.Method, "VisitUnary");
346 }
347 if (before.Operand != null && after.Operand != null)
348 {
349 ValidateChildType(before.Operand.Type, after.Operand.Type, "VisitUnary");
350 }
351 }
352 return after;
353 }
354
356 {
357 if (before != after && before.Method == null)
358 {
359 if (after.Method != null)
360 {
361 throw Error.MustRewriteWithoutMethod(after.Method, "VisitBinary");
362 }
363 ValidateChildType(before.Left.Type, after.Left.Type, "VisitBinary");
364 ValidateChildType(before.Right.Type, after.Right.Type, "VisitBinary");
365 }
366 return after;
367 }
368
370 {
371 if (before.Comparison == null && after.Comparison != null)
372 {
373 throw Error.MustRewriteWithoutMethod(after.Comparison, "VisitSwitch");
374 }
375 return after;
376 }
377
378 private static void ValidateChildType(Type before, Type after, string methodName)
379 {
380 if (before.IsValueType)
381 {
382 if (TypeUtils.AreEquivalent(before, after))
383 {
384 return;
385 }
386 }
387 else if (!after.IsValueType)
388 {
389 return;
390 }
391 throw Error.MustRewriteChildToSameType(before, after, methodName);
392 }
393
394 protected internal virtual Expression VisitDynamic(DynamicExpression node)
395 {
397 if (array == null)
398 {
399 return node;
400 }
401 return node.Rewrite(array);
402 }
403}
static void RequiresNotNull(object value, string paramName)
static ParameterExpression[] VisitParameters(ExpressionVisitor visitor, IParameterProvider nodes, string callerName)
static Expression[] VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
static Expression[] VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
static bool AreEquivalent(Type t1, Type t2)
Definition TypeUtils.cs:664
BinaryExpression Update(Expression left, LambdaExpression? conversion, Expression right)
virtual BlockExpression Rewrite(ReadOnlyCollection< ParameterExpression > variables, Expression[] args)
ReadOnlyCollection< ParameterExpression > Variables
ParameterExpression? Variable
Definition CatchBlock.cs:8
CatchBlock Update(ParameterExpression? variable, Expression? filter, Expression body)
Definition CatchBlock.cs:29
ConditionalExpression Update(Expression test, Expression ifTrue, Expression ifFalse)
virtual DynamicExpression Rewrite(Expression[] args)
ReadOnlyCollection< Expression > Arguments
ElementInit Update(IEnumerable< Expression > arguments)
static Exception MustRewriteChildToSameType(object p0, object p1, object p2)
Definition Error.cs:788
static Exception UnhandledBindingType(object p0)
Definition Error.cs:643
static Exception MustRewriteWithoutMethod(object p0, object p1)
Definition Error.cs:793
static Exception MustRewriteToSameNode(object p0, object p1, object p2)
Definition Error.cs:783
virtual Expression VisitIndex(IndexExpression node)
static void ValidateChildType(Type before, Type after, string methodName)
virtual MemberAssignment VisitMemberAssignment(MemberAssignment node)
virtual ? Expression Visit(Expression? node)
virtual Expression VisitNew(NewExpression node)
static BinaryExpression ValidateBinary(BinaryExpression before, BinaryExpression after)
virtual Expression VisitBlock(BlockExpression node)
virtual Expression VisitParameter(ParameterExpression node)
Expression[] VisitArguments(IArgumentProvider nodes)
virtual Expression VisitListInit(ListInitExpression node)
virtual SwitchCase VisitSwitchCase(SwitchCase node)
virtual Expression VisitLambda< T >(Expression< T > node)
virtual Expression VisitMember(MemberExpression node)
virtual MemberListBinding VisitMemberListBinding(MemberListBinding node)
virtual Expression VisitLabel(LabelExpression node)
static SwitchExpression ValidateSwitch(SwitchExpression before, SwitchExpression after)
virtual Expression VisitUnary(UnaryExpression node)
virtual Expression VisitMethodCall(MethodCallExpression node)
virtual Expression VisitExtension(Expression node)
virtual Expression VisitDynamic(DynamicExpression node)
virtual Expression VisitTry(TryExpression node)
T? VisitAndConvert< T >(T? node, string? callerName)
virtual Expression VisitDebugInfo(DebugInfoExpression node)
virtual Expression VisitConditional(ConditionalExpression node)
static ReadOnlyCollection< T > Visit< T >(ReadOnlyCollection< T > nodes, Func< T, T > elementVisitor)
virtual Expression VisitInvocation(InvocationExpression node)
virtual Expression VisitGoto(GotoExpression node)
virtual ? LabelTarget VisitLabelTarget(LabelTarget? node)
virtual Expression VisitTypeBinary(TypeBinaryExpression node)
static UnaryExpression ValidateUnary(UnaryExpression before, UnaryExpression after)
virtual Expression VisitConstant(ConstantExpression node)
virtual Expression VisitMemberInit(MemberInitExpression node)
virtual Expression VisitRuntimeVariables(RuntimeVariablesExpression node)
ParameterExpression[] VisitParameters(IParameterProvider nodes, string callerName)
virtual MemberBinding VisitMemberBinding(MemberBinding node)
virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding node)
ReadOnlyCollection< Expression > Visit(ReadOnlyCollection< Expression > nodes)
virtual CatchBlock VisitCatchBlock(CatchBlock node)
virtual Expression VisitLoop(LoopExpression node)
virtual Expression VisitNewArray(NewArrayExpression node)
virtual ElementInit VisitElementInit(ElementInit node)
virtual Expression VisitSwitch(SwitchExpression node)
virtual Expression VisitDefault(DefaultExpression node)
virtual Expression VisitBinary(BinaryExpression node)
virtual Expression Accept(ExpressionVisitor visitor)
virtual Expression VisitChildren(ExpressionVisitor visitor)
virtual Expression< TDelegate > Rewrite(Expression body, ParameterExpression[] parameters)
GotoExpression Update(LabelTarget target, Expression? value)
Expression Rewrite(Expression instance, Expression[] arguments)
virtual InvocationExpression Rewrite(Expression lambda, Expression[] arguments)
LabelExpression Update(LabelTarget target, Expression? defaultValue)
ListInitExpression Update(NewExpression newExpression, IEnumerable< ElementInit > initializers)
ReadOnlyCollection< ElementInit > Initializers
LoopExpression Update(LabelTarget? breakLabel, LabelTarget? continueLabel, Expression body)
MemberAssignment Update(Expression expression)
MemberExpression Update(Expression? expression)
ReadOnlyCollection< MemberBinding > Bindings
MemberInitExpression Update(NewExpression newExpression, IEnumerable< MemberBinding > bindings)
MemberListBinding Update(IEnumerable< ElementInit > initializers)
ReadOnlyCollection< ElementInit > Initializers
MemberMemberBinding Update(IEnumerable< MemberBinding > bindings)
ReadOnlyCollection< MemberBinding > Bindings
virtual MethodCallExpression Rewrite(Expression instance, IReadOnlyList< Expression > args)
ReadOnlyCollection< Expression > Expressions
NewArrayExpression Update(IEnumerable< Expression > expressions)
NewExpression Update(IEnumerable< Expression >? arguments)
ReadOnlyCollection< ParameterExpression > Variables
RuntimeVariablesExpression Update(IEnumerable< ParameterExpression > variables)
SwitchCase Update(IEnumerable< Expression > testValues, Expression body)
Definition SwitchCase.cs:26
ReadOnlyCollection< Expression > TestValues
Definition SwitchCase.cs:11
ReadOnlyCollection< SwitchCase > Cases
SwitchExpression Update(Expression switchValue, IEnumerable< SwitchCase >? cases, Expression? defaultBody)
ReadOnlyCollection< CatchBlock > Handlers
TryExpression Update(Expression body, IEnumerable< CatchBlock >? handlers, Expression? @finally, Expression? fault)
TypeBinaryExpression Update(Expression expression)
UnaryExpression Update(Expression operand)
bool IsValueType
Definition Type.cs:234