2008-01-14 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / System.Core / System.Linq.Expressions / Expression.cs
1 //
2 // Expression.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@novell.com)
6 //   Miguel de Icaza (miguel@novell.com)
7 //
8 // (C) 2008 Novell, Inc. (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System;
31 using System.Collections.Generic;
32 using System.Collections.ObjectModel;
33 using System.Reflection;
34
35 namespace System.Linq.Expressions {
36
37         public abstract class Expression {
38
39                 ExpressionType node_type;
40                 Type type;
41
42                 public ExpressionType NodeType {
43                         get { return node_type; }
44                 }
45
46                 public Type Type {
47                         get { return type; }
48                 }
49
50                 // TODO: remove when all Expression subtypes
51                 // have their constructor implemented
52                 protected Expression ()
53                 {
54                 }
55
56                 protected Expression (ExpressionType node_type, Type type)
57                 {
58                         this.node_type = node_type;
59                         this.type = type;
60                 }
61
62                 public override string ToString ()
63                 {
64                         return ExpressionPrinter.ToString (this);
65                 }
66
67 #region Binary Expressions
68
69                 static void BinaryCoreCheck (Expression left, Expression right)
70                 {
71                         if (left == null)
72                                 throw new ArgumentNullException ("left");
73                         if (right == null)
74                                 throw new ArgumentNullException ("right");
75
76                         if (left.Type != right.Type)
77                                 throw new InvalidOperationException ("Both expressions must have the same type");
78                 }
79
80                 static BinaryExpression MakeSimpleBinary (ExpressionType et, Expression left, Expression right, MethodInfo method)
81                 {
82                         return new BinaryExpression (et, left.Type, left, right, method);
83                 }
84
85                 static BinaryExpression MakeSimpleBinary (ExpressionType et, Type result, Expression left, Expression right, MethodInfo method)
86                 {
87                         return new BinaryExpression (et, result, left, right, method);
88                 }
89
90                 static BinaryExpression MakeBoolBinary (ExpressionType et, Expression left, Expression right, bool liftToNull, MethodInfo method)
91                 {
92                         return new BinaryExpression (et, typeof (bool), left, right, method);
93                 }
94
95                 //
96                 // Arithmetic
97                 //
98                 public static BinaryExpression Add (Expression left, Expression right)
99                 {
100                         return Add (left, right, null);
101                 }
102
103                 public static BinaryExpression Add (Expression left, Expression right, MethodInfo method)
104                 {
105                         BinaryCoreCheck (left, right);
106
107                         return MakeSimpleBinary (ExpressionType.Add, left, right, method);
108                 }
109
110                 public static BinaryExpression AddChecked (Expression left, Expression right)
111                 {
112                         return AddChecked (left, right, null);
113                 }
114
115                 public static BinaryExpression AddChecked (Expression left, Expression right, MethodInfo method)
116                 {
117                         return MakeSimpleBinary (ExpressionType.AddChecked, left, right, method);
118                 }
119
120                 public static BinaryExpression Subtract (Expression left, Expression right)
121                 {
122                         return Subtract (left, right, null);
123                 }
124
125                 public static BinaryExpression Subtract (Expression left, Expression right, MethodInfo method)
126                 {
127                         BinaryCoreCheck (left, right);
128                         return MakeSimpleBinary (ExpressionType.Subtract, left, right, method);
129                 }
130
131                 public static BinaryExpression SubtractChecked (Expression left, Expression right)
132                 {
133                         return SubtractChecked (left, right, null);
134                 }
135
136                 public static BinaryExpression SubtractChecked (Expression left, Expression right, MethodInfo method)
137                 {
138                         BinaryCoreCheck (left, right);
139                         return MakeSimpleBinary (ExpressionType.SubtractChecked, left, right, method);
140                 }
141
142                 public static BinaryExpression Modulo (Expression left, Expression right)
143                 {
144                         return Modulo (left, right, null);
145                 }
146
147                 public static BinaryExpression Modulo (Expression left, Expression right, MethodInfo method)
148                 {
149                         BinaryCoreCheck (left, right);
150                         
151                         return MakeSimpleBinary (ExpressionType.Modulo, left, right, method);
152                 }
153
154                 public static BinaryExpression Multiply (Expression left, Expression right)
155                 {
156                         return Multiply (left, right);
157                 }
158
159                 public static BinaryExpression Multiply (Expression left, Expression right, MethodInfo method)
160                 {
161                         BinaryCoreCheck (left, right);
162
163                         return MakeSimpleBinary (ExpressionType.Multiply, left, right, method);
164                 }
165
166                 public static BinaryExpression MultiplyChecked (Expression left, Expression right)
167                 {
168                         return MultiplyChecked (left, right, null);
169                 }
170
171                 public static BinaryExpression MultiplyChecked (Expression left, Expression right, MethodInfo method)
172                 {
173                         BinaryCoreCheck (left, right);
174
175                         return MakeSimpleBinary (ExpressionType.MultiplyChecked, left, right, method);
176                 }
177
178                 public static BinaryExpression Divide (Expression left, Expression right)
179                 {
180                         return Divide (left, right, null);
181                 }
182
183                 public static BinaryExpression Divide (Expression left, Expression right, MethodInfo method)
184                 {
185                         BinaryCoreCheck (left, right);
186
187                         return MakeSimpleBinary (ExpressionType.Divide, left, right, method);
188                 }
189
190                 public static BinaryExpression Power (Expression left, Expression right)
191                 {
192                         return Power (left, right, null);
193                 }
194
195                 public static BinaryExpression Power (Expression left, Expression right, MethodInfo method)
196                 {
197                         BinaryCoreCheck (left, right);
198
199                         if (left.Type != typeof (double))
200                                 throw new InvalidOperationException ("Power only supports double arguments");
201                         
202                         return MakeSimpleBinary (ExpressionType.Power, left, right, method);
203                 }
204
205                 //
206                 // Bitwise
207                 //
208                 static bool IsInt (Type t)
209                 {
210                         return
211                                 t == typeof (int)   || t == typeof (uint) ||
212                                 t == typeof (short) || t == typeof (ushort) ||
213                                 t == typeof (long)  || t == typeof (ulong);
214                 }
215                 
216                 public static BinaryExpression And (Expression left, Expression right)
217                 {
218                         return And (left, right, null);
219                 }
220
221                 public static BinaryExpression And (Expression left, Expression right, MethodInfo method)
222                 {
223                         BinaryCoreCheck (left, right);
224
225                         if (left.Type == typeof (bool) || IsInt (left.Type))
226                                 return MakeSimpleBinary (ExpressionType.And, left, right, method);
227
228                         throw new InvalidOperationException ("Only integral or bool types allowed");
229                 }
230
231                 public static BinaryExpression Or (Expression left, Expression right)
232                 {
233                         return Or (left, right, null);
234                 }
235
236                 public static BinaryExpression Or (Expression left, Expression right, MethodInfo method)
237                 {
238                         BinaryCoreCheck (left, right);
239
240                         if (left.Type == typeof (bool) || IsInt (left.Type))
241                                 return MakeSimpleBinary (ExpressionType.Or, left, right, method);
242
243                         throw new InvalidOperationException ("Only integral or bool types allowed");
244                 }
245
246                 public static BinaryExpression ExclusiveOr (Expression left, Expression right)
247                 {
248                         return ExclusiveOr (left, right);
249                 }
250
251                 public static BinaryExpression ExclusiveOr (Expression left, Expression right, MethodInfo method)
252                 {
253                         BinaryCoreCheck (left, right);
254
255                         if (left.Type == typeof (bool) || IsInt (left.Type))
256                                 return MakeSimpleBinary (ExpressionType.ExclusiveOr, left, right, method);
257
258                         throw new InvalidOperationException ("Only integral or bool types allowed");
259                 }
260
261                 public static BinaryExpression LeftShift (Expression left, Expression right)
262                 {
263                         return LeftShift (left, right, null);
264                 }
265
266                 public static BinaryExpression LeftShift (Expression left, Expression right, MethodInfo method)
267                 {
268                         BinaryCoreCheck (left, right);
269
270                         if (left.Type == typeof (int))
271                                 return MakeSimpleBinary (ExpressionType.LeftShift, left, right, method);
272
273                         throw new InvalidOperationException ("Only int32 is allowed for shifts");
274                 }
275
276                 public static BinaryExpression RightShift (Expression left, Expression right)
277                 {
278                         return RightShift (left, right);
279                 }
280
281                 public static BinaryExpression RightShift (Expression left, Expression right, MethodInfo method)
282                 {
283                         BinaryCoreCheck (left, right);
284                         if (left.Type == typeof (int))
285                                 return MakeSimpleBinary (ExpressionType.RightShift, left, right, method);
286
287                         throw new InvalidOperationException ("Only int32 is allowed for shifts");
288                 }
289
290                 //
291                 // Short-circuit
292                 //
293                 public static BinaryExpression AndAlso (Expression left, Expression right)
294                 {
295                         return AndAlso (left, right, null);
296                 }
297
298                 [MonoTODO]
299                 public static BinaryExpression AndAlso (Expression left, Expression right, MethodInfo method)
300                 {
301                         // This does not work with int, int pairs;   Figure out when its valid
302                         
303                         throw new NotImplementedException ();
304                 }
305
306                 [MonoTODO]
307                 public static BinaryExpression OrElse (Expression left, Expression right)
308                 {
309                         throw new NotImplementedException ();
310                 }
311
312                 [MonoTODO]
313                 public static BinaryExpression OrElse (Expression left, Expression right, MethodInfo method)
314                 {
315                         throw new NotImplementedException ();
316                 }
317
318                 //
319                 // Comparison
320                 //
321                 public static BinaryExpression Equal (Expression left, Expression right)
322                 {
323                         return Equal (left, right, false, null);
324                 }
325
326                 public static BinaryExpression Equal (Expression left, Expression right, bool liftToNull, MethodInfo method)
327                 {
328                         BinaryCoreCheck (left, right);
329
330                         return MakeBoolBinary (ExpressionType.Equal, left, right, liftToNull, method);
331                 }
332
333                 public static BinaryExpression NotEqual (Expression left, Expression right)
334                 {
335                         return NotEqual (left, right, false, null);
336                 }
337
338
339                 public static BinaryExpression NotEqual (Expression left, Expression right, bool liftToNull, MethodInfo method)
340                 {
341                         BinaryCoreCheck (left, right);
342
343                         return MakeBoolBinary (ExpressionType.NotEqual, left, right, liftToNull, method);
344                 }
345
346                 public static BinaryExpression GreaterThan (Expression left, Expression right)
347                 {
348                         return GreaterThan (left, right, false, null);
349                 }
350
351                 public static BinaryExpression GreaterThan (Expression left, Expression right, bool liftToNull, MethodInfo method)
352                 {
353                         BinaryCoreCheck (left, right);
354
355                         return MakeBoolBinary (ExpressionType.GreaterThan, left, right, liftToNull, method);
356                 }
357
358                 public static BinaryExpression GreaterThanOrEqual (Expression left, Expression right)
359                 {
360                         return GreaterThanOrEqual (left, right, false, null);
361                 }
362
363
364                 public static BinaryExpression GreaterThanOrEqual (Expression left, Expression right, bool liftToNull, MethodInfo method)
365                 {
366                         BinaryCoreCheck (left, right);
367
368                         return MakeBoolBinary (ExpressionType.GreaterThanOrEqual, left, right, liftToNull, method);
369                 }
370
371                 public static BinaryExpression LessThan (Expression left, Expression right)
372                 {
373                         return LessThan (left, right, false, null);
374                 }
375
376                 public static BinaryExpression LessThan (Expression left, Expression right, bool liftToNull, MethodInfo method)
377                 {
378                         return MakeBoolBinary (ExpressionType.LessThan, left, right, liftToNull, method);
379                 }
380
381                 public static BinaryExpression LessThanOrEqual (Expression left, Expression right)
382                 {
383                         return LessThanOrEqual (left, right, false, null);
384                 }
385
386                 public static BinaryExpression LessThanOrEqual (Expression left, Expression right, bool liftToNull, MethodInfo method)
387                 {
388                         BinaryCoreCheck (left, right);
389
390                         return MakeBoolBinary (ExpressionType.LessThanOrEqual, left, right, liftToNull, method);
391                 }
392
393                 //
394                 // Miscelaneous
395                 //
396                 [MonoTODO]
397                 public static BinaryExpression ArrayIndex (Expression left, Expression index)
398                 {
399                         throw new NotImplementedException ();
400                 }
401
402                 public static BinaryExpression Coalesce (Expression left, Expression right)
403                 {
404                         return Coalesce (left, right, null);
405                 }
406
407                 [MonoTODO]
408                 public static BinaryExpression Coalesce (Expression left, Expression right, LambdaExpression conversion)
409                 {
410                         BinaryCoreCheck (left, right);
411
412                         throw new NotImplementedException ();
413                 }
414
415                 //
416                 // MakeBinary constructors
417                 //
418                 public static BinaryExpression MakeBinary (ExpressionType binaryType, Expression left, Expression right)
419                 {
420                         return MakeBinary (binaryType, left, right, false, null);
421                 }
422
423                 public static BinaryExpression MakeBinary (ExpressionType binaryType, Expression left, Expression right, bool liftToNull, MethodInfo method)
424                 {
425                         return MakeBinary (binaryType, left, right, liftToNull, method, null);
426                 }
427
428                 public static BinaryExpression MakeBinary (ExpressionType binaryType, Expression left, Expression right, bool liftToNull, MethodInfo method, LambdaExpression conversion)
429                 {
430                         switch (binaryType) {
431                         case ExpressionType.Add:
432                                 return Add (left, right, method);
433                         case ExpressionType.AddChecked:
434                                 return AddChecked (left, right, method);
435                         case ExpressionType.AndAlso:
436                                 return AndAlso (left, right);
437                         case ExpressionType.Coalesce:
438                                 return Coalesce (left, right, conversion);
439                         case ExpressionType.Divide:
440                                 return Divide (left, right, method);
441                         case ExpressionType.Equal:
442                                 return Equal (left, right, liftToNull, method);
443                         case ExpressionType.ExclusiveOr:
444                                 return ExclusiveOr (left, right, method);
445                         case ExpressionType.GreaterThan:
446                                 return GreaterThan (left, right, liftToNull, method);
447                         case ExpressionType.GreaterThanOrEqual:
448                                 return GreaterThanOrEqual (left, right, liftToNull, method);
449                         case ExpressionType.LeftShift:
450                                 return LeftShift (left, right, method);
451                         case ExpressionType.LessThan:
452                                 return LessThan (left, right, liftToNull, method);
453                         case ExpressionType.LessThanOrEqual:
454                                 return LessThanOrEqual (left, right, liftToNull, method);
455                         case ExpressionType.Modulo:
456                                 return Modulo (left, right, method);
457                         case ExpressionType.Multiply:
458                                 return Multiply (left, right, method);
459                         case ExpressionType.MultiplyChecked:
460                                 return MultiplyChecked (left, right, method);
461                         case ExpressionType.NotEqual:
462                                 return NotEqual (left, right, liftToNull, method);
463                         case ExpressionType.OrElse:
464                                 return OrElse (left, right);
465                         case ExpressionType.Power:
466                                 return Power (left, right, method);
467                         case ExpressionType.RightShift:
468                                 return RightShift (left, right, method);
469                         case ExpressionType.Subtract:
470                                 return Subtract (left, right, method);
471                         case ExpressionType.SubtractChecked:
472                                 return SubtractChecked (left, right, method);
473                         case ExpressionType.And:
474                                 return And (left, right, method);
475                         case ExpressionType.Or:
476                                 return Or (left, right, method);
477                         }
478
479                         throw new ArgumentException ("MakeBinary expect a binary node type");
480                 }
481
482 #endregion
483         
484                 [MonoTODO]
485                 public static MethodCallExpression ArrayIndex (Expression left, params Expression [] indexes)
486                 {
487                         throw new NotImplementedException ();
488                 }
489
490                 [MonoTODO]
491                 public static MethodCallExpression ArrayIndex (Expression left, IEnumerable<Expression> indexes)
492                 {
493                         throw new NotImplementedException ();
494                 }
495
496                 public static UnaryExpression ArrayLength (Expression array)
497                 {
498                         if (array == null)
499                                 throw new ArgumentNullException ("array");
500                         if (!array.Type.IsArray)
501                                 throw new ArgumentException ("The type of the expression must me Array");
502                         if (array.Type.GetArrayRank () != 1)
503                                 throw new ArgumentException ("The array must be a single dimensional array");
504
505                         return new UnaryExpression (ExpressionType.ArrayLength, array, typeof (int));
506                 }
507
508                 [MonoTODO]
509                 public static MemberAssignment Bind (MemberInfo member, Expression expression)
510                 {
511                         throw new NotImplementedException ();
512                 }
513
514                 [MonoTODO]
515                 public static MemberAssignment Bind (MethodInfo propertyAccessor, Expression expression)
516                 {
517                         throw new NotImplementedException ();
518                 }
519
520                 [MonoTODO]
521                 public static MethodCallExpression Call (Expression instance, MethodInfo method)
522                 {
523                         throw new NotImplementedException ();
524                 }
525
526                 [MonoTODO]
527                 public static MethodCallExpression Call (MethodInfo method, params Expression [] arguments)
528                 {
529                         throw new NotImplementedException ();
530                 }
531
532                 [MonoTODO]
533                 public static MethodCallExpression Call (Expression instance, MethodInfo method, params Expression [] arguments)
534                 {
535                         throw new NotImplementedException ();
536                 }
537
538                 [MonoTODO]
539                 public static MethodCallExpression Call (Expression instance, MethodInfo method, IEnumerable<Expression> arguments)
540                 {
541                         throw new NotImplementedException ();
542                 }
543
544                 [MonoTODO]
545                 public static MethodCallExpression Call (Expression instance, string methodName, Type [] typeArguments, params Expression [] arguments)
546                 {
547                         throw new NotImplementedException ();
548                 }
549
550                 [MonoTODO]
551                 public static MethodCallExpression Call (Type type, string methodName, Type [] typeArguments, params Expression [] arguments)
552                 {
553                         throw new NotImplementedException ();
554                 }
555
556                 [MonoTODO]
557                 public static ConditionalExpression Condition (Expression test, Expression ifTrue, Expression ifFalse)
558                 {
559                         throw new NotImplementedException ();
560                 }
561
562                 public static ConstantExpression Constant (object value)
563                 {
564                         if (value == null)
565                                 return new ConstantExpression (null, typeof (object));
566
567                         return Constant (value, value.GetType ());
568                 }
569
570                 public static ConstantExpression Constant (object value, Type type)
571                 {
572                         if (type == null)
573                                 throw new ArgumentNullException ("type");
574
575                         //
576                         // value must be compatible with type, no conversions
577                         // are allowed
578                         //
579                         if (value == null){
580                                 if (type.IsValueType && !IsNullable (type))
581                                         throw new ArgumentException ();
582                         } else {
583                                 if (!(type.IsValueType && IsNullable (type)) && value.GetType () != type)
584                                         throw new ArgumentException ();
585
586                         }
587
588                         return new ConstantExpression (value, type);
589                 }
590
591                 [MonoTODO]
592                 public static UnaryExpression Convert (Expression expression, Type type)
593                 {
594                         throw new NotImplementedException ();
595                 }
596
597                 [MonoTODO]
598                 public static UnaryExpression Convert (Expression expression, Type type, MethodInfo method)
599                 {
600                         throw new NotImplementedException ();
601                 }
602
603                 [MonoTODO]
604                 public static UnaryExpression ConvertChecked (Expression expression, Type type)
605                 {
606                         throw new NotImplementedException ();
607                 }
608
609                 [MonoTODO]
610                 public static UnaryExpression ConvertChecked (Expression expression, Type type, MethodInfo method)
611                 {
612                         throw new NotImplementedException ();
613                 }
614
615                 [MonoTODO]
616                 public static ElementInit ElementInit (MethodInfo addMethod, params Expression [] arguments)
617                 {
618                         throw new NotImplementedException ();
619                 }
620
621                 [MonoTODO]
622                 public static ElementInit ElementInit (MethodInfo addMethod, IEnumerable<Expression> arguments)
623                 {
624                         throw new NotImplementedException ();
625                 }
626
627                 [MonoTODO]
628                 public static MemberExpression Field (Expression expression, FieldInfo field)
629                 {
630                         throw new NotImplementedException ();
631                 }
632
633                 [MonoTODO]
634                 public static MemberExpression Field (Expression expression, string fieldName)
635                 {
636                         throw new NotImplementedException ();
637                 }
638
639                 public static Type GetActionType (params Type [] typeArgs)
640                 {
641                         if (typeArgs == null)
642                                 throw new ArgumentNullException ("typeArgs");
643
644                         if (typeArgs.Length > 4)
645                                 throw new ArgumentException ("No Action type of this arity");
646
647                         if (typeArgs.Length == 0)
648                                 return typeof (Action);
649
650                         Type action = null;
651                         switch (typeArgs.Length) {
652                         case 1:
653                                 action = typeof (Action<>);
654                                 break;
655                         case 2:
656                                 action = typeof (Action<,>);
657                                 break;
658                         case 3:
659                                 action = typeof (Action<,,>);
660                                 break;
661                         case 4:
662                                 action = typeof (Action<,,,>);
663                                 break;
664                         }
665
666                         return action.MakeGenericType (typeArgs);
667                 }
668
669                 public static Type GetFuncType (params Type [] typeArgs)
670                 {
671                         if (typeArgs == null)
672                                 throw new ArgumentNullException ("typeArgs");
673
674                         if (typeArgs.Length < 1 || typeArgs.Length > 5)
675                                 throw new ArgumentException ("No Func type of this arity");
676
677                         Type func = null;
678                         switch (typeArgs.Length) {
679                         case 1:
680                                 func = typeof (Func<>);
681                                 break;
682                         case 2:
683                                 func = typeof (Func<,>);
684                                 break;
685                         case 3:
686                                 func = typeof (Func<,,>);
687                                 break;
688                         case 4:
689                                 func = typeof (Func<,,,>);
690                                 break;
691                         case 5:
692                                 func = typeof (Func<,,,,>);
693                                 break;
694                         }
695
696                         return func.MakeGenericType (typeArgs);
697                 }
698
699                 [MonoTODO]
700                 public static InvocationExpression Invoke (Expression expression, params Expression [] arguments)
701                 {
702                         throw new NotImplementedException ();
703                 }
704
705                 [MonoTODO]
706                 public static InvocationExpression Invoke (Expression expression, IEnumerable<Expression> arguments)
707                 {
708                         throw new NotImplementedException ();
709                 }
710
711                 [MonoTODO]
712                 public static Expression<TDelegate> Lambda<TDelegate> (Expression body, params ParameterExpression [] parameters)
713                 {
714                         throw new NotImplementedException ();
715                 }
716
717                 [MonoTODO]
718                 public static Expression<TDelegate> Lambda<TDelegate> (Expression body, IEnumerable<ParameterExpression> parameters)
719                 {
720                         throw new NotImplementedException ();
721                 }
722
723                 [MonoTODO]
724                 public static LambdaExpression Lambda (Expression body, params ParameterExpression [] parameters)
725                 {
726                         throw new NotImplementedException ();
727                 }
728
729                 [MonoTODO]
730                 public static LambdaExpression Lambda (Type delegateType, Expression body, params ParameterExpression [] parameters)
731                 {
732                         throw new NotImplementedException ();
733                 }
734
735                 [MonoTODO]
736                 public static LambdaExpression Lambda (Type delegateType, Expression body, IEnumerable<ParameterExpression> parameters)
737                 {
738                         throw new NotImplementedException ();
739                 }
740
741                 public static MemberListBinding ListBind (MemberInfo member, params ElementInit [] initializers)
742                 {
743                         throw new NotImplementedException ();
744                 }
745
746                 [MonoTODO]
747                 public static MemberListBinding ListBind (MemberInfo member, IEnumerable<ElementInit> initializers)
748                 {
749                         throw new NotImplementedException ();
750                 }
751
752                 [MonoTODO]
753                 public static MemberListBinding ListBind (MethodInfo propertyAccessor, params ElementInit [] initializers)
754                 {
755                         throw new NotImplementedException ();
756                 }
757
758                 [MonoTODO]
759                 public static MemberListBinding ListBind (MethodInfo propertyAccessor, IEnumerable<ElementInit> initializers)
760                 {
761                         throw new NotImplementedException ();
762                 }
763
764                 [MonoTODO]
765                 public static ListInitExpression ListInit (NewExpression newExpression, params ElementInit [] initializers)
766                 {
767                         throw new NotImplementedException ();
768                 }
769
770                 [MonoTODO]
771                 public static ListInitExpression ListInit (NewExpression newExpression, IEnumerable<ElementInit> initializers)
772                 {
773                         throw new NotImplementedException ();
774                 }
775
776                 [MonoTODO]
777                 public static ListInitExpression ListInit (NewExpression newExpression, params Expression [] initializers)
778                 {
779                         throw new NotImplementedException ();
780                 }
781
782                 [MonoTODO]
783                 public static ListInitExpression ListInit (NewExpression newExpression, IEnumerable<Expression> initializers)
784                 {
785                         throw new NotImplementedException ();
786                 }
787
788                 [MonoTODO]
789                 public static ListInitExpression ListInit (NewExpression newExpression, MethodInfo addMethod, params Expression [] initializers)
790                 {
791                         throw new NotImplementedException ();
792                 }
793
794                 [MonoTODO]
795                 public static ListInitExpression ListInit (NewExpression newExpression, MethodInfo addMethod, IEnumerable<Expression> initializers)
796                 {
797                         throw new NotImplementedException ();
798                 }
799
800                 [MonoTODO]
801                 public static MemberExpression MakeMemberAccess (Expression expression, MemberInfo member)
802                 {
803                         throw new NotImplementedException ();
804                 }
805
806                 public static UnaryExpression MakeUnary (ExpressionType unaryType, Expression operand, Type type)
807                 {
808                         return MakeUnary (unaryType, operand, type, null);
809                 }
810
811                 public static UnaryExpression MakeUnary (ExpressionType unaryType, Expression operand, Type type, MethodInfo method)
812                 {
813                         switch (unaryType) {
814                         case ExpressionType.ArrayLength:
815                                 return ArrayLength (operand);
816                         case ExpressionType.Convert:
817                                 return Convert (operand, type, method);
818                         case ExpressionType.ConvertChecked:
819                                 return ConvertChecked (operand, type, method);
820                         case ExpressionType.Negate:
821                                 return Negate (operand, method);
822                         case ExpressionType.NegateChecked:
823                                 return NegateChecked (operand, method);
824                         case ExpressionType.Not:
825                                 return Not (operand, method);
826                         case ExpressionType.Quote:
827                                 return Quote (operand);
828                         case ExpressionType.TypeAs:
829                                 return TypeAs (operand, type);
830                         case ExpressionType.UnaryPlus:
831                                 return UnaryPlus (operand, method);
832                         }
833
834                         throw new ArgumentException ("MakeUnary expect an unary operator");
835                 }
836
837                 [MonoTODO]
838                 public static MemberMemberBinding MemberBind (MemberInfo member, params MemberBinding [] binding)
839                 {
840                         throw new NotImplementedException ();
841                 }
842
843                 [MonoTODO]
844                 public static MemberMemberBinding MemberBind (MemberInfo member, IEnumerable<MemberBinding> binding)
845                 {
846                         throw new NotImplementedException ();
847                 }
848
849                 [MonoTODO]
850                 public static MemberMemberBinding MemberBind (MethodInfo propertyAccessor, params MemberBinding [] binding)
851                 {
852                         throw new NotImplementedException ();
853                 }
854
855                 [MonoTODO]
856                 public static MemberMemberBinding MemberBind (MethodInfo propertyAccessor, IEnumerable<MemberBinding> binding)
857                 {
858                         throw new NotImplementedException ();
859                 }
860
861                 [MonoTODO]
862                 public static MemberInitExpression MemberInit (NewExpression newExpression, params MemberBinding [] binding)
863                 {
864                         throw new NotImplementedException ();
865                 }
866
867                 [MonoTODO]
868                 public static MemberInitExpression MemberInit (NewExpression newExpression, IEnumerable<MemberBinding> binding)
869                 {
870                         throw new NotImplementedException ();
871                 }
872
873                 [MonoTODO]
874                 public static UnaryExpression Negate (Expression expression)
875                 {
876                         throw new NotImplementedException ();
877                 }
878
879                 [MonoTODO]
880                 public static UnaryExpression Negate (Expression expression, MethodInfo method)
881                 {
882                         throw new NotImplementedException ();
883                 }
884
885                 [MonoTODO]
886                 public static UnaryExpression NegateChecked (Expression expression)
887                 {
888                         throw new NotImplementedException ();
889                 }
890
891                 [MonoTODO]
892                 public static UnaryExpression NegateChecked (Expression expression, MethodInfo method)
893                 {
894                         throw new NotImplementedException ();
895                 }
896
897                 [MonoTODO]
898                 public static NewExpression New (ConstructorInfo constructor)
899                 {
900                         throw new NotImplementedException ();
901                 }
902
903                 [MonoTODO]
904                 public static NewExpression New (Type type)
905                 {
906                         throw new NotImplementedException ();
907                 }
908
909                 [MonoTODO]
910                 public static NewExpression New (ConstructorInfo constructor, params Expression [] arguments)
911                 {
912                         throw new NotImplementedException ();
913                 }
914
915                 [MonoTODO]
916                 public static NewExpression New (ConstructorInfo constructor, IEnumerable<Expression> arguments)
917                 {
918                         throw new NotImplementedException ();
919                 }
920
921                 [MonoTODO]
922                 public static NewExpression New (ConstructorInfo constructor, IEnumerable<Expression> arguments, params MemberInfo [] members)
923                 {
924                         throw new NotImplementedException ();
925                 }
926
927                 [MonoTODO]
928                 public static NewExpression New (ConstructorInfo constructor, IEnumerable<Expression> arguments, IEnumerable<MemberInfo> members)
929                 {
930                         throw new NotImplementedException ();
931                 }
932
933                 [MonoTODO]
934                 public static NewArrayExpression NewArrayBounds (Type type, params Expression [] bounds)
935                 {
936                         throw new NotImplementedException ();
937                 }
938
939                 [MonoTODO]
940                 public static NewArrayExpression NewArrayBounds (Type type, IEnumerable<Expression> bounds)
941                 {
942                         throw new NotImplementedException ();
943                 }
944
945                 [MonoTODO]
946                 public static NewArrayExpression NewArrayInit (Type type, params Expression [] bounds)
947                 {
948                         throw new NotImplementedException ();
949                 }
950
951                 [MonoTODO]
952                 public static NewArrayExpression NewArrayInit (Type type, IEnumerable<Expression> bounds)
953                 {
954                         throw new NotImplementedException ();
955                 }
956
957                 [MonoTODO]
958                 public static UnaryExpression Not (Expression expression)
959                 {
960                         throw new NotImplementedException ();
961                 }
962
963                 [MonoTODO]
964                 public static UnaryExpression Not (Expression expression, MethodInfo method)
965                 {
966                         throw new NotImplementedException ();
967                 }
968
969                 [MonoTODO]
970                 public static ParameterExpression Parameter (Type type, string name)
971                 {
972                         throw new NotImplementedException ();
973                 }
974
975                 [MonoTODO]
976                 public static MemberExpression Property (Expression expression, MethodInfo propertyAccessor)
977                 {
978                         throw new NotImplementedException ();
979                 }
980
981                 [MonoTODO]
982                 public static MemberExpression Property (Expression expression, PropertyInfo property)
983                 {
984                         throw new NotImplementedException ();
985                 }
986
987                 [MonoTODO]
988                 public static MemberExpression Property (Expression expression, string propertyName)
989                 {
990                         throw new NotImplementedException ();
991                 }
992
993                 [MonoTODO]
994                 public static MemberExpression PropertyOrField (Expression expression, string propertyOrFieldName)
995                 {
996                         throw new NotImplementedException ();
997                 }
998
999                 public static UnaryExpression Quote (Expression expression)
1000                 {
1001                         if (expression == null)
1002                                 throw new ArgumentNullException ("expression");
1003
1004                         return new UnaryExpression (ExpressionType.Quote, expression, expression.GetType ());
1005                 }
1006
1007                 public static UnaryExpression TypeAs (Expression expression, Type type)
1008                 {
1009                         if (expression == null)
1010                                 throw new ArgumentNullException ("expression");
1011                         if (type == null)
1012                                 throw new ArgumentNullException ("type");
1013                         if (type.IsValueType && !IsNullable (type))
1014                                 throw new ArgumentException ("TypeAs expect a reference or a nullable type");
1015
1016                         return new UnaryExpression (ExpressionType.TypeAs, expression, type);
1017                 }
1018
1019                 public static TypeBinaryExpression TypeIs (Expression expression, Type type)
1020                 {
1021                         if (expression == null)
1022                                 throw new ArgumentNullException ("expression");
1023                         if (type == null)
1024                                 throw new ArgumentNullException ("type");
1025
1026                         return new TypeBinaryExpression (ExpressionType.TypeIs, expression, type, typeof (bool));
1027                 }
1028
1029                 [MonoTODO]
1030                 public static UnaryExpression UnaryPlus (Expression expression)
1031                 {
1032                         throw new NotImplementedException ();
1033                 }
1034
1035                 [MonoTODO]
1036                 public static UnaryExpression UnaryPlus (Expression expression, MethodInfo method)
1037                 {
1038                         throw new NotImplementedException ();
1039                 }
1040
1041                 static bool IsNullable (Type type)
1042                 {
1043                         return type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Nullable<>);
1044                 }
1045         }
1046 }