a128bcc43668c6ad54c857f8572f18ee553dd596
[mono.git] / mcs / mcs / expression.cs
1 //
2 // expression.cs: Expression representation for the IL tree.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.
8 //
9 namespace CIR {
10         using System.Collections;
11         using System.Diagnostics;
12         using System;
13         using System.Reflection;
14         using System.Reflection.Emit;
15
16         // <remarks>
17         //   The ExprClass class contains the is used to pass the 
18         //   classification of an expression (value, variable, namespace,
19         //   type, method group, property access, event access, indexer access,
20         //   nothing).
21         // </remarks>
22         public enum ExprClass {
23                 Invalid,
24                 
25                 Value, Variable, Namespace, Type,
26                 MethodGroup, PropertyAccess,
27                 EventAccess, IndexerAccess, Nothing, 
28         }
29
30         // <remarks>
31         //   Base class for expressions
32         // </remarks>
33         public abstract class Expression {
34                 protected ExprClass eclass;
35                 protected Type      type;
36                 
37                 public Type Type {
38                         get {
39                                 return type;
40                         }
41
42                         set {
43                                 type = value;
44                         }
45                 }
46
47                 public ExprClass ExprClass {
48                         get {
49                                 return eclass;
50                         }
51
52                         set {
53                                 eclass = value;
54                         }
55                 }
56
57                 public abstract Expression Resolve (TypeContainer tc);
58                 public abstract void Emit (EmitContext ec);
59                 
60                 // <summary>
61                 //   Protected constructor.  Only derivate types should
62                 //   be able to be created
63                 // </summary>
64
65                 protected Expression ()
66                 {
67                         eclass = ExprClass.Invalid;
68                         type = null;
69                 }
70
71                 // 
72                 // Returns a fully formed expression after a MemberLookup
73                 //
74                 static Expression ExprClassFromMemberInfo (MemberInfo mi)
75                 {
76                         if (mi is EventInfo){
77                                 return new EventExpr ((EventInfo) mi);
78                         } else if (mi is FieldInfo){
79                                 return new FieldExpr ((FieldInfo) mi);
80                         } else if (mi is PropertyInfo){
81                                 return new PropertyExpr ((PropertyInfo) mi);
82                         } else if (mi is Type)
83                                 return new TypeExpr ((Type) mi);
84
85                         return null;
86                 }
87                 
88                 //
89                 // FIXME: Probably implement a cache for (t,name,current_access_set)?
90                 //
91                 // FIXME: We need to cope with access permissions here, or this wont
92                 // work!
93                 //
94                 // This code could use some optimizations, but we need to do some
95                 // measurements.  For example, we could use a delegate to `flag' when
96                 // something can not any longer be a method-group (because it is something
97                 // else).
98                 //
99                 // Return values:
100                 //     If the return value is an Array, then it is an array of
101                 //     MethodInfos
102                 //   
103                 //     If the return value is an MemberInfo, it is anything, but a Method
104                 //
105                 //     null on error.
106                 //
107                 // FIXME: When calling MemberLookup inside an `Invocation', we should pass
108                 // the arguments here and have MemberLookup return only the methods that
109                 // match the argument count/type, unlike we are doing now (we delay this
110                 // decision).
111                 //
112                 // This is so we can catch correctly attempts to invoke instance methods
113                 // from a static body (scan for error 120 in ResolveSimpleName).
114                 // 
115                 protected static Expression MemberLookup (Report r, Type t, string name, bool same_type)
116                 {
117                         MemberTypes mt =
118                                 // MemberTypes.Constructor |
119                                 MemberTypes.Event       |
120                                 MemberTypes.Field       |
121                                 MemberTypes.Method      |
122                                 MemberTypes.NestedType  |
123                                 MemberTypes.Property;
124                         
125                         BindingFlags bf =
126                                 BindingFlags.Public |
127                                 BindingFlags.Static |
128                                 BindingFlags.Instance;
129                         
130                         if (same_type)
131                                 bf |= BindingFlags.NonPublic;
132
133                         
134                         MemberInfo [] mi = t.FindMembers (mt, bf, Type.FilterName, name);
135
136                         if (mi.Length == 1 && !(mi [0] is MethodInfo))
137                                 return Expression.ExprClassFromMemberInfo (mi [0]);
138
139                         for (int i = 0; i < mi.Length; i++)
140                                 if (!(mi [i] is MethodInfo)){
141                                         r.Error (-5, "Do not know how to reproduce this case: Methods and non-Method with the same name, report this please");
142                                         
143                                 }
144
145                         return new MethodGroupExpr (mi);
146                 }
147                 
148                 // <summary>
149                 //   Resolves the E in `E.I' side for a member_access
150                 //
151                 // This is suboptimal and should be merged with ResolveMemberAccess
152                 static Expression ResolvePrimary (TypeContainer tc, string name)
153                 {
154                         int dot_pos = name.LastIndexOf (".");
155
156                         if (tc.RootContext.IsNamespace (name))
157                                 return new NamespaceExpr (name);
158
159                         if (dot_pos != -1){
160                         } else {
161                                 Type t = tc.LookupType (name, false);
162
163                                 if (t != null)
164                                         return new TypeExpr (t);
165                         }
166
167                         return null;
168                 }
169                         
170                 static public Expression ResolveMemberAccess (TypeContainer tc, string name)
171                 {
172                         Expression left_e;
173                         int dot_pos = name.LastIndexOf (".");
174                         string left = name.Substring (0, dot_pos);
175                         string right = name.Substring (dot_pos + 1);
176
177                         left_e = ResolvePrimary (tc, left);
178                         if (left_e == null)
179                                 return null;
180
181                         switch (left_e.ExprClass){
182                         case ExprClass.Type:
183                                 return  MemberLookup (tc.RootContext.Report,
184                                                       left_e.Type, right,
185                                                       left_e.Type == tc.TypeBuilder);
186                                 
187                         case ExprClass.Namespace:
188                         case ExprClass.PropertyAccess:
189                         case ExprClass.IndexerAccess:
190                         case ExprClass.Variable:
191                         case ExprClass.Value:
192                         case ExprClass.Nothing:
193                         case ExprClass.EventAccess:
194                         case ExprClass.MethodGroup:
195                         case ExprClass.Invalid:
196                                 tc.RootContext.Report.Error (-1000,
197                                                              "Internal compiler error, should have " +
198                                                              "got these handled before");
199                                 break;
200                         }
201                         
202                         return null;
203                 }
204                 
205         }
206
207         public class Unary : Expression {
208                 public enum Operator {
209                         Plus, Minus, Negate, BitComplement,
210                         Indirection, AddressOf, PreIncrement,
211                         PreDecrement, PostIncrement, PostDecrement
212                 }
213
214                 Operator   oper;
215                 Expression expr;
216                 
217                 public Unary (Operator op, Expression expr)
218                 {
219                         this.oper = op;
220                         this.expr = expr;
221                 }
222
223                 public Expression Expr {
224                         get {
225                                 return expr;
226                         }
227
228                         set {
229                                 expr = value;
230                         }
231                 }
232
233                 public Operator Oper {
234                         get {
235                                 return oper;
236                         }
237
238                         set {
239                                 oper = value;
240                         }
241                 }
242
243                 public override Expression Resolve (TypeContainer tc)
244                 {
245                         // FIXME: Implement;
246                         return this;
247                 }
248
249                 public override void Emit (EmitContext ec)
250                 {
251                 }
252         }
253
254         public class Probe : Expression {
255                 string probe_type;
256                 Expression expr;
257                 Operator oper;
258
259                 public enum Operator {
260                         Is, As
261                 }
262                 
263                 public Probe (Operator oper, Expression expr, string probe_type)
264                 {
265                         this.oper = oper;
266                         this.probe_type = probe_type;
267                         this.expr = expr;
268                 }
269
270                 public Operator Oper {
271                         get {
272                                 return oper;
273                         }
274                 }
275
276                 public Expression Expr {
277                         get {
278                                 return expr;
279                         }
280                 }
281
282                 public string ProbeType {
283                         get {
284                                 return probe_type;
285                         }
286                 }
287
288                 public override Expression Resolve (TypeContainer tc)
289                 {
290                         // FIXME: Implement;
291                         return this;
292                 }
293
294                 public override void Emit (EmitContext ec)
295                 {
296                 }
297         }
298         
299         public class Cast : Expression {
300                 string target_type;
301                 Expression expr;
302                 
303                 public Cast (string cast_type, Expression expr)
304                 {
305                         this.target_type = target_type;
306                         this.expr = expr;
307                 }
308
309                 public string TargetType {
310                         get {
311                                 return target_type;
312                         }
313                 }
314
315                 public Expression Expr {
316                         get {
317                                 return expr;
318                         }
319                         set {
320                                 expr = value;
321                         }
322                 }
323                 
324                 public override Expression Resolve (TypeContainer tc)
325                 {
326                         // FIXME: Implement;
327                         return this;
328                 }
329
330                 public override void Emit (EmitContext ec)
331                 {
332                 }
333         }
334
335         public class Binary : Expression {
336                 public enum Operator {
337                         Multiply, Divide, Modulo,
338                         Add, Substract,
339                         ShiftLeft, ShiftRight,
340                         LessThan, GreatherThan, LessOrEqual, GreatherOrEqual, 
341                         Equal, NotEqual,
342                         BitwiseAnd,
343                         ExclusiveOr,
344                         BitwiseOr,
345                         LogicalAnd,
346                         LogicalOr
347                 }
348
349                 Operator oper;
350                 Expression left, right;
351
352                 OpCode opcode, opcode_check;
353                 
354                 public Binary (Operator oper, Expression left, Expression right)
355                 {
356                         this.oper = oper;
357                         this.left = left;
358                         this.right = right;
359                 }
360
361                 public Operator Oper {
362                         get {
363                                 return oper;
364                         }
365                         set {
366                                 oper = value;
367                         }
368                 }
369                 
370                 public Expression Left {
371                         get {
372                                 return left;
373                         }
374                         set {
375                                 left = value;
376                         }
377                 }
378
379                 public Expression Right {
380                         get {
381                                 return right;
382                         }
383                         set {
384                                 right = value;
385                         }
386                 }
387
388                 Expression ResolveOperator (Operator oper, Type l, Type r)
389                 {
390                         //
391                         // Step 1: Perform Operator Overload location
392                         //
393
394                         //
395                         // Step 2: Default operations
396                         //
397                         switch (oper){
398                         case Operator.Multiply:
399                                 opcode = OpCodes.Mul;
400                                 if (l == TypeManager.int32_type)
401                                         opcode_check = OpCodes.Mul_Ovf;
402                                 else if (l == TypeManager.uint32_type)
403                                         opcode_check = OpCodes.Mul_Ovf_Un;
404                                 else if (l == TypeManager.uint64_type) 
405                                         opcode_check = OpCodes.Mul_Ovf_Un;
406                                 else if (l == TypeManager.int64_type) 
407                                         opcode_check = OpCodes.Mul_Ovf;
408                                 else
409                                         opcode_check = OpCodes.Mul;
410                                 break;
411                         }
412
413                         return this;
414                 }
415                 
416                 public override Expression Resolve (TypeContainer tc)
417                 {
418                         left = left.Resolve (tc);
419                         right = right.Resolve (tc);
420
421                         if (left == null || right == null)
422                                 return null;
423                                         
424                         return ResolveOperator (oper, left.Type, right.Type);
425                 }
426
427                 public override void Emit (EmitContext ec)
428                 {
429                         ILGenerator ig = ec.ig;
430
431                         left.Emit (ec);
432                         right.Emit (ec);
433
434                         if (ec.CheckState)
435                                 ec.ig.Emit (opcode_check);
436                         else
437                                 ec.ig.Emit (opcode);
438                 }
439         }
440
441         public class Conditional : Expression {
442                 Expression expr, trueExpr, falseExpr;
443                 
444                 public Conditional (Expression expr, Expression trueExpr, Expression falseExpr)
445                 {
446                         this.expr = expr;
447                         this.trueExpr = trueExpr;
448                         this.falseExpr = falseExpr;
449                 }
450
451                 public Expression Expr {
452                         get {
453                                 return expr;
454                         }
455                 }
456
457                 public Expression TrueExpr {
458                         get {
459                                 return trueExpr;
460                         }
461                 }
462
463                 public Expression FalseExpr {
464                         get {
465                                 return falseExpr;
466                         }
467                 }
468
469                 public override Expression Resolve (TypeContainer tc)
470                 {
471                         // FIXME: Implement;
472                         return this;
473                 }
474
475                 public override void Emit (EmitContext ec)
476                 {
477                 }
478         }
479
480         public class SimpleName : Expression {
481                 string name;
482                 
483                 public SimpleName (string name)
484                 {
485                         this.name = name;
486                 }
487
488                 public string Name {
489                         get {
490                                 return name;
491                         }
492                 }
493
494                 //
495                 // Checks whether we are trying to access an instance
496                 // property, method or field from a static body.
497                 //
498                 Expression MemberStaticCheck (Report r, Expression e)
499                 {
500                         if (e is FieldExpr){
501                                 FieldInfo fi = ((FieldExpr) e).FieldInfo;
502                                 
503                                 if (!fi.IsStatic){
504                                         r.Error (120,
505                                                  "An object reference is required " +
506                                                  "for the non-static field `"+name+"'");
507                                         return null;
508                                 }
509                         } else if (e is MethodGroupExpr){
510                                 // FIXME: Pending reorganization of MemberLookup
511                                 // Basically at this point we should have the
512                                 // best match already selected for us, and
513                                 // we should only have to check a *single*
514                                 // Method for its static on/off bit.
515                                 return e;
516                         } else if (e is PropertyExpr){
517                                 if (!((PropertyExpr) e).IsStatic){
518                                         r.Error (120,
519                                                  "An object reference is required " +
520                                                  "for the non-static property access `"+
521                                                  name+"'");
522                                         return null;
523                                 }
524                         }
525
526                         return e;
527                 }
528                 
529                 //
530                 // 7.5.2: Simple Names. 
531                 //
532                 // Local Variables and Parameters are handled at
533                 // parse time, so they never occur as SimpleNames.
534                 //
535                 Expression ResolveSimpleName (TypeContainer tc)
536                 {
537                         Expression e;
538                         Report r = tc.RootContext.Report;
539
540                         e = MemberLookup (tc.RootContext.Report, tc.TypeBuilder, name, true);
541                         if (e != null){
542                                 if (e is TypeExpr)
543                                         return e;
544                                 if ((tc.ModFlags & Modifiers.STATIC) != 0)
545                                         return MemberStaticCheck (r, e);
546                                 else
547                                         return e;
548                         }
549
550                         //
551                         // Do step 3 of the Simple Name resolution.
552                         //
553                         // FIXME: implement me.
554                         
555                         return this;
556                 }
557                 
558                 //
559                 // SimpleName needs to handle a multitude of cases:
560                 //
561                 // simple_names and qualified_identifiers are placed on
562                 // the tree equally.
563                 //
564                 public override Expression Resolve (TypeContainer tc)
565                 {
566                         if (name.IndexOf (".") != -1)
567                                 return ResolveMemberAccess (tc, name);
568                         else
569                                 return ResolveSimpleName (tc);
570                 }
571
572                 public override void Emit (EmitContext ec)
573                 {
574                 }
575         }
576         
577         public class LocalVariableReference : Expression {
578                 public readonly string Name;
579                 public readonly Block Block;
580                 
581                 public LocalVariableReference (Block block, string name)
582                 {
583                         Block = block;
584                         Name = name;
585                         eclass = ExprClass.Variable;
586                 }
587
588                 public VariableInfo VariableInfo {
589                         get {
590                                 return (VariableInfo) Block.GetVariableInfo (Name);
591                         }
592                 }
593                 
594                 public override Expression Resolve (TypeContainer tc)
595                 {
596                         return this;
597                 }
598
599                 public override void Emit (EmitContext ec)
600                 {
601                         Console.WriteLine ("Internal compiler error, LocalVariableReference should not be emitted");
602                 }
603         }
604
605         public class ParameterReference : Expression {
606                 public readonly Parameters Pars;
607                 public readonly String Name;
608                 public readonly int Idx;
609                 
610                 public ParameterReference (Parameters pars, int idx, string name)
611                 {
612                         Pars = pars;
613                         Idx  = idx;
614                         Name = name;
615                 }
616
617                 public override Expression Resolve (TypeContainer tc)
618                 {
619                         // FIXME: Implement;
620                         return this;
621                 }
622
623                 public override void Emit (EmitContext ec)
624                 {
625                 }
626         }
627         
628         // <summary>
629         //   Used for arguments to New(), Invocation()
630         // </summary>
631         public class Argument {
632                 public enum AType {
633                         Expression,
634                         Ref,
635                         Out
636                 };
637
638                 public readonly AType Type;
639                 Expression expr;
640
641                 public Argument (Expression expr, AType type)
642                 {
643                         this.expr = expr;
644                         this.Type = type;
645                 }
646
647                 public Expression Expr {
648                         get {
649                                 return expr;
650                         }
651                 }
652
653                 public bool Resolve (TypeContainer tc)
654                 {
655                         expr = expr.Resolve (tc);
656                         return expr != null;
657                 }
658
659                 public void Emit (EmitContext ec)
660                 {
661                         expr.Emit (ec);
662                 }
663         }
664
665         // <summary>
666         //   Invocation of methods or delegates.
667         // </summary>
668         public class Invocation : Expression {
669                 public readonly ArrayList Arguments;
670                 Expression expr;
671                 MethodInfo method = null;
672                 
673                 //
674                 // arguments is an ArrayList, but we do not want to typecast,
675                 // as it might be null.
676                 //
677                 // FIXME: only allow expr to be a method invocation or a
678                 // delegate invocation (7.5.5)
679                 //
680                 public Invocation (Expression expr, ArrayList arguments)
681                 {
682                         this.expr = expr;
683                         Arguments = arguments;
684                 }
685
686                 public Expression Expr {
687                         get {
688                                 return expr;
689                         }
690                 }
691
692                 /// <summary>
693                 ///   Computes whether Argument `a' and the ParameterInfo `pi' are
694                 ///   compatible, and if so, how good is the match (in terms of
695                 ///   "better conversions" (7.4.2.3).
696                 ///
697                 ///   0   is the best possible match.
698                 ///   -1  represents a type mismatch.
699                 ///   -2  represents a ref/out mismatch.
700                 /// </summary>
701                 static int Badness (Argument a, ParameterInfo pi)
702                 {
703                         if (pi.ParameterType == a.Expr.Type)
704                                 return 0;
705
706                         // FIXME: Implement implicit conversions here.
707                         // FIXME: Implement better conversion here.
708                         
709                         return -1;
710                 }
711
712                 // <summary>
713                 //   Find the Applicable Function Members (7.4.2.1)
714                 // </summary>
715                 static MethodInfo OverloadResolve (MethodGroupExpr me, ArrayList Arguments)
716                 {
717                         ArrayList afm = new ArrayList ();
718                         int best_match = 10000;
719                         int best_match_idx = -1;
720                         MethodInfo method = null;
721                         
722                         for (int i = me.Methods.Length; i > 0; ){
723                                 i--;
724                                 ParameterInfo [] pi = me.Methods [i].GetParameters ();
725
726                                 //
727                                 // Compute how good this is
728                                 //
729                                 if (pi.Length == Arguments.Count){
730                                         int badness = 0;
731                                         
732                                         for (int j = Arguments.Count; j > 0;){
733                                                 int x;
734                                                 j--;
735
736                                                 Argument a = (Argument) Arguments [j];
737
738                                                 x = Badness (a, pi [j]);
739
740                                                 if (x < 0){
741                                                         // FIXME: report nice error.
742                                                 } else
743                                                         badness += x;
744                                         }
745
746                                         if (badness < best_match){
747                                                 best_match = badness;
748                                                 method = me.Methods [i];
749                                                 best_match_idx = i;
750                                         }
751                                 }
752                         }
753
754                         if (best_match_idx == -1)
755                                 return null;
756                         
757                         return method;
758                 }
759
760                         
761                 public override Expression Resolve (TypeContainer tc)
762                 {
763                         //
764                         // First, resolve the expression that is used to
765                         // trigger the invocation
766                         //
767                         this.expr = expr.Resolve (tc);
768                         if (this.expr == null)
769                                 return null;
770
771                         if (!(this.expr is MethodGroupExpr)){
772                                 tc.RootContext.Report.Error (118,
773                                        "Denotes an " + this.expr.ExprClass + " while a method was expected");
774                                 return null;
775                         }
776
777                         //
778                         // Next, evaluate all the expressions in the argument list
779                         //
780                         if (Arguments != null){
781                                 for (int i = Arguments.Count; i > 0;){
782                                         --i;
783                                         Argument a = (Argument) Arguments [i];
784
785                                         if (!a.Resolve (tc))
786                                                 return null;
787                                 }
788                         }
789
790                         method = OverloadResolve ((MethodGroupExpr) this.expr, Arguments);
791
792                         if (method == null){
793                                 tc.RootContext.Report.Error (-6,
794                                 "Figure out error: Can not find a good function for this argument list");
795                                 return null;
796                         }
797
798                         Console.WriteLine ("Found a method! " + method);
799
800                         return this;
801                 }
802
803                 public override void Emit (EmitContext ec)
804                 {
805                         int top = Arguments.Count;
806
807                         for (int i = 0; i < top; i++){
808                                 Argument a = (Argument) Arguments [i];
809
810                                 a.Emit (ec);
811                         }
812
813                         ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
814                 }
815         }
816
817         public class New : Expression {
818
819                 public enum NType {
820                         Object,
821                         Array
822                 };
823
824                 public readonly NType     NewType;
825                 public readonly ArrayList Arguments;
826                 public readonly string    RequestedType;
827                 // These are for the case when we have an array
828                 public readonly string    Rank;
829                 public readonly ArrayList Indices;
830                 public readonly ArrayList Initializers;
831                 
832
833                 public New (string requested_type, ArrayList arguments)
834                 {
835                         RequestedType = requested_type;
836                         Arguments = arguments;
837                         NewType = NType.Object;
838                 }
839
840                 public New (string requested_type, ArrayList exprs, string rank, ArrayList initializers)
841                 {
842                         RequestedType = requested_type;
843                         Indices       = exprs;
844                         Rank          = rank;
845                         Initializers  = initializers;
846                         NewType       = NType.Array;
847                 }
848                 
849                 public override Expression Resolve (TypeContainer tc)
850                 {
851                         // FIXME: Implement;
852                         return this;
853                 }
854
855                 public override void Emit (EmitContext ec)
856                 {
857                 }
858         }
859
860         public class This : Expression {
861                 public override Expression Resolve (TypeContainer tc)
862                 {
863                         // FIXME: Implement;
864                         return this;
865                 }
866
867                 public override void Emit (EmitContext ec)
868                 {
869                 }
870         }
871
872         public class TypeOf : Expression {
873                 public readonly string QueriedType;
874                 
875                 public TypeOf (string queried_type)
876                 {
877                         QueriedType = queried_type;
878                 }
879
880                 public override Expression Resolve (TypeContainer tc)
881                 {
882                         // FIXME: Implement;
883                         return this;
884                 }
885
886                 public override void Emit (EmitContext ec)
887                 {
888                 }
889         }
890
891         public class SizeOf : Expression {
892                 public readonly string QueriedType;
893                 
894                 public SizeOf (string queried_type)
895                 {
896                         this.QueriedType = queried_type;
897                 }
898
899                 public override Expression Resolve (TypeContainer tc)
900                 {
901                         // FIXME: Implement;
902                         return this;
903                 }
904
905                 public override void Emit (EmitContext ec)
906                 {
907                 }
908         }
909
910         public class MemberAccess : Expression {
911                 public readonly string Identifier;
912                 Expression expr;
913                 
914                 public MemberAccess (Expression expr, string id)
915                 {
916                         this.expr = expr;
917                         Identifier = id;
918                 }
919
920                 public Expression Expr {
921                         get {
922                                 return expr;
923                         }
924                 }
925                 
926                 public override Expression Resolve (TypeContainer tc)
927                 {
928                         // FIXME: Implement;
929                         return this;
930                 }
931
932                 public override void Emit (EmitContext ec)
933                 {
934                 }
935
936         }
937
938         // <summary>
939         //   Nodes of type Namespace are created during the semantic
940         //   analysis to resolve member_access/qualified_identifier/simple_name
941         //   accesses.
942         //
943         //   They are born `resolved'. 
944         // </summary>
945         public class NamespaceExpr : Expression {
946                 public readonly string Name;
947                 
948                 public NamespaceExpr (string name)
949                 {
950                         Name = name;
951                         eclass = ExprClass.Namespace;
952                 }
953
954                 public override Expression Resolve (TypeContainer tc)
955                 {
956                         return this;
957                 }
958
959                 public override void Emit (EmitContext ec)
960                 {
961                 }
962         }
963
964         // <summary>
965         //   Fully resolved expression that evaluates to a type
966         // </summary>
967         public class TypeExpr : Expression {
968                 public TypeExpr (Type t)
969                 {
970                         Type = t;
971                         eclass = ExprClass.Type;
972                 }
973
974                 override public Expression Resolve (TypeContainer tc)
975                 {
976                         return this;
977                 }
978
979                 override public void Emit (EmitContext ec)
980                 {
981                         
982                 }
983         }
984
985         // <summary>
986         //   Fully resolved expression that evaluates to a type
987         // </summary>
988         public class MethodGroupExpr : Expression {
989                 public readonly MethodInfo [] Methods;
990                 
991                 public MethodGroupExpr (MemberInfo [] mi)
992                 {
993                         Methods = new MethodInfo [mi.Length];
994                         mi.CopyTo (Methods, 0);
995                         eclass = ExprClass.MethodGroup;
996                 }
997
998                 override public Expression Resolve (TypeContainer tc)
999                 {
1000                         return this;
1001                 }
1002
1003                 override public void Emit (EmitContext ec)
1004                 {
1005                         
1006                 }
1007         }
1008         
1009         public class BuiltinTypeAccess : Expression {
1010                 public readonly string AccessBase;
1011                 public readonly string Method;
1012                 
1013                 public BuiltinTypeAccess (string type, string method)
1014                 {
1015                         System.Console.WriteLine ("DUDE! This type should be fully resolved!");
1016                         AccessBase = type;
1017                         Method = method;
1018                 }
1019
1020                 public override Expression Resolve (TypeContainer tc)
1021                 {
1022                         // FIXME: Implement;
1023                         return this;
1024                 }
1025
1026                 public override void Emit (EmitContext ec)
1027                 {
1028                 }
1029         }
1030
1031
1032         //   Fully resolved expression that evaluates to a Field
1033         // </summary>
1034         public class FieldExpr : Expression {
1035                 public readonly FieldInfo FieldInfo;
1036
1037                 public FieldExpr (FieldInfo fi)
1038                 {
1039                         FieldInfo = fi;
1040                         eclass = ExprClass.Variable;
1041                 }
1042
1043                 override public Expression Resolve (TypeContainer tc)
1044                 {
1045                         // We are born in resolved state. 
1046                         return this;
1047                 }
1048
1049                 override public void Emit (EmitContext ec)
1050                 {
1051                         // FIXME: Assert that this should not be reached?
1052                 }
1053         }
1054         
1055         // <summary>
1056         //   Fully resolved expression that evaluates to a Property
1057         // </summary>
1058         public class PropertyExpr : Expression {
1059                 public readonly PropertyInfo PropertyInfo;
1060                 public readonly bool IsStatic;
1061                 
1062                 public PropertyExpr (PropertyInfo pi)
1063                 {
1064                         PropertyInfo = pi;
1065                         eclass = ExprClass.PropertyAccess;
1066                         IsStatic = false;
1067                                 
1068                         MethodInfo [] acc = pi.GetAccessors ();
1069
1070                         for (int i = 0; i < acc.Length; i++)
1071                                 if (acc [i].IsStatic)
1072                                         IsStatic = true;
1073                 }
1074
1075                 override public Expression Resolve (TypeContainer tc)
1076                 {
1077                         // We are born in resolved state. 
1078                         return this;
1079                 }
1080
1081                 override public void Emit (EmitContext ec)
1082                 {
1083                         // FIXME: Implement.
1084                 }
1085         }
1086
1087         // <summary>
1088         //   Fully resolved expression that evaluates to a Property
1089         // </summary>
1090         public class EventExpr : Expression {
1091                 public readonly EventInfo EventInfo;
1092                 
1093                 public EventExpr (EventInfo ei)
1094                 {
1095                         EventInfo = ei;
1096                         eclass = ExprClass.EventAccess;
1097                 }
1098
1099                 override public Expression Resolve (TypeContainer tc)
1100                 {
1101                         // We are born in resolved state. 
1102                         return this;
1103                 }
1104
1105                 override public void Emit (EmitContext ec)
1106                 {
1107                         // FIXME: Implement.
1108                 }
1109         }
1110         
1111         public class CheckedExpr : Expression {
1112
1113                 public readonly Expression Expr;
1114
1115                 public CheckedExpr (Expression e)
1116                 {
1117                         Expr = e;
1118                 }
1119
1120                 public override Expression Resolve (TypeContainer tc)
1121                 {
1122                         // FIXME : Implement !
1123                         return this;
1124                 }
1125
1126                 public override void Emit (EmitContext ec)
1127                 {
1128                 }
1129                 
1130         }
1131
1132         public class UnCheckedExpr : Expression {
1133
1134                 public readonly Expression Expr;
1135
1136                 public UnCheckedExpr (Expression e)
1137                 {
1138                         Expr = e;
1139                 }
1140
1141                 public override Expression Resolve (TypeContainer tc)
1142                 {
1143                         // FIXME : Implement !
1144                         return this;
1145                 }
1146
1147                 public override void Emit (EmitContext ec)
1148                 {
1149                 }
1150                 
1151         }
1152
1153                 public class ElementAccess : Expression {
1154
1155                 public readonly ArrayList  Arguments;
1156                 public readonly Expression Expr;
1157
1158                 public ElementAccess (Expression e, ArrayList e_list)
1159                 {
1160                         Expr = e;
1161                         Arguments = e_list;
1162                 }
1163
1164                 public override Expression Resolve (TypeContainer tc)
1165                 {
1166                         // FIXME : Implement
1167                         return this;
1168                 }
1169
1170                 public override void Emit (EmitContext ec)
1171                 {
1172                         // FIXME : Implement !
1173                 }
1174
1175         }
1176
1177         public class BaseAccess : Expression {
1178
1179                 public enum BaseAccessType {
1180                         Member,
1181                         Indexer
1182                 };
1183                 
1184                 public readonly BaseAccessType BAType;
1185                 public readonly string         Member;
1186                 public readonly ArrayList      Arguments;
1187
1188                 public BaseAccess (BaseAccessType t, string member, ArrayList args)
1189                 {
1190                         BAType = t;
1191                         Member = member;
1192                         Arguments = args;
1193                         
1194                 }
1195
1196                 public override Expression Resolve (TypeContainer tc)
1197                 {
1198                         // FIXME : Implement !
1199                         return this;
1200                 }
1201
1202                 public override void Emit (EmitContext ec)
1203                 {
1204                 }
1205         }
1206 }