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)) {
468 if (TypeManager.IsNullableType (parameter_type)) {
469 rc.Compiler.Report.Error (1770, default_expr.Location,
470 "The expression being assigned to nullable optional parameter `{0}' must be default value",
473 rc.Compiler.Report.Error (1736, default_expr.Location,
474 "The expression being assigned to optional parameter `{0}' must be a constant or default value",
481 if (default_expr.Type == parameter_type)
484 if (TypeManager.IsNullableType (parameter_type)) {
485 if (Convert.ImplicitNulableConversion (rc, default_expr, parameter_type) != null)
488 var res = Convert.ImplicitConversionStandard (rc, default_expr, parameter_type, default_expr.Location);
490 if (!default_expr.IsNull && TypeManager.IsReferenceType (parameter_type) && parameter_type != TypeManager.string_type) {
491 rc.Compiler.Report.Error (1763, default_expr.Location,
492 "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
493 Name, GetSignatureForError ());
502 rc.Compiler.Report.Error (1750, Location,
503 "Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'",
504 TypeManager.CSharpName (default_expr.Type), GetSignatureForError ());
509 public bool HasDefaultValue {
510 get { return default_expr != null; }
513 public bool HasExtensionMethodModifier {
514 get { return (modFlags & Modifier.This) != 0; }
518 // Hoisted parameter variant
520 public HoistedVariable HoistedVariant {
522 return hoisted_variant;
525 hoisted_variant = value;
529 public Modifier ModFlags {
530 get { return modFlags & ~Modifier.This; }
535 set { name = value; }
538 ParameterAttributes Attributes {
539 get { return ParametersCompiled.GetParameterAttribute (modFlags) |
540 (HasDefaultValue ? ParameterAttributes.Optional : ParameterAttributes.None); }
543 public override AttributeTargets AttributeTargets {
545 return AttributeTargets.Parameter;
549 public virtual string GetSignatureForError ()
552 if (parameter_type != null)
553 type_name = TypeManager.CSharpName (parameter_type);
555 type_name = texpr.GetSignatureForError ();
557 string mod = GetModifierSignature (modFlags);
559 return String.Concat (mod, " ", type_name);
564 public static string GetModifierSignature (Modifier mod)
569 case Modifier.PARAMS:
580 public void IsClsCompliant (IMemberContext ctx)
582 if (parameter_type.IsCLSCompliant ())
585 ctx.Compiler.Report.Warning (3001, 1, Location,
586 "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
589 public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
592 builder = cb.DefineParameter (index, Attributes, Name);
594 builder = mb.DefineParameter (index, Attributes, Name);
596 if (OptAttributes != null)
597 OptAttributes.Emit ();
599 if (HasDefaultValue) {
601 // Emit constant values for true constants only, the other
602 // constant-like expressions will rely on default value expression
604 Constant c = default_expr as Constant;
606 if (default_expr.Type == TypeManager.decimal_type) {
607 builder.SetCustomAttribute (Const.CreateDecimalConstantAttribute (c, pa));
609 builder.SetConstant (c.GetTypedValue ());
614 if (parameter_type == InternalType.Dynamic) {
615 pa.Dynamic.EmitAttribute (builder);
617 var trans_flags = TypeManager.HasDynamicTypeUsed (parameter_type);
618 if (trans_flags != null) {
619 var dt = pa.DynamicTransform;
620 if (dt.Constructor != null || dt.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
621 builder.SetCustomAttribute (
622 new CustomAttributeBuilder (dt.Constructor, new object [] { trans_flags }));
628 public Parameter Clone ()
630 Parameter p = (Parameter) MemberwiseClone ();
631 if (attributes != null)
632 p.attributes = attributes.Clone ();
637 public ExpressionStatement CreateExpressionTreeVariable (BlockContext ec)
639 if ((modFlags & Modifier.ISBYREF) != 0)
640 ec.Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
642 expr_tree_variable = TemporaryVariableReference.Create (ResolveParameterExpressionType (ec, Location).Type, ec.CurrentBlock.ParametersBlock, Location);
643 expr_tree_variable = (TemporaryVariableReference) expr_tree_variable.Resolve (ec);
645 Arguments arguments = new Arguments (2);
646 arguments.Add (new Argument (new TypeOf (
647 new TypeExpression (parameter_type, Location), Location)));
648 arguments.Add (new Argument (new StringConstant (Name, Location)));
649 return new SimpleAssign (ExpressionTreeVariableReference (),
650 Expression.CreateExpressionFactoryCall (ec, "Parameter", null, arguments, Location));
653 public void Emit (EmitContext ec)
659 ParameterReference.EmitLdArg (ec, arg_idx);
662 public void EmitAssign (EmitContext ec)
669 ec.Emit (OpCodes.Starg_S, (byte) arg_idx);
671 ec.Emit (OpCodes.Starg, arg_idx);
674 public void EmitAddressOf (EmitContext ec)
681 bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
683 ParameterReference.EmitLdArg (ec, arg_idx);
686 ec.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
688 ec.Emit (OpCodes.Ldarga, arg_idx);
692 public TemporaryVariableReference ExpressionTreeVariableReference ()
694 return expr_tree_variable;
698 // System.Linq.Expressions.ParameterExpression type
700 public static TypeExpr ResolveParameterExpressionType (IMemberContext ec, Location location)
702 if (parameter_expr_tree_type != null)
703 return parameter_expr_tree_type;
705 TypeSpec p_type = TypeManager.parameter_expression_type;
706 if (p_type == null) {
707 p_type = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "ParameterExpression", MemberKind.Class, true);
708 TypeManager.parameter_expression_type = p_type;
711 parameter_expr_tree_type = new TypeExpression (p_type, location).
712 ResolveAsTypeTerminal (ec, false);
714 return parameter_expr_tree_type;
717 public void Warning_UselessOptionalParameter (Report Report)
719 Report.Warning (1066, 1, Location,
720 "The default value specified for optional parameter `{0}' will never be used",
726 // Imported or resolved parameter information
728 public class ParameterData : IParameterData
730 readonly string name;
731 readonly Parameter.Modifier modifiers;
732 readonly Expression default_value;
734 public ParameterData (string name, Parameter.Modifier modifiers)
737 this.modifiers = modifiers;
740 public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
741 : this (name, modifiers)
743 this.default_value = defaultValue;
746 #region IParameterData Members
748 public Expression DefaultValue {
749 get { return default_value; }
752 public bool HasExtensionMethodModifier {
753 get { return (modifiers & Parameter.Modifier.This) != 0; }
756 public bool HasDefaultValue {
757 get { return default_value != null; }
760 public Parameter.Modifier ModFlags {
761 get { return modifiers & ~Parameter.Modifier.This; }
771 public abstract class AParametersCollection
773 protected bool has_arglist;
774 protected bool has_params;
776 // Null object pattern
777 protected IParameterData [] parameters;
778 protected TypeSpec [] types;
780 public CallingConventions CallingConvention {
783 CallingConventions.VarArgs :
784 CallingConventions.Standard;
789 get { return parameters.Length; }
792 public TypeSpec ExtensionMethodType {
797 return FixedParameters [0].HasExtensionMethodModifier ?
802 public IParameterData [] FixedParameters {
808 public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
810 return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
811 ParameterAttributes.Out : ParameterAttributes.None;
814 // Very expensive operation
815 public Type[] GetMetaInfo ()
820 return Type.EmptyTypes;
822 types = new Type [Count - 1];
825 return Type.EmptyTypes;
827 types = new Type [Count];
830 for (int i = 0; i < types.Length; ++i) {
831 types[i] = Types[i].GetMetaInfo ();
833 if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
836 // TODO MemberCache: Should go to MetaInfo getter
837 types [i] = types [i].MakeByRefType ();
844 // Returns the parameter information based on the name
846 public int GetParameterIndexByName (string name)
848 for (int idx = 0; idx < Count; ++idx) {
849 if (parameters [idx].Name == name)
856 public string GetSignatureForError ()
858 return GetSignatureForError ("(", ")", Count);
861 public string GetSignatureForError (string start, string end, int count)
863 StringBuilder sb = new StringBuilder (start);
864 for (int i = 0; i < count; ++i) {
867 sb.Append (ParameterDesc (i));
870 return sb.ToString ();
873 public bool HasArglist {
874 get { return has_arglist; }
877 public bool HasExtensionMethodType {
882 return FixedParameters [0].HasExtensionMethodModifier;
886 public bool HasParams {
887 get { return has_params; }
890 public bool IsEmpty {
891 get { return parameters.Length == 0; }
894 public AParametersCollection Inflate (TypeParameterInflator inflator)
896 TypeSpec[] inflated_types = null;
897 bool default_value = false;
899 for (int i = 0; i < Count; ++i) {
900 var inflated_param = inflator.Inflate (types[i]);
901 if (inflated_types == null) {
902 if (inflated_param == types[i])
905 default_value |= FixedParameters[i] is DefaultValueExpression;
906 inflated_types = new TypeSpec[types.Length];
907 Array.Copy (types, inflated_types, types.Length);
910 inflated_types[i] = inflated_param;
913 if (inflated_types == null)
916 var clone = (AParametersCollection) MemberwiseClone ();
917 clone.types = inflated_types;
919 for (int i = 0; i < Count; ++i) {
920 var dve = clone.FixedParameters[i] as DefaultValueExpression;
922 throw new NotImplementedException ("net");
923 // clone.FixedParameters [i].DefaultValue = new DefaultValueExpression ();
931 public string ParameterDesc (int pos)
933 if (types == null || types [pos] == null)
934 return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
936 string type = TypeManager.CSharpName (types [pos]);
937 if (FixedParameters [pos].HasExtensionMethodModifier)
938 return "this " + type;
940 Parameter.Modifier mod = FixedParameters [pos].ModFlags;
944 return Parameter.GetModifierSignature (mod) + " " + type;
947 public TypeSpec[] Types {
948 get { return types; }
949 set { types = value; }
954 // A collection of imported or resolved parameters
956 public class ParametersImported : AParametersCollection
958 public ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
960 this.parameters = parameters;
962 this.has_arglist = hasArglist;
963 this.has_params = hasParams;
966 public ParametersImported (IParameterData[] param, TypeSpec[] types, bool hasParams)
968 this.parameters = param;
970 this.has_params = hasParams;
975 /// Represents the methods parameters
977 public class ParametersCompiled : AParametersCollection
979 public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
981 // Used by C# 2.0 delegates
982 public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
984 private ParametersCompiled ()
986 parameters = new Parameter [0];
987 types = TypeSpec.EmptyTypes;
990 private ParametersCompiled (IParameterData[] parameters, TypeSpec[] types)
992 this.parameters = parameters;
996 public ParametersCompiled (params Parameter[] parameters)
998 if (parameters == null || parameters.Length == 0)
999 throw new ArgumentException ("Use EmptyReadOnlyParameters");
1001 this.parameters = parameters;
1002 int count = parameters.Length;
1004 for (int i = 0; i < count; i++){
1005 has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
1009 public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
1012 this.has_arglist = has_arglist;
1015 public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
1017 return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
1020 public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, TypeSpec[] types)
1022 return new ParametersCompiled (parameters, types);
1026 // TODO: This does not fit here, it should go to different version of AParametersCollection
1027 // as the underlying type is not Parameter and some methods will fail to cast
1029 public static AParametersCollection CreateFullyResolved (TypeSpec[] types)
1031 var pd = new ParameterData [types.Length];
1032 for (int i = 0; i < pd.Length; ++i)
1033 pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null);
1035 return new ParametersCompiled (pd, types);
1038 public static ParametersCompiled CreateImplicitParameter (FullNamedExpression texpr, Location loc)
1040 return new ParametersCompiled (
1041 new[] { new Parameter (texpr, "value", Parameter.Modifier.NONE, null, loc) },
1046 // Returns non-zero value for equal CLS parameter signatures
1048 public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
1052 for (int i = 0; i < a.Count; ++i) {
1053 var a_type = a.Types[i];
1054 var b_type = b.Types[i];
1055 if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
1056 const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
1057 if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
1063 var ac_a = a_type as ArrayContainer;
1067 var ac_b = b_type as ArrayContainer;
1071 if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
1076 if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
1087 public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
1089 return MergeGenerated (ctx, userParams, checkConflicts,
1090 new Parameter [] { compilerParams },
1091 new TypeSpec [] { compilerTypes });
1095 // Use this method when you merge compiler generated parameters with user parameters
1097 public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
1099 Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1100 userParams.FixedParameters.CopyTo(all_params, 0);
1102 TypeSpec [] all_types;
1103 if (userParams.types != null) {
1104 all_types = new TypeSpec [all_params.Length];
1105 userParams.Types.CopyTo (all_types, 0);
1110 int last_filled = userParams.Count;
1112 foreach (Parameter p in compilerParams) {
1113 for (int i = 0; i < last_filled; ++i) {
1114 while (p.Name == all_params [i].Name) {
1115 if (checkConflicts && i < userParams.Count) {
1116 ctx.Report.Error (316, userParams[i].Location,
1117 "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1119 p.Name = '_' + p.Name;
1122 all_params [last_filled] = p;
1123 if (all_types != null)
1124 all_types [last_filled] = compilerTypes [index++];
1128 ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1129 parameters.has_params = userParams.has_params;
1133 public bool Resolve (IMemberContext ec)
1138 types = new TypeSpec [Count];
1142 for (int i = 0; i < FixedParameters.Length; ++i) {
1144 TypeSpec t = p.Resolve (ec, i);
1156 public void ResolveDefaultValues (MemberCore m)
1158 var count = parameters.Length;
1161 // Try not to enter default values resolution if there are not any
1163 if (parameters[count - 1].HasDefaultValue || (HasParams && count > 1 && parameters[count - 2].HasDefaultValue) ||
1164 ((Parameter) parameters[count - 1]).OptAttributes != null) {
1165 var rc = new ResolveContext (m);
1166 for (int i = 0; i < count; ++i) {
1167 this [i].ResolveDefaultValue (rc);
1172 // Define each type attribute (in/out/ref) and
1173 // the argument names.
1174 public void ApplyAttributes (IMemberContext mc, MethodBase builder)
1179 MethodBuilder mb = builder as MethodBuilder;
1180 ConstructorBuilder cb = builder as ConstructorBuilder;
1181 var pa = mc.Compiler.PredefinedAttributes;
1183 for (int i = 0; i < Count; i++) {
1184 this [i].ApplyAttributes (mb, cb, i + 1, pa);
1188 public void VerifyClsCompliance (IMemberContext ctx)
1190 foreach (Parameter p in FixedParameters)
1191 p.IsClsCompliant (ctx);
1194 public Parameter this [int pos] {
1195 get { return (Parameter) parameters [pos]; }
1198 public Expression CreateExpressionTree (BlockContext ec, Location loc)
1200 var initializers = new ArrayInitializer (Count, loc);
1201 foreach (Parameter p in FixedParameters) {
1203 // Each parameter expression is stored to local variable
1204 // to save some memory when referenced later.
1206 StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec));
1207 if (se.Resolve (ec)) {
1208 ec.CurrentBlock.AddScopeStatement (new TemporaryVariableReference.Declarator (p.ExpressionTreeVariableReference ()));
1209 ec.CurrentBlock.AddScopeStatement (se);
1212 initializers.Add (p.ExpressionTreeVariableReference ());
1215 return new ArrayCreation (
1216 Parameter.ResolveParameterExpressionType (ec, loc),
1220 public ParametersCompiled Clone ()
1222 ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1224 p.parameters = new IParameterData [parameters.Length];
1225 for (int i = 0; i < Count; ++i)
1226 p.parameters [i] = this [i].Clone ();