refactoring
[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 using System;
30 using System.Collections.ObjectModel;
31
32 namespace System.Linq.Expressions {
33
34         abstract class ExpressionVisitor {
35
36                 protected ExpressionVisitor ()
37                 {
38                 }
39
40                 protected virtual void Visit (Expression expression)
41                 {
42                         if (expression == null)
43                                 return;
44
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);
56                                 break;
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);
81                                 break;
82                         case ExpressionType.TypeIs:
83                                 VisitTypeIs ((TypeBinaryExpression) expression);
84                                 break;
85                         case ExpressionType.Conditional:
86                                 VisitConditional ((ConditionalExpression) expression);
87                                 break;
88                         case ExpressionType.Constant:
89                                 VisitConstant ((ConstantExpression) expression);
90                                 break;
91                         case ExpressionType.Parameter:
92                                 VisitParameter ((ParameterExpression) expression);
93                                 break;
94                         case ExpressionType.MemberAccess:
95                                 VisitMemberAccess ((MemberExpression) expression);
96                                 break;
97                         case ExpressionType.Call:
98                                 VisitMethodCall ((MethodCallExpression) expression);
99                                 break;
100                         case ExpressionType.Lambda:
101                                 VisitLambda ((LambdaExpression) expression);
102                                 break;
103                         case ExpressionType.New:
104                                 VisitNew ((NewExpression) expression);
105                                 break;
106                         case ExpressionType.NewArrayInit:
107                         case ExpressionType.NewArrayBounds:
108                                 VisitNewArray ((NewArrayExpression) expression);
109                                 break;
110                         case ExpressionType.Invoke:
111                                 VisitInvocation ((InvocationExpression) expression);
112                                 break;
113                         case ExpressionType.MemberInit:
114                                 VisitMemberInit ((MemberInitExpression) expression);
115                                 break;
116                         case ExpressionType.ListInit:
117                                 VisitListInit ((ListInitExpression) expression);
118                                 break;
119                         default:
120                                 throw new ArgumentException (string.Format ("Unhandled expression type: '{0}'", expression.NodeType));
121                         }
122                 }
123
124                 protected virtual void VisitBinding (MemberBinding binding)
125                 {
126                         switch (binding.BindingType) {
127                         case MemberBindingType.Assignment:
128                                 VisitMemberAssignment ((MemberAssignment) binding);
129                                 break;
130                         case MemberBindingType.MemberBinding:
131                                 VisitMemberMemberBinding ((MemberMemberBinding) binding);
132                                 break;
133                         case MemberBindingType.ListBinding:
134                                 VisitMemberListBinding ((MemberListBinding) binding);
135                                 break;
136                         default:
137                                 throw new ArgumentException (string.Format ("Unhandled binding type '{0}'", binding.BindingType));
138                         }
139                 }
140
141                 protected virtual void VisitElementInitializer (ElementInit initializer)
142                 {
143                         VisitExpressionList (initializer.Arguments);
144                 }
145
146                 protected virtual void VisitUnary (UnaryExpression unary)
147                 {
148                         Visit (unary.Operand);
149                 }
150
151                 protected virtual void VisitBinary (BinaryExpression binary)
152                 {
153                         Visit (binary.Left);
154                         Visit (binary.Right);
155                         Visit (binary.Conversion);
156                 }
157
158                 protected virtual void VisitTypeIs (TypeBinaryExpression type)
159                 {
160                         Visit (type.Expression);
161                 }
162
163                 protected virtual void VisitConstant (ConstantExpression constant)
164                 {
165                 }
166
167                 protected virtual void VisitConditional (ConditionalExpression conditional)
168                 {
169                         Visit (conditional.Test);
170                         Visit (conditional.IfTrue);
171                         Visit (conditional.IfFalse);
172                 }
173
174                 protected virtual void VisitParameter (ParameterExpression parameter)
175                 {
176                 }
177
178                 protected virtual void VisitMemberAccess (MemberExpression member)
179                 {
180                         Visit (member.Expression);
181                 }
182
183                 protected virtual void VisitMethodCall (MethodCallExpression methodCall)
184                 {
185                         Visit (methodCall.Object);
186                         VisitExpressionList (methodCall.Arguments);
187                 }
188
189                 protected virtual void VisitList<T> (ReadOnlyCollection<T> list, Action<T> visitor)
190                 {
191                         foreach (T element in list) {
192                                 visitor (element);
193                         }
194                 }
195
196                 protected virtual void VisitExpressionList (ReadOnlyCollection<Expression> list)
197                 {
198                         VisitList (list, Visit);
199                 }
200
201                 protected virtual void VisitMemberAssignment (MemberAssignment assignment)
202                 {
203                         Visit (assignment.Expression);
204                 }
205
206                 protected virtual void VisitMemberMemberBinding (MemberMemberBinding binding)
207                 {
208                         VisitBindingList (binding.Bindings);
209                 }
210
211                 protected virtual void VisitMemberListBinding (MemberListBinding binding)
212                 {
213                         VisitElementInitializerList (binding.Initializers);
214                 }
215
216                 protected virtual void VisitBindingList (ReadOnlyCollection<MemberBinding> list)
217                 {
218                         VisitList (list, VisitBinding);
219                 }
220
221                 protected virtual void VisitElementInitializerList (ReadOnlyCollection<ElementInit> list)
222                 {
223                         VisitList (list, VisitElementInitializer);
224                 }
225
226                 protected virtual void VisitLambda (LambdaExpression lambda)
227                 {
228                         Visit (lambda.Body);
229                 }
230
231                 protected virtual void VisitNew (NewExpression nex)
232                 {
233                         VisitExpressionList (nex.Arguments);
234                 }
235
236                 protected virtual void VisitMemberInit (MemberInitExpression init)
237                 {
238                         VisitNew (init.NewExpression);
239                         VisitBindingList (init.Bindings);
240                 }
241
242                 protected virtual void VisitListInit (ListInitExpression init)
243                 {
244                         VisitNew (init.NewExpression);
245                         VisitElementInitializerList (init.Initializers);
246                 }
247
248                 protected virtual void VisitNewArray (NewArrayExpression newArray)
249                 {
250                         VisitExpressionList (newArray.Expressions);
251                 }
252
253                 protected virtual void VisitInvocation (InvocationExpression invocation)
254                 {
255                         VisitExpressionList (invocation.Arguments);
256                         Visit (invocation.Expression);
257                 }
258         }
259 }