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.NONE, 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 (ArglistAccess);
212 public override string GetSignatureForError ()
218 public interface IParameterData
220 Expression DefaultValue { get; }
221 bool HasExtensionMethodModifier { get; }
222 bool HasDefaultValue { get; }
223 Parameter.Modifier ModFlags { get; }
228 // Parameter information created by parser
230 public class Parameter : ParameterBase, IParameterData, ILocalVariable {
232 public enum Modifier : byte {
234 REF = REFMASK | ISBYREF,
235 OUT = OUTMASK | ISBYREF,
237 // This is a flag which says that it's either REF or OUT.
244 static string[] attribute_targets = new string [] { "param" };
246 protected FullNamedExpression TypeName;
247 readonly Modifier modFlags;
249 Expression default_expr;
250 protected Type parameter_type;
251 public readonly Location Location;
253 public bool HasAddressTaken;
255 IResolveContext resolve_context;
256 LocalVariableReference expr_tree_variable;
257 static TypeExpr parameter_expr_tree_type;
259 public HoistedVariable HoistedVariableReference;
261 public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
264 if (type == TypeManager.system_void_expr)
265 Report.Error (1536, loc, "Invalid parameter type `void'");
273 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
275 if (a.Type == pa.In && ModFlags == Modifier.OUT) {
276 Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
280 if (a.Type == pa.ParamArray) {
281 Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
285 if (a.Type == PredefinedAttributes.Get.Out && (ModFlags & Modifier.REF) == Modifier.REF &&
286 !OptAttributes.Contains (pa.In)) {
287 Report.Error (662, a.Location,
288 "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
292 if (a.Type == pa.CLSCompliant) {
293 Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
296 if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) {
297 Report.Error (1745, a.Location,
298 "Cannot specify `{0}' attribute on optional parameter `{1}'",
299 TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
303 if (a.Type == pa.DefaultParameterValue) {
304 object val = a.GetParameterDefaultValue ();
306 Type t = val.GetType ();
307 if (t.IsArray || TypeManager.IsSubclassOf (t, TypeManager.type_type)) {
308 if (parameter_type == TypeManager.object_type) {
310 t = TypeManager.type_type;
312 Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
313 TypeManager.CSharpName (t));
315 Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
316 TypeManager.CSharpName (parameter_type)); ;
322 if (parameter_type == TypeManager.object_type ||
323 (val == null && !TypeManager.IsGenericParameter (parameter_type) && TypeManager.IsReferenceType (parameter_type)) ||
324 (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
325 builder.SetConstant (val);
327 Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
331 base.ApplyAttributeBuilder (a, cb, pa);
334 public virtual bool CheckAccessibility (InterfaceMemberBase member)
336 if (parameter_type == null || TypeManager.IsGenericParameter (parameter_type))
339 return member.IsAccessibleAs (parameter_type);
342 public override IResolveContext ResolveContext {
344 return resolve_context;
349 // Resolve is used in method definitions
351 public virtual Type Resolve (IResolveContext rc)
353 // HACK: to resolve attributes correctly
354 this.resolve_context = rc;
356 if (parameter_type != null)
357 return parameter_type;
359 TypeExpr texpr = TypeName.ResolveAsTypeTerminal (rc, false);
363 parameter_type = texpr.Type;
365 // Ignore all checks for dummy members
366 AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;
367 if (pem != null && pem.IsDummy)
368 return parameter_type;
370 if (default_expr != null) {
371 EmitContext ec = new EmitContext (rc, rc.GenericDeclContainer, Location, null, parameter_type, 0);
372 default_expr = default_expr.Resolve (ec);
373 if (default_expr != null) {
374 Constant value = default_expr as Constant;
376 if (default_expr != null) {
377 bool is_valid = false;
378 if (default_expr is DefaultValueExpression) {
380 } else if (default_expr is New && ((New) default_expr).IsDefaultValueType) {
381 is_valid = TypeManager.IsEqual (parameter_type, default_expr.Type) ||
382 (TypeManager.IsNullableType (parameter_type) &&
383 Convert.ImplicitNulableConversion (ec, default_expr, parameter_type) != EmptyExpression.Null);
385 Report.Error (1736, default_expr.Location,
386 "The expression being assigned to optional parameter `{0}' must be a constant or default value",
393 Report.Error (1763, Location,
394 "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
395 Name, GetSignatureForError ());
399 Constant c = value.ConvertImplicitly (parameter_type);
401 if (parameter_type == TypeManager.object_type) {
402 Report.Error (1763, Location,
403 "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
404 Name, GetSignatureForError ());
406 Report.Error (1750, Location,
407 "Optional parameter value `{0}' cannot be converted to parameter type `{1}'",
408 value.GetValue (), GetSignatureForError ());
416 if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
417 TypeManager.IsSpecialType (parameter_type)) {
418 Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
419 GetSignatureForError ());
423 TypeManager.CheckTypeVariance (parameter_type,
424 (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
427 if (texpr is TypeParameterExpr)
428 return parameter_type;
430 if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
431 Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
432 texpr.GetSignatureForError ());
433 return parameter_type;
436 if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) {
437 Report.Error (1103, Location, "The type of extension method cannot be `{0}'",
438 TypeManager.CSharpName (parameter_type));
441 return parameter_type;
444 public void ResolveVariable (int idx)
449 public bool HasDefaultValue {
450 get { return default_expr != null; }
453 public bool HasExtensionMethodModifier {
454 get { return (modFlags & Modifier.This) != 0; }
457 public Modifier ModFlags {
458 get { return modFlags & ~Modifier.This; }
463 set { name = value; }
466 ParameterAttributes Attributes {
467 get { return ParametersCompiled.GetParameterAttribute (modFlags) |
468 (HasDefaultValue ? ParameterAttributes.Optional : ParameterAttributes.None); }
471 public override AttributeTargets AttributeTargets {
473 return AttributeTargets.Parameter;
477 public virtual string GetSignatureForError ()
480 if (parameter_type != null)
481 type_name = TypeManager.CSharpName (parameter_type);
483 type_name = TypeName.GetSignatureForError ();
485 string mod = GetModifierSignature (modFlags);
487 return String.Concat (mod, " ", type_name);
492 public static string GetModifierSignature (Modifier mod)
497 case Modifier.PARAMS:
508 public void IsClsCompliant ()
510 if (AttributeTester.IsClsCompliant (parameter_type))
513 Report.Warning (3001, 1, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
516 public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
519 builder = cb.DefineParameter (index, Attributes, Name);
521 builder = mb.DefineParameter (index, Attributes, Name);
523 if (OptAttributes != null)
524 OptAttributes.Emit ();
526 if (HasDefaultValue) {
528 // Emit constant values for true constants only, the other
529 // constant-like expressions will rely on default value expression
531 Constant c = default_expr as Constant;
533 if (default_expr.Type == TypeManager.decimal_type) {
534 builder.SetCustomAttribute (Const.CreateDecimalConstantAttribute (c));
536 builder.SetConstant (c.GetValue ());
542 public override string[] ValidAttributeTargets {
544 return attribute_targets;
548 public Parameter Clone ()
550 Parameter p = (Parameter) MemberwiseClone ();
551 if (attributes != null) {
552 p.attributes = attributes.Clone ();
553 p.attributes.AttachTo (p);
559 public ExpressionStatement CreateExpressionTreeVariable (EmitContext ec)
562 // A parameter is not hoisted when used directly as ET
564 HoistedVariableReference = null;
566 if ((modFlags & Modifier.ISBYREF) != 0)
567 Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
569 LocalInfo variable = ec.CurrentBlock.AddTemporaryVariable (
570 ResolveParameterExpressionType (ec, Location), Location);
571 variable.Resolve (ec);
573 expr_tree_variable = new LocalVariableReference (
574 ec.CurrentBlock, variable.Name, Location, variable, false);
576 Arguments arguments = new Arguments (2);
577 arguments.Add (new Argument (new TypeOf (
578 new TypeExpression (parameter_type, Location), Location)));
579 arguments.Add (new Argument (new StringConstant (Name, Location)));
580 return new SimpleAssign (ExpressionTreeVariableReference (),
581 Expression.CreateExpressionFactoryCall ("Parameter", null, arguments, Location));
584 public Expression DefaultValue {
585 get { return default_expr; }
586 set { default_expr = value; }
589 public void Emit (EmitContext ec)
595 ParameterReference.EmitLdArg (ec.ig, arg_idx);
598 public void EmitAssign (EmitContext ec)
605 ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
607 ec.ig.Emit (OpCodes.Starg, arg_idx);
610 public void EmitAddressOf (EmitContext ec)
617 bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
619 ParameterReference.EmitLdArg (ec.ig, arg_idx);
622 ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
624 ec.ig.Emit (OpCodes.Ldarga, arg_idx);
628 public Expression ExpressionTreeVariableReference ()
630 return expr_tree_variable;
634 // System.Linq.Expressions.ParameterExpression type
636 public static TypeExpr ResolveParameterExpressionType (EmitContext ec, Location location)
638 if (parameter_expr_tree_type != null)
639 return parameter_expr_tree_type;
641 Type p_type = TypeManager.parameter_expression_type;
642 if (p_type == null) {
643 p_type = TypeManager.CoreLookupType ("System.Linq.Expressions", "ParameterExpression", Kind.Class, true);
644 TypeManager.parameter_expression_type = p_type;
647 parameter_expr_tree_type = new TypeExpression (p_type, location).
648 ResolveAsTypeTerminal (ec, false);
650 return parameter_expr_tree_type;
653 public void Warning_UselessOptionalParameter ()
655 Report.Warning (1066, 1, Location,
656 "The default value specified for optional parameter `{0}' will never be used",
662 // Imported or resolved parameter information
664 public class ParameterData : IParameterData
666 readonly string name;
667 readonly Parameter.Modifier modifiers;
668 readonly Expression default_value;
670 public ParameterData (string name, Parameter.Modifier modifiers)
673 this.modifiers = modifiers;
676 public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
677 : this (name, modifiers)
679 this.default_value = defaultValue;
682 #region IParameterData Members
684 public Expression DefaultValue {
685 get { return default_value; }
688 public bool HasExtensionMethodModifier {
689 get { return (modifiers & Parameter.Modifier.This) != 0; }
692 public bool HasDefaultValue {
693 get { return default_value != null; }
696 public Parameter.Modifier ModFlags {
697 get { return modifiers & ~Parameter.Modifier.This; }
707 public abstract class AParametersCollection
709 protected bool has_arglist;
710 protected bool has_params;
712 // Null object pattern
713 protected IParameterData [] parameters;
714 protected Type [] types;
717 get { return parameters.Length; }
720 public Type ExtensionMethodType {
725 return FixedParameters [0].HasExtensionMethodModifier ?
730 public IParameterData [] FixedParameters {
736 public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
738 return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
739 ParameterAttributes.Out : ParameterAttributes.None;
742 public Type [] GetEmitTypes ()
744 Type [] types = null;
747 return Type.EmptyTypes;
749 types = new Type [Count - 1];
750 Array.Copy (Types, types, types.Length);
753 for (int i = 0; i < Count; ++i) {
754 if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
758 types = (Type []) Types.Clone ();
760 types [i] = TypeManager.GetReferenceType (types [i]);
770 // Returns the parameter information based on the name
772 public int GetParameterIndexByName (string name)
774 for (int idx = 0; idx < Count; ++idx) {
775 if (parameters [idx].Name == name)
782 public string GetSignatureForError ()
784 StringBuilder sb = new StringBuilder ("(");
785 for (int i = 0; i < Count; ++i) {
788 sb.Append (ParameterDesc (i));
791 return sb.ToString ();
794 public bool HasArglist {
795 get { return has_arglist; }
798 public bool HasExtensionMethodType {
803 return FixedParameters [0].HasExtensionMethodModifier;
807 public bool HasParams {
808 get { return has_params; }
811 public bool IsEmpty {
812 get { return parameters.Length == 0; }
815 public string ParameterDesc (int pos)
817 if (types == null || types [pos] == null)
818 return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
820 string type = TypeManager.CSharpName (types [pos]);
821 if (FixedParameters [pos].HasExtensionMethodModifier)
822 return "this " + type;
824 Parameter.Modifier mod = FixedParameters [pos].ModFlags;
828 return Parameter.GetModifierSignature (mod) + " " + type;
831 public Type[] Types {
832 get { return types; }
833 set { types = value; }
837 public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
839 AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone ();
841 for (int i = 0; i < Count; ++i) {
842 if (types[i].IsGenericType) {
843 Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
844 Type[] gen_arguments = types[i].GetGenericArguments ();
845 for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
846 if (gen_arguments[ii].IsGenericParameter) {
847 Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
848 gen_arguments_open[ii] = t;
850 gen_arguments_open[ii] = gen_arguments[ii];
853 p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
857 if (types[i].IsGenericParameter) {
858 Type gen_argument = argTypes[types[i].GenericParameterPosition];
859 p.types[i] = gen_argument;
870 // A collection of imported or resolved parameters
872 public class ParametersImported : AParametersCollection
874 ParametersImported (AParametersCollection param, Type[] types)
876 this.parameters = param.FixedParameters;
878 has_arglist = param.HasArglist;
879 has_params = param.HasParams;
882 ParametersImported (IParameterData [] parameters, Type [] types, bool hasArglist, bool hasParams)
884 this.parameters = parameters;
886 this.has_arglist = hasArglist;
887 this.has_params = hasParams;
890 public ParametersImported (IParameterData [] param, Type[] types)
892 this.parameters = param;
896 public static AParametersCollection Create (MethodBase method)
898 return Create (method.GetParameters (), method);
902 // Generic method parameters importer, param is shared between all instances
904 public static AParametersCollection Create (AParametersCollection param, MethodBase method)
909 ParameterInfo [] pi = method.GetParameters ();
910 Type [] types = new Type [pi.Length];
911 for (int i = 0; i < types.Length; i++) {
912 Type t = pi [i].ParameterType;
914 t = TypeManager.GetElementType (t);
916 types [i] = TypeManager.TypeToCoreType (t);
919 return new ParametersImported (param, types);
923 // Imports SRE parameters
925 public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method)
927 int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
929 if (pi.Length == 0 && varargs == 0)
930 return ParametersCompiled.EmptyReadOnlyParameters;
932 Type [] types = new Type [pi.Length + varargs];
933 IParameterData [] par = new IParameterData [pi.Length + varargs];
934 bool is_params = false;
935 PredefinedAttribute extension_attr = PredefinedAttributes.Get.Extension;
936 PredefinedAttribute param_attr = PredefinedAttributes.Get.ParamArray;
937 for (int i = 0; i < pi.Length; i++) {
938 types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType);
940 ParameterInfo p = pi [i];
941 Parameter.Modifier mod = 0;
942 Expression default_value = null;
943 if (types [i].IsByRef) {
944 if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
945 mod = Parameter.Modifier.OUT;
947 mod = Parameter.Modifier.REF;
950 // Strip reference wrapping
952 types [i] = TypeManager.GetElementType (types [i]);
953 } else if (i == 0 && extension_attr.IsDefined && method != null && method.IsStatic &&
954 (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
955 method.IsDefined (extension_attr.Type, false)) {
956 mod = Parameter.Modifier.This;
958 if (i >= pi.Length - 2 && types[i].IsArray) {
959 if (p.IsDefined (param_attr.Type, false)) {
960 mod = Parameter.Modifier.PARAMS;
965 if (!is_params && p.IsOptional) {
966 if (p.DefaultValue == Missing.Value)
967 default_value = EmptyExpression.Null;
969 default_value = Constant.CreateConstant (types[i], p.DefaultValue, Location.Null);
973 par [i] = new ParameterData (p.Name, mod, default_value);
977 par [par.Length - 1] = new ArglistParameter (Location.Null);
978 types [types.Length - 1] = typeof (ArglistAccess);
981 return method != null ?
982 new ParametersImported (par, types, varargs != 0, is_params) :
983 new ParametersImported (par, types);
988 /// Represents the methods parameters
990 public class ParametersCompiled : AParametersCollection
992 public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
994 // Used by C# 2.0 delegates
995 public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
997 private ParametersCompiled ()
999 parameters = new Parameter [0];
1000 types = Type.EmptyTypes;
1003 private ParametersCompiled (Parameter [] parameters, Type [] types)
1005 this.parameters = parameters;
1009 public ParametersCompiled (params Parameter[] parameters)
1011 if (parameters == null)
1012 throw new ArgumentException ("Use EmptyReadOnlyParameters");
1014 this.parameters = parameters;
1015 int count = parameters.Length;
1021 has_params = (parameters [0].ModFlags & Parameter.Modifier.PARAMS) != 0;
1025 for (int i = 0; i < count; i++){
1026 string base_name = parameters [i].Name;
1027 has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
1029 for (int j = i + 1; j < count; j++){
1030 if (base_name != parameters [j].Name)
1033 ErrorDuplicateName (parameters [i]);
1039 public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
1042 this.has_arglist = has_arglist;
1045 public static ParametersCompiled CreateFullyResolved (Parameter p, Type type)
1047 return new ParametersCompiled (new Parameter [] { p }, new Type [] { type });
1050 public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, Type[] types)
1052 return new ParametersCompiled (parameters, types);
1055 public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
1057 return MergeGenerated (userParams, checkConflicts,
1058 new Parameter [] { compilerParams },
1059 new Type [] { compilerTypes });
1063 // Use this method when you merge compiler generated parameters with user parameters
1065 public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
1067 Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1068 userParams.FixedParameters.CopyTo(all_params, 0);
1071 if (userParams.types != null) {
1072 all_types = new Type [all_params.Length];
1073 userParams.Types.CopyTo (all_types, 0);
1078 int last_filled = userParams.Count;
1080 foreach (Parameter p in compilerParams) {
1081 for (int i = 0; i < last_filled; ++i) {
1082 while (p.Name == all_params [i].Name) {
1083 if (checkConflicts && i < userParams.Count) {
1084 Report.Error (316, userParams [i].Location,
1085 "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1087 p.Name = '_' + p.Name;
1090 all_params [last_filled] = p;
1091 if (all_types != null)
1092 all_types [last_filled] = compilerTypes [index++];
1096 ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1097 parameters.has_params = userParams.has_params;
1101 protected virtual void ErrorDuplicateName (Parameter p)
1103 Report.Error (100, p.Location, "The parameter name `{0}' is a duplicate", p.Name);
1106 public bool Resolve (IResolveContext ec)
1111 types = new Type [Count];
1115 for (int i = 0; i < FixedParameters.Length; ++i) {
1117 Type t = p.Resolve (ec);
1129 public void ResolveVariable ()
1131 for (int i = 0; i < FixedParameters.Length; ++i) {
1132 this [i].ResolveVariable (i);
1136 public CallingConventions CallingConvention
1140 return CallingConventions.VarArgs;
1142 return CallingConventions.Standard;
1146 // Define each type attribute (in/out/ref) and
1147 // the argument names.
1148 public void ApplyAttributes (MethodBase builder)
1153 MethodBuilder mb = builder as MethodBuilder;
1154 ConstructorBuilder cb = builder as ConstructorBuilder;
1156 for (int i = 0; i < Count; i++) {
1157 this [i].ApplyAttributes (mb, cb, i + 1);
1161 public void VerifyClsCompliance ()
1163 foreach (Parameter p in FixedParameters)
1164 p.IsClsCompliant ();
1167 public Parameter this [int pos] {
1168 get { return (Parameter) parameters [pos]; }
1171 public Expression CreateExpressionTree (EmitContext ec, Location loc)
1173 ArrayList initializers = new ArrayList (Count);
1174 foreach (Parameter p in FixedParameters) {
1176 // Each parameter expression is stored to local variable
1177 // to save some memory when referenced later.
1179 StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec));
1180 if (se.Resolve (ec))
1181 ec.CurrentBlock.AddScopeStatement (se);
1183 initializers.Add (p.ExpressionTreeVariableReference ());
1186 return new ArrayCreation (
1187 Parameter.ResolveParameterExpressionType (ec, loc),
1188 "[]", initializers, loc);
1191 public ParametersCompiled Clone ()
1193 ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1195 p.parameters = new IParameterData [parameters.Length];
1196 for (int i = 0; i < Count; ++i)
1197 p.parameters [i] = this [i].Clone ();