Added target 'clean' so as make clean in the parent directory does not fail.
[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 (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
328                 //
329                 // Populates the properties in the interface
330                 //
331                 void PopulateProperty (InterfaceProperty ip)
332                 {
333                         PropertyBuilder pb;
334                         MethodBuilder get = null, set = null;
335                         Type prop_type = RootContext.LookupType (this, ip.Type, false, ip.Location);
336                         Type [] setter_args = new Type [1];
337
338                         if (prop_type == null)
339                                 return;
340
341                         if (prop_type.IsPointer && !UnsafeOK (this))
342                                 return;
343                         
344                         setter_args [0] = prop_type;
345
346                         //
347                         // FIXME: properties are missing the following
348                         // flags: hidebysig newslot specialname
349                         //
350                         pb = TypeBuilder.DefineProperty (
351                                 ip.Name, PropertyAttributes.None,
352                                 prop_type, null);
353
354                         if (ip.HasGet){
355                                 get = TypeBuilder.DefineMethod (
356                                         "get_" + ip.Name, property_attributes ,
357                                         prop_type, null);
358
359                                 //
360                                 // HACK because System.Reflection.Emit is lame
361                                 //
362                                 Type [] null_types = null;
363                                 InternalParameters inp = new InternalParameters
364                                         (null_types, Parameters.GetEmptyReadOnlyParameters ());
365                                 
366                                 if (!RegisterMethod (get, inp, null)) {
367                                         Error111 (ip);
368                                         return;
369                                 }
370                                 
371                                 pb.SetGetMethod (get);
372                         }
373
374                         if (ip.HasSet){
375                                 setter_args [0] = prop_type;
376
377                                 set = TypeBuilder.DefineMethod (
378                                         "set_" + ip.Name, property_attributes,
379                                         TypeManager.void_type, setter_args);
380
381                                 set.DefineParameter (1, ParameterAttributes.None, "value");
382                                 pb.SetSetMethod (set);
383
384                                 //
385                                 // HACK because System.Reflection.Emit is lame
386                                 //
387                                 Parameter [] parms = new Parameter [1];
388                                 parms [0] = new Parameter (ip.Type, "value", Parameter.Modifier.NONE, null);
389                                 InternalParameters ipp = new InternalParameters (
390                                         this, new Parameters (parms, null, Location.Null));
391                                         
392                                 if (!RegisterMethod (set, ipp, setter_args)) {
393                                         Error111 (ip);
394                                         return;
395                                 }
396                         }
397
398                         TypeManager.RegisterProperty (pb, get, set);
399                         property_builders.Add (pb);
400                 }
401
402                 //
403                 // Populates the events in the interface
404                 //
405                 void PopulateEvent (InterfaceEvent ie)
406                 {
407                         //
408                         // FIXME: We need to do this after delegates have been
409                         // declared or we declare them recursively.
410                         //
411                 }
412
413                 //
414                 // Populates the indexers in the interface
415                 //
416                 void PopulateIndexer (InterfaceIndexer ii)
417                 {
418                         PropertyBuilder pb;
419                         Type prop_type = RootContext.LookupType (this, ii.Type, false, ii.Location);
420                         Type [] arg_types = ii.ParameterTypes (this);
421                         Type [] value_arg_types;
422
423                         if (prop_type == null)
424                                 return;
425
426                         if (prop_type.IsPointer && !UnsafeOK (this))
427                                 return;
428                         
429                         //
430                         // Sets up the extra invisible `value' argument for setters.
431                         // 
432                         if (arg_types != null){
433                                 int count = arg_types.Length;
434                                 value_arg_types = new Type [count + 1];
435
436                                 arg_types.CopyTo (value_arg_types, 0);
437                                 value_arg_types [count] = prop_type;
438
439                                 foreach (Type t in arg_types){
440                                         if (t.IsPointer && !UnsafeOK (this))
441                                                 return;
442                                 }
443                         } else {
444                                 value_arg_types = new Type [1];
445
446                                 value_arg_types [1] = prop_type;
447                         }
448
449                         pb = TypeBuilder.DefineProperty (
450                                 "Item", PropertyAttributes.None,
451                                 prop_type, arg_types);
452
453                         if (ii.HasGet){
454                                 MethodBuilder get_item;
455                                 Parameter [] p = ii.Parameters.FixedParameters;
456                                 
457                                 get_item = TypeBuilder.DefineMethod (
458                                         "get_Item", property_attributes, prop_type, arg_types);
459                                 pb.SetGetMethod (get_item);
460                                 //
461                                 // HACK because System.Reflection.Emit is lame
462                                 //
463                                 InternalParameters ip = new InternalParameters (
464                                         arg_types, ii.Parameters);
465                                 
466                                 if (!RegisterMethod (get_item, ip, arg_types)) {
467                                         Error111 (ii);
468                                         return;
469                                 }
470
471                                 if (p != null){
472                                         for (int i = 0; i < p.Length; i++)
473                                                 get_item.DefineParameter (
474                                                         i + 1,
475                                                         p [i].Attributes, p [i].Name);
476                                 }
477                         }
478
479                         if (ii.HasSet){
480                                 Parameter [] p = ii.Parameters.FixedParameters;
481                                 MethodBuilder set_item;
482                                 int i = 0;
483                                 
484                                 set_item = TypeBuilder.DefineMethod (
485                                         "set_Item", property_attributes,
486                                         TypeManager.void_type, value_arg_types);
487                                 pb.SetSetMethod (set_item);
488                                 //
489                                 // HACK because System.Reflection.Emit is lame
490                                 //
491                                 InternalParameters ip = new InternalParameters (
492                                         value_arg_types, ii.Parameters);
493                                 if (!RegisterMethod (set_item, ip, value_arg_types)) {
494                                         Error111 (ii);
495                                         return;
496                                 }
497
498                                 if (p != null){
499                                         for (; i < p.Length; i++)
500                                                 set_item.DefineParameter (
501                                                         i + 1,
502                                                         p [i].Attributes, p [i].Name);
503                                 }
504                                 
505                                 set_item.DefineParameter (i + 1, ParameterAttributes.None, "value");
506                         }
507                 }
508
509                 /// <summary>
510                 ///   Performs the semantic analysis for all the interface members
511                 ///   that were declared
512                 /// </summary>
513                 bool SemanticAnalysis ()
514                 {
515                         Hashtable methods = new Hashtable ();
516
517                         
518                         if (defined_method != null){
519                                 foreach (InterfaceMethod im in defined_method){
520                                         string sig = im.GetSignature (this);
521                                         
522                                         //
523                                         // If there was an undefined Type on the signatures
524                                         // 
525                                         if (sig == null)
526                                                 continue;
527                                         
528                                         if (methods [sig] != null){
529                                                 Error111 (im);
530                                                 return false;
531                                         }
532                                 }
533                         }
534
535                         //
536                         // FIXME: Here I should check i
537                         // 
538                         return true;
539                 }
540
541                 Type GetInterfaceTypeByName (string name)
542                 {
543                         Type t = FindType (name);
544
545                         if (t == null)
546                                 return null;
547                         
548                         if (t.IsInterface)
549                                 return t;
550                                 
551                         string cause;
552                         
553                         if (t.IsValueType)
554                                 cause = "is a struct";
555                         else if (t.IsClass) 
556                                 cause = "is a class";
557                         else
558                                 cause = "Should not happen.";
559                         
560                         Report.Error (527, Location, "`"+name+"' " + cause +
561                                       ", need an interface instead");
562                         
563                         return null;
564                 }
565                 
566                 //
567                 // Returns the list of interfaces that this interface implements
568                 // Or null if it does not implement any interface.
569                 //
570                 // Sets the error boolean accoringly.
571                 //
572                 Type [] GetInterfaceBases (out bool error)
573                 {
574                         Type [] tbases;
575                         int i;
576
577                         error = false;
578                         if (Bases == null)
579                                 return null;
580                         
581                         tbases = new Type [Bases.Count];
582                         i = 0;
583
584                         foreach (string name in Bases){
585                                 Type t;
586
587                                 t = GetInterfaceTypeByName (name);
588                                 if (t == null){
589                                         error = true;
590                                         return null;
591                                 }
592                                 
593                                 tbases [i++] = t;
594                         }
595                         
596                         return tbases;
597                 }
598                 
599                 //
600                 // <summary>
601                 //  Defines the Interface in the appropriate ModuleBuilder or TypeBuilder
602                 // </summary>
603                 //
604                 // TODO:
605                 //   Rework the way we recurse, because for recursive
606                 //   definitions of interfaces (A:B and B:A) we report the
607                 //   error twice, rather than once.  
608                 
609                 public override TypeBuilder DefineType ()
610                 {
611                         Type [] ifaces;
612                         bool error;
613
614                         if (TypeBuilder != null)
615                                 return TypeBuilder;
616                         
617                         if (InTransit)
618                                 return null;
619                         
620                         InTransit = true;
621                         
622                         ifaces = GetInterfaceBases (out error);
623
624                         if (error)
625                                 return null;
626
627                         if (IsTopLevel) {
628                                 ModuleBuilder builder = CodeGen.ModuleBuilder;
629
630                                 TypeBuilder = builder.DefineType (
631                                         Name,
632                                         InterfaceAttr,
633                                         (Type)null,   // Parent Type
634                                         ifaces);
635                                 RootContext.RegisterOrder (this);
636                         } else {
637                                 TypeBuilder builder = Parent.TypeBuilder;
638
639                                 TypeBuilder = builder.DefineNestedType (
640                                         Basename,
641                                         InterfaceAttr,
642                                         (Type) null, //parent type
643                                         ifaces);
644
645                                 TypeContainer tc = TypeManager.LookupTypeContainer (builder);
646                                 tc.RegisterOrder (this);
647                         }
648                         
649                         TypeManager.AddUserInterface (Name, TypeBuilder, this);
650                         InTransit = false;
651                         
652                         return TypeBuilder;
653                 }
654                 
655                 /// <summary>
656                 ///   Performs semantic analysis, and then generates the IL interfaces
657                 /// </summary>
658                 public override bool Define (TypeContainer parent)
659                 {
660                         if (!SemanticAnalysis ())
661                                 return false;
662
663                         if (defined_method != null){
664                                 foreach (InterfaceMethod im in defined_method)
665                                         PopulateMethod (im);
666                         }
667
668                         if (defined_properties != null){
669                                 foreach (InterfaceProperty ip in defined_properties)
670                                         PopulateProperty (ip);
671                         }
672
673                         if (defined_events != null)
674                                 foreach (InterfaceEvent ie in defined_events)
675                                         PopulateEvent (ie);
676
677                         if (defined_indexer != null) {
678                                 foreach (InterfaceIndexer ii in defined_indexer)
679                                         PopulateIndexer (ii);
680
681                                 CustomAttributeBuilder cb = EmitDefaultMemberAttr (parent, ModFlags, Location);
682                                 if (cb != null)
683                                         TypeBuilder.SetCustomAttribute (cb);
684                         }
685                         
686                         return true;
687                 }
688
689                 public static CustomAttributeBuilder EmitDefaultMemberAttr (TypeContainer parent, int flags,
690                                                                             Location loc)
691                 {
692                         EmitContext ec = new EmitContext (parent, loc, null, null, flags);
693
694                         Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
695                                                                  ".ctor", MemberTypes.Constructor,
696                                                                  BindingFlags.Public | BindingFlags.Instance,
697                                                                  Location.Null);
698                         
699                         if (!(ml is MethodGroupExpr)) {
700                                 Console.WriteLine ("Internal error !!!!");
701                                 return null;
702                         }
703                         
704                         MethodGroupExpr mg = (MethodGroupExpr) ml;
705
706                         MethodBase constructor = mg.Methods [0];
707
708                         string [] vals = { "Item" };
709
710                         CustomAttributeBuilder cb = null;
711                         try {
712                                 cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
713                         } catch {
714                                 Report.Warning (-100, "Can not set the indexer default member attribute");
715                         }
716
717                         return cb;
718                 }
719
720         }
721
722         public class InterfaceMemberBase {
723                 public readonly string Name;
724                 public readonly bool IsNew;
725                 public Attributes OptAttributes;
726                 
727                 public InterfaceMemberBase (string name, bool is_new, Attributes attrs)
728                 {
729                         Name = name;
730                         IsNew = is_new;
731                         OptAttributes = attrs;
732                 }
733         }
734         
735         public class InterfaceProperty : InterfaceMemberBase {
736                 public readonly bool HasSet;
737                 public readonly bool HasGet;
738                 public readonly string Type;
739                 public readonly string type;
740                 public readonly Location Location;
741                 
742                 public InterfaceProperty (string type, string name,
743                                           bool is_new, bool has_get, bool has_set,
744                                           Attributes attrs, Location loc)
745                         : base (name, is_new, attrs)
746                 {
747                         Type = type;
748                         HasGet = has_get;
749                         HasSet = has_set;
750                         Location = loc;
751                 }
752         }
753
754         public class InterfaceEvent : InterfaceMemberBase {
755                 public readonly string Type;
756                 
757                 public InterfaceEvent (string type, string name, bool is_new, Attributes attrs)
758                         : base (name, is_new, attrs)
759                 {
760                         Type = type;
761                 }
762         }
763         
764         public class InterfaceMethod : InterfaceMemberBase {
765                 public readonly string     ReturnType;
766                 public readonly Parameters Parameters;
767                 public readonly Location Location;
768                 
769                 public InterfaceMethod (string return_type, string name, bool is_new, Parameters args,
770                                         Attributes attrs, Location l)
771                         : base (name, is_new, attrs)
772                 {
773                         this.ReturnType = return_type;
774                         this.Parameters = args;
775                         Location = l;
776                 }
777
778                 /// <summary>
779                 ///   Returns the signature for this interface method
780                 /// </summary>
781                 public string GetSignature (DeclSpace ds)
782                 {
783                         Type ret = RootContext.LookupType (ds, ReturnType, false, Location);
784                         string args = Parameters.GetSignature (ds);
785
786                         if ((ret == null) || (args == null))
787                                 return null;
788                         
789                         return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
790                 }
791
792                 public Type [] ParameterTypes (DeclSpace ds)
793                 {
794                         return Parameters.GetParameterInfo (ds);
795                 }
796         }
797
798         public class InterfaceIndexer : InterfaceMemberBase {
799                 public readonly bool HasGet, HasSet;
800                 public readonly Parameters Parameters;
801                 public readonly string Type;
802                 public readonly Location Location;
803                 
804                 public InterfaceIndexer (string type, Parameters args, bool do_get, bool do_set,
805                                          bool is_new, Attributes attrs, Location loc)
806                         : base ("", is_new, attrs)
807                 {
808                         Type = type;
809                         Parameters = args;
810                         HasGet = do_get;
811                         HasSet = do_set;
812                         Location = loc;
813                 }
814
815                 public Type [] ParameterTypes (DeclSpace ds)
816                 {
817                         return Parameters.GetParameterInfo (ds);
818                 }
819         }
820 }