In System.Xml:
[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 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){
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                                 int i = 0;
494                                 
495                                 set_item = TypeBuilder.DefineMethod (
496                                         "set_Item", property_attributes,
497                                         TypeManager.void_type, value_arg_types);
498                                 pb.SetSetMethod (set_item);
499                                 //
500                                 // HACK because System.Reflection.Emit is lame
501                                 //
502                                 InternalParameters ip = new InternalParameters (
503                                         value_arg_types, ii.Parameters);
504                                 if (!RegisterMethod (set_item, ip, value_arg_types)) {
505                                         Error111 (ii);
506                                         return;
507                                 }
508
509                                 if (p != null){
510                                         for (; i < p.Length; i++)
511                                                 set_item.DefineParameter (
512                                                         i + 1,
513                                                         p [i].Attributes, p [i].Name);
514                                 }
515                                 
516                                 set_item.DefineParameter (i + 1, ParameterAttributes.None, "value");
517                         }
518
519                         EmitContext ec = new EmitContext (parent, decl_space, Location, null,
520                                                           null, ModFlags, false);
521
522                         if (ii.OptAttributes != null)
523                                 Attribute.ApplyAttributes (ec, pb, ii, ii.OptAttributes, Location);
524                 }
525
526                 /// <summary>
527                 ///   Performs the semantic analysis for all the interface members
528                 ///   that were declared
529                 /// </summary>
530                 bool SemanticAnalysis ()
531                 {
532                         Hashtable methods = new Hashtable ();
533
534                         
535                         if (defined_method != null){
536                                 foreach (InterfaceMethod im in defined_method){
537                                         string sig = im.GetSignature (this);
538                                         
539                                         //
540                                         // If there was an undefined Type on the signatures
541                                         // 
542                                         if (sig == null)
543                                                 continue;
544                                         
545                                         if (methods [sig] != null){
546                                                 Error111 (im);
547                                                 return false;
548                                         }
549                                 }
550                         }
551
552                         //
553                         // FIXME: Here I should check i
554                         // 
555                         return true;
556                 }
557
558                 Type GetInterfaceTypeByName (string name)
559                 {
560                         Type t = FindType (name);
561
562                         if (t == null)
563                                 return null;
564                         
565                         if (t.IsInterface)
566                                 return t;
567                                 
568                         string cause;
569                         
570                         if (t.IsValueType)
571                                 cause = "is a struct";
572                         else if (t.IsClass) 
573                                 cause = "is a class";
574                         else
575                                 cause = "Should not happen.";
576                         
577                         Report.Error (527, Location, "`"+name+"' " + cause +
578                                       ", need an interface instead");
579                         
580                         return null;
581                 }
582                 
583                 //
584                 // Returns the list of interfaces that this interface implements
585                 // Or null if it does not implement any interface.
586                 //
587                 // Sets the error boolean accoringly.
588                 //
589                 Type [] GetInterfaceBases (out bool error)
590                 {
591                         Type [] tbases;
592                         int i;
593
594                         error = false;
595                         if (Bases == null)
596                                 return null;
597                         
598                         tbases = new Type [Bases.Count];
599                         i = 0;
600
601                         foreach (string name in Bases){
602                                 Type t;
603
604                                 t = GetInterfaceTypeByName (name);
605                                 if (t == null){
606                                         error = true;
607                                         return null;
608                                 }
609                                 
610                                 tbases [i++] = t;
611                         }
612                         
613                         return tbases;
614                 }
615                 
616                 //
617                 // <summary>
618                 //  Defines the Interface in the appropriate ModuleBuilder or TypeBuilder
619                 // </summary>
620                 //
621                 // TODO:
622                 //   Rework the way we recurse, because for recursive
623                 //   definitions of interfaces (A:B and B:A) we report the
624                 //   error twice, rather than once.  
625                 
626                 public override TypeBuilder DefineType ()
627                 {
628                         Type [] ifaces;
629                         bool error;
630
631                         if (TypeBuilder != null)
632                                 return TypeBuilder;
633                         
634                         if (InTransit)
635                                 return null;
636                         
637                         InTransit = true;
638                         
639                         ifaces = GetInterfaceBases (out error);
640
641                         if (error)
642                                 return null;
643
644                         if (IsTopLevel) {
645                                 ModuleBuilder builder = CodeGen.ModuleBuilder;
646
647                                 TypeBuilder = builder.DefineType (
648                                         Name,
649                                         InterfaceAttr,
650                                         (Type)null,   // Parent Type
651                                         ifaces);
652                                 RootContext.RegisterOrder (this);
653                         } else {
654                                 TypeBuilder builder = Parent.TypeBuilder;
655
656                                 TypeBuilder = builder.DefineNestedType (
657                                         Basename,
658                                         InterfaceAttr,
659                                         (Type) null, //parent type
660                                         ifaces);
661
662                                 TypeContainer tc = TypeManager.LookupTypeContainer (builder);
663                                 tc.RegisterOrder (this);
664                         }
665
666                         TypeManager.AddUserInterface (Name, TypeBuilder, this, ifaces);
667                         InTransit = false;
668                         
669                         return TypeBuilder;
670                 }
671                 
672                 /// <summary>
673                 ///   Performs semantic analysis, and then generates the IL interfaces
674                 /// </summary>
675                 public override bool Define (TypeContainer parent)
676                 {
677                         if (!SemanticAnalysis ())
678                                 return false;
679
680                         if (defined_method != null){
681                                 foreach (InterfaceMethod im in defined_method)
682                                         PopulateMethod (parent, this, im);
683                         }
684
685                         if (defined_properties != null){
686                                 foreach (InterfaceProperty ip in defined_properties)
687                                         PopulateProperty (parent, this, ip);
688                         }
689
690                         if (defined_events != null)
691                                 foreach (InterfaceEvent ie in defined_events)
692                                         PopulateEvent (parent, this, ie);
693
694                         //
695                         // FIXME: Pull the right indexer name out of the `IndexerName' attribute
696                         //
697                         if (defined_indexer != null) {
698                                 foreach (InterfaceIndexer ii in defined_indexer)
699                                         PopulateIndexer (parent, this, ii);
700
701                                 CustomAttributeBuilder cb = EmitDefaultMemberAttr (
702                                         parent, "Item", ModFlags, Location);
703                                 if (cb != null)
704                                         TypeBuilder.SetCustomAttribute (cb);
705                         }
706                         
707                         return true;
708                 }
709
710                 public static CustomAttributeBuilder EmitDefaultMemberAttr (TypeContainer parent,
711                                                                             string name,
712                                                                             int flags,
713                                                                             Location loc)
714                 {
715                         EmitContext ec = new EmitContext (parent, loc, null, null, flags);
716
717                         Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
718                                                                  ".ctor", MemberTypes.Constructor,
719                                                                  BindingFlags.Public | BindingFlags.Instance,
720                                                                  Location.Null);
721                         
722                         if (!(ml is MethodGroupExpr)) {
723                                 Console.WriteLine ("Internal error !!!!");
724                                 return null;
725                         }
726                         
727                         MethodGroupExpr mg = (MethodGroupExpr) ml;
728
729                         MethodBase constructor = mg.Methods [0];
730
731                         string [] vals = { name };
732
733                         CustomAttributeBuilder cb = null;
734                         try {
735                                 cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
736                         } catch {
737                                 Report.Warning (-100, "Can not set the indexer default member attribute");
738                         }
739
740                         return cb;
741                 }
742
743         }
744
745         public class InterfaceMemberBase {
746                 public readonly string Name;
747                 public readonly bool IsNew;
748                 public Attributes OptAttributes;
749                 
750                 public InterfaceMemberBase (string name, bool is_new, Attributes attrs)
751                 {
752                         Name = name;
753                         IsNew = is_new;
754                         OptAttributes = attrs;
755                 }
756         }
757         
758         public class InterfaceProperty : InterfaceMemberBase {
759                 public readonly bool HasSet;
760                 public readonly bool HasGet;
761                 public readonly string Type;
762                 public readonly string type;
763                 public readonly Location Location;
764                 
765                 public InterfaceProperty (string type, string name,
766                                           bool is_new, bool has_get, bool has_set,
767                                           Attributes attrs, Location loc)
768                         : base (name, is_new, attrs)
769                 {
770                         Type = type;
771                         HasGet = has_get;
772                         HasSet = has_set;
773                         Location = loc;
774                 }
775         }
776
777         public class InterfaceEvent : InterfaceMemberBase {
778                 public readonly string Type;
779                 
780                 public InterfaceEvent (string type, string name, bool is_new, Attributes attrs)
781                         : base (name, is_new, attrs)
782                 {
783                         Type = type;
784                 }
785         }
786         
787         public class InterfaceMethod : InterfaceMemberBase {
788                 public readonly string     ReturnType;
789                 public readonly Parameters Parameters;
790                 public readonly Location Location;
791                 
792                 public InterfaceMethod (string return_type, string name, bool is_new, Parameters args,
793                                         Attributes attrs, Location l)
794                         : base (name, is_new, attrs)
795                 {
796                         this.ReturnType = return_type;
797                         this.Parameters = args;
798                         Location = l;
799                 }
800
801                 /// <summary>
802                 ///   Returns the signature for this interface method
803                 /// </summary>
804                 public string GetSignature (DeclSpace ds)
805                 {
806                         Type ret = RootContext.LookupType (ds, ReturnType, false, Location);
807                         string args = Parameters.GetSignature (ds);
808
809                         if ((ret == null) || (args == null))
810                                 return null;
811                         
812                         return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
813                 }
814
815                 public Type [] ParameterTypes (DeclSpace ds)
816                 {
817                         return Parameters.GetParameterInfo (ds);
818                 }
819         }
820
821         public class InterfaceIndexer : InterfaceMemberBase {
822                 public readonly bool HasGet, HasSet;
823                 public readonly Parameters Parameters;
824                 public readonly string Type;
825                 public readonly Location Location;
826                 
827                 public InterfaceIndexer (string type, Parameters args, bool do_get, bool do_set,
828                                          bool is_new, Attributes attrs, Location loc)
829                         : base ("", is_new, attrs)
830                 {
831                         Type = type;
832                         Parameters = args;
833                         HasGet = do_get;
834                         HasSet = do_set;
835                         Location = loc;
836                 }
837
838                 public Type [] ParameterTypes (DeclSpace ds)
839                 {
840                         return Parameters.GetParameterInfo (ds);
841                 }
842         }
843 }