X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fparameter.cs;h=e5fcae8576581a39864147e9bb03609758788fe2;hb=209eae257ac9c28f1c8361fd78b2933744dd19af;hp=95de5e22374a4decd9c433240c2b305cf2c4692a;hpb=7dbb973a996579e750103bf1ff888d542278fe42;p=mono.git diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs index 95de5e22374..e5fcae85765 100644 --- a/mcs/mcs/parameter.cs +++ b/mcs/mcs/parameter.cs @@ -32,6 +32,7 @@ namespace Mono.CSharp { public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { +#if !NET_2_0 if (a.Type == TypeManager.marshal_as_attr_type) { UnmanagedMarshal marshal = a.GetMarshal (this); if (marshal != null) { @@ -39,7 +40,7 @@ namespace Mono.CSharp { } return; } - +#endif if (a.HasSecurityAttribute) { a.Error_InvalidSecurityParent (); return; @@ -142,17 +143,21 @@ namespace Mono.CSharp { public class ImplicitLambdaParameter : Parameter { public ImplicitLambdaParameter (string name, Location loc) - : base ((Type)null, name, Modifier.NONE, null, loc) + : base (null, name, Modifier.NONE, null, loc) { } - public override bool Resolve (IResolveContext ec) + public override Type Resolve (IResolveContext ec) { if (parameter_type == null) throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set", Name); - return true; + return parameter_type; + } + + public Type Type { + set { parameter_type = value; } } } @@ -162,16 +167,17 @@ namespace Mono.CSharp { { } - public override bool Resolve (IResolveContext ec) + public override Type Resolve (IResolveContext ec) { - if (!base.Resolve (ec)) - return false; + if (base.Resolve (ec) == null) + return null; if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) { Report.Error (225, Location, "The params parameter must be a single dimensional array"); - return false; + return null; } - return true; + + return parameter_type; } public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index) @@ -197,19 +203,24 @@ namespace Mono.CSharp { public class ArglistParameter : Parameter { // Doesn't have proper type because it's never chosen for better conversion - public ArglistParameter () : - base (typeof (ArglistParameter), String.Empty, Parameter.Modifier.ARGLIST, null, Location.Null) + public ArglistParameter (Location loc) : + base (null, String.Empty, Parameter.Modifier.ARGLIST, null, loc) { } + public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index) + { + // Nothing to do + } + public override bool CheckAccessibility (InterfaceMemberBase member) { return true; } - public override bool Resolve (IResolveContext ec) + public override Type Resolve (IResolveContext ec) { - return true; + return typeof (ArglistParameter); } public override string GetSignatureForError () @@ -218,10 +229,17 @@ namespace Mono.CSharp { } } - /// - /// Represents a single method parameter - /// - public class Parameter : ParameterBase, ILocalVariable { + public interface IParameterData + { + bool HasExtensionMethodModifier { get; } + Parameter.Modifier ModFlags { get; } + string Name { get; } + } + + // + // Parameter information created by parser + // + public class Parameter : ParameterBase, IParameterData, ILocalVariable { [Flags] public enum Modifier : byte { NONE = 0, @@ -238,12 +256,13 @@ namespace Mono.CSharp { static string[] attribute_targets = new string [] { "param" }; - FullNamedExpression TypeName; + protected FullNamedExpression TypeName; readonly Modifier modFlags; - public string Name; + string name; protected Type parameter_type; public readonly Location Location; int idx; + public bool HasAddressTaken; IResolveContext resolve_context; LocalVariableReference expr_tree_variable; @@ -252,21 +271,15 @@ namespace Mono.CSharp { public HoistedVariable HoistedVariableReference; public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc) - : this (type.Type, name, mod, attrs, loc) + : base (attrs) { if (type == TypeManager.system_void_expr) Report.Error (1536, loc, "Invalid parameter type `void'"); - - TypeName = type; - } - public Parameter (Type type, string name, Modifier mod, Attributes attrs, Location loc) - : base (attrs) - { - Name = name; + this.name = name; modFlags = mod; - parameter_type = type; Location = loc; + TypeName = type; } public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) @@ -326,7 +339,7 @@ namespace Mono.CSharp { public virtual bool CheckAccessibility (InterfaceMemberBase member) { - if (TypeManager.IsGenericParameter (parameter_type)) + if (parameter_type == null || TypeManager.IsGenericParameter (parameter_type)) return true; return member.IsAccessibleAs (parameter_type); @@ -341,49 +354,46 @@ namespace Mono.CSharp { // // Resolve is used in method definitions // - public virtual bool Resolve (IResolveContext ec) + public virtual Type Resolve (IResolveContext ec) { // HACK: to resolve attributes correctly this.resolve_context = ec; if (parameter_type != null) - return true; + return parameter_type; TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false); if (texpr == null) - return false; + return null; parameter_type = texpr.Type; + if ((modFlags & Parameter.Modifier.ISBYREF) != 0 && + TypeManager.IsSpecialType (parameter_type)) { + Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'", + GetSignatureForError ()); + return null; + } + #if GMCS_SOURCE TypeParameterExpr tparam = texpr as TypeParameterExpr; if (tparam != null) { - return true; + return parameter_type; } #endif if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) { Report.Error (721, Location, "`{0}': static types cannot be used as parameters", texpr.GetSignatureForError ()); - return false; - } - - if ((modFlags & Parameter.Modifier.ISBYREF) != 0){ - if (parameter_type == TypeManager.typed_reference_type || - parameter_type == TypeManager.arg_iterator_type){ - Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'", - GetSignatureForError ()); - return false; - } + return parameter_type; } if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) { Report.Error (1103, Location, "The type of extension method cannot be `{0}'", TypeManager.CSharpName (parameter_type)); - return false; } - - return true; + + return parameter_type; } public void ResolveVariable (int idx) @@ -391,14 +401,6 @@ namespace Mono.CSharp { this.idx = idx; } - public Type ExternalType () - { - if ((modFlags & Parameter.Modifier.ISBYREF) != 0) - return TypeManager.GetReferenceType (parameter_type); - - return parameter_type; - } - public bool HasExtensionMethodModifier { get { return (modFlags & Modifier.This) != 0; } } @@ -407,40 +409,15 @@ namespace Mono.CSharp { get { return modFlags & ~Modifier.This; } } - public Type ParameterType { - get { - return parameter_type; - } - set { - parameter_type = value; - } + public string Name { + get { return name; } + set { name = value; } } ParameterAttributes Attributes { - get { - return (modFlags & Modifier.OUT) == Modifier.OUT ? - ParameterAttributes.Out : ParameterAttributes.None; - } + get { return Parameters.GetParameterAttribute (modFlags); } } - // TODO: should be removed !!!!!!! - public static ParameterAttributes GetParameterAttributes (Modifier mod) - { - int flags = ((int) mod) & ~((int) Parameter.Modifier.ISBYREF); - switch ((Modifier) flags) { - case Modifier.NONE: - return ParameterAttributes.None; - case Modifier.REF: - return ParameterAttributes.None; - case Modifier.OUT: - return ParameterAttributes.Out; - case Modifier.PARAMS: - return 0; - } - - return ParameterAttributes.None; - } - public override AttributeTargets AttributeTargets { get { return AttributeTargets.Parameter; @@ -457,7 +434,7 @@ namespace Mono.CSharp { string mod = GetModifierSignature (modFlags); if (mod.Length > 0) - return String.Concat (mod, ' ', type_name); + return String.Concat (mod, " ", type_name); return type_name; } @@ -465,27 +442,25 @@ namespace Mono.CSharp { public static string GetModifierSignature (Modifier mod) { switch (mod) { - case Modifier.OUT: - return "out"; - case Modifier.PARAMS: - return "params"; - case Modifier.REF: - return "ref"; - case Modifier.ARGLIST: - return "__arglist"; - case Modifier.This: - return "this"; - default: - return ""; + case Modifier.OUT: + return "out"; + case Modifier.PARAMS: + return "params"; + case Modifier.REF: + return "ref"; + case Modifier.This: + return "this"; + default: + return ""; } } public void IsClsCompliant () { - if (AttributeTester.IsClsCompliant (ExternalType ())) + if (AttributeTester.IsClsCompliant (parameter_type)) return; - Report.Error (3001, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ()); + Report.Warning (3001, 1, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ()); } public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index) @@ -507,7 +482,13 @@ namespace Mono.CSharp { public Parameter Clone () { - return new Parameter (parameter_type, Name, modFlags, attributes, Location); + Parameter p = (Parameter) MemberwiseClone (); + if (attributes != null) { + p.attributes = attributes.Clone (); + p.attributes.AttachTo (p); + } + + return p; } public ExpressionStatement CreateExpressionTreeVariable (EmitContext ec) @@ -598,104 +579,53 @@ namespace Mono.CSharp { } } - /// - /// Represents the methods parameters - /// - public class Parameters : ParameterData { - // Null object pattern - public readonly Parameter [] FixedParameters; - public readonly bool HasArglist; - Type [] types; - readonly int count; - - public static readonly Parameters EmptyReadOnlyParameters = new Parameters (); - static readonly Parameter ArgList = new ArglistParameter (); - -#if GMCS_SOURCE -// public readonly TypeParameter[] TypeParameters; -#endif + // + // Imported or resolved parameter information + // + public class ParameterData : IParameterData + { + readonly string name; + readonly Parameter.Modifier modifiers; - private Parameters () + public ParameterData (string name, Parameter.Modifier modifiers) { - FixedParameters = new Parameter[0]; - types = new Type [0]; + this.name = name; + this.modifiers = modifiers; } - private Parameters (Parameter[] parameters, Type[] types) - { - FixedParameters = parameters; - this.types = types; - count = types.Length; - } - - public Parameters (params Parameter[] parameters) - { - if (parameters == null) - throw new ArgumentException ("Use EmptyReadOnlyPatameters"); + #region IParameterData Members - FixedParameters = parameters; - count = parameters.Length; + public bool HasExtensionMethodModifier { + get { return (modifiers & Parameter.Modifier.This) != 0; } } - public Parameters (Parameter[] parameters, bool has_arglist): - this (parameters) - { - HasArglist = has_arglist; - } - - public static Parameters CreateFullyResolved (Parameter p) - { - return new Parameters (new Parameter [] { p }, new Type [] { p.ParameterType }); + public Parameter.Modifier ModFlags { + get { return modifiers & ~Parameter.Modifier.This; } } - - public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types) - { - return new Parameters (parameters, types); + + public string Name { + get { return name; } } - /// - /// Use this method when you merge compiler generated argument with user arguments - /// - public static Parameters MergeGenerated (Parameters userParams, params Parameter[] compilerParams) - { - Parameter[] all_params = new Parameter [userParams.count + compilerParams.Length]; - Type[] all_types = new Type[all_params.Length]; - userParams.FixedParameters.CopyTo(all_params, 0); - userParams.Types.CopyTo (all_types, 0); + #endregion + } - int last_filled = userParams.Count; - foreach (Parameter p in compilerParams) { - for (int i = 0; i < last_filled; ++i) { - while (p.Name == all_params [i].Name) { - p.Name = '_' + p.Name; - } - } - all_params [last_filled] = p; - all_types [last_filled] = p.ParameterType; - ++last_filled; - } - - return new Parameters (all_params, all_types); - } + public abstract class AParametersCollection + { + protected bool has_arglist; + protected bool has_params; - public bool Empty { - get { - return count == 0; - } - } + // Null object pattern + protected IParameterData [] parameters; + protected Type [] types; public int Count { - get { - return HasArglist ? count + 1 : count; - } + get { return parameters.Length; } } - // - // The property can be used after parameter types were resolved. - // public Type ExtensionMethodType { get { - if (count == 0) + if (Count == 0) return null; return FixedParameters [0].HasExtensionMethodModifier ? @@ -703,129 +633,107 @@ namespace Mono.CSharp { } } - public bool HasExtensionMethodType { + public IParameterData [] FixedParameters { get { - if (count == 0) - return false; - - return FixedParameters [0].HasExtensionMethodModifier; + return parameters; } } - - bool VerifyArgs () + public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags) { - if (count < 2) - return true; + return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ? + ParameterAttributes.Out : ParameterAttributes.None; + } - for (int i = 0; i < count; i++){ - string base_name = FixedParameters [i].Name; - for (int j = i + 1; j < count; j++){ - if (base_name != FixedParameters [j].Name) - continue; + public Type [] GetEmitTypes () + { + Type [] types = null; + if (has_arglist) { + if (Count == 1) + return Type.EmptyTypes; - Report.Error (100, FixedParameters [i].Location, - "The parameter name `{0}' is a duplicate", base_name); - return false; - } + types = new Type [Count - 1]; + Array.Copy (Types, types, types.Length); } - return true; - } - - - /// - /// Returns the paramenter information based on the name - /// - public Parameter GetParameterByName (string name, out int idx) - { - idx = 0; - if (count == 0) - return null; + for (int i = 0; i < Count; ++i) { + if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0) + continue; - int i = 0; + if (types == null) + types = (Type []) Types.Clone (); - foreach (Parameter par in FixedParameters){ - if (par.Name == name){ - idx = i; - return par; - } - i++; + types [i] = TypeManager.GetReferenceType (types [i]); } - return null; + + if (types == null) + types = Types; + + return types; } - public Parameter GetParameterByName (string name) + public string GetSignatureForError () { - int idx; + StringBuilder sb = new StringBuilder ("("); + for (int i = 0; i < Count; ++i) { + if (i != 0) + sb.Append (", "); + sb.Append (ParameterDesc (i)); + } + sb.Append (')'); + return sb.ToString (); + } - return GetParameterByName (name, out idx); + public bool HasArglist { + get { return has_arglist; } } - - public bool Resolve (IResolveContext ec) - { - if (types != null) - return true; - types = new Type [count]; - - if (!VerifyArgs ()) - return false; + public bool HasExtensionMethodType { + get { + if (Count == 0) + return false; - bool ok = true; - Parameter p; - for (int i = 0; i < FixedParameters.Length; ++i) { - p = FixedParameters [i]; - if (!p.Resolve (ec)) { - ok = false; - continue; - } - types [i] = p.ExternalType (); + return FixedParameters [0].HasExtensionMethodModifier; } - - return ok; } - public void ResolveVariable () - { - for (int i = 0; i < FixedParameters.Length; ++i) { - Parameter p = FixedParameters [i]; - p.ResolveVariable (i); - } + public bool HasParams { + get { return has_params; } } - public CallingConventions CallingConvention - { - get { - if (HasArglist) - return CallingConventions.VarArgs; - else - return CallingConventions.Standard; - } + public bool IsEmpty { + get { return parameters.Length == 0; } } - // Define each type attribute (in/out/ref) and - // the argument names. - public void ApplyAttributes (MethodBase builder) + public string ParameterDesc (int pos) { - if (count == 0) - return; + if (types == null || types [pos] == null) + return ((Parameter)FixedParameters [pos]).GetSignatureForError (); - MethodBuilder mb = builder as MethodBuilder; - ConstructorBuilder cb = builder as ConstructorBuilder; + string type = TypeManager.CSharpName (types [pos]); + if (FixedParameters [pos].HasExtensionMethodModifier) + return "this " + type; - for (int i = 0; i < FixedParameters.Length; i++) { - FixedParameters [i].ApplyAttributes (mb, cb, i + 1); - } + Parameter.Modifier mod = FixedParameters [pos].ModFlags & ~Parameter.Modifier.ARGLIST; + if (mod == 0) + return type; + + return Parameter.GetModifierSignature (mod) + " " + type; + } + + public Type[] Types { + get { return types; } + set { types = value; } } #if MS_COMPATIBLE - public ParameterData InflateTypes (Type[] genArguments, Type[] argTypes) + public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes) { - Parameters p = Clone (); - for (int i = 0; i < count; ++i) { + AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone (); + + for (int i = 0; i < Count; ++i) { if (types[i].IsGenericType) { - Type[] gen_arguments_open = new Type [types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length]; + Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length]; Type[] gen_arguments = types[i].GetGenericArguments (); for (int ii = 0; ii < gen_arguments_open.Length; ++ii) { if (gen_arguments[ii].IsGenericParameter) { @@ -835,14 +743,13 @@ namespace Mono.CSharp { gen_arguments_open[ii] = gen_arguments[ii]; } - p.FixedParameters [i].ParameterType = p.types[i] = - types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open); + p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open); continue; } if (types[i].IsGenericParameter) { Type gen_argument = argTypes[types[i].GenericParameterPosition]; - p.FixedParameters[i].ParameterType = p.types[i] = gen_argument; + p.types[i] = gen_argument; continue; } } @@ -850,98 +757,318 @@ namespace Mono.CSharp { return p; } #endif + } - public void VerifyClsCompliance () + // + // A collection of imported or resolved parameters + // + public class ParametersCollection : AParametersCollection + { + ParametersCollection (AParametersCollection param, Type[] types) { - foreach (Parameter p in FixedParameters) - p.IsClsCompliant (); + this.parameters = param.FixedParameters; + this.types = types; + has_arglist = param.HasArglist; + has_params = param.HasParams; } - public string GetSignatureForError () + ParametersCollection (IParameterData [] parameters, Type [] types, MethodBase method, bool hasParams) { - StringBuilder sb = new StringBuilder ("("); - if (count > 0) { - for (int i = 0; i < FixedParameters.Length; ++i) { - sb.Append (FixedParameters[i].GetSignatureForError ()); - if (i < FixedParameters.Length - 1) - sb.Append (", "); - } + this.parameters = parameters; + this.types = types; + has_arglist = (method.CallingConvention & CallingConventions.VarArgs) != 0; + if (has_arglist) { + this.parameters = new IParameterData [parameters.Length + 1]; + parameters.CopyTo (this.parameters, 0); + this.parameters [parameters.Length] = new ArglistParameter (Location.Null); + this.types = new Type [types.Length + 1]; + types.CopyTo (this.types, 0); + this.types [types.Length] = TypeManager.arg_iterator_type; } + has_params = hasParams; + } - if (HasArglist) { - if (sb.Length > 1) - sb.Append (", "); - sb.Append ("__arglist"); + public ParametersCollection (IParameterData [] param, Type[] types) + { + this.parameters = param; + this.types = types; + } + + public static AParametersCollection Create (MethodBase method) + { + return Create (method.GetParameters (), method); + } + + // + // Generic method parameters importer, param is shared between all instances + // + public static AParametersCollection Create (AParametersCollection param, MethodBase method) + { + if (param.IsEmpty) + return param; + + ParameterInfo [] pi = method.GetParameters (); + Type [] types = new Type [pi.Length]; + for (int i = 0; i < types.Length; i++) { + Type t = pi [i].ParameterType; + if (t.IsByRef) + t = TypeManager.GetElementType (t); + + types [i] = TypeManager.TypeToCoreType (t); } - sb.Append (')'); - return sb.ToString (); + return new ParametersCollection (param, types); } - public Type[] Types { - get { - return types; + // + // Imports SRE parameters + // + public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method) + { + if (pi.Length == 0) { + if (method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0) + return new ParametersCollection (new IParameterData [0], Type.EmptyTypes, method, false); + + return Parameters.EmptyReadOnlyParameters; } - // - // Dangerous, used by implicit lambda parameters - // only to workaround bad design - // - set { - types = value; + + Type [] types = new Type [pi.Length]; + IParameterData [] par = new IParameterData [pi.Length]; + bool is_params = false; + for (int i = 0; i < types.Length; i++) { + types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType); + + ParameterInfo p = pi [i]; + Parameter.Modifier mod = 0; + if (types [i].IsByRef) { + if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out) + mod = Parameter.Modifier.OUT; + else + mod = Parameter.Modifier.REF; + + // + // Strip reference wrapping + // + types [i] = TypeManager.GetElementType (types [i]); + } else if (i == 0 && TypeManager.extension_attribute_type != null && method != null && method.IsStatic && + (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute && + method.IsDefined (TypeManager.extension_attribute_type, false)) { + mod = Parameter.Modifier.This; + } else if (i >= pi.Length - 2 && types [i].IsArray) { + if (p.IsDefined (TypeManager.param_array_type, false)) { + mod = Parameter.Modifier.PARAMS; + is_params = true; + } + } + + par [i] = new ParameterData (p.Name, mod); } + + return method != null ? + new ParametersCollection (par, types, method, is_params) : + new ParametersCollection (par, types); } + } - public Parameter this [int pos] + /// + /// Represents the methods parameters + /// + public class Parameters : AParametersCollection { + public static readonly Parameters EmptyReadOnlyParameters = new Parameters (); + + // Used by C# 2.0 delegates + public static readonly Parameters Undefined = new Parameters (); + + private Parameters () { - get { - if (pos >= count && (HasArglist || HasParams)) { - if (HasArglist && (pos == 0 || pos >= count)) - return ArgList; - pos = count - 1; + parameters = new Parameter [0]; + types = Type.EmptyTypes; + } + + private Parameters (Parameter [] parameters, Type [] types) + { + this.parameters = parameters; + this.types = types; + } + + public Parameters (params Parameter[] parameters) + { + if (parameters == null) + throw new ArgumentException ("Use EmptyReadOnlyParameters"); + + this.parameters = parameters; + int count = parameters.Length; + + if (count == 0) + return; + + if (count == 1) { + has_params = (parameters [0].ModFlags & Parameter.Modifier.PARAMS) != 0; + return; + } + + for (int i = 0; i < count; i++){ + string base_name = parameters [i].Name; + has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0; + + for (int j = i + 1; j < count; j++){ + if (base_name != parameters [j].Name) + continue; + + ErrorDuplicateName (parameters [i]); + i = j; } + } + } - return FixedParameters [pos]; + public Parameters (Parameter [] parameters, bool has_arglist) : + this (parameters) + { + this.has_arglist = has_arglist; + } + + public static Parameters CreateFullyResolved (Parameter p, Type type) + { + return new Parameters (new Parameter [] { p }, new Type [] { type }); + } + + public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types) + { + return new Parameters (parameters, types); + } + + public static Parameters MergeGenerated (Parameters userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes) + { + return MergeGenerated (userParams, checkConflicts, + new Parameter [] { compilerParams }, + new Type [] { compilerTypes }); + } + + // + // Use this method when you merge compiler generated parameters with user parameters + // + public static Parameters MergeGenerated (Parameters userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes) + { + Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length]; + userParams.FixedParameters.CopyTo(all_params, 0); + + Type [] all_types; + if (userParams.types != null) { + all_types = new Type [all_params.Length]; + userParams.Types.CopyTo (all_types, 0); + } else { + all_types = null; } + + int last_filled = userParams.Count; + int index = 0; + foreach (Parameter p in compilerParams) { + for (int i = 0; i < last_filled; ++i) { + while (p.Name == all_params [i].Name) { + if (checkConflicts && i < userParams.Count) { + Report.Error (316, userParams [i].Location, + "The parameter name `{0}' conflicts with a compiler generated name", p.Name); + } + p.Name = '_' + p.Name; + } + } + all_params [last_filled] = p; + if (all_types != null) + all_types [last_filled] = compilerTypes [index++]; + ++last_filled; + } + + Parameters parameters = new Parameters (all_params, all_types); + parameters.has_params = userParams.has_params; + return parameters; } - #region ParameterData Members + protected virtual void ErrorDuplicateName (Parameter p) + { + Report.Error (100, p.Location, "The parameter name `{0}' is a duplicate", p.Name); + } - public Type ParameterType (int pos) + /// + /// Returns the parameter information based on the name + /// + public int GetParameterIndexByName (string name) { - return this [pos].ExternalType (); + for (int idx = 0; idx < Count; ++idx) { + if (parameters [idx].Name == name) + return idx; + } + + return -1; } - public bool HasParams { - get { - if (count == 0) - return false; + public bool Resolve (IResolveContext ec) + { + if (types != null) + return true; - for (int i = count; i != 0; --i) { - if ((FixedParameters [i - 1].ModFlags & Parameter.Modifier.PARAMS) != 0) - return true; + types = new Type [Count]; + + bool ok = true; + Parameter p; + for (int i = 0; i < FixedParameters.Length; ++i) { + p = this [i]; + Type t = p.Resolve (ec); + if (t == null) { + ok = false; + continue; } - return false; + + types [i] = t; } + + return ok; } - public string ParameterName (int pos) + public void ResolveVariable () { - return this [pos].Name; + for (int i = 0; i < FixedParameters.Length; ++i) { + this [i].ResolveVariable (i); + } } - public string ParameterDesc (int pos) + public CallingConventions CallingConvention { - return this [pos].GetSignatureForError (); + get { + if (HasArglist) + return CallingConventions.VarArgs; + else + return CallingConventions.Standard; + } } - public Parameter.Modifier ParameterModifier (int pos) + // Define each type attribute (in/out/ref) and + // the argument names. + public void ApplyAttributes (MethodBase builder) + { + if (Count == 0) + return; + + MethodBuilder mb = builder as MethodBuilder; + ConstructorBuilder cb = builder as ConstructorBuilder; + + for (int i = 0; i < Count; i++) { + this [i].ApplyAttributes (mb, cb, i + 1); + } + } + + public void VerifyClsCompliance () { - return this [pos].ModFlags; + foreach (Parameter p in FixedParameters) + p.IsClsCompliant (); + } + + public Parameter this [int pos] { + get { return (Parameter) parameters [pos]; } } public Expression CreateExpressionTree (EmitContext ec, Location loc) { - ArrayList initializers = new ArrayList (count); + ArrayList initializers = new ArrayList (Count); foreach (Parameter p in FixedParameters) { // // Each parameter expression is stored to local variable @@ -961,16 +1088,13 @@ namespace Mono.CSharp { public Parameters Clone () { - Parameter [] parameters_copy = new Parameter [FixedParameters.Length]; - int i = 0; - foreach (Parameter p in FixedParameters) - parameters_copy [i++] = p.Clone (); - Parameters ps = new Parameters (parameters_copy, HasArglist); - if (types != null) - ps.types = (Type[])types.Clone (); - return ps; + Parameters p = (Parameters) MemberwiseClone (); + + p.parameters = new IParameterData [parameters.Length]; + for (int i = 0; i < Count; ++i) + p.parameters [i] = this [i].Clone (); + + return p; } - - #endregion } }