2002-07-22 Tim Coleman <tim@timcoleman.com>
[mono.git] / mcs / mbas / 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 virtual TypeAttributes InterfaceAttr {
174                         get {
175                                 TypeAttributes x = TypeAttributes.Interface | TypeAttributes.Abstract;
176
177                                 if (IsTopLevel == false) {
178                                         
179                                         if ((ModFlags & Modifiers.PROTECTED) != 0
180                                             && (ModFlags & Modifiers.INTERNAL) != 0)
181                                                 x |= TypeAttributes.NestedFamORAssem;
182                                         else if ((ModFlags & Modifiers.PROTECTED) != 0)
183                                                 x |= TypeAttributes.NestedFamily;
184                                         else if ((ModFlags & Modifiers.INTERNAL) != 0)
185                                                 x |= TypeAttributes.NestedAssembly;
186                                         else if ((ModFlags & Modifiers.PUBLIC) != 0)
187                                                 x |= TypeAttributes.NestedPublic;
188                                         else
189                                                 x |= TypeAttributes.NestedPrivate;
190                                 } else {
191                                         if ((ModFlags & Modifiers.PUBLIC) != 0)
192                                                 x |= TypeAttributes.Public;
193                                         else if ((ModFlags & Modifiers.PRIVATE) != 0)
194                                                 x |= TypeAttributes.NotPublic;
195                                 }
196                                 
197                                 if ((ModFlags & Modifiers.ABSTRACT) != 0)
198                                         x |= TypeAttributes.Abstract;
199                                 
200                                 if ((ModFlags & Modifiers.SEALED) != 0)
201                                         x |= TypeAttributes.Sealed;
202
203                                 return x;
204                         }
205                 }
206                 
207                 void Error111 (InterfaceMemberBase ib)
208                 {
209                         Report.Error (
210                                 111,
211                                 "Interface `" + Name + "' already contains a definition with the " +
212                                 "same return value and parameter types for member `" + ib.Name + "'");
213                 }
214
215                 bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] types)
216                 {
217                         if (!TypeManager.RegisterMethod (mb, ip, types))
218                                 return false;
219
220                         method_builders.Add (mb);
221                         return true;
222                 }
223
224                 public MethodInfo [] GetMethods ()
225                 {
226                         int n = method_builders.Count;
227                         MethodInfo [] mi = new MethodInfo [n];
228                         
229                         method_builders.CopyTo (mi, 0);
230
231                         return mi;
232                 }
233
234                 // Hack around System.Reflection as found everywhere else
235                 public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
236                 {
237                         ArrayList members = new ArrayList ();
238
239                         if ((mt & MemberTypes.Method) != 0) {
240                                 foreach (MethodBuilder mb in method_builders)
241                                         if (filter (mb, criteria))
242                                                 members.Add (mb);
243                         }
244
245                         if ((mt & MemberTypes.Property) != 0) {
246                                 foreach (PropertyBuilder pb in property_builders)
247                                         if (filter (pb, criteria))
248                                                 members.Add (pb);
249                         }
250
251                         if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
252                                 MemberInfo [] parent_mi;
253                                 
254                                 parent_mi = TypeContainer.FindMembers (
255                                         TypeBuilder.BaseType, mt, bf, filter, criteria);
256
257                                 if (parent_mi != null)
258                                         members.AddRange (parent_mi);
259                         }
260                         
261                         // The rest of the cases, if any, are unhandled at present.
262
263                         int count = members.Count;
264
265                         if (count > 0) {
266                                 MemberInfo [] mi = new MemberInfo [count];
267                                 members.CopyTo (mi, 0);
268                                 return mi;
269                         }
270
271                         return null;
272                 }
273
274                 //
275                 // Populates the methods in the interface
276                 //
277                 void PopulateMethod (TypeContainer parent, DeclSpace decl_space, InterfaceMethod im)
278                 {
279                         Type return_type = RootContext.LookupType (this, im.ReturnType, false, im.Location);
280                         Type [] arg_types = im.ParameterTypes (this);
281                         MethodBuilder mb;
282                         Parameter [] p;
283                         int i;
284
285                         if (return_type == null)
286                                 return;
287
288                         if (return_type.IsPointer && !UnsafeOK (this))
289                                 return;
290
291                         foreach (Type t in arg_types){
292
293                                 if (t == null)
294                                         return;
295                                 
296                                 if (t.IsPointer && !UnsafeOK (this))
297                                         return;
298                         }
299                         
300                         //
301                         // Create the method
302                         //
303                         mb = TypeBuilder.DefineMethod (
304                                 im.Name, interface_method_attributes,
305                                 return_type, arg_types);
306
307                         InternalParameters ip = new InternalParameters (arg_types, im.Parameters);
308                         
309                         if (!RegisterMethod (mb, ip, arg_types)) {
310                                 Error111 (im);
311                                 return;
312                         }
313
314                         //
315                         // Define each type attribute (in/out/ref) and
316                         // the argument names.
317                         //
318                         p = im.Parameters.FixedParameters;
319                         if (p != null){
320                                 for (i = 0; i < p.Length; i++)
321                                         mb.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
322
323                                 if (i != arg_types.Length)
324                                         Console.WriteLine ("Implement the type definition for params");
325                         }
326
327                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
328                                                           return_type, ModFlags, false);
329
330                         if (im.OptAttributes != null)
331                                 Attribute.ApplyAttributes (ec, mb, im, im.OptAttributes, Location);
332                 }
333
334                 //
335                 // Populates the properties in the interface
336                 //
337                 void PopulateProperty (TypeContainer parent, DeclSpace decl_space, InterfaceProperty ip)
338                 {
339                         PropertyBuilder pb;
340                         MethodBuilder get = null, set = null;
341                         Type prop_type = RootContext.LookupType (this, ip.Type, false, ip.Location);
342                         Type [] setter_args = new Type [1];
343
344                         if (prop_type == null)
345                                 return;
346
347                         if (prop_type.IsPointer && !UnsafeOK (this))
348                                 return;
349                         
350                         setter_args [0] = prop_type;
351
352                         //
353                         // FIXME: properties are missing the following
354                         // flags: hidebysig newslot specialname
355                         //
356                         pb = TypeBuilder.DefineProperty (
357                                 ip.Name, PropertyAttributes.None,
358                                 prop_type, null);
359
360                         if (ip.HasGet){
361                                 get = TypeBuilder.DefineMethod (
362                                         "get_" + ip.Name, property_attributes ,
363                                         prop_type, null);
364
365                                 //
366                                 // HACK because System.Reflection.Emit is lame
367                                 //
368                                 Type [] null_types = null;
369                                 InternalParameters inp = new InternalParameters
370                                         (null_types, Parameters.GetEmptyReadOnlyParameters ());
371                                 
372                                 if (!RegisterMethod (get, inp, null)) {
373                                         Error111 (ip);
374                                         return;
375                                 }
376                                 
377                                 pb.SetGetMethod (get);
378                         }
379
380                         if (ip.HasSet){
381                                 setter_args [0] = prop_type;
382
383                                 set = TypeBuilder.DefineMethod (
384                                         "set_" + ip.Name, property_attributes,
385                                         TypeManager.void_type, setter_args);
386
387                                 set.DefineParameter (1, ParameterAttributes.None, "value");
388                                 pb.SetSetMethod (set);
389
390                                 //
391                                 // HACK because System.Reflection.Emit is lame
392                                 //
393                                 Parameter [] parms = new Parameter [1];
394                                 parms [0] = new Parameter (ip.Type, "value", Parameter.Modifier.NONE, null);
395                                 InternalParameters ipp = new InternalParameters (
396                                         this, new Parameters (parms, null, Location.Null));
397                                         
398                                 if (!RegisterMethod (set, ipp, setter_args)) {
399                                         Error111 (ip);
400                                         return;
401                                 }
402                         }
403
404                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
405                                                           null, ModFlags, false);
406
407                         if (ip.OptAttributes != null)
408                                 Attribute.ApplyAttributes (ec, pb, ip, ip.OptAttributes, Location);
409
410                         TypeManager.RegisterProperty (pb, get, set);
411                         property_builders.Add (pb);
412                 }
413
414                 //
415                 // Populates the events in the interface
416                 //
417                 void PopulateEvent (TypeContainer parent, DeclSpace decl_space, InterfaceEvent ie)
418                 {
419                         //
420                         // FIXME: We need to do this after delegates have been
421                         // declared or we declare them recursively.
422                         //
423                 }
424
425                 //
426                 // Populates the indexers in the interface
427                 //
428                 void PopulateIndexer (TypeContainer parent, DeclSpace decl_space, InterfaceIndexer ii)
429                 {
430                         PropertyBuilder pb;
431                         Type prop_type = RootContext.LookupType (this, ii.Type, false, ii.Location);
432                         Type [] arg_types = ii.ParameterTypes (this);
433                         Type [] value_arg_types;
434
435                         if (prop_type == null)
436                                 return;
437
438                         if (prop_type.IsPointer && !UnsafeOK (this))
439                                 return;
440                         
441                         //
442                         // Sets up the extra invisible `value' argument for setters.
443                         // 
444                         if (arg_types != null){
445                                 int count = arg_types.Length;
446                                 value_arg_types = new Type [count + 1];
447
448                                 arg_types.CopyTo (value_arg_types, 0);
449                                 value_arg_types [count] = prop_type;
450
451                                 foreach (Type t in arg_types){
452                                         if (t.IsPointer && !UnsafeOK (this))
453                                                 return;
454                                 }
455                         } else {
456                                 value_arg_types = new Type [1];
457
458                                 value_arg_types [1] = prop_type;
459                         }
460
461                         pb = TypeBuilder.DefineProperty (
462                                 "Item", PropertyAttributes.None,
463                                 prop_type, arg_types);
464                         
465                         MethodBuilder set_item = null, get_item = null;
466                         if (ii.HasGet){
467                                 Parameter [] p = ii.Parameters.FixedParameters;
468                                 
469                                 get_item = TypeBuilder.DefineMethod (
470                                         "get_Item", property_attributes, prop_type, arg_types);
471                                 pb.SetGetMethod (get_item);
472                                 //
473                                 // HACK because System.Reflection.Emit is lame
474                                 //
475                                 InternalParameters ip = new InternalParameters (
476                                         arg_types, ii.Parameters);
477                                 
478                                 if (!RegisterMethod (get_item, ip, arg_types)) {
479                                         Error111 (ii);
480                                         return;
481                                 }
482
483                                 if (p != null){
484                                         for (int i = 0; i < p.Length; i++)
485                                                 get_item.DefineParameter (
486                                                         i + 1,
487                                                         p [i].Attributes, p [i].Name);
488                                 }
489                         }
490
491                         if (ii.HasSet){
492                                 Parameter [] p = ii.Parameters.FixedParameters;
493                                 Parameter [] pv;
494                                 int i = 0;
495                                 
496                                 pv = new Parameter [p.Length + 1];
497                                 p.CopyTo (pv, 0);
498                                 pv [p.Length] = new Parameter (ii.Type, "value", Parameter.Modifier.NONE, null);
499                                 Parameters value_params = new Parameters (pv, null, Location.Null);
500                                 value_params.GetParameterInfo (decl_space);
501                                 
502                                 set_item = TypeBuilder.DefineMethod (
503                                         "set_Item", property_attributes,
504                                         TypeManager.void_type, value_arg_types);
505                                 pb.SetSetMethod (set_item);
506                                 //
507                                 // HACK because System.Reflection.Emit is lame
508                                 //
509                                 InternalParameters ip = new InternalParameters (
510                                         value_arg_types, value_params);
511                                 if (!RegisterMethod (set_item, ip, value_arg_types)) {
512                                         Error111 (ii);
513                                         return;
514                                 }
515
516                                 if (p != null){
517                                         for (; i < p.Length; i++)
518                                                 set_item.DefineParameter (
519                                                         i + 1,
520                                                         p [i].Attributes, p [i].Name);
521                                 }
522                                 
523                                 set_item.DefineParameter (i + 1, ParameterAttributes.None, "value");
524                         }
525
526                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
527                                                           null, ModFlags, false);
528
529                         if (ii.OptAttributes != null)
530                                 Attribute.ApplyAttributes (ec, pb, ii, ii.OptAttributes, Location);
531
532                         property_builders.Add (pb);
533                 }
534
535                 /// <summary>
536                 ///   Performs the semantic analysis for all the interface members
537                 ///   that were declared
538                 /// </summary>
539                 bool SemanticAnalysis ()
540                 {
541                         Hashtable methods = new Hashtable ();
542
543                         
544                         if (defined_method != null){
545                                 foreach (InterfaceMethod im in defined_method){
546                                         string sig = im.GetSignature (this);
547                                         
548                                         //
549                                         // If there was an undefined Type on the signatures
550                                         // 
551                                         if (sig == null)
552                                                 continue;
553                                         
554                                         if (methods [sig] != null){
555                                                 Error111 (im);
556                                                 return false;
557                                         }
558                                 }
559                         }
560
561                         //
562                         // FIXME: Here I should check i
563                         // 
564                         return true;
565                 }
566
567                 Type GetInterfaceTypeByName (string name)
568                 {
569                         Type t = FindType (name);
570
571                         if (t == null)
572                                 return null;
573                         
574                         if (t.IsInterface)
575                                 return t;
576                                 
577                         string cause;
578                         
579                         if (t.IsValueType)
580                                 cause = "is a struct";
581                         else if (t.IsClass) 
582                                 cause = "is a class";
583                         else
584                                 cause = "Should not happen.";
585                         
586                         Report.Error (527, Location, "`"+name+"' " + cause +
587                                       ", need an interface instead");
588                         
589                         return null;
590                 }
591                 
592                 //
593                 // Returns the list of interfaces that this interface implements
594                 // Or null if it does not implement any interface.
595                 //
596                 // Sets the error boolean accoringly.
597                 //
598                 Type [] GetInterfaceBases (out bool error)
599                 {
600                         Type [] tbases;
601                         int i;
602
603                         error = false;
604                         if (Bases == null)
605                                 return null;
606                         
607                         tbases = new Type [Bases.Count];
608                         i = 0;
609
610                         foreach (string name in Bases){
611                                 Type t;
612
613                                 t = GetInterfaceTypeByName (name);
614                                 if (t == null){
615                                         error = true;
616                                         return null;
617                                 }
618                                 
619                                 tbases [i++] = t;
620                         }
621                         
622                         return TypeManager.ExpandInterfaces (tbases);
623                 }
624                 
625                 //
626                 // <summary>
627                 //  Defines the Interface in the appropriate ModuleBuilder or TypeBuilder
628                 // </summary>
629                 //
630                 // TODO:
631                 //   Rework the way we recurse, because for recursive
632                 //   definitions of interfaces (A:B and B:A) we report the
633                 //   error twice, rather than once.  
634                 
635                 public override TypeBuilder DefineType ()
636                 {
637                         Type [] ifaces;
638                         bool error;
639
640                         if (TypeBuilder != null)
641                                 return TypeBuilder;
642                         
643                         if (InTransit)
644                                 return null;
645                         
646                         InTransit = true;
647                         
648                         ifaces = GetInterfaceBases (out error);
649
650                         if (error)
651                                 return null;
652
653                         if (IsTopLevel) {
654                                 ModuleBuilder builder = CodeGen.ModuleBuilder;
655
656                                 TypeBuilder = builder.DefineType (
657                                         Name,
658                                         InterfaceAttr,
659                                         (Type)null,   // Parent Type
660                                         ifaces);
661                                 RootContext.RegisterOrder (this);
662                         } else {
663                                 TypeBuilder builder = Parent.TypeBuilder;
664
665                                 TypeBuilder = builder.DefineNestedType (
666                                         Basename,
667                                         InterfaceAttr,
668                                         (Type) null, //parent type
669                                         ifaces);
670
671                                 TypeContainer tc = TypeManager.LookupTypeContainer (builder);
672                                 tc.RegisterOrder (this);
673                         }
674
675                         TypeManager.AddUserInterface (Name, TypeBuilder, this, ifaces);
676                         InTransit = false;
677                         
678                         return TypeBuilder;
679                 }
680                 
681                 /// <summary>
682                 ///   Performs semantic analysis, and then generates the IL interfaces
683                 /// </summary>
684                 public override bool Define (TypeContainer parent)
685                 {
686                         if (!SemanticAnalysis ())
687                                 return false;
688
689                         if (defined_method != null){
690                                 foreach (InterfaceMethod im in defined_method)
691                                         PopulateMethod (parent, this, im);
692                         }
693
694                         if (defined_properties != null){
695                                 foreach (InterfaceProperty ip in defined_properties)
696                                         PopulateProperty (parent, this, ip);
697                         }
698
699                         if (defined_events != null)
700                                 foreach (InterfaceEvent ie in defined_events)
701                                         PopulateEvent (parent, this, ie);
702
703                         //
704                         // FIXME: Pull the right indexer name out of the `IndexerName' attribute
705                         //
706                         if (defined_indexer != null) {
707                                 foreach (InterfaceIndexer ii in defined_indexer)
708                                         PopulateIndexer (parent, this, ii);
709
710                                 CustomAttributeBuilder cb = EmitDefaultMemberAttr (
711                                         parent, "Item", ModFlags, Location);
712                                 if (cb != null)
713                                         TypeBuilder.SetCustomAttribute (cb);
714                         }
715                         
716                         return true;
717                 }
718
719                 public static CustomAttributeBuilder EmitDefaultMemberAttr (TypeContainer parent,
720                                                                             string name,
721                                                                             int flags,
722                                                                             Location loc)
723                 {
724                         EmitContext ec = new EmitContext (parent, loc, null, null, flags);
725
726                         Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
727                                                                  ".ctor", MemberTypes.Constructor,
728                                                                  BindingFlags.Public | BindingFlags.Instance,
729                                                                  Location.Null);
730                         
731                         if (!(ml is MethodGroupExpr)) {
732                                 Console.WriteLine ("Internal error !!!!");
733                                 return null;
734                         }
735                         
736                         MethodGroupExpr mg = (MethodGroupExpr) ml;
737
738                         MethodBase constructor = mg.Methods [0];
739
740                         string [] vals = { name };
741
742                         CustomAttributeBuilder cb = null;
743                         try {
744                                 cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
745                         } catch {
746                                 Report.Warning (-100, "Can not set the indexer default member attribute");
747                         }
748
749                         return cb;
750                 }
751
752         }
753
754         public class InterfaceMemberBase {
755                 public readonly string Name;
756                 public readonly bool IsNew;
757                 public Attributes OptAttributes;
758                 
759                 public InterfaceMemberBase (string name, bool is_new, Attributes attrs)
760                 {
761                         Name = name;
762                         IsNew = is_new;
763                         OptAttributes = attrs;
764                 }
765         }
766         
767         public class InterfaceProperty : InterfaceMemberBase {
768                 public readonly bool HasSet;
769                 public readonly bool HasGet;
770                 public readonly string Type;
771                 public readonly string type;
772                 public readonly Location Location;
773                 
774                 public InterfaceProperty (string type, string name,
775                                           bool is_new, bool has_get, bool has_set,
776                                           Attributes attrs, Location loc)
777                         : base (name, is_new, attrs)
778                 {
779                         Type = type;
780                         HasGet = has_get;
781                         HasSet = has_set;
782                         Location = loc;
783                 }
784         }
785
786         public class InterfaceEvent : InterfaceMemberBase {
787                 public readonly string Type;
788                 
789                 public InterfaceEvent (string type, string name, bool is_new, Attributes attrs)
790                         : base (name, is_new, attrs)
791                 {
792                         Type = type;
793                 }
794         }
795         
796         public class InterfaceMethod : InterfaceMemberBase {
797                 public readonly string     ReturnType;
798                 public readonly Parameters Parameters;
799                 public readonly Location Location;
800                 
801                 public InterfaceMethod (string return_type, string name, bool is_new, Parameters args,
802                                         Attributes attrs, Location l)
803                         : base (name, is_new, attrs)
804                 {
805                         this.ReturnType = return_type;
806                         this.Parameters = args;
807                         Location = l;
808                 }
809
810                 /// <summary>
811                 ///   Returns the signature for this interface method
812                 /// </summary>
813                 public string GetSignature (DeclSpace ds)
814                 {
815                         Type ret = RootContext.LookupType (ds, ReturnType, false, Location);
816                         string args = Parameters.GetSignature (ds);
817
818                         if ((ret == null) || (args == null))
819                                 return null;
820                         
821                         return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
822                 }
823
824                 public Type [] ParameterTypes (DeclSpace ds)
825                 {
826                         return Parameters.GetParameterInfo (ds);
827                 }
828         }
829
830         public class InterfaceIndexer : InterfaceMemberBase {
831                 public readonly bool HasGet, HasSet;
832                 public readonly Parameters Parameters;
833                 public readonly string Type;
834                 public readonly Location Location;
835                 
836                 public InterfaceIndexer (string type, Parameters args, bool do_get, bool do_set,
837                                          bool is_new, Attributes attrs, Location loc)
838                         : base ("", is_new, attrs)
839                 {
840                         Type = type;
841                         Parameters = args;
842                         HasGet = do_get;
843                         HasSet = do_set;
844                         Location = loc;
845                 }
846
847                 public Type [] ParameterTypes (DeclSpace ds)
848                 {
849                         return Parameters.GetParameterInfo (ds);
850                 }
851         }
852 }