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.
17 using MetaType = IKVM.Reflection.Type;
18 using IKVM.Reflection;
19 using IKVM.Reflection.Emit;
21 using MetaType = System.Type;
22 using System.Reflection;
23 using System.Reflection.Emit;
26 namespace Mono.CSharp {
29 /// Abstract Base class for parameters of a method.
31 public abstract class ParameterBase : Attributable
33 protected ParameterBuilder builder;
35 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
38 if (a.Type == pa.MarshalAs) {
39 UnmanagedMarshal marshal = a.GetMarshal (this);
40 if (marshal != null) {
41 builder.SetMarshal (marshal);
46 if (a.HasSecurityAttribute) {
47 a.Error_InvalidSecurityParent ();
51 if (a.Type == pa.Dynamic) {
52 a.Error_MisusedDynamicAttribute ();
56 builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
59 public ParameterBuilder Builder {
65 public override bool IsClsComplianceRequired()
72 /// Class for applying custom attributes on the return type
74 public class ReturnParameter : ParameterBase
78 // TODO: merge method and mb
79 public ReturnParameter (MemberCore method, MethodBuilder mb, Location location)
83 builder = mb.DefineParameter (0, ParameterAttributes.None, "");
85 catch (ArgumentOutOfRangeException) {
86 method.Compiler.Report.RuntimeMissingSupport (location, "custom attributes on the return type");
90 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
92 if (a.Type == pa.CLSCompliant) {
93 method.Compiler.Report.Warning (3023, 1, a.Location,
94 "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
97 // This occurs after Warning -28
101 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
104 public override AttributeTargets AttributeTargets {
106 return AttributeTargets.ReturnValue;
113 public override string[] ValidAttributeTargets {
120 public class ImplicitLambdaParameter : Parameter
122 public ImplicitLambdaParameter (string name, Location loc)
123 : base (null, name, Modifier.NONE, null, loc)
127 public override TypeSpec Resolve (IMemberContext ec, int index)
129 if (parameter_type == null)
130 throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
134 return parameter_type;
137 public void SetParameterType (TypeSpec type)
139 parameter_type = type;
143 public class ParamsParameter : Parameter {
144 public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
145 base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
149 public override TypeSpec Resolve (IMemberContext ec, int index)
151 if (base.Resolve (ec, index) == null)
154 var ac = parameter_type as ArrayContainer;
155 if (ac == null || ac.Rank != 1) {
156 ec.Compiler.Report.Error (225, Location, "The params parameter must be a single dimensional array");
160 return parameter_type;
163 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
165 base.ApplyAttributes (mb, cb, index, pa);
166 pa.ParamArray.EmitAttribute (builder);
170 public class ArglistParameter : Parameter {
171 // Doesn't have proper type because it's never chosen for better conversion
172 public ArglistParameter (Location loc) :
173 base (null, String.Empty, Parameter.Modifier.NONE, null, loc)
175 parameter_type = InternalType.Arglist;
178 public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
183 public override bool CheckAccessibility (InterfaceMemberBase member)
188 public override TypeSpec Resolve (IMemberContext ec, int index)
190 return parameter_type;
194 public interface IParameterData
196 Expression DefaultValue { get; }
197 bool HasExtensionMethodModifier { get; }
198 bool HasDefaultValue { get; }
199 Parameter.Modifier ModFlags { get; }
204 // Parameter information created by parser
206 public class Parameter : ParameterBase, IParameterData, ILocalVariable // TODO: INamedBlockVariable
209 public enum Modifier : byte {
211 REF = REFMASK | ISBYREF,
212 OUT = OUTMASK | ISBYREF,
214 // This is a flag which says that it's either REF or OUT.
221 static string[] attribute_targets = new string [] { "param" };
223 FullNamedExpression texpr;
224 readonly Modifier modFlags;
226 Expression default_expr;
227 protected TypeSpec parameter_type;
228 readonly Location loc;
230 public bool HasAddressTaken;
232 TemporaryVariableReference expr_tree_variable;
233 static TypeExpr parameter_expr_tree_type;
235 HoistedVariable hoisted_variant;
237 public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
244 // Only assign, attributes will be attached during resolve
245 base.attributes = attrs;
250 public Expression DefaultValue {
255 default_expr = value;
259 public Location Location {
265 public TypeSpec Type {
267 return parameter_type;
271 public FullNamedExpression TypeExpression {
277 public override string[] ValidAttributeTargets {
279 return attribute_targets;
285 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
287 if (a.Type == pa.In && ModFlags == Modifier.OUT) {
288 a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
292 if (a.Type == pa.ParamArray) {
293 a.Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
297 if (a.Type == pa.Out && (ModFlags & Modifier.REF) == Modifier.REF &&
298 !OptAttributes.Contains (pa.In)) {
299 a.Report.Error (662, a.Location,
300 "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
304 if (a.Type == pa.CLSCompliant) {
305 a.Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
308 if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) {
309 a.Report.Error (1745, a.Location,
310 "Cannot specify `{0}' attribute on optional parameter `{1}'",
311 TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
315 if (a.Type == pa.DefaultParameterValue) {
317 var c = a.GetParameterDefaultValue (out arg_type);
319 if (parameter_type == TypeManager.object_type) {
320 a.Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
321 arg_type.GetSignatureForError ());
323 a.Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
324 parameter_type.GetSignatureForError ()); ;
330 if (arg_type == parameter_type || parameter_type == TypeManager.object_type ||
331 (c.IsNull && TypeManager.IsReferenceType (parameter_type) && !TypeManager.IsGenericParameter (parameter_type)))
332 builder.SetConstant (c.GetValue ());
334 a.Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
339 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
342 public virtual bool CheckAccessibility (InterfaceMemberBase member)
344 if (parameter_type == null)
347 return member.IsAccessibleAs (parameter_type);
350 public static void Reset ()
352 parameter_expr_tree_type = null;
356 // Resolve is used in method definitions
358 public virtual TypeSpec Resolve (IMemberContext rc, int index)
360 if (parameter_type != null)
361 return parameter_type;
363 if (attributes != null)
364 attributes.AttachTo (this, rc);
366 var expr = texpr.ResolveAsTypeTerminal (rc, false);
372 parameter_type = texpr.Type;
374 if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
375 TypeManager.IsSpecialType (parameter_type)) {
376 rc.Compiler.Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
377 GetSignatureForError ());
381 TypeManager.CheckTypeVariance (parameter_type,
382 (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
385 if (parameter_type.IsStatic) {
386 rc.Compiler.Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
387 texpr.GetSignatureForError ());
388 return parameter_type;
391 if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || parameter_type == InternalType.Dynamic)) {
392 rc.Compiler.Report.Error (1103, Location, "The extension method cannot be of type `{0}'",
393 TypeManager.CSharpName (parameter_type));
396 return parameter_type;
399 public void ResolveDefaultValue (ResolveContext rc)
402 // Default value was specified using an expression
404 if (default_expr != null) {
405 default_expr = ResolveDefaultExpression (rc);
409 if (attributes == null)
412 var pa = attributes.Search (rc.Module.PredefinedAttributes.OptionalParameter);
417 // Default value was specified using an attribute
419 attributes.Attrs.Remove (pa);
421 TypeSpec expr_type = null;
422 pa = attributes.Search (rc.Module.PredefinedAttributes.DefaultParameterValue);
424 attributes.Attrs.Remove (pa);
425 default_expr = pa.GetParameterDefaultValue (out expr_type);
427 default_expr = EmptyExpression.MissingValue;
430 if (default_expr == null) {
431 if (expr_type == null)
432 expr_type = parameter_type;
434 default_expr = new DefaultValueExpression (new TypeExpression (expr_type, Location), Location);
437 default_expr = default_expr.Resolve (rc);
440 Expression ResolveDefaultExpression (ResolveContext rc)
442 default_expr = default_expr.Resolve (rc);
443 if (default_expr == null)
446 if (!(default_expr is Constant || default_expr is DefaultValueExpression || (default_expr is New && ((New)default_expr).IsDefaultStruct))) {
447 rc.Compiler.Report.Error (1736, default_expr.Location,
448 "The expression being assigned to optional parameter `{0}' must be a constant or default value",
454 if (default_expr.Type == parameter_type)
457 var res = Convert.ImplicitConversionStandard (rc, default_expr, parameter_type, default_expr.Location);
459 if (TypeManager.IsNullableType (parameter_type) && res is Nullable.Wrap) {
460 Nullable.Wrap wrap = (Nullable.Wrap) res;
462 if (!(res is Constant)) {
463 rc.Compiler.Report.Error (1770, default_expr.Location,
464 "The expression being assigned to nullable optional parameter `{0}' must be default value",
470 if (!default_expr.IsNull && TypeManager.IsReferenceType (parameter_type) && parameter_type != TypeManager.string_type) {
471 rc.Compiler.Report.Error (1763, default_expr.Location,
472 "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
473 Name, GetSignatureForError ());
481 rc.Compiler.Report.Error (1750, Location,
482 "Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'",
483 TypeManager.CSharpName (default_expr.Type), GetSignatureForError ());
488 public bool HasDefaultValue {
489 get { return default_expr != null; }
492 public bool HasExtensionMethodModifier {
493 get { return (modFlags & Modifier.This) != 0; }
497 // Hoisted parameter variant
499 public HoistedVariable HoistedVariant {
501 return hoisted_variant;
504 hoisted_variant = value;
508 public Modifier ModFlags {
509 get { return modFlags & ~Modifier.This; }
514 set { name = value; }
517 ParameterAttributes Attributes {
518 get { return ParametersCompiled.GetParameterAttribute (modFlags) |
519 (HasDefaultValue ? ParameterAttributes.Optional : ParameterAttributes.None); }
522 public override AttributeTargets AttributeTargets {
524 return AttributeTargets.Parameter;
528 public virtual string GetSignatureForError ()
531 if (parameter_type != null)
532 type_name = TypeManager.CSharpName (parameter_type);
534 type_name = texpr.GetSignatureForError ();
536 string mod = GetModifierSignature (modFlags);
538 return String.Concat (mod, " ", type_name);
543 public static string GetModifierSignature (Modifier mod)
548 case Modifier.PARAMS:
559 public void IsClsCompliant (IMemberContext ctx)
561 if (parameter_type.IsCLSCompliant ())
564 ctx.Compiler.Report.Warning (3001, 1, Location,
565 "Argument type `{0}' is not CLS-compliant", parameter_type.GetSignatureForError ());
568 public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
571 throw new InternalErrorException ("builder already exists");
574 builder = cb.DefineParameter (index, Attributes, Name);
576 builder = mb.DefineParameter (index, Attributes, Name);
578 if (OptAttributes != null)
579 OptAttributes.Emit ();
581 if (HasDefaultValue) {
583 // Emit constant values for true constants only, the other
584 // constant-like expressions will rely on default value expression
586 Constant c = default_expr as Constant;
588 if (default_expr.Type == TypeManager.decimal_type) {
589 pa.DecimalConstant.EmitAttribute (builder, (decimal) c.GetValue (), c.Location);
591 builder.SetConstant (c.GetValue ());
593 } else if (default_expr.Type.IsStruct) {
595 // Handles special case where default expression is used with value-type
597 // void Foo (S s = default (S)) {}
599 builder.SetConstant (null);
603 if (parameter_type != null) {
604 if (parameter_type == InternalType.Dynamic) {
605 pa.Dynamic.EmitAttribute (builder);
606 } else if (parameter_type.HasDynamicElement) {
607 pa.Dynamic.EmitAttribute (builder, parameter_type, Location);
612 public Parameter Clone ()
614 Parameter p = (Parameter) MemberwiseClone ();
615 if (attributes != null)
616 p.attributes = attributes.Clone ();
621 public ExpressionStatement CreateExpressionTreeVariable (BlockContext ec)
623 if ((modFlags & Modifier.ISBYREF) != 0)
624 ec.Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
626 expr_tree_variable = TemporaryVariableReference.Create (ResolveParameterExpressionType (ec, Location).Type, ec.CurrentBlock.ParametersBlock, Location);
627 expr_tree_variable = (TemporaryVariableReference) expr_tree_variable.Resolve (ec);
629 Arguments arguments = new Arguments (2);
630 arguments.Add (new Argument (new TypeOf (
631 new TypeExpression (parameter_type, Location), Location)));
632 arguments.Add (new Argument (new StringConstant (Name, Location)));
633 return new SimpleAssign (ExpressionTreeVariableReference (),
634 Expression.CreateExpressionFactoryCall (ec, "Parameter", null, arguments, Location));
637 public void Emit (EmitContext ec)
643 ParameterReference.EmitLdArg (ec, arg_idx);
646 public void EmitAssign (EmitContext ec)
653 ec.Emit (OpCodes.Starg_S, (byte) arg_idx);
655 ec.Emit (OpCodes.Starg, arg_idx);
658 public void EmitAddressOf (EmitContext ec)
665 bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
667 ParameterReference.EmitLdArg (ec, arg_idx);
670 ec.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
672 ec.Emit (OpCodes.Ldarga, arg_idx);
676 public TemporaryVariableReference ExpressionTreeVariableReference ()
678 return expr_tree_variable;
682 // System.Linq.Expressions.ParameterExpression type
684 public static TypeExpr ResolveParameterExpressionType (IMemberContext ec, Location location)
686 if (parameter_expr_tree_type != null)
687 return parameter_expr_tree_type;
689 TypeSpec p_type = ec.Module.PredefinedTypes.ParameterExpression.Resolve (location);
690 parameter_expr_tree_type = new TypeExpression (p_type, location).
691 ResolveAsTypeTerminal (ec, false);
693 return parameter_expr_tree_type;
696 public void Warning_UselessOptionalParameter (Report Report)
698 Report.Warning (1066, 1, Location,
699 "The default value specified for optional parameter `{0}' will never be used",
705 // Imported or resolved parameter information
707 public class ParameterData : IParameterData
709 readonly string name;
710 readonly Parameter.Modifier modifiers;
711 readonly Expression default_value;
713 public ParameterData (string name, Parameter.Modifier modifiers)
716 this.modifiers = modifiers;
719 public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
720 : this (name, modifiers)
722 this.default_value = defaultValue;
725 #region IParameterData Members
727 public Expression DefaultValue {
728 get { return default_value; }
731 public bool HasExtensionMethodModifier {
732 get { return (modifiers & Parameter.Modifier.This) != 0; }
735 public bool HasDefaultValue {
736 get { return default_value != null; }
739 public Parameter.Modifier ModFlags {
740 get { return modifiers & ~Parameter.Modifier.This; }
750 public abstract class AParametersCollection
752 protected bool has_arglist;
753 protected bool has_params;
755 // Null object pattern
756 protected IParameterData [] parameters;
757 protected TypeSpec [] types;
759 public CallingConventions CallingConvention {
762 CallingConventions.VarArgs :
763 CallingConventions.Standard;
768 get { return parameters.Length; }
771 public TypeSpec ExtensionMethodType {
776 return FixedParameters [0].HasExtensionMethodModifier ?
781 public IParameterData [] FixedParameters {
787 public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
789 return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
790 ParameterAttributes.Out : ParameterAttributes.None;
793 // Very expensive operation
794 public MetaType[] GetMetaInfo ()
799 return MetaType.EmptyTypes;
801 types = new MetaType[Count - 1];
804 return MetaType.EmptyTypes;
806 types = new MetaType[Count];
809 for (int i = 0; i < types.Length; ++i) {
810 types[i] = Types[i].GetMetaInfo ();
812 if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
815 // TODO MemberCache: Should go to MetaInfo getter
816 types [i] = types [i].MakeByRefType ();
823 // Returns the parameter information based on the name
825 public int GetParameterIndexByName (string name)
827 for (int idx = 0; idx < Count; ++idx) {
828 if (parameters [idx].Name == name)
835 public string GetSignatureForError ()
837 return GetSignatureForError ("(", ")", Count);
840 public string GetSignatureForError (string start, string end, int count)
842 StringBuilder sb = new StringBuilder (start);
843 for (int i = 0; i < count; ++i) {
846 sb.Append (ParameterDesc (i));
849 return sb.ToString ();
852 public bool HasArglist {
853 get { return has_arglist; }
856 public bool HasExtensionMethodType {
861 return FixedParameters [0].HasExtensionMethodModifier;
865 public bool HasParams {
866 get { return has_params; }
869 public bool IsEmpty {
870 get { return parameters.Length == 0; }
873 public AParametersCollection Inflate (TypeParameterInflator inflator)
875 TypeSpec[] inflated_types = null;
876 bool default_value = false;
878 for (int i = 0; i < Count; ++i) {
879 var inflated_param = inflator.Inflate (types[i]);
880 if (inflated_types == null) {
881 if (inflated_param == types[i])
884 default_value |= FixedParameters[i] is DefaultValueExpression;
885 inflated_types = new TypeSpec[types.Length];
886 Array.Copy (types, inflated_types, types.Length);
889 inflated_types[i] = inflated_param;
892 if (inflated_types == null)
895 var clone = (AParametersCollection) MemberwiseClone ();
896 clone.types = inflated_types;
898 for (int i = 0; i < Count; ++i) {
899 var dve = clone.FixedParameters[i] as DefaultValueExpression;
901 throw new NotImplementedException ("net");
902 // clone.FixedParameters [i].DefaultValue = new DefaultValueExpression ();
910 public string ParameterDesc (int pos)
912 if (types == null || types [pos] == null)
913 return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
915 string type = TypeManager.CSharpName (types [pos]);
916 if (FixedParameters [pos].HasExtensionMethodModifier)
917 return "this " + type;
919 Parameter.Modifier mod = FixedParameters [pos].ModFlags;
923 return Parameter.GetModifierSignature (mod) + " " + type;
926 public TypeSpec[] Types {
927 get { return types; }
928 set { types = value; }
933 // A collection of imported or resolved parameters
935 public class ParametersImported : AParametersCollection
937 public ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
939 this.parameters = parameters;
941 this.has_arglist = hasArglist;
942 this.has_params = hasParams;
945 public ParametersImported (IParameterData[] param, TypeSpec[] types, bool hasParams)
947 this.parameters = param;
949 this.has_params = hasParams;
954 /// Represents the methods parameters
956 public class ParametersCompiled : AParametersCollection
958 public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
960 // Used by C# 2.0 delegates
961 public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
963 private ParametersCompiled ()
965 parameters = new Parameter [0];
966 types = TypeSpec.EmptyTypes;
969 private ParametersCompiled (IParameterData[] parameters, TypeSpec[] types)
971 this.parameters = parameters;
975 public ParametersCompiled (params Parameter[] parameters)
977 if (parameters == null || parameters.Length == 0)
978 throw new ArgumentException ("Use EmptyReadOnlyParameters");
980 this.parameters = parameters;
981 int count = parameters.Length;
983 for (int i = 0; i < count; i++){
984 has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
988 public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
991 this.has_arglist = has_arglist;
994 public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
996 return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
999 public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, TypeSpec[] types)
1001 return new ParametersCompiled (parameters, types);
1005 // TODO: This does not fit here, it should go to different version of AParametersCollection
1006 // as the underlying type is not Parameter and some methods will fail to cast
1008 public static AParametersCollection CreateFullyResolved (TypeSpec[] types)
1010 var pd = new ParameterData [types.Length];
1011 for (int i = 0; i < pd.Length; ++i)
1012 pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null);
1014 return new ParametersCompiled (pd, types);
1017 public static ParametersCompiled CreateImplicitParameter (FullNamedExpression texpr, Location loc)
1019 return new ParametersCompiled (
1020 new[] { new Parameter (texpr, "value", Parameter.Modifier.NONE, null, loc) },
1025 // Returns non-zero value for equal CLS parameter signatures
1027 public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
1031 for (int i = 0; i < a.Count; ++i) {
1032 var a_type = a.Types[i];
1033 var b_type = b.Types[i];
1034 if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
1035 const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
1036 if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
1042 var ac_a = a_type as ArrayContainer;
1046 var ac_b = b_type as ArrayContainer;
1050 if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
1055 if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
1066 public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
1068 return MergeGenerated (ctx, userParams, checkConflicts,
1069 new Parameter [] { compilerParams },
1070 new TypeSpec [] { compilerTypes });
1074 // Use this method when you merge compiler generated parameters with user parameters
1076 public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
1078 Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1079 userParams.FixedParameters.CopyTo(all_params, 0);
1081 TypeSpec [] all_types;
1082 if (userParams.types != null) {
1083 all_types = new TypeSpec [all_params.Length];
1084 userParams.Types.CopyTo (all_types, 0);
1089 int last_filled = userParams.Count;
1091 foreach (Parameter p in compilerParams) {
1092 for (int i = 0; i < last_filled; ++i) {
1093 while (p.Name == all_params [i].Name) {
1094 if (checkConflicts && i < userParams.Count) {
1095 ctx.Report.Error (316, userParams[i].Location,
1096 "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1098 p.Name = '_' + p.Name;
1101 all_params [last_filled] = p;
1102 if (all_types != null)
1103 all_types [last_filled] = compilerTypes [index++];
1107 ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1108 parameters.has_params = userParams.has_params;
1112 public bool Resolve (IMemberContext ec)
1117 types = new TypeSpec [Count];
1121 for (int i = 0; i < FixedParameters.Length; ++i) {
1123 TypeSpec t = p.Resolve (ec, i);
1135 public void ResolveDefaultValues (MemberCore m)
1137 ResolveContext rc = null;
1138 for (int i = 0; i < parameters.Length; ++i) {
1139 Parameter p = (Parameter) parameters [i];
1142 // Try not to enter default values resolution if there are is not any default value possible
1144 if (p.HasDefaultValue || p.OptAttributes != null) {
1146 rc = new ResolveContext (m);
1148 p.ResolveDefaultValue (rc);
1153 // Define each type attribute (in/out/ref) and
1154 // the argument names.
1155 public void ApplyAttributes (IMemberContext mc, MethodBase builder)
1160 MethodBuilder mb = builder as MethodBuilder;
1161 ConstructorBuilder cb = builder as ConstructorBuilder;
1162 var pa = mc.Module.PredefinedAttributes;
1164 for (int i = 0; i < Count; i++) {
1165 this [i].ApplyAttributes (mb, cb, i + 1, pa);
1169 public void VerifyClsCompliance (IMemberContext ctx)
1171 foreach (Parameter p in FixedParameters)
1172 p.IsClsCompliant (ctx);
1175 public Parameter this [int pos] {
1176 get { return (Parameter) parameters [pos]; }
1179 public Expression CreateExpressionTree (BlockContext ec, Location loc)
1181 var initializers = new ArrayInitializer (Count, loc);
1182 foreach (Parameter p in FixedParameters) {
1184 // Each parameter expression is stored to local variable
1185 // to save some memory when referenced later.
1187 StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec));
1188 if (se.Resolve (ec)) {
1189 ec.CurrentBlock.AddScopeStatement (new TemporaryVariableReference.Declarator (p.ExpressionTreeVariableReference ()));
1190 ec.CurrentBlock.AddScopeStatement (se);
1193 initializers.Add (p.ExpressionTreeVariableReference ());
1196 return new ArrayCreation (
1197 Parameter.ResolveParameterExpressionType (ec, loc),
1201 public ParametersCompiled Clone ()
1203 ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1205 p.parameters = new IParameterData [parameters.Length];
1206 for (int i = 0; i < Count; ++i)
1207 p.parameters [i] = this [i].Clone ();