9950ac8e018cce9ddf77eeaede297b10d6520f4e
[mono.git] / mcs / class / System.Core / System.Linq.Expressions / ExpressionVisitor.cs
1 //
2 // ExpressionVisitor.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@novell.com)
6 //
7 // (C) 2008 Novell, Inc. (http://www.novell.com)
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27 //
28
29 #if !NET_4_0
30
31 using System;
32 using System.Collections.ObjectModel;
33
34 namespace System.Linq.Expressions {
35
36         abstract class ExpressionVisitor {
37
38                 protected virtual void Visit (Expression expression)
39                 {
40                         if (expression == null)
41                                 return;
42
43                         switch (expression.NodeType) {
44                         case ExpressionType.Negate:
45                         case ExpressionType.NegateChecked:
46                         case ExpressionType.Not:
47                         case ExpressionType.Convert:
48                         case ExpressionType.ConvertChecked:
49                         case ExpressionType.ArrayLength:
50                         case ExpressionType.Quote:
51                         case ExpressionType.TypeAs:
52                         case ExpressionType.UnaryPlus:
53                                 VisitUnary ((UnaryExpression) expression);
54                                 break;
55                         case ExpressionType.Add:
56                         case ExpressionType.AddChecked:
57                         case ExpressionType.Subtract:
58                         case ExpressionType.SubtractChecked:
59                         case ExpressionType.Multiply:
60                         case ExpressionType.MultiplyChecked:
61                         case ExpressionType.Divide:
62                         case ExpressionType.Modulo:
63                         case ExpressionType.Power:
64                         case ExpressionType.And:
65                         case ExpressionType.AndAlso:
66                         case ExpressionType.Or:
67                         case ExpressionType.OrElse:
68                         case ExpressionType.LessThan:
69                         case ExpressionType.LessThanOrEqual:
70                         case ExpressionType.GreaterThan:
71                         case ExpressionType.GreaterThanOrEqual:
72                         case ExpressionType.Equal:
73                         case ExpressionType.NotEqual:
74                         case ExpressionType.Coalesce:
75                         case ExpressionType.ArrayIndex:
76                         case ExpressionType.RightShift:
77                         case ExpressionType.LeftShift:
78                         case ExpressionType.ExclusiveOr:
79                                 VisitBinary ((BinaryExpression) expression);
80                                 break;
81                         case ExpressionType.TypeIs:
82                                 VisitTypeIs ((TypeBinaryExpression) expression);
83                                 break;
84                         case ExpressionType.Conditional:
85                                 VisitConditional ((ConditionalExpression) expression);
86                                 break;
87                         case ExpressionType.Constant:
88                                 VisitConstant ((ConstantExpression) expression);
89                                 break;
90                         case ExpressionType.Parameter:
91                                 VisitParameter ((ParameterExpression) expression);
92                                 break;
93                         case ExpressionType.MemberAccess:
94                                 VisitMemberAccess ((MemberExpression) expression);
95                                 break;
96                         case ExpressionType.Call:
97                                 VisitMethodCall ((MethodCallExpression) expression);
98                                 break;
99                         case ExpressionType.Lambda:
100                                 VisitLambda ((LambdaExpression) expression);
101                                 break;
102                         case ExpressionType.New:
103                                 VisitNew ((NewExpression) expression);
104                                 break;
105                         case ExpressionType.NewArrayInit:
106                         case ExpressionType.NewArrayBounds:
107                                 VisitNewArray ((NewArrayExpression) expression);
108                                 break;
109                         case ExpressionType.Invoke:
110                                 VisitInvocation ((InvocationExpression) expression);
111                                 break;
112                         case ExpressionType.MemberInit:
113                                 VisitMemberInit ((MemberInitExpression) expression);
114                                 break;
115                         case ExpressionType.ListInit:
116                                 VisitListInit ((ListInitExpression) expression);
117                                 break;
118                         default:
119                                 throw new ArgumentException (string.Format ("Unhandled expression type: '{0}'", expression.NodeType));
120                         }
121                 }
122
123                 protected virtual void VisitBinding (MemberBinding binding)
124                 {
125                         switch (binding.BindingType) {
126                         case MemberBindingType.Assignment:
127                                 VisitMemberAssignment ((MemberAssignment) binding);
128                                 break;
129                         case MemberBindingType.MemberBinding:
130                                 VisitMemberMemberBinding ((MemberMemberBinding) binding);
131                                 break;
132                         case MemberBindingType.ListBinding:
133                                 VisitMemberListBinding ((MemberListBinding) binding);
134                                 break;
135                         default:
136                                 throw new ArgumentException (string.Format ("Unhandled binding type '{0}'", binding.BindingType));
137                         }
138                 }
139
140                 protected virtual void VisitElementInitializer (ElementInit initializer)
141                 {
142                         VisitExpressionList (initializer.Arguments);
143                 }
144
145                 protected virtual void VisitUnary (UnaryExpression unary)
146                 {
147                         Visit (unary.Operand);
148                 }
149
150                 protected virtual void VisitBinary (BinaryExpression binary)
151                 {
152                         Visit (binary.Left);
153                         Visit (binary.Right);
154                         Visit (binary.Conversion);
155                 }
156
157                 protected virtual void VisitTypeIs (TypeBinaryExpression type)
158                 {
159                         Visit (type.Expression);
160                 }
161
162                 protected virtual void VisitConstant (ConstantExpression constant)
163                 {
164                 }
165
166                 protected virtual void VisitConditional (ConditionalExpression conditional)
167                 {
168                         Visit (conditional.Test);
169                         Visit (conditional.IfTrue);
170                         Visit (conditional.IfFalse);
171                 }
172
173                 protected virtual void VisitParameter (ParameterExpression parameter)
174                 {
175                 }
176
177                 protected virtual void VisitMemberAccess (MemberExpression member)
178                 {
179                         Visit (member.Expression);
180                 }
181
182                 protected virtual void VisitMethodCall (MethodCallExpression methodCall)
183                 {
184                         Visit (methodCall.Object);
185                         VisitExpressionList (methodCall.Arguments);
186                 }
187
188                 protected virtual void VisitList<T> (ReadOnlyCollection<T> list, Action<T> visitor)
189                 {
190                         foreach (T element in list) {
191                                 visitor (element);
192                         }
193                 }
194
195                 protected virtual void VisitExpressionList (ReadOnlyCollection<Expression> list)
196                 {
197                         VisitList (list, Visit);
198                 }
199
200                 protected virtual void VisitMemberAssignment (MemberAssignment assignment)
201                 {
202                         Visit (assignment.Expression);
203                 }
204
205                 protected virtual void VisitMemberMemberBinding (MemberMemberBinding binding)
206                 {
207                         VisitBindingList (binding.Bindings);
208                 }
209
210                 protected virtual void VisitMemberListBinding (MemberListBinding binding)
211                 {
212                         VisitElementInitializerList (binding.Initializers);
213                 }
214
215                 protected virtual void VisitBindingList (ReadOnlyCollection<MemberBinding> list)
216                 {
217                         VisitList (list, VisitBinding);
218                 }
219
220                 protected virtual void VisitElementInitializerList (ReadOnlyCollection<ElementInit> list)
221                 {
222                         VisitList (list, VisitElementInitializer);
223                 }
224
225                 protected virtual void VisitLambda (LambdaExpression lambda)
226                 {
227                         Visit (lambda.Body);
228                 }
229
230                 protected virtual void VisitNew (NewExpression nex)
231                 {
232                         VisitExpressionList (nex.Arguments);
233                 }
234
235                 protected virtual void VisitMemberInit (MemberInitExpression init)
236                 {
237                         VisitNew (init.NewExpression);
238                         VisitBindingList (init.Bindings);
239                 }
240
241                 protected virtual void VisitListInit (ListInitExpression init)
242                 {
243                         VisitNew (init.NewExpression);
244                         VisitElementInitializerList (init.Initializers);
245                 }
246
247                 protected virtual void VisitNewArray (NewArrayExpression newArray)
248                 {
249                         VisitExpressionList (newArray.Expressions);
250                 }
251
252                 protected virtual void VisitInvocation (InvocationExpression invocation)
253                 {
254                         VisitExpressionList (invocation.Arguments);
255                         Visit (invocation.Expression);
256                 }
257         }
258 }
259
260 #endif