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