2 // ExpressionVisitor.cs
5 // Jb Evain (jbevain@novell.com)
7 // (C) 2008 Novell, Inc. (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections.ObjectModel;
32 namespace System.Linq.Expressions {
34 abstract class ExpressionVisitor {
36 protected ExpressionVisitor ()
40 protected virtual void Visit (Expression expression)
42 if (expression == null)
45 switch (expression.NodeType) {
46 case ExpressionType.Negate:
47 case ExpressionType.NegateChecked:
48 case ExpressionType.Not:
49 case ExpressionType.Convert:
50 case ExpressionType.ConvertChecked:
51 case ExpressionType.ArrayLength:
52 case ExpressionType.Quote:
53 case ExpressionType.TypeAs:
54 case ExpressionType.UnaryPlus:
55 VisitUnary ((UnaryExpression) expression);
57 case ExpressionType.Add:
58 case ExpressionType.AddChecked:
59 case ExpressionType.Subtract:
60 case ExpressionType.SubtractChecked:
61 case ExpressionType.Multiply:
62 case ExpressionType.MultiplyChecked:
63 case ExpressionType.Divide:
64 case ExpressionType.Modulo:
65 case ExpressionType.And:
66 case ExpressionType.AndAlso:
67 case ExpressionType.Or:
68 case ExpressionType.OrElse:
69 case ExpressionType.LessThan:
70 case ExpressionType.LessThanOrEqual:
71 case ExpressionType.GreaterThan:
72 case ExpressionType.GreaterThanOrEqual:
73 case ExpressionType.Equal:
74 case ExpressionType.NotEqual:
75 case ExpressionType.Coalesce:
76 case ExpressionType.ArrayIndex:
77 case ExpressionType.RightShift:
78 case ExpressionType.LeftShift:
79 case ExpressionType.ExclusiveOr:
80 VisitBinary ((BinaryExpression) expression);
82 case ExpressionType.TypeIs:
83 VisitTypeIs ((TypeBinaryExpression) expression);
85 case ExpressionType.Conditional:
86 VisitConditional ((ConditionalExpression) expression);
88 case ExpressionType.Constant:
89 VisitConstant ((ConstantExpression) expression);
91 case ExpressionType.Parameter:
92 VisitParameter ((ParameterExpression) expression);
94 case ExpressionType.MemberAccess:
95 VisitMemberAccess ((MemberExpression) expression);
97 case ExpressionType.Call:
98 VisitMethodCall ((MethodCallExpression) expression);
100 case ExpressionType.Lambda:
101 VisitLambda ((LambdaExpression) expression);
103 case ExpressionType.New:
104 VisitNew ((NewExpression) expression);
106 case ExpressionType.NewArrayInit:
107 case ExpressionType.NewArrayBounds:
108 VisitNewArray ((NewArrayExpression) expression);
110 case ExpressionType.Invoke:
111 VisitInvocation ((InvocationExpression) expression);
113 case ExpressionType.MemberInit:
114 VisitMemberInit ((MemberInitExpression) expression);
116 case ExpressionType.ListInit:
117 VisitListInit ((ListInitExpression) expression);
120 throw new ArgumentException (string.Format ("Unhandled expression type: '{0}'", expression.NodeType));
124 protected virtual void VisitBinding (MemberBinding binding)
126 switch (binding.BindingType) {
127 case MemberBindingType.Assignment:
128 VisitMemberAssignment ((MemberAssignment) binding);
130 case MemberBindingType.MemberBinding:
131 VisitMemberMemberBinding ((MemberMemberBinding) binding);
133 case MemberBindingType.ListBinding:
134 VisitMemberListBinding ((MemberListBinding) binding);
137 throw new ArgumentException (string.Format ("Unhandled binding type '{0}'", binding.BindingType));
141 protected virtual void VisitElementInitializer (ElementInit initializer)
143 VisitExpressionList (initializer.Arguments);
146 protected virtual void VisitUnary (UnaryExpression unary)
148 Visit (unary.Operand);
151 protected virtual void VisitBinary (BinaryExpression binary)
154 Visit (binary.Right);
155 Visit (binary.Conversion);
158 protected virtual void VisitTypeIs (TypeBinaryExpression type)
160 Visit (type.Expression);
163 protected virtual void VisitConstant (ConstantExpression constant)
167 protected virtual void VisitConditional (ConditionalExpression conditional)
169 Visit (conditional.Test);
170 Visit (conditional.IfTrue);
171 Visit (conditional.IfFalse);
174 protected virtual void VisitParameter (ParameterExpression parameter)
178 protected virtual void VisitMemberAccess (MemberExpression member)
180 Visit (member.Expression);
183 protected virtual void VisitMethodCall (MethodCallExpression methodCall)
185 Visit (methodCall.Object);
186 VisitExpressionList (methodCall.Arguments);
189 protected virtual void VisitList<T> (ReadOnlyCollection<T> list, Action<T> visitor)
191 foreach (T element in list) {
196 protected virtual void VisitExpressionList (ReadOnlyCollection<Expression> list)
198 VisitList (list, Visit);
201 protected virtual void VisitMemberAssignment (MemberAssignment assignment)
203 Visit (assignment.Expression);
206 protected virtual void VisitMemberMemberBinding (MemberMemberBinding binding)
208 VisitBindingList (binding.Bindings);
211 protected virtual void VisitMemberListBinding (MemberListBinding binding)
213 VisitElementInitializerList (binding.Initializers);
216 protected virtual void VisitBindingList (ReadOnlyCollection<MemberBinding> list)
218 VisitList (list, VisitBinding);
221 protected virtual void VisitElementInitializerList (ReadOnlyCollection<ElementInit> list)
223 VisitList (list, VisitElementInitializer);
226 protected virtual void VisitLambda (LambdaExpression lambda)
231 protected virtual void VisitNew (NewExpression nex)
233 VisitExpressionList (nex.Arguments);
236 protected virtual void VisitMemberInit (MemberInitExpression init)
238 VisitNew (init.NewExpression);
239 VisitBindingList (init.Bindings);
242 protected virtual void VisitListInit (ListInitExpression init)
244 VisitNew (init.NewExpression);
245 VisitElementInitializerList (init.Initializers);
248 protected virtual void VisitNewArray (NewArrayExpression newArray)
250 VisitExpressionList (newArray.Expressions);
253 protected virtual void VisitInvocation (InvocationExpression invocation)
255 VisitExpressionList (invocation.Arguments);
256 Visit (invocation.Expression);