* Makefile: integrate Mono.Mozilla wrapper in the build.
[mono.git] / mcs / mcs / parameter.cs
1 //
2 // parameter.cs: Parameter definition.
3 //
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 //         Marek Safar (marek.safar@seznam.cz)
6 //
7 // Licensed under the terms of the GNU GPL
8 //
9 // (C) 2001 Ximian, Inc (http://www.ximian.com)
10 //
11 //
12 //
13 using System;
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Collections;
17 using System.Text;
18
19 namespace Mono.CSharp {
20
21         /// <summary>
22         ///   Abstract Base class for parameters of a method.
23         /// </summary>
24         public abstract class ParameterBase : Attributable {
25
26                 protected ParameterBuilder builder;
27
28                 protected ParameterBase (Attributes attrs)
29                         : base (attrs)
30                 {
31                 }
32
33                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
34                 {
35                         if (a.Type == TypeManager.marshal_as_attr_type) {
36                                 UnmanagedMarshal marshal = a.GetMarshal (this);
37                                 if (marshal != null) {
38                                         builder.SetMarshal (marshal);
39                                 }
40                                 return;
41                         }
42
43                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
44                                 a.Error_InvalidSecurityParent ();
45                                 return;
46                         }
47
48                         builder.SetCustomAttribute (cb);
49                 }
50
51                 public override bool IsClsComplianceRequired()
52                 {
53                         return false;
54                 }
55         }
56
57         /// <summary>
58         /// Class for applying custom attributes on the return type
59         /// </summary>
60         public class ReturnParameter : ParameterBase {
61                 public ReturnParameter (MethodBuilder mb, Location location):
62                         base (null)
63                 {
64                         try {
65                                 builder = mb.DefineParameter (0, ParameterAttributes.None, "");                 
66                         }
67                         catch (ArgumentOutOfRangeException) {
68                                 Report.RuntimeMissingSupport (location, "custom attributes on the return type");
69                         }
70                 }
71
72                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
73                 {
74                         if (a.Type == TypeManager.cls_compliant_attribute_type) {
75                                 Report.Warning (3023, 1, a.Location, "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
76                         }
77
78                         // This occurs after Warning -28
79                         if (builder == null)
80                                 return;
81
82                         base.ApplyAttributeBuilder (a, cb);
83                 }
84
85                 public override AttributeTargets AttributeTargets {
86                         get {
87                                 return AttributeTargets.ReturnValue;
88                         }
89                 }
90
91                 public override IResolveContext ResolveContext {
92                         get {
93                                 throw new NotSupportedException ();
94                         }
95                 }
96
97                 /// <summary>
98                 /// Is never called
99                 /// </summary>
100                 public override string[] ValidAttributeTargets {
101                         get {
102                                 return null;
103                         }
104                 }
105         }
106
107         /// <summary>
108         /// Class for applying custom attributes on the implicit parameter type
109         /// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
110         /// </summary>
111         /// 
112         // TODO: should use more code from Parameter.ApplyAttributeBuilder
113         public class ImplicitParameter : ParameterBase {
114                 public ImplicitParameter (MethodBuilder mb):
115                         base (null)
116                 {
117                         builder = mb.DefineParameter (1, ParameterAttributes.None, "");                 
118                 }
119
120                 public override AttributeTargets AttributeTargets {
121                         get {
122                                 return AttributeTargets.Parameter;
123                         }
124                 }
125
126                 public override IResolveContext ResolveContext {
127                         get {
128                                 throw new NotSupportedException ();
129                         }
130                 }
131
132                 /// <summary>
133                 /// Is never called
134                 /// </summary>
135                 public override string[] ValidAttributeTargets {
136                         get {
137                                 return null;
138                         }
139                 }
140         }
141
142         public class ImplicitLambdaParameter : Parameter
143         {
144                 public ImplicitLambdaParameter (string name, Location loc)
145                         : base ((Type)null, name, Modifier.NONE, null, loc)
146                 {
147                 }
148
149                 public override bool Resolve (IResolveContext ec)
150                 {
151                         if (parameter_type == null)
152                                 throw new InternalErrorException ("Implicit lambda parameter type is not set");
153
154                         return true;
155                 }
156         }
157
158         public class ParamsParameter : Parameter {
159                 public ParamsParameter (Expression type, string name, Attributes attrs, Location loc):
160                         base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
161                 {
162                 }
163
164                 public override bool Resolve (IResolveContext ec)
165                 {
166                         if (!base.Resolve (ec))
167                                 return false;
168
169                         if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
170                                 Report.Error (225, Location, "The params parameter must be a single dimensional array");
171                                 return false;
172                         }
173                         return true;
174                 }
175
176                 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
177                 {
178                         base.ApplyAttributes (mb, cb, index);
179
180                         CustomAttributeBuilder a = new CustomAttributeBuilder (
181                                 TypeManager.cons_param_array_attribute, new object[0]);
182                                 
183                         builder.SetCustomAttribute (a);
184                 }
185         }
186
187         public class ArglistParameter : Parameter {
188                 // Doesn't have proper type because it's never chosen for better conversion
189                 public ArglistParameter () :
190                         base (typeof (ArglistParameter), String.Empty, Parameter.Modifier.ARGLIST, null, Location.Null)
191                 {
192                 }
193
194                 public override bool CheckAccessibility (InterfaceMemberBase member)
195                 {
196                         return true;
197                 }
198
199                 public override bool Resolve (IResolveContext ec)
200                 {
201                         return true;
202                 }
203
204                 public override string GetSignatureForError ()
205                 {
206                         return "__arglist";
207                 }
208         }
209
210         /// <summary>
211         ///   Represents a single method parameter
212         /// </summary>
213         public class Parameter : ParameterBase {
214                 [Flags]
215                 public enum Modifier : byte {
216                         NONE    = 0,
217                         REF     = REFMASK | ISBYREF,
218                         OUT     = OUTMASK | ISBYREF,
219                         PARAMS  = 4,
220                         // This is a flag which says that it's either REF or OUT.
221                         ISBYREF = 8,
222                         ARGLIST = 16,
223                         REFMASK = 32,
224                         OUTMASK = 64,
225                         This    = 128
226                 }
227
228                 static string[] attribute_targets = new string [] { "param" };
229
230                 Expression TypeName;
231                 public Modifier modFlags;
232                 public string Name;
233                 public bool IsCaptured;
234                 protected Type parameter_type;
235                 public readonly Location Location;
236
237                 IResolveContext resolve_context;
238
239                 Variable var;
240                 public Variable Variable {
241                         get { return var; }
242                 }
243
244 #if GMCS_SOURCE
245                 public bool IsTypeParameter;
246                 GenericConstraints constraints;
247 #else
248                 public bool IsTypeParameter {
249                         get {
250                                 return false;
251                         }
252                         set {
253                                 if (value)
254                                         throw new Exception ("You can not se TypeParameter in MCS");
255                         }
256                 }
257 #endif
258                 
259                 public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
260                         : this (type.Type, name, mod, attrs, loc)
261                 {
262                         if (type == TypeManager.system_void_expr)
263                                 Report.Error (1536, loc, "Invalid parameter type `void'");
264                         
265                         TypeName = type;
266                 }
267
268                 public Parameter (Type type, string name, Modifier mod, Attributes attrs, Location loc)
269                         : base (attrs)
270                 {
271                         Name = name;
272                         modFlags = mod;
273                         parameter_type = type;
274                         Location = loc;
275                 }
276
277                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
278                 {
279                         if (a.Type == TypeManager.in_attribute_type && ModFlags == Modifier.OUT) {
280                                 Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
281                                 return;
282                         }
283
284                         if (a.Type == TypeManager.param_array_type) {
285                                 Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
286                                 return;
287                         }
288
289                         if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) == Modifier.REF &&
290                             !OptAttributes.Contains (TypeManager.in_attribute_type)) {
291                                 Report.Error (662, a.Location,
292                                         "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
293                                 return;
294                         }
295
296                         if (a.Type == TypeManager.cls_compliant_attribute_type) {
297                                 Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
298                         }
299
300                         // TypeManager.default_parameter_value_attribute_type is null if !NET_2_0, or if System.dll is not referenced
301                         if (a.Type == TypeManager.default_parameter_value_attribute_type) {
302                                 object val = a.GetParameterDefaultValue ();
303                                 if (val != null) {
304                                         Type t = val.GetType ();
305                                         if (t.IsArray || TypeManager.IsSubclassOf (t, TypeManager.type_type)) {
306                                                 if (parameter_type == TypeManager.object_type) {
307                                                         if (!t.IsArray)
308                                                                 t = TypeManager.type_type;
309
310                                                         Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultValue attribute",
311                                                                 TypeManager.CSharpName (t));
312                                                 } else {
313                                                         Report.Error (1909, a.Location, "The DefaultValue attribute is not applicable on parameters of type `{0}'",
314                                                                 TypeManager.CSharpName (parameter_type)); ;
315                                                 }
316                                                 return;
317                                         }
318                                 }
319
320                                 if (parameter_type == TypeManager.object_type ||
321                                     (val == null && !TypeManager.IsValueType (parameter_type)) ||
322                                     (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
323                                         builder.SetConstant (val);
324                                 else
325                                         Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
326                                 return;
327                         }
328
329                         base.ApplyAttributeBuilder (a, cb);
330                 }
331                 
332                 public virtual bool CheckAccessibility (InterfaceMemberBase member)
333                 {
334                         if (IsTypeParameter)
335                                 return true;
336
337                         return member.ds.AsAccessible (parameter_type, member.ModFlags);
338                 }
339
340                 public override IResolveContext ResolveContext {
341                         get {
342                                 return resolve_context;
343                         }
344                 }
345
346                 // <summary>
347                 //   Resolve is used in method definitions
348                 // </summary>
349                 public virtual bool Resolve (IResolveContext ec)
350                 {
351                         // HACK: to resolve attributes correctly
352                         this.resolve_context = ec;
353
354                         if (parameter_type != null)
355                                 return true;
356
357                         TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false);
358                         if (texpr == null)
359                                 return false;
360
361                         parameter_type = texpr.Type;
362
363 #if GMCS_SOURCE
364                         TypeParameterExpr tparam = texpr as TypeParameterExpr;
365                         if (tparam != null) {
366                                 IsTypeParameter = true;
367                                 constraints = tparam.TypeParameter.Constraints;
368                                 return true;
369                         }
370 #endif
371
372                         if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
373                                 Report.Error (721, Location, "`{0}': static types cannot be used as parameters", 
374                                         texpr.GetSignatureForError ());
375                                 return false;
376                         }
377
378                         if ((modFlags & Parameter.Modifier.ISBYREF) != 0){
379                                 if (parameter_type == TypeManager.typed_reference_type ||
380                                     parameter_type == TypeManager.arg_iterator_type){
381                                         Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
382                                                 GetSignatureForError ());
383                                         return false;
384                                 }
385                         }
386
387                         if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) {
388                                 Report.Error (1103, Location, "The type of extension method cannot be `{0}'",
389                                         TypeManager.CSharpName (parameter_type));
390                                 return false;
391                         }
392                         
393                         return true;
394                 }
395
396                 public void ResolveVariable (ToplevelBlock toplevel, int idx)
397                 {
398                         if (toplevel.RootScope != null)
399                                 var = toplevel.RootScope.GetCapturedParameter (this);
400                         if (var == null)
401                                 var = new ParameterVariable (this, idx);
402                 }
403
404                 public Type ExternalType ()
405                 {
406                         if ((modFlags & Parameter.Modifier.ISBYREF) != 0)
407                                 return TypeManager.GetReferenceType (parameter_type);
408                         
409                         return parameter_type;
410                 }
411
412                 public bool HasExtensionMethodModifier {
413                         get { return (modFlags & Modifier.This) != 0; }
414                 }
415
416                 public Modifier ModFlags {
417                         get { return modFlags & ~Modifier.This; }
418                 }
419
420                 public Type ParameterType {
421                         get {
422                                 return parameter_type;
423                         }
424                         set {
425                                 parameter_type = value;
426                                 IsTypeParameter = false;
427                         }
428                 }
429
430 #if GMCS_SOURCE
431                 public GenericConstraints GenericConstraints {
432                         get {
433                                 return constraints;
434                         }
435                 }
436 #endif
437
438                 ParameterAttributes Attributes {
439                         get {
440                                 return (modFlags & Modifier.OUT) == Modifier.OUT ?
441                                         ParameterAttributes.Out : ParameterAttributes.None;
442                         }
443                 }
444
445                 // TODO: should be removed !!!!!!!
446                 public static ParameterAttributes GetParameterAttributes (Modifier mod)
447                 {
448                         int flags = ((int) mod) & ~((int) Parameter.Modifier.ISBYREF);
449                         switch ((Modifier) flags) {
450                         case Modifier.NONE:
451                                 return ParameterAttributes.None;
452                         case Modifier.REF:
453                                 return ParameterAttributes.None;
454                         case Modifier.OUT:
455                                 return ParameterAttributes.Out;
456                         case Modifier.PARAMS:
457                                 return 0;
458                         }
459                                 
460                         return ParameterAttributes.None;
461                 }
462                 
463                 public override AttributeTargets AttributeTargets {
464                         get {
465                                 return AttributeTargets.Parameter;
466                         }
467                 }
468
469                 public virtual string GetSignatureForError ()
470                 {
471                         string type_name;
472                         if (parameter_type != null)
473                                 type_name = TypeManager.CSharpName (parameter_type);
474                         else
475                                 type_name = TypeName.GetSignatureForError ();
476
477                         string mod = GetModifierSignature (modFlags);
478                         if (mod.Length > 0)
479                                 return String.Concat (mod, ' ', type_name);
480
481                         return type_name;
482                 }
483
484                 public static string GetModifierSignature (Modifier mod)
485                 {
486                         switch (mod) {
487                                 case Modifier.OUT:
488                                         return "out";
489                                 case Modifier.PARAMS:
490                                         return "params";
491                                 case Modifier.REF:
492                                         return "ref";
493                                 case Modifier.ARGLIST:
494                                         return "__arglist";
495                                 case Modifier.This:
496                                         return "this";
497                                 default:
498                                         return "";
499                         }
500                 }
501
502                 public void IsClsCompliant ()
503                 {
504                         if (AttributeTester.IsClsCompliant (ExternalType ()))
505                                 return;
506
507                         Report.Error (3001, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
508                 }
509
510                 public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
511                 {
512 #if !GMCS_SOURCE || !MS_COMPATIBLE
513                         // TODO: It should use mb.DefineGenericParameters
514                         if (mb == null)
515                                 builder = cb.DefineParameter (index, Attributes, Name);
516                         else 
517                                 builder = mb.DefineParameter (index, Attributes, Name);
518 #endif
519
520                         if (OptAttributes != null)
521                                 OptAttributes.Emit ();
522                 }
523
524                 public override string[] ValidAttributeTargets {
525                         get {
526                                 return attribute_targets;
527                         }
528                 }
529
530                 protected class ParameterVariable : Variable
531                 {
532                         public readonly Parameter Parameter;
533                         public readonly int Idx;
534                         public readonly bool IsRef;
535
536                         public ParameterVariable (Parameter par, int idx)
537                         {
538                                 this.Parameter = par;
539                                 this.Idx = idx;
540                                 this.IsRef = (par.ModFlags & Parameter.Modifier.ISBYREF) != 0;
541                         }
542
543                         public override Type Type {
544                                 get { return Parameter.ParameterType; }
545                         }
546
547                         public override bool HasInstance {
548                                 get { return false; }
549                         }
550
551                         public override bool NeedsTemporary {
552                                 get { return false; }
553                         }
554
555                         public override void EmitInstance (EmitContext ec)
556                         {
557                         }
558
559                         public override void Emit (EmitContext ec)
560                         {
561                                 int arg_idx = Idx;
562                                 if (!ec.MethodIsStatic)
563                                         arg_idx++;
564
565                                 ParameterReference.EmitLdArg (ec.ig, arg_idx);
566                         }
567
568                         public override void EmitAssign (EmitContext ec)
569                         {
570                                 int arg_idx = Idx;
571                                 if (!ec.MethodIsStatic)
572                                         arg_idx++;
573
574                                 if (arg_idx <= 255)
575                                         ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
576                                 else
577                                         ec.ig.Emit (OpCodes.Starg, arg_idx);
578                         }
579
580                         public override void EmitAddressOf (EmitContext ec)
581                         {
582                                 int arg_idx = Idx;
583
584                                 if (!ec.MethodIsStatic)
585                                         arg_idx++;
586
587                                 if (IsRef) {
588                                         if (arg_idx <= 255)
589                                                 ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
590                                         else
591                                                 ec.ig.Emit (OpCodes.Ldarg, arg_idx);
592                                 } else {
593                                         if (arg_idx <= 255)
594                                                 ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
595                                         else
596                                                 ec.ig.Emit (OpCodes.Ldarga, arg_idx);
597                                 }
598                         }
599                 }
600
601                 public Parameter Clone ()
602                 {
603                         Parameter p = new Parameter (parameter_type, Name, ModFlags, attributes, Location);
604                         p.IsTypeParameter = IsTypeParameter;
605
606                         return p;
607                 }
608         }
609
610         /// <summary>
611         ///   Represents the methods parameters
612         /// </summary>
613         public class Parameters : ParameterData {
614                 // Null object pattern
615                 public Parameter [] FixedParameters;
616                 public readonly bool HasArglist;
617                 Type [] types;
618                 int count;
619
620                 public static readonly Parameters EmptyReadOnlyParameters = new Parameters ();
621                 static readonly Parameter ArgList = new ArglistParameter ();
622
623 #if GMCS_SOURCE
624 //              public readonly TypeParameter[] TypeParameters;
625 #endif
626
627                 private Parameters ()
628                 {
629                         FixedParameters = new Parameter[0];
630                         types = new Type [0];
631                 }
632
633                 private Parameters (Parameter[] parameters, Type[] types)
634                 {
635                         FixedParameters = parameters;
636                         this.types = types;
637                         count = types.Length;
638                 }
639                 
640                 public Parameters (params Parameter[] parameters)
641                 {
642                         if (parameters == null)
643                                 throw new ArgumentException ("Use EmptyReadOnlyPatameters");
644
645                         FixedParameters = parameters;
646                         count = parameters.Length;
647                 }
648
649                 public Parameters (Parameter[] parameters, bool has_arglist):
650                         this (parameters)
651                 {
652                         HasArglist = has_arglist;
653                 }
654                 
655                 public static Parameters CreateFullyResolved (Parameter p)
656                 {
657                         return new Parameters (new Parameter [] { p }, new Type [] { p.ParameterType });
658                 }
659                 
660                 public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types)
661                 {
662                         return new Parameters (parameters, types);
663                 }
664
665                 /// <summary>
666                 /// Use this method when you merge compiler generated argument with user arguments
667                 /// </summary>
668                 public static Parameters MergeGenerated (Parameters userParams, params Parameter[] compilerParams)
669                 {
670                         Parameter[] all_params = new Parameter [userParams.count + compilerParams.Length];
671                         Type[] all_types = new Type[all_params.Length];
672                         userParams.FixedParameters.CopyTo(all_params, 0);
673                         userParams.Types.CopyTo (all_types, 0);
674
675                         int last_filled = userParams.Count;
676                         foreach (Parameter p in compilerParams) {
677                                 for (int i = 0; i < last_filled; ++i) {
678                                         while (p.Name == all_params [i].Name) {
679                                                 p.Name = '_' + p.Name;
680                                         }
681                                 }
682                                 all_params [last_filled] = p;
683                                 all_types [last_filled] = p.ParameterType;
684                                 ++last_filled;
685                         }
686                         
687                         return new Parameters (all_params, all_types);
688                 }
689
690                 public bool Empty {
691                         get {
692                                 return count == 0;
693                         }
694                 }
695
696                 public int Count {
697                         get {
698                                 return HasArglist ? count + 1 : count;
699                         }
700                 }
701
702                 //
703                 // The property can be used after parameter types were resolved.
704                 //
705                 public Type ExtensionMethodType {
706                         get {
707                                 if (count == 0)
708                                         return null;
709
710                                 return FixedParameters [0].HasExtensionMethodModifier ?
711                                         types [0] : null;
712                         }
713                 }
714
715                 public bool HasExtensionMethodType {
716                         get {
717                                 if (count == 0)
718                                         return false;
719
720                                 return FixedParameters [0].HasExtensionMethodModifier;
721                         }
722                 }
723
724
725                 bool VerifyArgs ()
726                 {
727                         if (count < 2)
728                                 return true;
729
730                         for (int i = 0; i < count; i++){
731                                 string base_name = FixedParameters [i].Name;
732                                 for (int j = i + 1; j < count; j++){
733                                         if (base_name != FixedParameters [j].Name)
734                                                 continue;
735
736                                         Report.Error (100, FixedParameters [i].Location,
737                                                 "The parameter name `{0}' is a duplicate", base_name);
738                                         return false;
739                                 }
740                         }
741                         return true;
742                 }
743                 
744                 
745                 /// <summary>
746                 ///    Returns the paramenter information based on the name
747                 /// </summary>
748                 public Parameter GetParameterByName (string name, out int idx)
749                 {
750                         idx = 0;
751
752                         if (count == 0)
753                                 return null;
754
755                         int i = 0;
756
757                         foreach (Parameter par in FixedParameters){
758                                 if (par.Name == name){
759                                         idx = i;
760                                         return par;
761                                 }
762                                 i++;
763                         }
764                         return null;
765                 }
766
767                 public Parameter GetParameterByName (string name)
768                 {
769                         int idx;
770
771                         return GetParameterByName (name, out idx);
772                 }
773                 
774                 public bool Resolve (IResolveContext ec)
775                 {
776                         if (types != null)
777                                 return true;
778
779                         types = new Type [count];
780                         
781                         if (!VerifyArgs ())
782                                 return false;
783
784                         bool ok = true;
785                         Parameter p;
786                         for (int i = 0; i < FixedParameters.Length; ++i) {
787                                 p = FixedParameters [i];
788                                 if (!p.Resolve (ec)) {
789                                         ok = false;
790                                         continue;
791                                 }
792                                 types [i] = p.ExternalType ();
793                         }
794
795                         return ok;
796                 }
797
798                 public void ResolveVariable (ToplevelBlock toplevel)
799                 {
800                         for (int i = 0; i < FixedParameters.Length; ++i) {
801                                 Parameter p = FixedParameters [i];
802                                 p.ResolveVariable (toplevel, i);
803                         }
804                 }
805
806                 public CallingConventions CallingConvention
807                 {
808                         get {
809                                 if (HasArglist)
810                                         return CallingConventions.VarArgs;
811                                 else
812                                         return CallingConventions.Standard;
813                         }
814                 }
815
816                 // Define each type attribute (in/out/ref) and
817                 // the argument names.
818                 public void ApplyAttributes (MethodBase builder)
819                 {
820                         if (count == 0)
821                                 return;
822
823                         MethodBuilder mb = builder as MethodBuilder;
824                         ConstructorBuilder cb = builder as ConstructorBuilder;
825
826                         for (int i = 0; i < FixedParameters.Length; i++) {
827                                 FixedParameters [i].ApplyAttributes (mb, cb, i + 1);
828                         }
829                 }
830
831 #if MS_COMPATIBLE
832                 public ParameterData InflateTypes (Type[] genArguments, Type[] argTypes)
833                 {
834                         Parameters p = Clone ();
835                         for (int i = 0; i < count; ++i) {
836                                 if (types[i].IsGenericType) {
837                                         Type[] gen_arguments_open = new Type [types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
838                                         Type[] gen_arguments = types[i].GetGenericArguments ();
839                                         for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
840                                                 if (gen_arguments[ii].IsGenericParameter) {
841                                                         Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
842                                                         gen_arguments_open[ii] = t;
843                                                 } else
844                                                         gen_arguments_open[ii] = gen_arguments[ii];
845                                         }
846
847                                         p.FixedParameters [i].ParameterType = p.types[i] =
848                                                 types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
849                                         continue;
850                                 }
851
852                                 if (types[i].IsGenericParameter) {
853                                         Type gen_argument = argTypes[types[i].GenericParameterPosition];
854                                         p.FixedParameters[i].ParameterType = p.types[i] = gen_argument;
855                                         continue;
856                                 }
857                         }
858
859                         return p;
860                 }
861 #endif
862
863                 public void VerifyClsCompliance ()
864                 {
865                         foreach (Parameter p in FixedParameters)
866                                 p.IsClsCompliant ();
867                 }
868
869                 public string GetSignatureForError ()
870                 {
871                         StringBuilder sb = new StringBuilder ("(");
872                         if (count > 0) {
873                                 for (int i = 0; i < FixedParameters.Length; ++i) {
874                                         sb.Append (FixedParameters[i].GetSignatureForError ());
875                                         if (i < FixedParameters.Length - 1)
876                                                 sb.Append (", ");
877                                 }
878                         }
879
880                         if (HasArglist) {
881                                 if (sb.Length > 1)
882                                         sb.Append (", ");
883                                 sb.Append ("__arglist");
884                         }
885
886                         sb.Append (')');
887                         return sb.ToString ();
888                 }
889
890                 public Type[] Types {
891                         get {
892                                 return types;
893                         }
894                         //
895                         // Dangerous, used by implicit lambda parameters
896                         // only to workaround bad design
897                         //
898                         set {
899                                 types = value;
900                         }
901                 }
902
903                 public Parameter this [int pos]
904                 {
905                         get {
906                                 if (pos >= count && (HasArglist || HasParams)) {
907                                         if (HasArglist && (pos == 0 || pos >= count))
908                                                 return ArgList;
909                                         pos = count - 1;
910                                 }
911
912                                 return FixedParameters [pos];
913                         }
914                 }
915
916                 #region ParameterData Members
917
918                 public Type ParameterType (int pos)
919                 {
920                         return this [pos].ExternalType ();
921                 }
922
923                 public bool HasParams {
924                         get {
925                                 if (count == 0)
926                                         return false;
927
928                                 for (int i = count; i != 0; --i) {
929                                         if ((FixedParameters [i - 1].ModFlags & Parameter.Modifier.PARAMS) != 0)
930                                                 return true;
931                                 }
932                                 return false;
933                         }
934                 }
935
936                 public string ParameterName (int pos)
937                 {
938                         return this [pos].Name;
939                 }
940
941                 public string ParameterDesc (int pos)
942                 {
943                         return this [pos].GetSignatureForError ();
944                 }
945
946                 public Parameter.Modifier ParameterModifier (int pos)
947                 {
948                         return this [pos].ModFlags;
949                 }
950
951                 public Parameters Clone ()
952                 {
953                         Parameter [] parameters_copy = new Parameter [FixedParameters.Length];
954                         int i = 0;
955                         foreach (Parameter p in FixedParameters)
956                                 parameters_copy [i++] = p.Clone ();
957                         Parameters ps = new Parameters (parameters_copy, HasArglist);
958                         if (types != null)
959                                 ps.types = (Type[])types.Clone ();
960                         return ps;
961                 }
962                 
963                 #endregion
964         }
965 }