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 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
31 if (a.Type == pa.MarshalAs) {
32 UnmanagedMarshal marshal = a.GetMarshal (this);
33 if (marshal != null) {
34 builder.SetMarshal (marshal);
39 if (a.HasSecurityAttribute) {
40 a.Error_InvalidSecurityParent ();
44 builder.SetCustomAttribute (cb);
47 public override bool IsClsComplianceRequired()
54 /// Class for applying custom attributes on the return type
56 public class ReturnParameter : ParameterBase {
57 public ReturnParameter (MethodBuilder mb, Location location)
60 builder = mb.DefineParameter (0, ParameterAttributes.None, "");
62 catch (ArgumentOutOfRangeException) {
63 Report.RuntimeMissingSupport (location, "custom attributes on the return type");
67 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
69 if (a.Type == pa.CLSCompliant) {
70 Report.Warning (3023, 1, a.Location, "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
73 // This occurs after Warning -28
77 base.ApplyAttributeBuilder (a, cb, pa);
80 public override AttributeTargets AttributeTargets {
82 return AttributeTargets.ReturnValue;
86 public void EmitPredefined (PredefinedAttribute pa, Location loc)
89 pa.EmitAttribute (builder, loc);
95 public override string[] ValidAttributeTargets {
103 /// Class for applying custom attributes on the implicit parameter type
104 /// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
107 // TODO: should use more code from Parameter.ApplyAttributeBuilder
108 public class ImplicitParameter : ParameterBase {
109 public ImplicitParameter (MethodBuilder mb)
111 builder = mb.DefineParameter (1, ParameterAttributes.None, "value");
114 public override AttributeTargets AttributeTargets {
116 return AttributeTargets.Parameter;
123 public override string[] ValidAttributeTargets {
130 public class ImplicitLambdaParameter : Parameter
132 public ImplicitLambdaParameter (string name, Location loc)
133 : base (null, name, Modifier.NONE, null, loc)
137 public override Type Resolve (IResolveContext ec)
139 if (parameter_type == null)
140 throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
143 return parameter_type;
147 set { parameter_type = value; }
151 public class ParamsParameter : Parameter {
152 public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
153 base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
157 public override Type Resolve (IResolveContext ec)
159 if (base.Resolve (ec) == null)
162 if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
163 Report.Error (225, Location, "The params parameter must be a single dimensional array");
167 return parameter_type;
170 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
172 base.ApplyAttributes (mb, cb, index);
173 PredefinedAttributes.Get.ParamArray.EmitAttribute (builder, Location);
177 public class ArglistParameter : Parameter {
178 // Doesn't have proper type because it's never chosen for better conversion
179 public ArglistParameter (Location loc) :
180 base (null, String.Empty, Parameter.Modifier.NONE, null, loc)
184 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
189 public override bool CheckAccessibility (InterfaceMemberBase member)
194 public override Type Resolve (IResolveContext ec)
196 return InternalType.Arglist;
199 public override string GetSignatureForError ()
205 public interface IParameterData
207 Expression DefaultValue { get; }
208 bool HasExtensionMethodModifier { get; }
209 bool HasDefaultValue { get; }
210 Parameter.Modifier ModFlags { get; }
215 // Parameter information created by parser
217 public class Parameter : ParameterBase, IParameterData, ILocalVariable {
219 public enum Modifier : byte {
221 REF = REFMASK | ISBYREF,
222 OUT = OUTMASK | ISBYREF,
224 // This is a flag which says that it's either REF or OUT.
231 static string[] attribute_targets = new string [] { "param" };
233 protected FullNamedExpression TypeName;
234 readonly Modifier modFlags;
236 Expression default_expr;
237 protected Type parameter_type;
238 public readonly Location Location;
240 public bool HasAddressTaken;
242 LocalVariableReference expr_tree_variable;
243 static TypeExpr parameter_expr_tree_type;
245 public HoistedVariable HoistedVariableReference;
247 public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
249 if (type == TypeManager.system_void_expr)
250 Report.Error (1536, loc, "Invalid parameter type `void'");
257 // Only assign, attributes will be attached during resolve
258 base.attributes = attrs;
261 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
263 if (a.Type == pa.In && ModFlags == Modifier.OUT) {
264 Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
268 if (a.Type == pa.ParamArray) {
269 Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
273 if (a.Type == PredefinedAttributes.Get.Out && (ModFlags & Modifier.REF) == Modifier.REF &&
274 !OptAttributes.Contains (pa.In)) {
275 Report.Error (662, a.Location,
276 "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
280 if (a.Type == pa.CLSCompliant) {
281 Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
284 if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) {
285 Report.Error (1745, a.Location,
286 "Cannot specify `{0}' attribute on optional parameter `{1}'",
287 TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
291 if (a.Type == pa.DefaultParameterValue) {
292 object val = a.GetParameterDefaultValue ();
294 Type t = val.GetType ();
295 if (t.IsArray || TypeManager.IsSubclassOf (t, TypeManager.type_type)) {
296 if (parameter_type == TypeManager.object_type) {
298 t = TypeManager.type_type;
300 Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
301 TypeManager.CSharpName (t));
303 Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
304 TypeManager.CSharpName (parameter_type)); ;
310 if (parameter_type == TypeManager.object_type ||
311 (val == null && !TypeManager.IsGenericParameter (parameter_type) && TypeManager.IsReferenceType (parameter_type)) ||
312 (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
313 builder.SetConstant (val);
315 Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
319 base.ApplyAttributeBuilder (a, cb, pa);
322 public virtual bool CheckAccessibility (InterfaceMemberBase member)
324 if (parameter_type == null || TypeManager.IsGenericParameter (parameter_type))
327 return member.IsAccessibleAs (parameter_type);
331 // Resolve is used in method definitions
333 public virtual Type Resolve (IResolveContext rc)
335 if (parameter_type != null)
336 return parameter_type;
338 if (attributes != null)
339 attributes.AttachTo (this, rc);
341 TypeExpr texpr = TypeName.ResolveAsTypeTerminal (rc, false);
345 parameter_type = texpr.Type;
347 // Ignore all checks for dummy members
348 AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;
349 if (pem != null && pem.IsDummy)
350 return parameter_type;
352 if (default_expr != null) {
353 EmitContext ec = new EmitContext (rc, rc.GenericDeclContainer, null, parameter_type);
354 default_expr = default_expr.Resolve (ec);
355 if (default_expr != null) {
356 Constant value = default_expr as Constant;
358 if (default_expr != null) {
359 bool is_valid = false;
360 if (default_expr is DefaultValueExpression) {
362 } else if (default_expr is New && ((New) default_expr).IsDefaultValueType) {
363 is_valid = TypeManager.IsEqual (parameter_type, default_expr.Type) ||
364 (TypeManager.IsNullableType (parameter_type) &&
365 Convert.ImplicitNulableConversion (ec, default_expr, parameter_type) != EmptyExpression.Null);
367 Report.Error (1736, default_expr.Location,
368 "The expression being assigned to optional parameter `{0}' must be a constant or default value",
375 Report.Error (1763, Location,
376 "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
377 Name, GetSignatureForError ());
381 Constant c = value.ConvertImplicitly (parameter_type);
383 if (parameter_type == TypeManager.object_type) {
384 Report.Error (1763, Location,
385 "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
386 Name, GetSignatureForError ());
388 Report.Error (1750, Location,
389 "Optional parameter value `{0}' cannot be converted to parameter type `{1}'",
390 value.GetValue (), GetSignatureForError ());
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 (TypeManager.IsGenericParameter (parameter_type))
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 || TypeManager.IsDynamicType (parameter_type))) {
419 Report.Error (1103, Location, "The extension method cannot be of type `{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) {
510 // Emit constant values for true constants only, the other
511 // constant-like expressions will rely on default value expression
513 Constant c = default_expr as Constant;
515 if (default_expr.Type == TypeManager.decimal_type) {
516 builder.SetCustomAttribute (Const.CreateDecimalConstantAttribute (c));
518 builder.SetConstant (c.GetValue ());
523 if (TypeManager.IsDynamicType (parameter_type))
524 PredefinedAttributes.Get.Dynamic.EmitAttribute (builder, Location);
527 public override string[] ValidAttributeTargets {
529 return attribute_targets;
533 public Parameter Clone ()
535 Parameter p = (Parameter) MemberwiseClone ();
536 if (attributes != null)
537 p.attributes = attributes.Clone ();
542 public ExpressionStatement CreateExpressionTreeVariable (EmitContext ec)
545 // A parameter is not hoisted when used directly as ET
547 HoistedVariableReference = null;
549 if ((modFlags & Modifier.ISBYREF) != 0)
550 Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
552 LocalInfo variable = ec.CurrentBlock.AddTemporaryVariable (
553 ResolveParameterExpressionType (ec, Location), Location);
554 variable.Resolve (ec);
556 expr_tree_variable = new LocalVariableReference (
557 ec.CurrentBlock, variable.Name, Location, variable, false);
559 Arguments arguments = new Arguments (2);
560 arguments.Add (new Argument (new TypeOf (
561 new TypeExpression (parameter_type, Location), Location)));
562 arguments.Add (new Argument (new StringConstant (Name, Location)));
563 return new SimpleAssign (ExpressionTreeVariableReference (),
564 Expression.CreateExpressionFactoryCall ("Parameter", null, arguments, Location));
567 public Expression DefaultValue {
568 get { return default_expr; }
569 set { default_expr = value; }
572 public void Emit (EmitContext ec)
578 ParameterReference.EmitLdArg (ec.ig, arg_idx);
581 public void EmitAssign (EmitContext ec)
588 ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
590 ec.ig.Emit (OpCodes.Starg, arg_idx);
593 public void EmitAddressOf (EmitContext ec)
600 bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
602 ParameterReference.EmitLdArg (ec.ig, arg_idx);
605 ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
607 ec.ig.Emit (OpCodes.Ldarga, arg_idx);
611 public Expression ExpressionTreeVariableReference ()
613 return expr_tree_variable;
617 // System.Linq.Expressions.ParameterExpression type
619 public static TypeExpr ResolveParameterExpressionType (EmitContext ec, Location location)
621 if (parameter_expr_tree_type != null)
622 return parameter_expr_tree_type;
624 Type p_type = TypeManager.parameter_expression_type;
625 if (p_type == null) {
626 p_type = TypeManager.CoreLookupType ("System.Linq.Expressions", "ParameterExpression", Kind.Class, true);
627 TypeManager.parameter_expression_type = p_type;
630 parameter_expr_tree_type = new TypeExpression (p_type, location).
631 ResolveAsTypeTerminal (ec, false);
633 return parameter_expr_tree_type;
636 public void Warning_UselessOptionalParameter ()
638 Report.Warning (1066, 1, Location,
639 "The default value specified for optional parameter `{0}' will never be used",
645 // Imported or resolved parameter information
647 public class ParameterData : IParameterData
649 readonly string name;
650 readonly Parameter.Modifier modifiers;
651 readonly Expression default_value;
653 public ParameterData (string name, Parameter.Modifier modifiers)
656 this.modifiers = modifiers;
659 public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
660 : this (name, modifiers)
662 this.default_value = defaultValue;
665 #region IParameterData Members
667 public Expression DefaultValue {
668 get { return default_value; }
671 public bool HasExtensionMethodModifier {
672 get { return (modifiers & Parameter.Modifier.This) != 0; }
675 public bool HasDefaultValue {
676 get { return default_value != null; }
679 public Parameter.Modifier ModFlags {
680 get { return modifiers & ~Parameter.Modifier.This; }
690 public abstract class AParametersCollection
692 protected bool has_arglist;
693 protected bool has_params;
695 // Null object pattern
696 protected IParameterData [] parameters;
697 protected Type [] types;
700 get { return parameters.Length; }
703 public Type ExtensionMethodType {
708 return FixedParameters [0].HasExtensionMethodModifier ?
713 public IParameterData [] FixedParameters {
719 public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
721 return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
722 ParameterAttributes.Out : ParameterAttributes.None;
725 public Type [] GetEmitTypes ()
727 Type [] types = null;
730 return Type.EmptyTypes;
732 types = new Type [Count - 1];
733 Array.Copy (Types, types, types.Length);
736 for (int i = 0; i < Count; ++i) {
737 if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
741 types = (Type []) Types.Clone ();
743 types [i] = TypeManager.GetReferenceType (types [i]);
753 // Returns the parameter information based on the name
755 public int GetParameterIndexByName (string name)
757 for (int idx = 0; idx < Count; ++idx) {
758 if (parameters [idx].Name == name)
765 public string GetSignatureForError ()
767 StringBuilder sb = new StringBuilder ("(");
768 for (int i = 0; i < Count; ++i) {
771 sb.Append (ParameterDesc (i));
774 return sb.ToString ();
777 public bool HasArglist {
778 get { return has_arglist; }
781 public bool HasExtensionMethodType {
786 return FixedParameters [0].HasExtensionMethodModifier;
790 public bool HasParams {
791 get { return has_params; }
794 public bool IsEmpty {
795 get { return parameters.Length == 0; }
798 public string ParameterDesc (int pos)
800 if (types == null || types [pos] == null)
801 return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
803 string type = TypeManager.CSharpName (types [pos]);
804 if (FixedParameters [pos].HasExtensionMethodModifier)
805 return "this " + type;
807 Parameter.Modifier mod = FixedParameters [pos].ModFlags;
811 return Parameter.GetModifierSignature (mod) + " " + type;
814 public Type[] Types {
815 get { return types; }
816 set { types = value; }
820 public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
822 AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone ();
824 for (int i = 0; i < Count; ++i) {
825 if (types[i].IsGenericType) {
826 Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
827 Type[] gen_arguments = types[i].GetGenericArguments ();
828 for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
829 if (gen_arguments[ii].IsGenericParameter) {
830 Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
831 gen_arguments_open[ii] = t;
833 gen_arguments_open[ii] = gen_arguments[ii];
836 p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
840 if (types[i].IsGenericParameter) {
841 Type gen_argument = argTypes[types[i].GenericParameterPosition];
842 p.types[i] = gen_argument;
853 // A collection of imported or resolved parameters
855 public class ParametersImported : AParametersCollection
857 ParametersImported (AParametersCollection param, Type[] types)
859 this.parameters = param.FixedParameters;
861 has_arglist = param.HasArglist;
862 has_params = param.HasParams;
865 ParametersImported (IParameterData [] parameters, Type [] types, bool hasArglist, bool hasParams)
867 this.parameters = parameters;
869 this.has_arglist = hasArglist;
870 this.has_params = hasParams;
873 public ParametersImported (IParameterData [] param, Type[] types)
875 this.parameters = param;
879 public static AParametersCollection Create (MethodBase method)
881 return Create (method.GetParameters (), method);
885 // Generic method parameters importer, param is shared between all instances
887 public static AParametersCollection Create (AParametersCollection param, MethodBase method)
892 ParameterInfo [] pi = method.GetParameters ();
893 Type [] types = new Type [pi.Length];
894 for (int i = 0; i < types.Length; i++) {
895 Type t = pi [i].ParameterType;
897 t = TypeManager.GetElementType (t);
899 types [i] = TypeManager.TypeToCoreType (t);
902 return new ParametersImported (param, types);
906 // Imports SRE parameters
908 public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method)
910 int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
912 if (pi.Length == 0 && varargs == 0)
913 return ParametersCompiled.EmptyReadOnlyParameters;
915 Type [] types = new Type [pi.Length + varargs];
916 IParameterData [] par = new IParameterData [pi.Length + varargs];
917 bool is_params = false;
918 PredefinedAttribute extension_attr = PredefinedAttributes.Get.Extension;
919 PredefinedAttribute param_attr = PredefinedAttributes.Get.ParamArray;
920 for (int i = 0; i < pi.Length; i++) {
921 types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType);
923 ParameterInfo p = pi [i];
924 Parameter.Modifier mod = 0;
925 Expression default_value = null;
926 if (types [i].IsByRef) {
927 if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
928 mod = Parameter.Modifier.OUT;
930 mod = Parameter.Modifier.REF;
933 // Strip reference wrapping
935 types [i] = TypeManager.GetElementType (types [i]);
936 } else if (i == 0 && extension_attr.IsDefined && method != null && method.IsStatic &&
937 (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
938 method.IsDefined (extension_attr.Type, false)) {
939 mod = Parameter.Modifier.This;
941 if (i >= pi.Length - 2 && types[i].IsArray) {
942 if (p.IsDefined (param_attr.Type, false)) {
943 mod = Parameter.Modifier.PARAMS;
948 if (!is_params && p.IsOptional) {
949 if (p.DefaultValue == Missing.Value)
950 default_value = EmptyExpression.Null;
952 default_value = Constant.CreateConstant (types[i], p.DefaultValue, Location.Null);
956 par [i] = new ParameterData (p.Name, mod, default_value);
960 par [par.Length - 1] = new ArglistParameter (Location.Null);
961 types [types.Length - 1] = InternalType.Arglist;
964 return method != null ?
965 new ParametersImported (par, types, varargs != 0, is_params) :
966 new ParametersImported (par, types);
971 /// Represents the methods parameters
973 public class ParametersCompiled : AParametersCollection
975 public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
977 // Used by C# 2.0 delegates
978 public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
980 private ParametersCompiled ()
982 parameters = new Parameter [0];
983 types = Type.EmptyTypes;
986 private ParametersCompiled (Parameter [] parameters, Type [] types)
988 this.parameters = parameters;
992 public ParametersCompiled (params Parameter[] parameters)
994 if (parameters == null)
995 throw new ArgumentException ("Use EmptyReadOnlyParameters");
997 this.parameters = parameters;
998 int count = parameters.Length;
1004 has_params = (parameters [0].ModFlags & Parameter.Modifier.PARAMS) != 0;
1008 for (int i = 0; i < count; i++){
1009 string base_name = parameters [i].Name;
1010 has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
1012 for (int j = i + 1; j < count; j++){
1013 if (base_name != parameters [j].Name)
1016 ErrorDuplicateName (parameters [i]);
1022 public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
1025 this.has_arglist = has_arglist;
1028 public static ParametersCompiled CreateFullyResolved (Parameter p, Type type)
1030 return new ParametersCompiled (new Parameter [] { p }, new Type [] { type });
1033 public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, Type[] types)
1035 return new ParametersCompiled (parameters, types);
1038 public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
1040 return MergeGenerated (userParams, checkConflicts,
1041 new Parameter [] { compilerParams },
1042 new Type [] { compilerTypes });
1046 // Use this method when you merge compiler generated parameters with user parameters
1048 public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
1050 Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1051 userParams.FixedParameters.CopyTo(all_params, 0);
1054 if (userParams.types != null) {
1055 all_types = new Type [all_params.Length];
1056 userParams.Types.CopyTo (all_types, 0);
1061 int last_filled = userParams.Count;
1063 foreach (Parameter p in compilerParams) {
1064 for (int i = 0; i < last_filled; ++i) {
1065 while (p.Name == all_params [i].Name) {
1066 if (checkConflicts && i < userParams.Count) {
1067 Report.Error (316, userParams [i].Location,
1068 "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1070 p.Name = '_' + p.Name;
1073 all_params [last_filled] = p;
1074 if (all_types != null)
1075 all_types [last_filled] = compilerTypes [index++];
1079 ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1080 parameters.has_params = userParams.has_params;
1084 protected virtual void ErrorDuplicateName (Parameter p)
1086 Report.Error (100, p.Location, "The parameter name `{0}' is a duplicate", p.Name);
1089 public bool Resolve (IResolveContext ec)
1094 types = new Type [Count];
1098 for (int i = 0; i < FixedParameters.Length; ++i) {
1100 Type t = p.Resolve (ec);
1112 public void ResolveVariable ()
1114 for (int i = 0; i < FixedParameters.Length; ++i) {
1115 this [i].ResolveVariable (i);
1119 public CallingConventions CallingConvention
1123 return CallingConventions.VarArgs;
1125 return CallingConventions.Standard;
1129 // Define each type attribute (in/out/ref) and
1130 // the argument names.
1131 public void ApplyAttributes (MethodBase builder)
1136 MethodBuilder mb = builder as MethodBuilder;
1137 ConstructorBuilder cb = builder as ConstructorBuilder;
1139 for (int i = 0; i < Count; i++) {
1140 this [i].ApplyAttributes (mb, cb, i + 1);
1144 public void VerifyClsCompliance ()
1146 foreach (Parameter p in FixedParameters)
1147 p.IsClsCompliant ();
1150 public Parameter this [int pos] {
1151 get { return (Parameter) parameters [pos]; }
1154 public Expression CreateExpressionTree (EmitContext ec, Location loc)
1156 ArrayList initializers = new ArrayList (Count);
1157 foreach (Parameter p in FixedParameters) {
1159 // Each parameter expression is stored to local variable
1160 // to save some memory when referenced later.
1162 StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec));
1163 if (se.Resolve (ec))
1164 ec.CurrentBlock.AddScopeStatement (se);
1166 initializers.Add (p.ExpressionTreeVariableReference ());
1169 return new ArrayCreation (
1170 Parameter.ResolveParameterExpressionType (ec, loc),
1171 "[]", initializers, loc);
1174 public ParametersCompiled Clone ()
1176 ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1178 p.parameters = new IParameterData [parameters.Length];
1179 for (int i = 0; i < Count; ++i)
1180 p.parameters [i] = this [i].Clone ();