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