61636f399945348c02b3fce36e8e09f10a18e588
[mono.git] / mcs / mcs / interface.cs
1 //
2 // interface.cs: Interface handler
3 //
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 //
6 // Licensed under the terms of the GNU GPL
7 //
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
9 //
10 #define CACHE
11 using System.Collections;
12 using System;
13 using System.IO;
14 using System.Reflection;
15 using System.Reflection.Emit;
16
17 namespace Mono.CSharp {
18
19         /// <summary>
20         ///   Interfaces
21         /// </summary>
22         public class Interface : DeclSpace, IMemberContainer {
23                 const MethodAttributes interface_method_attributes =
24                         MethodAttributes.Public |
25                         MethodAttributes.Abstract |
26                         MethodAttributes.HideBySig |
27                         MethodAttributes.NewSlot |
28                         MethodAttributes.Virtual;
29
30                 const MethodAttributes property_attributes =
31                         MethodAttributes.Public |
32                         MethodAttributes.Abstract |
33                         MethodAttributes.HideBySig |
34                         MethodAttributes.NewSlot |
35                         MethodAttributes.SpecialName |
36                         MethodAttributes.Virtual;
37                 
38                 ArrayList bases;
39                 
40                 ArrayList defined_method;
41                 ArrayList defined_indexer;
42                 ArrayList defined_events;
43                 ArrayList defined_properties;
44
45                 ArrayList method_builders;
46                 ArrayList property_builders;
47                 ArrayList event_builders;
48                 
49                 Attributes OptAttributes;
50
51                 public string IndexerName;
52
53                 IMemberContainer parent_container;
54                 MemberCache member_cache;
55
56                 // These will happen after the semantic analysis
57                 
58                 // Hashtable defined_indexers;
59                 // Hashtable defined_methods;
60                 
61                 /// <summary>
62                 ///   Modifiers allowed in a class declaration
63                 /// </summary>
64                 public const int AllowedModifiers =
65                         Modifiers.NEW       |
66                         Modifiers.PUBLIC    |
67                         Modifiers.PROTECTED |
68                         Modifiers.INTERNAL  |
69                         Modifiers.UNSAFE    |
70                         Modifiers.PRIVATE;
71
72                 public Interface (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
73                         : base (parent, name, l)
74                 {
75                         ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE, l);
76                         OptAttributes = attrs;
77                         
78                         method_builders = new ArrayList ();
79                         property_builders = new ArrayList ();
80                         event_builders = new ArrayList ();
81                 }
82
83                 public AdditionResult AddMethod (InterfaceMethod imethod)
84                 {
85                         string name = imethod.Name;
86                         Object value = defined_names [name];
87
88                         if (value != null){
89                                 if (!(value is InterfaceMethod))
90                                         return AdditionResult.NameExists;
91                         } 
92
93                         if (defined_method == null)
94                                 defined_method = new ArrayList ();
95
96                         defined_method.Add (imethod);
97                         if (value == null)
98                                 DefineName (name, imethod);
99                         
100                         return AdditionResult.Success;
101                 }
102
103                 public AdditionResult AddProperty (InterfaceProperty iprop)
104                 {
105                         AdditionResult res;
106                         string name = iprop.Name;
107
108                         if ((res = IsValid (name)) != AdditionResult.Success)
109                                 return res;
110
111                         DefineName (name, iprop);
112
113                         if (defined_properties == null)
114                                 defined_properties = new ArrayList ();
115
116                         defined_properties.Add (iprop);
117                         return AdditionResult.Success;
118                 }
119
120                 public AdditionResult AddEvent (InterfaceEvent ievent)
121                 {
122                         string name = ievent.Name;
123                         AdditionResult res;
124                         
125                         if ((res = IsValid (name)) != AdditionResult.Success)
126                                 return res;
127
128                         DefineName (name, ievent);
129
130                         if (defined_events == null)
131                                 defined_events = new ArrayList ();
132
133                         defined_events.Add (ievent);
134                         return AdditionResult.Success;
135                 }
136
137                 public bool AddIndexer (InterfaceIndexer iindexer)
138                 {
139                         if (defined_indexer == null)
140                                 defined_indexer = new ArrayList ();
141                         
142                         defined_indexer.Add (iindexer);
143                         return true;
144                 }
145                 
146                 public ArrayList InterfaceMethods {
147                         get {
148                                 return defined_method;
149                         }
150                 }
151
152                 public ArrayList InterfaceProperties {
153                         get {
154                                 return defined_properties;
155                         }
156                 }
157
158                 public ArrayList InterfaceEvents {
159                         get {
160                                 return defined_events;
161                         }
162                 }
163
164                 public ArrayList InterfaceIndexers {
165                         get {
166                                 return defined_indexer;
167                         }
168                 }
169
170                 public ArrayList Bases {
171                         get {
172                                 return bases;
173                         }
174
175                         set {
176                                 bases = value;
177                         }
178                 }
179
180                 public virtual TypeAttributes InterfaceAttr {
181                         get {
182                                 TypeAttributes x = TypeAttributes.Interface | TypeAttributes.Abstract;
183
184                                 if (IsTopLevel == false) {
185                                         
186                                         if ((ModFlags & Modifiers.PROTECTED) != 0
187                                             && (ModFlags & Modifiers.INTERNAL) != 0)
188                                                 x |= TypeAttributes.NestedFamORAssem;
189                                         else if ((ModFlags & Modifiers.PROTECTED) != 0)
190                                                 x |= TypeAttributes.NestedFamily;
191                                         else if ((ModFlags & Modifiers.INTERNAL) != 0)
192                                                 x |= TypeAttributes.NestedAssembly;
193                                         else if ((ModFlags & Modifiers.PUBLIC) != 0)
194                                                 x |= TypeAttributes.NestedPublic;
195                                         else
196                                                 x |= TypeAttributes.NestedPrivate;
197                                 } else {
198                                         if ((ModFlags & Modifiers.PUBLIC) != 0)
199                                                 x |= TypeAttributes.Public;
200                                         else if ((ModFlags & Modifiers.PRIVATE) != 0)
201                                                 x |= TypeAttributes.NotPublic;
202                                 }
203                                 
204                                 if ((ModFlags & Modifiers.ABSTRACT) != 0)
205                                         x |= TypeAttributes.Abstract;
206                                 
207                                 if ((ModFlags & Modifiers.SEALED) != 0)
208                                         x |= TypeAttributes.Sealed;
209
210                                 return x;
211                         }
212                 }
213                 
214                 void Error111 (InterfaceMemberBase ib)
215                 {
216                         Report.Error (
217                                 111,
218                                 "Interface `" + Name + "' already contains a definition with the " +
219                                 "same return value and parameter types for member `" + ib.Name + "'");
220                 }
221
222                 bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] types)
223                 {
224                         if (!TypeManager.RegisterMethod (mb, ip, types))
225                                 return false;
226
227                         method_builders.Add (mb);
228                         return true;
229                 }
230
231                 public MethodInfo [] GetMethods ()
232                 {
233                         int n = method_builders.Count;
234                         MethodInfo [] mi = new MethodInfo [n];
235                         
236                         method_builders.CopyTo (mi, 0);
237
238                         return mi;
239                 }
240
241                 // Hack around System.Reflection as found everywhere else
242                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
243                                                         MemberFilter filter, object criteria)
244                 {
245                         ArrayList members = new ArrayList ();
246
247                         if ((mt & MemberTypes.Method) != 0) {
248                                 foreach (MethodBuilder mb in method_builders)
249                                         if (filter (mb, criteria))
250                                                 members.Add (mb);
251                         }
252
253                         if ((mt & MemberTypes.Property) != 0) {
254                                 foreach (PropertyBuilder pb in property_builders)
255                                         if (filter (pb, criteria))
256                                                 members.Add (pb);
257                         }
258
259                         if ((mt & MemberTypes.Event) != 0) {
260                                 foreach (MyEventBuilder eb in event_builders)
261                                         if (filter (eb, criteria))
262                                                 members.Add (eb);
263                         }
264
265                         if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
266                                 MemberList parent_mi;
267                                 
268                                 parent_mi = TypeContainer.FindMembers (
269                                         TypeBuilder.BaseType, mt, bf, filter, criteria);
270
271                                 members.AddRange (parent_mi);
272                         }
273
274                         return new MemberList (members);
275                 }
276
277                 public override MemberCache MemberCache {
278                         get {
279                                 return member_cache;
280                         }
281                 }
282
283                 //
284                 // Populates the methods in the interface
285                 //
286                 void PopulateMethod (TypeContainer parent, DeclSpace decl_space, InterfaceMethod im)
287                 {
288                         Type return_type = this.ResolveType (im.ReturnType, false, im.Location);
289                         Type [] arg_types = im.ParameterTypes (this);
290                         MethodBuilder mb;
291                         Parameter [] p;
292                         int i;
293
294                         if (return_type == null)
295                                 return;
296
297                         if (return_type.IsPointer && !UnsafeOK (this))
298                                 return;
299
300                         if (arg_types == null)
301                                 return;
302
303                         foreach (Type t in arg_types){
304
305                                 if (t == null)
306                                         return;
307                                 
308                                 if (t.IsPointer && !UnsafeOK (this))
309                                         return;
310                         }
311                         
312                         //
313                         // Create the method
314                         //
315                         mb = TypeBuilder.DefineMethod (
316                                 im.Name, interface_method_attributes,
317                                 return_type, arg_types);
318
319                         InternalParameters ip = new InternalParameters (arg_types, im.Parameters);
320                         
321                         if (!RegisterMethod (mb, ip, arg_types)) {
322                                 Error111 (im);
323                                 return;
324                         }
325
326                         //
327                         // Define each type attribute (in/out/ref) and
328                         // the argument names.
329                         //
330                         p = im.Parameters.FixedParameters;
331                         if (p != null){
332                                 for (i = 0; i < p.Length; i++)
333                                         mb.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
334
335                                 if (i != arg_types.Length)
336                                         Console.WriteLine ("Implement the type definition for params");
337                         }
338
339                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
340                                                           return_type, ModFlags, false);
341
342                         if (im.OptAttributes != null)
343                                 Attribute.ApplyAttributes (ec, mb, im, im.OptAttributes, Location);
344                 }
345
346                 //
347                 // Populates the properties in the interface
348                 //
349                 void PopulateProperty (TypeContainer parent, DeclSpace decl_space, InterfaceProperty ip)
350                 {
351                         PropertyBuilder pb;
352                         MethodBuilder get = null, set = null;
353                         ip.Type = this.ResolveTypeExpr (ip.Type, false, ip.Location);
354                         Type prop_type = ip.Type.Type;
355                         Type [] setter_args = new Type [1];
356
357                         if (prop_type == null)
358                                 return;
359
360                         if (prop_type.IsPointer && !UnsafeOK (this))
361                                 return;
362                         
363                         setter_args [0] = prop_type;
364
365                         //
366                         // FIXME: properties are missing the following
367                         // flags: hidebysig newslot specialname
368                         //
369                         pb = TypeBuilder.DefineProperty (
370                                 ip.Name, PropertyAttributes.None,
371                                 prop_type, null);
372
373                         if (ip.HasGet){
374                                 get = TypeBuilder.DefineMethod (
375                                         "get_" + ip.Name, property_attributes ,
376                                         prop_type, null);
377
378                                 //
379                                 // HACK because System.Reflection.Emit is lame
380                                 //
381                                 Type [] null_types = null;
382                                 InternalParameters inp = new InternalParameters
383                                         (null_types, Parameters.EmptyReadOnlyParameters);
384                                 
385                                 if (!RegisterMethod (get, inp, null)) {
386                                         Error111 (ip);
387                                         return;
388                                 }
389                                 
390                                 pb.SetGetMethod (get);
391                         }
392
393                         if (ip.HasSet){
394                                 setter_args [0] = prop_type;
395
396                                 set = TypeBuilder.DefineMethod (
397                                         "set_" + ip.Name, property_attributes,
398                                         TypeManager.void_type, setter_args);
399
400                                 set.DefineParameter (1, ParameterAttributes.None, "value");
401                                 pb.SetSetMethod (set);
402
403                                 //
404                                 // HACK because System.Reflection.Emit is lame
405                                 //
406                                 Parameter [] parms = new Parameter [1];
407                                 parms [0] = new Parameter (ip.Type, "value", Parameter.Modifier.NONE, null);
408                                 InternalParameters ipp = new InternalParameters (
409                                         this, new Parameters (parms, null, Location.Null));
410                                         
411                                 if (!RegisterMethod (set, ipp, setter_args)) {
412                                         Error111 (ip);
413                                         return;
414                                 }
415                         }
416
417                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
418                                                           null, ModFlags, false);
419
420                         if (ip.OptAttributes != null)
421                                 Attribute.ApplyAttributes (ec, pb, ip, ip.OptAttributes, Location);
422
423                         TypeManager.RegisterProperty (pb, get, set);
424                         property_builders.Add (pb);
425                 }
426
427                 //
428                 // Populates the events in the interface
429                 //
430                 void PopulateEvent (TypeContainer parent, DeclSpace decl_space, InterfaceEvent ie)
431                 {
432                         //
433                         // FIXME: We need to do this after delegates have been
434                         // declared or we declare them recursively.
435                         //
436                         MyEventBuilder eb;
437                         MethodBuilder add = null, remove = null;
438                         ie.Type = this.ResolveTypeExpr (ie.Type, false, ie.Location);
439                         Type event_type = ie.Type.Type;
440
441                         if (event_type == null)
442                                 return;
443
444                         if (event_type.IsPointer && !UnsafeOK (this))
445                                 return;
446
447                         Type [] parameters = new Type [1];
448                         parameters [0] = event_type;
449
450                         eb = new MyEventBuilder (TypeBuilder, ie.Name,
451                                                  EventAttributes.None, event_type);
452
453                         //
454                         // Now define the accessors
455                         //
456                         string add_name = "add_" + ie.Name;
457                         
458                         add = TypeBuilder.DefineMethod (
459                                 add_name, property_attributes, null, parameters);
460                         add.DefineParameter (1, ParameterAttributes.None, "value");
461                         eb.SetAddOnMethod (add);
462
463                         string remove_name = "remove_" + ie.Name;
464                         remove = TypeBuilder.DefineMethod (
465                                 remove_name, property_attributes, null, parameters);
466                         remove.DefineParameter (1, ParameterAttributes.None, "value");
467                         eb.SetRemoveOnMethod (remove);
468
469                         Parameter [] parms = new Parameter [1];
470                         parms [0] = new Parameter (ie.Type, "value", Parameter.Modifier.NONE, null);
471                         InternalParameters ip = new InternalParameters (
472                                 this, new Parameters (parms, null, Location.Null));
473
474                         if (!RegisterMethod (add, ip, parameters)) {
475                                 Error111 (ie);
476                                 return;
477                         }
478                         
479                         if (!RegisterMethod (remove, ip, parameters)) {
480                                 Error111 (ie);
481                                 return;
482                         }
483
484                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
485                                                           null, ModFlags, false);
486
487
488                         if (ie.OptAttributes != null)
489                                 Attribute.ApplyAttributes (ec, eb, ie, ie.OptAttributes, Location);
490
491                         TypeManager.RegisterEvent (eb, add, remove);
492                         event_builders.Add (eb);
493                 }
494
495                 //
496                 // Populates the indexers in the interface
497                 //
498                 void PopulateIndexer (TypeContainer parent, DeclSpace decl_space, InterfaceIndexer ii)
499                 {
500                         PropertyBuilder pb;
501                         ii.Type = this.ResolveTypeExpr (ii.Type, false, ii.Location);
502                         Type prop_type = ii.Type.Type;
503                         Type [] arg_types = ii.ParameterTypes (this);
504                         Type [] value_arg_types;
505
506                         if (prop_type == null)
507                                 return;
508
509                         if (prop_type.IsPointer && !UnsafeOK (this))
510                                 return;
511                         
512                         //
513                         // Sets up the extra invisible `value' argument for setters.
514                         // 
515                         if (arg_types != null){
516                                 int count = arg_types.Length;
517                                 value_arg_types = new Type [count + 1];
518
519                                 arg_types.CopyTo (value_arg_types, 0);
520                                 value_arg_types [count] = prop_type;
521
522                                 foreach (Type t in arg_types){
523                                         if (t.IsPointer && !UnsafeOK (this))
524                                                 return;
525                                 }
526                         } else {
527                                 value_arg_types = new Type [1];
528
529                                 value_arg_types [1] = prop_type;
530                         }
531
532                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
533                                                           null, ModFlags, false);
534
535                         IndexerName = Attribute.ScanForIndexerName (ec, ii.OptAttributes);
536                         if (IndexerName == null)
537                                 IndexerName = "Item";
538                         
539                         pb = TypeBuilder.DefineProperty (
540                                 IndexerName, PropertyAttributes.None,
541                                 prop_type, arg_types);
542                         
543                         MethodBuilder set_item = null, get_item = null;
544                         if (ii.HasGet){
545                                 Parameter [] p = ii.Parameters.FixedParameters;
546                                 
547                                 get_item = TypeBuilder.DefineMethod (
548                                         "get_" + IndexerName, property_attributes,
549                                         prop_type, arg_types);
550                                 pb.SetGetMethod (get_item);
551                                 //
552                                 // HACK because System.Reflection.Emit is lame
553                                 //
554                                 InternalParameters ip = new InternalParameters (
555                                         arg_types, ii.Parameters);
556                                 
557                                 if (!RegisterMethod (get_item, ip, arg_types)) {
558                                         Error111 (ii);
559                                         return;
560                                 }
561
562                                 if (p != null){
563                                         for (int i = 0; i < p.Length; i++)
564                                                 get_item.DefineParameter (
565                                                         i + 1,
566                                                         p [i].Attributes, p [i].Name);
567                                 }
568                         }
569
570                         if (ii.HasSet){
571                                 Parameter [] p = ii.Parameters.FixedParameters;
572                                 Parameter [] pv;
573                                 int i = 0;
574                                 
575                                 pv = new Parameter [p.Length + 1];
576                                 p.CopyTo (pv, 0);
577                                 pv [p.Length] = new Parameter (ii.Type, "value", Parameter.Modifier.NONE, null);
578                                 Parameters value_params = new Parameters (pv, null, Location.Null);
579                                 value_params.GetParameterInfo (decl_space);
580                                 
581                                 set_item = TypeBuilder.DefineMethod (
582                                         "set_" + IndexerName, property_attributes,
583                                         TypeManager.void_type, value_arg_types);
584                                 pb.SetSetMethod (set_item);
585                                 //
586                                 // HACK because System.Reflection.Emit is lame
587                                 //
588                                 InternalParameters ip = new InternalParameters (
589                                         value_arg_types, value_params);
590                                 if (!RegisterMethod (set_item, ip, value_arg_types)) {
591                                         Error111 (ii);
592                                         return;
593                                 }
594
595                                 if (p != null){
596                                         for (; i < p.Length; i++)
597                                                 set_item.DefineParameter (
598                                                         i + 1,
599                                                         p [i].Attributes, p [i].Name);
600                                 }
601                                 
602                                 set_item.DefineParameter (i + 1, ParameterAttributes.None, "value");
603                         }
604
605                         if (ii.OptAttributes != null)
606                                 Attribute.ApplyAttributes (ec, pb, ii, ii.OptAttributes, Location);
607
608                         property_builders.Add (pb);
609                 }
610
611                 /// <summary>
612                 ///   Performs the semantic analysis for all the interface members
613                 ///   that were declared
614                 /// </summary>
615                 bool SemanticAnalysis ()
616                 {
617                         Hashtable methods = new Hashtable ();
618
619                         
620                         if (defined_method != null){
621                                 foreach (InterfaceMethod im in defined_method){
622                                         string sig = im.GetSignature (this);
623                                         
624                                         //
625                                         // If there was an undefined Type on the signatures
626                                         // 
627                                         if (sig == null)
628                                                 continue;
629                                         
630                                         if (methods [sig] != null){
631                                                 Error111 (im);
632                                                 return false;
633                                         }
634                                 }
635                         }
636
637                         //
638                         // FIXME: Here I should check i
639                         // 
640                         return true;
641                 }
642
643                 Type GetInterfaceTypeByName (string name)
644                 {
645                         Type t = FindType (name);
646
647                         if (t == null) {
648                                 Report.Error (246, Location, "The type or namespace `" + name +
649                                               "' could not be found");
650                                 return null;
651                         }
652                         
653                         if (t.IsInterface)
654                                 return t;
655                                 
656                         string cause;
657                         
658                         if (t.IsValueType)
659                                 cause = "is a struct";
660                         else if (t.IsClass) 
661                                 cause = "is a class";
662                         else
663                                 cause = "Should not happen.";
664                         
665                         Report.Error (527, Location, "`"+name+"' " + cause +
666                                       ", need an interface instead");
667                         
668                         return null;
669                 }
670                 
671                 //
672                 // Returns the list of interfaces that this interface implements
673                 // Or null if it does not implement any interface.
674                 //
675                 // Sets the error boolean accoringly.
676                 //
677                 Type [] GetInterfaceBases (out bool error)
678                 {
679                         Type [] tbases;
680                         int i;
681
682                         error = false;
683                         if (Bases == null)
684                                 return null;
685                         
686                         tbases = new Type [Bases.Count];
687                         i = 0;
688
689                         foreach (string name in Bases){
690                                 Type t;
691
692                                 t = GetInterfaceTypeByName (name);
693                                 if (t == null){
694                                         error = true;
695                                         return null;
696                                 }
697
698                                 if (!Parent.AsAccessible (t, ModFlags))
699                                         Report.Error (61, Location,
700                                                       "Inconsistent accessibility: base interface `" +
701                                                       TypeManager.CSharpName (t) + "' is less " +
702                                                       "accessible than interface `" +
703                                                       Name + "'");
704
705                                 tbases [i++] = t;
706                         }
707                         
708                         return TypeManager.ExpandInterfaces (tbases);
709                 }
710                 
711                 //
712                 // <summary>
713                 //  Defines the Interface in the appropriate ModuleBuilder or TypeBuilder
714                 // </summary>
715                 //
716                 // TODO:
717                 //   Rework the way we recurse, because for recursive
718                 //   definitions of interfaces (A:B and B:A) we report the
719                 //   error twice, rather than once.  
720                 
721                 public override TypeBuilder DefineType ()
722                 {
723                         Type [] ifaces;
724                         bool error;
725
726                         if (TypeBuilder != null)
727                                 return TypeBuilder;
728                         
729                         if (InTransit)
730                                 return null;
731                         
732                         InTransit = true;
733                         
734                         ifaces = GetInterfaceBases (out error);
735
736                         if (error)
737                                 return null;
738
739                         if (IsTopLevel) {
740                                 ModuleBuilder builder = CodeGen.ModuleBuilder;
741
742                                 TypeBuilder = builder.DefineType (
743                                         Name,
744                                         InterfaceAttr,
745                                         (Type)null,   // Parent Type
746                                         ifaces);
747                                 RootContext.RegisterOrder (this);
748                         } else {
749                                 TypeBuilder builder = Parent.TypeBuilder;
750
751                                 TypeBuilder = builder.DefineNestedType (
752                                         Basename,
753                                         InterfaceAttr,
754                                         (Type) null, //parent type
755                                         ifaces);
756
757                                 TypeContainer tc = TypeManager.LookupTypeContainer (builder);
758                                 tc.RegisterOrder (this);
759                         }
760
761                         TypeManager.AddUserInterface (Name, TypeBuilder, this, ifaces);
762                         InTransit = false;
763
764                         return TypeBuilder;
765                 }
766
767                 //
768                 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
769                 // interface is consistent.  Either it is `Item' or it is the name defined by all the
770                 // indexers with the `IndexerName' attribute.
771                 //
772                 // Turns out that the IndexerNameAttribute is applied to each indexer,
773                 // but it is never emitted, instead a DefaultName attribute is attached
774                 // to the interface
775                 //
776                 void DefineIndexers (TypeContainer parent)
777                 {
778                         string interface_indexer_name = null;
779
780                         foreach (InterfaceIndexer ii in defined_indexer){
781
782                                 PopulateIndexer (parent, this, ii);
783
784                                 if (interface_indexer_name == null){
785                                         interface_indexer_name = IndexerName;
786                                         continue;
787                                 }
788                                 
789                                 if (IndexerName == interface_indexer_name)
790                                         continue;
791                                 
792                                 Report.Error (
793                                         668, "Two indexers have different names, " +
794                                         " you should use the same name for all your indexers");
795                         }
796                         if (interface_indexer_name == null)
797                                 interface_indexer_name = "Item";
798                         IndexerName = interface_indexer_name;
799                 }
800                 
801                 /// <summary>
802                 ///   Performs semantic analysis, and then generates the IL interfaces
803                 /// </summary>
804                 public override bool DefineMembers (TypeContainer parent)
805                 {
806                         if (!SemanticAnalysis ())
807                                 return false;
808
809                         if (defined_method != null){
810                                 foreach (InterfaceMethod im in defined_method)
811                                         PopulateMethod (parent, this, im);
812                         }
813
814                         if (defined_properties != null){
815                                 foreach (InterfaceProperty ip in defined_properties)
816                                         PopulateProperty (parent, this, ip);
817                         }
818
819                         if (defined_events != null)
820                                 foreach (InterfaceEvent ie in defined_events)
821                                         PopulateEvent (parent, this, ie);
822
823                         if (defined_indexer != null) {
824                                 DefineIndexers (parent);
825
826                                 CustomAttributeBuilder cb = EmitDefaultMemberAttr (
827                                         parent, IndexerName, ModFlags, Location);
828                                 if (cb != null)
829                                         TypeBuilder.SetCustomAttribute (cb);
830                         }
831
832 #if CACHE
833                         if (TypeBuilder.BaseType != null)
834                                 parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
835
836                         member_cache = new MemberCache (this);
837 #endif
838
839                         return true;
840                 }
841
842                 /// <summary>
843                 ///   Applies all the attributes.
844                 /// </summary>
845                 public override bool Define (TypeContainer parent)
846                 {
847                         if (OptAttributes != null) {
848                                 EmitContext ec = new EmitContext (parent, this, Location, null, null,
849                                                                   ModFlags, false);
850                                 Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location);
851                         }
852
853                         return true;
854                 }
855
856                 public static CustomAttributeBuilder EmitDefaultMemberAttr (TypeContainer parent,
857                                                                             string name,
858                                                                             int flags,
859                                                                             Location loc)
860                 {
861                         EmitContext ec = new EmitContext (parent, loc, null, null, flags);
862
863                         Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
864                                                                  ".ctor", MemberTypes.Constructor,
865                                                                  BindingFlags.Public | BindingFlags.Instance,
866                                                                  Location.Null);
867                         
868                         if (!(ml is MethodGroupExpr)) {
869                                 Console.WriteLine ("Internal error !!!!");
870                                 return null;
871                         }
872                         
873                         MethodGroupExpr mg = (MethodGroupExpr) ml;
874
875                         MethodBase constructor = mg.Methods [0];
876
877                         string [] vals = { name };
878
879                         CustomAttributeBuilder cb = null;
880                         try {
881                                 cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
882                         } catch {
883                                 Report.Warning (-100, "Can not set the indexer default member attribute");
884                         }
885
886                         return cb;
887                 }
888
889                 //
890                 // IMemberContainer
891                 //
892
893                 string IMemberContainer.Name {
894                         get {
895                                 return Name;
896                         }
897                 }
898
899                 Type IMemberContainer.Type {
900                         get {
901                                 return TypeBuilder;
902                         }
903                 }
904
905                 IMemberContainer IMemberContainer.Parent {
906                         get {
907                                 return parent_container;
908                         }
909                 }
910
911                 MemberCache IMemberContainer.MemberCache {
912                         get {
913                                 return member_cache;
914                         }
915                 }
916
917                 bool IMemberContainer.IsInterface {
918                         get {
919                                 return true;
920                         }
921                 }
922
923                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
924                 {
925                         // Interfaces only contain instance members.
926                         if ((bf & BindingFlags.Instance) == 0)
927                                 return MemberList.Empty;
928                         if ((bf & BindingFlags.Public) == 0)
929                                 return MemberList.Empty;
930
931                         ArrayList members = new ArrayList ();
932
933                         if ((mt & MemberTypes.Method) != 0)
934                                 members.AddRange (method_builders);
935
936                         if ((mt & MemberTypes.Property) != 0)
937                                 members.AddRange (property_builders);
938
939                         if ((mt & MemberTypes.Event) != 0)
940                                 members.AddRange (event_builders);
941
942                         return new MemberList (members);
943                 }
944         }
945
946         public class InterfaceMemberBase {
947                 public readonly string Name;
948                 public readonly bool IsNew;
949                 public Attributes OptAttributes;
950                 
951                 public InterfaceMemberBase (string name, bool is_new, Attributes attrs)
952                 {
953                         Name = name;
954                         IsNew = is_new;
955                         OptAttributes = attrs;
956                 }
957         }
958         
959         public class InterfaceProperty : InterfaceMemberBase {
960                 public readonly bool HasSet;
961                 public readonly bool HasGet;
962                 public readonly Location Location;
963                 public Expression Type;
964                 
965                 public InterfaceProperty (Expression type, string name,
966                                           bool is_new, bool has_get, bool has_set,
967                                           Attributes attrs, Location loc)
968                         : base (name, is_new, attrs)
969                 {
970                         Type = type;
971                         HasGet = has_get;
972                         HasSet = has_set;
973                         Location = loc;
974                 }
975         }
976
977         public class InterfaceEvent : InterfaceMemberBase {
978                 public readonly Location Location;
979                 public Expression Type;
980                 
981                 public InterfaceEvent (Expression type, string name, bool is_new, Attributes attrs,
982                                        Location loc)
983                         : base (name, is_new, attrs)
984                 {
985                         Type = type;
986                         Location = loc;
987                 }
988         }
989         
990         public class InterfaceMethod : InterfaceMemberBase {
991                 public readonly Expression ReturnType;
992                 public readonly Parameters Parameters;
993                 public readonly Location Location;
994                 
995                 public InterfaceMethod (Expression return_type, string name, bool is_new, Parameters args,
996                                         Attributes attrs, Location l)
997                         : base (name, is_new, attrs)
998                 {
999                         this.ReturnType = return_type;
1000                         this.Parameters = args;
1001                         Location = l;
1002                 }
1003
1004                 /// <summary>
1005                 ///   Returns the signature for this interface method
1006                 /// </summary>
1007                 public string GetSignature (DeclSpace ds)
1008                 {
1009                         Type ret = ds.ResolveType (ReturnType, false, Location);
1010                         string args = Parameters.GetSignature (ds);
1011
1012                         if ((ret == null) || (args == null))
1013                                 return null;
1014                         
1015                         return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
1016                 }
1017
1018                 public Type [] ParameterTypes (DeclSpace ds)
1019                 {
1020                         return Parameters.GetParameterInfo (ds);
1021                 }
1022         }
1023
1024         public class InterfaceIndexer : InterfaceMemberBase {
1025                 public readonly bool HasGet, HasSet;
1026                 public readonly Parameters Parameters;
1027                 public readonly Location Location;
1028                 public Expression Type;
1029                 
1030                 public InterfaceIndexer (Expression type, Parameters args, bool do_get, bool do_set,
1031                                          bool is_new, Attributes attrs, Location loc)
1032                         : base ("", is_new, attrs)
1033                 {
1034                         Type = type;
1035                         Parameters = args;
1036                         HasGet = do_get;
1037                         HasSet = do_set;
1038                         Location = loc;
1039                 }
1040
1041                 public Type [] ParameterTypes (DeclSpace ds)
1042                 {
1043                         return Parameters.GetParameterInfo (ds);
1044                 }
1045         }
1046 }