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