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;
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, MethodSpec ctor, byte[] cdata, 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 if (a.Type == pa.Dynamic) {
45 a.Error_MisusedDynamicAttribute ();
49 builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
52 public ParameterBuilder Builder {
58 public override bool IsClsComplianceRequired()
65 /// Class for applying custom attributes on the return type
67 public class ReturnParameter : ParameterBase
71 // TODO: merge method and mb
72 public ReturnParameter (MemberCore method, MethodBuilder mb, Location location)
76 builder = mb.DefineParameter (0, ParameterAttributes.None, "");
78 catch (ArgumentOutOfRangeException) {
79 method.Compiler.Report.RuntimeMissingSupport (location, "custom attributes on the return type");
83 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
85 if (a.Type == pa.CLSCompliant) {
86 method.Compiler.Report.Warning (3023, 1, a.Location,
87 "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
90 // This occurs after Warning -28
94 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
97 public override AttributeTargets AttributeTargets {
99 return AttributeTargets.ReturnValue;
106 public override string[] ValidAttributeTargets {
114 /// Class for applying custom attributes on the implicit parameter type
115 /// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
118 // TODO: should use more code from Parameter.ApplyAttributeBuilder
119 public class ImplicitParameter : ParameterBase {
120 public ImplicitParameter (MethodBuilder mb)
122 builder = mb.DefineParameter (1, ParameterAttributes.None, "value");
125 public override AttributeTargets AttributeTargets {
127 return AttributeTargets.Parameter;
134 public override string[] ValidAttributeTargets {
141 public class ImplicitLambdaParameter : Parameter
143 public ImplicitLambdaParameter (string name, Location loc)
144 : base (null, name, Modifier.NONE, null, loc)
148 public override TypeSpec Resolve (IMemberContext ec, int index)
150 if (parameter_type == null)
151 throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
155 return parameter_type;
158 public void SetParameterType (TypeSpec type)
160 parameter_type = type;
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 TypeSpec Resolve (IMemberContext ec, int index)
172 if (base.Resolve (ec, index) == null)
175 var ac = parameter_type as ArrayContainer;
176 if (ac == null || ac.Rank != 1) {
177 ec.Compiler.Report.Error (225, Location, "The params parameter must be a single dimensional array");
181 return parameter_type;
184 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
186 base.ApplyAttributes (mb, cb, index, pa);
187 pa.ParamArray.EmitAttribute (builder);
191 public class ArglistParameter : Parameter {
192 // Doesn't have proper type because it's never chosen for better conversion
193 public ArglistParameter (Location loc) :
194 base (null, String.Empty, Parameter.Modifier.NONE, null, loc)
196 parameter_type = InternalType.Arglist;
199 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
204 public override bool CheckAccessibility (InterfaceMemberBase member)
209 public override TypeSpec Resolve (IMemberContext ec, int index)
211 return parameter_type;
215 public interface IParameterData
217 Expression DefaultValue { get; }
218 bool HasExtensionMethodModifier { get; }
219 bool HasDefaultValue { get; }
220 Parameter.Modifier ModFlags { get; }
225 // Parameter information created by parser
227 public class Parameter : ParameterBase, IParameterData, ILocalVariable // TODO: INamedBlockVariable
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.
242 static string[] attribute_targets = new string [] { "param" };
244 FullNamedExpression texpr;
245 readonly Modifier modFlags;
247 Expression default_expr;
248 protected TypeSpec parameter_type;
249 readonly Location loc;
251 public bool HasAddressTaken;
253 TemporaryVariableReference expr_tree_variable;
254 static TypeExpr parameter_expr_tree_type;
256 HoistedVariable hoisted_variant;
258 public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
265 // Only assign, attributes will be attached during resolve
266 base.attributes = attrs;
271 public Expression DefaultValue {
276 default_expr = value;
280 public Location Location {
286 public TypeSpec Type {
288 return parameter_type;
292 public FullNamedExpression TypeExpression {
298 public override string[] ValidAttributeTargets {
300 return attribute_targets;
306 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
308 if (a.Type == pa.In && ModFlags == Modifier.OUT) {
309 a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
313 if (a.Type == pa.ParamArray) {
314 a.Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
318 if (a.Type == pa.Out && (ModFlags & Modifier.REF) == Modifier.REF &&
319 !OptAttributes.Contains (pa.In)) {
320 a.Report.Error (662, a.Location,
321 "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
325 if (a.Type == pa.CLSCompliant) {
326 a.Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
329 if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) {
330 a.Report.Error (1745, a.Location,
331 "Cannot specify `{0}' attribute on optional parameter `{1}'",
332 TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
336 if (a.Type == pa.DefaultParameterValue) {
338 var c = a.GetParameterDefaultValue (out arg_type);
340 if (parameter_type == TypeManager.object_type) {
341 a.Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
342 arg_type.GetSignatureForError ());
344 a.Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
345 parameter_type.GetSignatureForError ()); ;
351 if (arg_type == parameter_type || parameter_type == TypeManager.object_type ||
352 (c.IsNull && TypeManager.IsReferenceType (parameter_type) && !TypeManager.IsGenericParameter (parameter_type)))
353 builder.SetConstant (c.GetValue ());
355 a.Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
360 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
363 public virtual bool CheckAccessibility (InterfaceMemberBase member)
365 if (parameter_type == null)
368 return member.IsAccessibleAs (parameter_type);
371 public static void Reset ()
373 parameter_expr_tree_type = null;
377 // Resolve is used in method definitions
379 public virtual TypeSpec Resolve (IMemberContext rc, int index)
381 if (parameter_type != null)
382 return parameter_type;
384 if (attributes != null)
385 attributes.AttachTo (this, rc);
387 var expr = texpr.ResolveAsTypeTerminal (rc, false);
393 parameter_type = texpr.Type;
395 if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
396 TypeManager.IsSpecialType (parameter_type)) {
397 rc.Compiler.Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
398 GetSignatureForError ());
402 TypeManager.CheckTypeVariance (parameter_type,
403 (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
406 if (parameter_type.IsStatic) {
407 rc.Compiler.Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
408 texpr.GetSignatureForError ());
409 return parameter_type;
412 if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || parameter_type == InternalType.Dynamic)) {
413 rc.Compiler.Report.Error (1103, Location, "The extension method cannot be of type `{0}'",
414 TypeManager.CSharpName (parameter_type));
417 return parameter_type;
420 public void ResolveDefaultValue (ResolveContext rc)
423 // Default value was specified using an expression
425 if (default_expr != null) {
426 default_expr = ResolveDefaultExpression (rc);
430 if (attributes == null)
433 var pa = attributes.Search (rc.Compiler.PredefinedAttributes.OptionalParameter);
438 // Default value was specified using an attribute
440 attributes.Attrs.Remove (pa);
442 TypeSpec expr_type = null;
443 pa = attributes.Search (rc.Compiler.PredefinedAttributes.DefaultParameterValue);
445 attributes.Attrs.Remove (pa);
446 default_expr = pa.GetParameterDefaultValue (out expr_type);
448 default_expr = EmptyExpression.MissingValue;
451 if (default_expr == null) {
452 if (expr_type == null)
453 expr_type = parameter_type;
455 default_expr = new DefaultValueExpression (new TypeExpression (expr_type, Location), Location);
458 default_expr = default_expr.Resolve (rc);
461 Expression ResolveDefaultExpression (ResolveContext rc)
463 default_expr = default_expr.Resolve (rc);
464 if (default_expr == null)
467 if (!(default_expr is Constant || default_expr is DefaultValueExpression || (default_expr is New && ((New)default_expr).IsDefaultStruct))) {
468 rc.Compiler.Report.Error (1736, default_expr.Location,
469 "The expression being assigned to optional parameter `{0}' must be a constant or default value",
475 if (default_expr.Type == parameter_type)
478 if (TypeManager.IsNullableType (parameter_type)) {
479 if (default_expr.Type == InternalType.Null)
482 var underlying = Nullable.NullableInfo.GetUnderlyingType (parameter_type);
483 var c = New.Constantify (underlying, Location.Null);
485 rc.Compiler.Report.Error (1770, default_expr.Location,
486 "The expression being assigned to nullable optional parameter `{0}' must be default value",
492 if (c.Type == default_expr.Type)
495 var res = Convert.ImplicitConversionStandard (rc, default_expr, parameter_type, default_expr.Location);
497 if (!default_expr.IsNull && TypeManager.IsReferenceType (parameter_type) && parameter_type != TypeManager.string_type) {
498 rc.Compiler.Report.Error (1763, default_expr.Location,
499 "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
500 Name, GetSignatureForError ());
509 rc.Compiler.Report.Error (1750, Location,
510 "Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'",
511 TypeManager.CSharpName (default_expr.Type), GetSignatureForError ());
516 public bool HasDefaultValue {
517 get { return default_expr != null; }
520 public bool HasExtensionMethodModifier {
521 get { return (modFlags & Modifier.This) != 0; }
525 // Hoisted parameter variant
527 public HoistedVariable HoistedVariant {
529 return hoisted_variant;
532 hoisted_variant = value;
536 public Modifier ModFlags {
537 get { return modFlags & ~Modifier.This; }
542 set { name = value; }
545 ParameterAttributes Attributes {
546 get { return ParametersCompiled.GetParameterAttribute (modFlags) |
547 (HasDefaultValue ? ParameterAttributes.Optional : ParameterAttributes.None); }
550 public override AttributeTargets AttributeTargets {
552 return AttributeTargets.Parameter;
556 public virtual string GetSignatureForError ()
559 if (parameter_type != null)
560 type_name = TypeManager.CSharpName (parameter_type);
562 type_name = texpr.GetSignatureForError ();
564 string mod = GetModifierSignature (modFlags);
566 return String.Concat (mod, " ", type_name);
571 public static string GetModifierSignature (Modifier mod)
576 case Modifier.PARAMS:
587 public void IsClsCompliant (IMemberContext ctx)
589 if (parameter_type.IsCLSCompliant ())
592 ctx.Compiler.Report.Warning (3001, 1, Location,
593 "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
596 public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
599 builder = cb.DefineParameter (index, Attributes, Name);
601 builder = mb.DefineParameter (index, Attributes, Name);
603 if (OptAttributes != null)
604 OptAttributes.Emit ();
606 if (HasDefaultValue) {
608 // Emit constant values for true constants only, the other
609 // constant-like expressions will rely on default value expression
611 Constant c = default_expr as Constant;
613 if (default_expr.Type == TypeManager.decimal_type) {
614 builder.SetCustomAttribute (Const.CreateDecimalConstantAttribute (c, pa));
616 builder.SetConstant (c.GetTypedValue ());
621 if (parameter_type == InternalType.Dynamic) {
622 pa.Dynamic.EmitAttribute (builder);
624 var trans_flags = TypeManager.HasDynamicTypeUsed (parameter_type);
625 if (trans_flags != null) {
626 var dt = pa.DynamicTransform;
627 if (dt.Constructor != null || dt.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
628 builder.SetCustomAttribute (
629 new CustomAttributeBuilder (dt.Constructor, new object [] { trans_flags }));
635 public Parameter Clone ()
637 Parameter p = (Parameter) MemberwiseClone ();
638 if (attributes != null)
639 p.attributes = attributes.Clone ();
644 public ExpressionStatement CreateExpressionTreeVariable (BlockContext ec)
646 if ((modFlags & Modifier.ISBYREF) != 0)
647 ec.Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
649 expr_tree_variable = TemporaryVariableReference.Create (ResolveParameterExpressionType (ec, Location).Type, ec.CurrentBlock.ParametersBlock, Location);
650 expr_tree_variable = (TemporaryVariableReference) expr_tree_variable.Resolve (ec);
652 Arguments arguments = new Arguments (2);
653 arguments.Add (new Argument (new TypeOf (
654 new TypeExpression (parameter_type, Location), Location)));
655 arguments.Add (new Argument (new StringConstant (Name, Location)));
656 return new SimpleAssign (ExpressionTreeVariableReference (),
657 Expression.CreateExpressionFactoryCall (ec, "Parameter", null, arguments, Location));
660 public void Emit (EmitContext ec)
666 ParameterReference.EmitLdArg (ec, arg_idx);
669 public void EmitAssign (EmitContext ec)
676 ec.Emit (OpCodes.Starg_S, (byte) arg_idx);
678 ec.Emit (OpCodes.Starg, arg_idx);
681 public void EmitAddressOf (EmitContext ec)
688 bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
690 ParameterReference.EmitLdArg (ec, arg_idx);
693 ec.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
695 ec.Emit (OpCodes.Ldarga, arg_idx);
699 public TemporaryVariableReference ExpressionTreeVariableReference ()
701 return expr_tree_variable;
705 // System.Linq.Expressions.ParameterExpression type
707 public static TypeExpr ResolveParameterExpressionType (IMemberContext ec, Location location)
709 if (parameter_expr_tree_type != null)
710 return parameter_expr_tree_type;
712 TypeSpec p_type = TypeManager.parameter_expression_type;
713 if (p_type == null) {
714 p_type = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "ParameterExpression", MemberKind.Class, true);
715 TypeManager.parameter_expression_type = p_type;
718 parameter_expr_tree_type = new TypeExpression (p_type, location).
719 ResolveAsTypeTerminal (ec, false);
721 return parameter_expr_tree_type;
724 public void Warning_UselessOptionalParameter (Report Report)
726 Report.Warning (1066, 1, Location,
727 "The default value specified for optional parameter `{0}' will never be used",
733 // Imported or resolved parameter information
735 public class ParameterData : IParameterData
737 readonly string name;
738 readonly Parameter.Modifier modifiers;
739 readonly Expression default_value;
741 public ParameterData (string name, Parameter.Modifier modifiers)
744 this.modifiers = modifiers;
747 public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
748 : this (name, modifiers)
750 this.default_value = defaultValue;
753 #region IParameterData Members
755 public Expression DefaultValue {
756 get { return default_value; }
759 public bool HasExtensionMethodModifier {
760 get { return (modifiers & Parameter.Modifier.This) != 0; }
763 public bool HasDefaultValue {
764 get { return default_value != null; }
767 public Parameter.Modifier ModFlags {
768 get { return modifiers & ~Parameter.Modifier.This; }
778 public abstract class AParametersCollection
780 protected bool has_arglist;
781 protected bool has_params;
783 // Null object pattern
784 protected IParameterData [] parameters;
785 protected TypeSpec [] types;
787 public CallingConventions CallingConvention {
790 CallingConventions.VarArgs :
791 CallingConventions.Standard;
796 get { return parameters.Length; }
799 public TypeSpec ExtensionMethodType {
804 return FixedParameters [0].HasExtensionMethodModifier ?
809 public IParameterData [] FixedParameters {
815 public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
817 return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
818 ParameterAttributes.Out : ParameterAttributes.None;
821 // Very expensive operation
822 public Type[] GetMetaInfo ()
827 return Type.EmptyTypes;
829 types = new Type [Count - 1];
832 return Type.EmptyTypes;
834 types = new Type [Count];
837 for (int i = 0; i < types.Length; ++i) {
838 types[i] = Types[i].GetMetaInfo ();
840 if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
843 // TODO MemberCache: Should go to MetaInfo getter
844 types [i] = types [i].MakeByRefType ();
851 // Returns the parameter information based on the name
853 public int GetParameterIndexByName (string name)
855 for (int idx = 0; idx < Count; ++idx) {
856 if (parameters [idx].Name == name)
863 public string GetSignatureForError ()
865 return GetSignatureForError ("(", ")", Count);
868 public string GetSignatureForError (string start, string end, int count)
870 StringBuilder sb = new StringBuilder (start);
871 for (int i = 0; i < count; ++i) {
874 sb.Append (ParameterDesc (i));
877 return sb.ToString ();
880 public bool HasArglist {
881 get { return has_arglist; }
884 public bool HasExtensionMethodType {
889 return FixedParameters [0].HasExtensionMethodModifier;
893 public bool HasParams {
894 get { return has_params; }
897 public bool IsEmpty {
898 get { return parameters.Length == 0; }
901 public AParametersCollection Inflate (TypeParameterInflator inflator)
903 TypeSpec[] inflated_types = null;
904 bool default_value = false;
906 for (int i = 0; i < Count; ++i) {
907 var inflated_param = inflator.Inflate (types[i]);
908 if (inflated_types == null) {
909 if (inflated_param == types[i])
912 default_value |= FixedParameters[i] is DefaultValueExpression;
913 inflated_types = new TypeSpec[types.Length];
914 Array.Copy (types, inflated_types, types.Length);
917 inflated_types[i] = inflated_param;
920 if (inflated_types == null)
923 var clone = (AParametersCollection) MemberwiseClone ();
924 clone.types = inflated_types;
926 for (int i = 0; i < Count; ++i) {
927 var dve = clone.FixedParameters[i] as DefaultValueExpression;
929 throw new NotImplementedException ("net");
930 // clone.FixedParameters [i].DefaultValue = new DefaultValueExpression ();
938 public string ParameterDesc (int pos)
940 if (types == null || types [pos] == null)
941 return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
943 string type = TypeManager.CSharpName (types [pos]);
944 if (FixedParameters [pos].HasExtensionMethodModifier)
945 return "this " + type;
947 Parameter.Modifier mod = FixedParameters [pos].ModFlags;
951 return Parameter.GetModifierSignature (mod) + " " + type;
954 public TypeSpec[] Types {
955 get { return types; }
956 set { types = value; }
961 // A collection of imported or resolved parameters
963 public class ParametersImported : AParametersCollection
965 public ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
967 this.parameters = parameters;
969 this.has_arglist = hasArglist;
970 this.has_params = hasParams;
973 public ParametersImported (IParameterData[] param, TypeSpec[] types, bool hasParams)
975 this.parameters = param;
977 this.has_params = hasParams;
982 /// Represents the methods parameters
984 public class ParametersCompiled : AParametersCollection
986 public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
988 // Used by C# 2.0 delegates
989 public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
991 private ParametersCompiled ()
993 parameters = new Parameter [0];
994 types = TypeSpec.EmptyTypes;
997 private ParametersCompiled (IParameterData[] parameters, TypeSpec[] types)
999 this.parameters = parameters;
1003 public ParametersCompiled (params Parameter[] parameters)
1005 if (parameters == null || parameters.Length == 0)
1006 throw new ArgumentException ("Use EmptyReadOnlyParameters");
1008 this.parameters = parameters;
1009 int count = parameters.Length;
1011 for (int i = 0; i < count; i++){
1012 has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
1016 public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
1019 this.has_arglist = has_arglist;
1022 public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
1024 return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
1027 public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, TypeSpec[] types)
1029 return new ParametersCompiled (parameters, types);
1033 // TODO: This does not fit here, it should go to different version of AParametersCollection
1034 // as the underlying type is not Parameter and some methods will fail to cast
1036 public static AParametersCollection CreateFullyResolved (TypeSpec[] types)
1038 var pd = new ParameterData [types.Length];
1039 for (int i = 0; i < pd.Length; ++i)
1040 pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null);
1042 return new ParametersCompiled (pd, types);
1045 public static ParametersCompiled CreateImplicitParameter (FullNamedExpression texpr, Location loc)
1047 return new ParametersCompiled (
1048 new[] { new Parameter (texpr, "value", Parameter.Modifier.NONE, null, loc) },
1053 // Returns non-zero value for equal CLS parameter signatures
1055 public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
1059 for (int i = 0; i < a.Count; ++i) {
1060 var a_type = a.Types[i];
1061 var b_type = b.Types[i];
1062 if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
1063 const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
1064 if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
1070 var ac_a = a_type as ArrayContainer;
1074 var ac_b = b_type as ArrayContainer;
1078 if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
1083 if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
1094 public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
1096 return MergeGenerated (ctx, userParams, checkConflicts,
1097 new Parameter [] { compilerParams },
1098 new TypeSpec [] { compilerTypes });
1102 // Use this method when you merge compiler generated parameters with user parameters
1104 public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
1106 Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1107 userParams.FixedParameters.CopyTo(all_params, 0);
1109 TypeSpec [] all_types;
1110 if (userParams.types != null) {
1111 all_types = new TypeSpec [all_params.Length];
1112 userParams.Types.CopyTo (all_types, 0);
1117 int last_filled = userParams.Count;
1119 foreach (Parameter p in compilerParams) {
1120 for (int i = 0; i < last_filled; ++i) {
1121 while (p.Name == all_params [i].Name) {
1122 if (checkConflicts && i < userParams.Count) {
1123 ctx.Report.Error (316, userParams[i].Location,
1124 "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1126 p.Name = '_' + p.Name;
1129 all_params [last_filled] = p;
1130 if (all_types != null)
1131 all_types [last_filled] = compilerTypes [index++];
1135 ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1136 parameters.has_params = userParams.has_params;
1140 public bool Resolve (IMemberContext ec)
1145 types = new TypeSpec [Count];
1149 for (int i = 0; i < FixedParameters.Length; ++i) {
1151 TypeSpec t = p.Resolve (ec, i);
1163 public void ResolveDefaultValues (MemberCore m)
1165 var count = parameters.Length;
1168 // Try not to enter default values resolution if there are not any
1170 if (parameters[count - 1].HasDefaultValue || (HasParams && count > 1 && parameters[count - 2].HasDefaultValue) ||
1171 ((Parameter) parameters[count - 1]).OptAttributes != null) {
1172 var rc = new ResolveContext (m);
1173 for (int i = 0; i < count; ++i) {
1174 this [i].ResolveDefaultValue (rc);
1179 // Define each type attribute (in/out/ref) and
1180 // the argument names.
1181 public void ApplyAttributes (IMemberContext mc, MethodBase builder)
1186 MethodBuilder mb = builder as MethodBuilder;
1187 ConstructorBuilder cb = builder as ConstructorBuilder;
1188 var pa = mc.Compiler.PredefinedAttributes;
1190 for (int i = 0; i < Count; i++) {
1191 this [i].ApplyAttributes (mb, cb, i + 1, pa);
1195 public void VerifyClsCompliance (IMemberContext ctx)
1197 foreach (Parameter p in FixedParameters)
1198 p.IsClsCompliant (ctx);
1201 public Parameter this [int pos] {
1202 get { return (Parameter) parameters [pos]; }
1205 public Expression CreateExpressionTree (BlockContext ec, Location loc)
1207 var initializers = new ArrayInitializer (Count, loc);
1208 foreach (Parameter p in FixedParameters) {
1210 // Each parameter expression is stored to local variable
1211 // to save some memory when referenced later.
1213 StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec));
1214 if (se.Resolve (ec)) {
1215 ec.CurrentBlock.AddScopeStatement (new TemporaryVariableReference.Declarator (p.ExpressionTreeVariableReference ()));
1216 ec.CurrentBlock.AddScopeStatement (se);
1219 initializers.Add (p.ExpressionTreeVariableReference ());
1222 return new ArrayCreation (
1223 Parameter.ResolveParameterExpressionType (ec, loc),
1227 public ParametersCompiled Clone ()
1229 ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1231 p.parameters = new IParameterData [parameters.Length];
1232 for (int i = 0; i < Count; ++i)
1233 p.parameters [i] = this [i].Clone ();