2 // parameter.cs: Parameter definition.
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 // Marek Safar (marek.safar@seznam.cz)
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2003-2008 Novell, Inc.
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Collections;
19 namespace Mono.CSharp {
22 /// Abstract Base class for parameters of a method.
24 public abstract class ParameterBase : Attributable {
26 protected ParameterBuilder builder;
28 protected ParameterBase (Attributes attrs)
33 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
36 if (a.Type == pa.MarshalAs) {
37 UnmanagedMarshal marshal = a.GetMarshal (this);
38 if (marshal != null) {
39 builder.SetMarshal (marshal);
44 if (a.HasSecurityAttribute) {
45 a.Error_InvalidSecurityParent ();
49 builder.SetCustomAttribute (cb);
52 public override bool IsClsComplianceRequired()
59 /// Class for applying custom attributes on the return type
61 public class ReturnParameter : ParameterBase {
62 public ReturnParameter (MethodBuilder mb, Location location):
66 builder = mb.DefineParameter (0, ParameterAttributes.None, "");
68 catch (ArgumentOutOfRangeException) {
69 Report.RuntimeMissingSupport (location, "custom attributes on the return type");
73 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
75 if (a.Type == pa.CLSCompliant) {
76 Report.Warning (3023, 1, a.Location, "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
79 // This occurs after Warning -28
83 base.ApplyAttributeBuilder (a, cb, pa);
86 public override AttributeTargets AttributeTargets {
88 return AttributeTargets.ReturnValue;
92 public override IResolveContext ResolveContext {
94 throw new NotSupportedException ();
101 public override string[] ValidAttributeTargets {
109 /// Class for applying custom attributes on the implicit parameter type
110 /// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
113 // TODO: should use more code from Parameter.ApplyAttributeBuilder
114 public class ImplicitParameter : ParameterBase {
115 public ImplicitParameter (MethodBuilder mb):
118 builder = mb.DefineParameter (1, ParameterAttributes.None, "value");
121 public override AttributeTargets AttributeTargets {
123 return AttributeTargets.Parameter;
127 public override IResolveContext ResolveContext {
129 throw new NotSupportedException ();
136 public override string[] ValidAttributeTargets {
143 public class ImplicitLambdaParameter : Parameter
145 public ImplicitLambdaParameter (string name, Location loc)
146 : base (null, name, Modifier.NONE, null, loc)
150 public override Type Resolve (IResolveContext ec)
152 if (parameter_type == null)
153 throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
156 return parameter_type;
160 set { parameter_type = value; }
164 public class ParamsParameter : Parameter {
165 public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
166 base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
170 public override Type Resolve (IResolveContext ec)
172 if (base.Resolve (ec) == null)
175 if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
176 Report.Error (225, Location, "The params parameter must be a single dimensional array");
180 return parameter_type;
183 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
185 base.ApplyAttributes (mb, cb, index);
186 PredefinedAttributes.Get.ParamArray.EmitAttribute (builder, Location);
190 public class ArglistParameter : Parameter {
191 // Doesn't have proper type because it's never chosen for better conversion
192 public ArglistParameter (Location loc) :
193 base (null, String.Empty, Parameter.Modifier.ARGLIST, null, loc)
197 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
202 public override bool CheckAccessibility (InterfaceMemberBase member)
207 public override Type Resolve (IResolveContext ec)
209 return typeof (ArglistParameter);
212 public override string GetSignatureForError ()
218 public interface IParameterData
220 bool HasExtensionMethodModifier { get; }
221 Parameter.Modifier ModFlags { get; }
226 // Parameter information created by parser
228 public class Parameter : ParameterBase, IParameterData, ILocalVariable {
230 public enum Modifier : byte {
232 REF = REFMASK | ISBYREF,
233 OUT = OUTMASK | ISBYREF,
235 // This is a flag which says that it's either REF or OUT.
243 static string[] attribute_targets = new string [] { "param" };
245 protected FullNamedExpression TypeName;
246 readonly Modifier modFlags;
248 Expression default_expr;
249 protected Type parameter_type;
250 public readonly Location Location;
252 public bool HasAddressTaken;
254 IResolveContext resolve_context;
255 LocalVariableReference expr_tree_variable;
256 static TypeExpr parameter_expr_tree_type;
258 public HoistedVariable HoistedVariableReference;
260 public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
263 if (type == TypeManager.system_void_expr)
264 Report.Error (1536, loc, "Invalid parameter type `void'");
272 public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Expression defaultValue, Location loc)
273 : this (type, name, mod, attrs, loc)
275 default_expr = defaultValue;
278 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
280 if (a.Type == pa.In && ModFlags == Modifier.OUT) {
281 Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
285 if (a.Type == pa.ParamArray) {
286 Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
290 if (a.Type == PredefinedAttributes.Get.Out && (ModFlags & Modifier.REF) == Modifier.REF &&
291 !OptAttributes.Contains (pa.In)) {
292 Report.Error (662, a.Location,
293 "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
297 if (a.Type == pa.CLSCompliant) {
298 Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
301 if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) {
302 Report.Error (1745, a.Location,
303 "Cannot specify `{0}' attribute on optional parameter `{1}'",
304 TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
308 if (a.Type == pa.DefaultParameterValue) {
309 object val = a.GetParameterDefaultValue ();
311 Type t = val.GetType ();
312 if (t.IsArray || TypeManager.IsSubclassOf (t, TypeManager.type_type)) {
313 if (parameter_type == TypeManager.object_type) {
315 t = TypeManager.type_type;
317 Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
318 TypeManager.CSharpName (t));
320 Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
321 TypeManager.CSharpName (parameter_type)); ;
327 if (parameter_type == TypeManager.object_type ||
328 (val == null && !TypeManager.IsGenericParameter (parameter_type) && TypeManager.IsReferenceType (parameter_type)) ||
329 (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
330 builder.SetConstant (val);
332 Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
336 base.ApplyAttributeBuilder (a, cb, pa);
339 public virtual bool CheckAccessibility (InterfaceMemberBase member)
341 if (parameter_type == null || TypeManager.IsGenericParameter (parameter_type))
344 return member.IsAccessibleAs (parameter_type);
347 public override IResolveContext ResolveContext {
349 return resolve_context;
354 // Resolve is used in method definitions
356 public virtual Type Resolve (IResolveContext rc)
358 // HACK: to resolve attributes correctly
359 this.resolve_context = rc;
361 if (parameter_type != null)
362 return parameter_type;
364 TypeExpr texpr = TypeName.ResolveAsTypeTerminal (rc, false);
368 parameter_type = texpr.Type;
370 // Ignore all checks for dummy members
371 AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;
372 if (pem != null && pem.IsDummy)
373 return parameter_type;
375 if (default_expr != null) {
376 EmitContext ec = new EmitContext (rc, rc.DeclContainer, Location, null, parameter_type, 0);
377 default_expr = default_expr.Resolve (ec);
378 if (default_expr != null) {
379 Constant value = default_expr as Constant;
381 if (default_expr != null)
382 Report.Error (1736, default_expr.Location, "The expression being assigned to optional parameter `{0}' must be constant",
385 Constant c = value.ConvertImplicitly (parameter_type);
387 Report.Error (1750, Location,
388 "Optional parameter value `{0}' cannot be converted to parameter type `{1}'",
389 value.GetValue (), GetSignatureForError ());
394 default_expr = value;
398 if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
399 TypeManager.IsSpecialType (parameter_type)) {
400 Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
401 GetSignatureForError ());
405 TypeManager.CheckTypeVariance (parameter_type,
406 (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
409 if (texpr is TypeParameterExpr)
410 return parameter_type;
412 if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
413 Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
414 texpr.GetSignatureForError ());
415 return parameter_type;
418 if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) {
419 Report.Error (1103, Location, "The type of extension method cannot be `{0}'",
420 TypeManager.CSharpName (parameter_type));
423 return parameter_type;
426 public void ResolveVariable (int idx)
431 public bool HasDefaultValue {
432 get { return default_expr != null; }
435 public bool HasExtensionMethodModifier {
436 get { return (modFlags & Modifier.This) != 0; }
439 public Modifier ModFlags {
440 get { return modFlags & ~Modifier.This; }
445 set { name = value; }
448 ParameterAttributes Attributes {
449 get { return ParametersCompiled.GetParameterAttribute (modFlags) |
450 (HasDefaultValue ? ParameterAttributes.Optional : ParameterAttributes.None); }
453 public override AttributeTargets AttributeTargets {
455 return AttributeTargets.Parameter;
459 public virtual string GetSignatureForError ()
462 if (parameter_type != null)
463 type_name = TypeManager.CSharpName (parameter_type);
465 type_name = TypeName.GetSignatureForError ();
467 string mod = GetModifierSignature (modFlags);
469 return String.Concat (mod, " ", type_name);
474 public static string GetModifierSignature (Modifier mod)
479 case Modifier.PARAMS:
490 public void IsClsCompliant ()
492 if (AttributeTester.IsClsCompliant (parameter_type))
495 Report.Warning (3001, 1, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
498 public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
501 builder = cb.DefineParameter (index, Attributes, Name);
503 builder = mb.DefineParameter (index, Attributes, Name);
505 if (OptAttributes != null)
506 OptAttributes.Emit ();
508 if (HasDefaultValue) {
509 Constant c = (Constant) default_expr;
510 if (default_expr.Type == TypeManager.decimal_type) {
511 builder.SetCustomAttribute (Const.CreateDecimalConstantAttribute (c));
513 builder.SetConstant (c.GetValue ());
518 public override string[] ValidAttributeTargets {
520 return attribute_targets;
524 public Parameter Clone ()
526 Parameter p = (Parameter) MemberwiseClone ();
527 if (attributes != null) {
528 p.attributes = attributes.Clone ();
529 p.attributes.AttachTo (p);
535 public ExpressionStatement CreateExpressionTreeVariable (EmitContext ec)
538 // A parameter is not hoisted when used directly as ET
540 HoistedVariableReference = null;
542 if ((modFlags & Modifier.ISBYREF) != 0)
543 Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
545 LocalInfo variable = ec.CurrentBlock.AddTemporaryVariable (
546 ResolveParameterExpressionType (ec, Location), Location);
547 variable.Resolve (ec);
549 expr_tree_variable = new LocalVariableReference (
550 ec.CurrentBlock, variable.Name, Location, variable, false);
552 ArrayList arguments = new ArrayList (2);
553 arguments.Add (new Argument (new TypeOf (
554 new TypeExpression (parameter_type, Location), Location)));
555 arguments.Add (new Argument (new StringConstant (Name, Location)));
556 return new SimpleAssign (ExpressionTreeVariableReference (),
557 Expression.CreateExpressionFactoryCall ("Parameter", null, arguments, Location));
560 public void Emit (EmitContext ec)
566 ParameterReference.EmitLdArg (ec.ig, arg_idx);
569 public void EmitAssign (EmitContext ec)
576 ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
578 ec.ig.Emit (OpCodes.Starg, arg_idx);
581 public void EmitAddressOf (EmitContext ec)
588 bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
590 ParameterReference.EmitLdArg (ec.ig, arg_idx);
593 ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
595 ec.ig.Emit (OpCodes.Ldarga, arg_idx);
599 public Expression ExpressionTreeVariableReference ()
601 return expr_tree_variable;
605 // System.Linq.Expressions.ParameterExpression type
607 public static TypeExpr ResolveParameterExpressionType (EmitContext ec, Location location)
609 if (parameter_expr_tree_type != null)
610 return parameter_expr_tree_type;
612 Type p_type = TypeManager.parameter_expression_type;
613 if (p_type == null) {
614 p_type = TypeManager.CoreLookupType ("System.Linq.Expressions", "ParameterExpression", Kind.Class, true);
615 TypeManager.parameter_expression_type = p_type;
618 parameter_expr_tree_type = new TypeExpression (p_type, location).
619 ResolveAsTypeTerminal (ec, false);
621 return parameter_expr_tree_type;
626 // Imported or resolved parameter information
628 public class ParameterData : IParameterData
630 readonly string name;
631 readonly Parameter.Modifier modifiers;
633 public ParameterData (string name, Parameter.Modifier modifiers)
636 this.modifiers = modifiers;
639 #region IParameterData Members
641 public bool HasExtensionMethodModifier {
642 get { return (modifiers & Parameter.Modifier.This) != 0; }
645 public Parameter.Modifier ModFlags {
646 get { return modifiers & ~Parameter.Modifier.This; }
656 public abstract class AParametersCollection
658 protected bool has_arglist;
659 protected bool has_params;
661 // Null object pattern
662 protected IParameterData [] parameters;
663 protected Type [] types;
666 get { return parameters.Length; }
669 public Type ExtensionMethodType {
674 return FixedParameters [0].HasExtensionMethodModifier ?
679 public IParameterData [] FixedParameters {
685 public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
687 return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
688 ParameterAttributes.Out : ParameterAttributes.None;
691 public Type [] GetEmitTypes ()
693 Type [] types = null;
696 return Type.EmptyTypes;
698 types = new Type [Count - 1];
699 Array.Copy (Types, types, types.Length);
702 for (int i = 0; i < Count; ++i) {
703 if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
707 types = (Type []) Types.Clone ();
709 types [i] = TypeManager.GetReferenceType (types [i]);
718 public string GetSignatureForError ()
720 StringBuilder sb = new StringBuilder ("(");
721 for (int i = 0; i < Count; ++i) {
724 sb.Append (ParameterDesc (i));
727 return sb.ToString ();
730 public bool HasArglist {
731 get { return has_arglist; }
734 public bool HasExtensionMethodType {
739 return FixedParameters [0].HasExtensionMethodModifier;
743 public bool HasParams {
744 get { return has_params; }
747 public bool IsEmpty {
748 get { return parameters.Length == 0; }
751 public string ParameterDesc (int pos)
753 if (types == null || types [pos] == null)
754 return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
756 string type = TypeManager.CSharpName (types [pos]);
757 if (FixedParameters [pos].HasExtensionMethodModifier)
758 return "this " + type;
760 Parameter.Modifier mod = FixedParameters [pos].ModFlags & ~Parameter.Modifier.ARGLIST;
764 return Parameter.GetModifierSignature (mod) + " " + type;
767 public Type[] Types {
768 get { return types; }
769 set { types = value; }
773 public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
775 AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone ();
777 for (int i = 0; i < Count; ++i) {
778 if (types[i].IsGenericType) {
779 Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
780 Type[] gen_arguments = types[i].GetGenericArguments ();
781 for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
782 if (gen_arguments[ii].IsGenericParameter) {
783 Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
784 gen_arguments_open[ii] = t;
786 gen_arguments_open[ii] = gen_arguments[ii];
789 p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
793 if (types[i].IsGenericParameter) {
794 Type gen_argument = argTypes[types[i].GenericParameterPosition];
795 p.types[i] = gen_argument;
806 // A collection of imported or resolved parameters
808 public class ParametersImported : AParametersCollection
810 ParametersImported (AParametersCollection param, Type[] types)
812 this.parameters = param.FixedParameters;
814 has_arglist = param.HasArglist;
815 has_params = param.HasParams;
818 ParametersImported (IParameterData [] parameters, Type [] types, MethodBase method, bool hasParams)
820 this.parameters = parameters;
822 has_arglist = (method.CallingConvention & CallingConventions.VarArgs) != 0;
824 this.parameters = new IParameterData [parameters.Length + 1];
825 parameters.CopyTo (this.parameters, 0);
826 this.parameters [parameters.Length] = new ArglistParameter (Location.Null);
827 this.types = new Type [types.Length + 1];
828 types.CopyTo (this.types, 0);
829 this.types [types.Length] = TypeManager.arg_iterator_type;
831 has_params = hasParams;
834 public ParametersImported (IParameterData [] param, Type[] types)
836 this.parameters = param;
840 public static AParametersCollection Create (MethodBase method)
842 return Create (method.GetParameters (), method);
846 // Generic method parameters importer, param is shared between all instances
848 public static AParametersCollection Create (AParametersCollection param, MethodBase method)
853 ParameterInfo [] pi = method.GetParameters ();
854 Type [] types = new Type [pi.Length];
855 for (int i = 0; i < types.Length; i++) {
856 Type t = pi [i].ParameterType;
858 t = TypeManager.GetElementType (t);
860 types [i] = TypeManager.TypeToCoreType (t);
863 return new ParametersImported (param, types);
867 // Imports SRE parameters
869 public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method)
871 if (pi.Length == 0) {
872 if (method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0)
873 return new ParametersImported (new IParameterData [0], Type.EmptyTypes, method, false);
875 return ParametersCompiled.EmptyReadOnlyParameters;
878 Type [] types = new Type [pi.Length];
879 IParameterData [] par = new IParameterData [pi.Length];
880 bool is_params = false;
881 PredefinedAttribute extension_attr = PredefinedAttributes.Get.Extension;
882 PredefinedAttribute param_attr = PredefinedAttributes.Get.ParamArray;
883 for (int i = 0; i < types.Length; i++) {
884 types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType);
886 ParameterInfo p = pi [i];
887 Parameter.Modifier mod = 0;
888 if (types [i].IsByRef) {
889 if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
890 mod = Parameter.Modifier.OUT;
892 mod = Parameter.Modifier.REF;
895 // Strip reference wrapping
897 types [i] = TypeManager.GetElementType (types [i]);
898 } else if (i == 0 && extension_attr.IsDefined && method != null && method.IsStatic &&
899 (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
900 method.IsDefined (extension_attr.Type, false)) {
901 mod = Parameter.Modifier.This;
902 } else if (i >= pi.Length - 2) {
903 if (types[i].IsArray) {
904 if (p.IsDefined (param_attr.Type, false)) {
905 mod = Parameter.Modifier.PARAMS;
908 } else if (types [i] == TypeManager.runtime_argument_handle_type) {
909 par [i] = new ArglistParameter (Location.Null);
914 par [i] = new ParameterData (p.Name, mod);
917 return method != null ?
918 new ParametersImported (par, types, method, is_params) :
919 new ParametersImported (par, types);
924 /// Represents the methods parameters
926 public class ParametersCompiled : AParametersCollection
928 public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
930 // Used by C# 2.0 delegates
931 public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
933 private ParametersCompiled ()
935 parameters = new Parameter [0];
936 types = Type.EmptyTypes;
939 private ParametersCompiled (Parameter [] parameters, Type [] types)
941 this.parameters = parameters;
945 public ParametersCompiled (params Parameter[] parameters)
947 if (parameters == null)
948 throw new ArgumentException ("Use EmptyReadOnlyParameters");
950 this.parameters = parameters;
951 int count = parameters.Length;
957 has_params = (parameters [0].ModFlags & Parameter.Modifier.PARAMS) != 0;
961 for (int i = 0; i < count; i++){
962 string base_name = parameters [i].Name;
963 has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
965 for (int j = i + 1; j < count; j++){
966 if (base_name != parameters [j].Name)
969 ErrorDuplicateName (parameters [i]);
975 public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
978 this.has_arglist = has_arglist;
981 public static ParametersCompiled CreateFullyResolved (Parameter p, Type type)
983 return new ParametersCompiled (new Parameter [] { p }, new Type [] { type });
986 public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, Type[] types)
988 return new ParametersCompiled (parameters, types);
991 public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
993 return MergeGenerated (userParams, checkConflicts,
994 new Parameter [] { compilerParams },
995 new Type [] { compilerTypes });
999 // Use this method when you merge compiler generated parameters with user parameters
1001 public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
1003 Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1004 userParams.FixedParameters.CopyTo(all_params, 0);
1007 if (userParams.types != null) {
1008 all_types = new Type [all_params.Length];
1009 userParams.Types.CopyTo (all_types, 0);
1014 int last_filled = userParams.Count;
1016 foreach (Parameter p in compilerParams) {
1017 for (int i = 0; i < last_filled; ++i) {
1018 while (p.Name == all_params [i].Name) {
1019 if (checkConflicts && i < userParams.Count) {
1020 Report.Error (316, userParams [i].Location,
1021 "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1023 p.Name = '_' + p.Name;
1026 all_params [last_filled] = p;
1027 if (all_types != null)
1028 all_types [last_filled] = compilerTypes [index++];
1032 ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1033 parameters.has_params = userParams.has_params;
1037 protected virtual void ErrorDuplicateName (Parameter p)
1039 Report.Error (100, p.Location, "The parameter name `{0}' is a duplicate", p.Name);
1043 /// Returns the parameter information based on the name
1045 public int GetParameterIndexByName (string name)
1047 for (int idx = 0; idx < Count; ++idx) {
1048 if (parameters [idx].Name == name)
1055 public bool Resolve (IResolveContext ec)
1060 types = new Type [Count];
1064 for (int i = 0; i < FixedParameters.Length; ++i) {
1066 Type t = p.Resolve (ec);
1078 public void ResolveVariable ()
1080 for (int i = 0; i < FixedParameters.Length; ++i) {
1081 this [i].ResolveVariable (i);
1085 public CallingConventions CallingConvention
1089 return CallingConventions.VarArgs;
1091 return CallingConventions.Standard;
1095 // Define each type attribute (in/out/ref) and
1096 // the argument names.
1097 public void ApplyAttributes (MethodBase builder)
1102 MethodBuilder mb = builder as MethodBuilder;
1103 ConstructorBuilder cb = builder as ConstructorBuilder;
1105 for (int i = 0; i < Count; i++) {
1106 this [i].ApplyAttributes (mb, cb, i + 1);
1110 public void VerifyClsCompliance ()
1112 foreach (Parameter p in FixedParameters)
1113 p.IsClsCompliant ();
1116 public Parameter this [int pos] {
1117 get { return (Parameter) parameters [pos]; }
1120 public Expression CreateExpressionTree (EmitContext ec, Location loc)
1122 ArrayList initializers = new ArrayList (Count);
1123 foreach (Parameter p in FixedParameters) {
1125 // Each parameter expression is stored to local variable
1126 // to save some memory when referenced later.
1128 StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec));
1129 if (se.Resolve (ec))
1130 ec.CurrentBlock.AddScopeStatement (se);
1132 initializers.Add (p.ExpressionTreeVariableReference ());
1135 return new ArrayCreation (
1136 Parameter.ResolveParameterExpressionType (ec, loc),
1137 "[]", initializers, loc);
1140 public ParametersCompiled Clone ()
1142 ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1144 p.parameters = new IParameterData [parameters.Length];
1145 for (int i = 0; i < Count; ++i)
1146 p.parameters [i] = this [i].Clone ();