2009-02-09 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / parameter.cs
index 6b9eae38da3c5f07c52e9068efbe8895d56745e2..392e98d42365ae2b94cdf8e2c91a973ba6d5a8b7 100644 (file)
@@ -326,7 +326,7 @@ namespace Mono.CSharp {
                                }
 
                                if (parameter_type == TypeManager.object_type ||
-                                   (val == null && !TypeManager.IsValueType (parameter_type)) ||
+                                   (val == null && !TypeManager.IsGenericParameter (parameter_type) && TypeManager.IsReferenceType (parameter_type)) ||
                                    (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
                                        builder.SetConstant (val);
                                else
@@ -376,8 +376,18 @@ namespace Mono.CSharp {
                        }
 
 #if GMCS_SOURCE
-                       TypeParameterExpr tparam = texpr as TypeParameterExpr;
-                       if (tparam != null) {
+                       if (parameter_type.IsGenericParameter) {
+                               AbstractPropertyEventMethod accessor = ec as AbstractPropertyEventMethod;
+                               if (accessor == null || !accessor.IsDummy) {
+                                       if ((parameter_type.GenericParameterAttributes & GenericParameterAttributes.Covariant) != 0) {
+                                               Report.Error (-38, Location, "Covariant type parameters cannot be used as method parameters");
+                                               return null;
+                                       } else if ((ModFlags & Modifier.ISBYREF) != 0 &&
+                                                  (parameter_type.GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0) {
+                                               Report.Error (-37, Location, "Contravariant type parameters cannot be used in output positions");
+                                               return null;
+                                       }
+                               }
                                return parameter_type;
                        }
 #endif
@@ -415,7 +425,7 @@ namespace Mono.CSharp {
                }
 
                ParameterAttributes Attributes {
-                       get { return Parameters.GetParameterAttribute (modFlags); }
+                       get { return ParametersCompiled.GetParameterAttribute (modFlags); }
                }
 
                public override AttributeTargets AttributeTargets {
@@ -541,10 +551,7 @@ namespace Mono.CSharp {
 
                        bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
                        if (is_ref) {
-                               if (arg_idx <= 255)
-                                       ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
-                               else
-                                       ec.ig.Emit (OpCodes.Ldarg, arg_idx);
+                               ParameterReference.EmitLdArg (ec.ig, arg_idx);
                        } else {
                                if (arg_idx <= 255)
                                        ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
@@ -725,14 +732,46 @@ namespace Mono.CSharp {
                        get { return types; }
                        set { types = value; }
                }
+
+#if MS_COMPATIBLE
+               public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
+               {
+                       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 = types[i].GetGenericArguments ();
+                                       for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
+                                               if (gen_arguments[ii].IsGenericParameter) {
+                                                       Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
+                                                       gen_arguments_open[ii] = t;
+                                               } else
+                                                       gen_arguments_open[ii] = gen_arguments[ii];
+                                       }
+
+                                       p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
+                                       continue;
+                               }
+
+                               if (types[i].IsGenericParameter) {
+                                       Type gen_argument = argTypes[types[i].GenericParameterPosition];
+                                       p.types[i] = gen_argument;
+                                       continue;
+                               }
+                       }
+
+                       return p;
+               }
+#endif
        }
 
        //
        // A collection of imported or resolved parameters
        //
-       public class ParametersCollection : AParametersCollection
+       public class ParametersImported : AParametersCollection
        {
-               ParametersCollection (AParametersCollection param, Type[] types)
+               ParametersImported (AParametersCollection param, Type[] types)
                {
                        this.parameters = param.FixedParameters;
                        this.types = types;
@@ -740,7 +779,7 @@ namespace Mono.CSharp {
                        has_params = param.HasParams;
                }
 
-               ParametersCollection (IParameterData [] parameters, Type [] types, MethodBase method, bool hasParams)
+               ParametersImported (IParameterData [] parameters, Type [] types, MethodBase method, bool hasParams)
                {
                        this.parameters = parameters;
                        this.types = types;
@@ -756,7 +795,7 @@ namespace Mono.CSharp {
                        has_params = hasParams;
                }
 
-               public ParametersCollection (IParameterData [] param, Type[] types)
+               public ParametersImported (IParameterData [] param, Type[] types)
                {
                        this.parameters = param;
                        this.types = types;
@@ -785,7 +824,7 @@ namespace Mono.CSharp {
                                types [i] = TypeManager.TypeToCoreType (t);
                        }
 
-                       return new ParametersCollection (param, types);
+                       return new ParametersImported (param, types);
                }
 
                //
@@ -795,9 +834,9 @@ namespace Mono.CSharp {
                {
                        if (pi.Length == 0) {
                                if (method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0)
-                                       return new ParametersCollection (new IParameterData [0], Type.EmptyTypes, method, false);
+                                       return new ParametersImported (new IParameterData [0], Type.EmptyTypes, method, false);
 
-                               return Parameters.EmptyReadOnlyParameters;
+                               return ParametersCompiled.EmptyReadOnlyParameters;
                        }
 
                        Type [] types = new Type [pi.Length];
@@ -833,33 +872,34 @@ namespace Mono.CSharp {
                        }
 
                        return method != null ?
-                               new ParametersCollection (par, types, method, is_params) :
-                               new ParametersCollection (par, types);
+                               new ParametersImported (par, types, method, is_params) :
+                               new ParametersImported (par, types);
                }
        }
 
        /// <summary>
        ///   Represents the methods parameters
        /// </summary>
-       public class Parameters : AParametersCollection {
-               public static readonly Parameters EmptyReadOnlyParameters = new Parameters ();
+       public class ParametersCompiled : AParametersCollection
+       {
+               public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
                
                // Used by C# 2.0 delegates
-               public static readonly Parameters Undefined = new Parameters ();
+               public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
 
-               private Parameters ()
+               private ParametersCompiled ()
                {
                        parameters = new Parameter [0];
                        types = Type.EmptyTypes;
                }
 
-               private Parameters (Parameter [] parameters, Type [] types)
+               private ParametersCompiled (Parameter [] parameters, Type [] types)
                {
                        this.parameters = parameters;
                    this.types = types;
                }
                
-               public Parameters (params Parameter[] parameters)
+               public ParametersCompiled (params Parameter[] parameters)
                {
                        if (parameters == null)
                                throw new ArgumentException ("Use EmptyReadOnlyParameters");
@@ -883,30 +923,29 @@ namespace Mono.CSharp {
                                        if (base_name != parameters [j].Name)
                                                continue;
 
-                                       Report.Error (100, parameters [i].Location,
-                                               "The parameter name `{0}' is a duplicate", base_name);
+                                       ErrorDuplicateName (parameters [i]);
                                        i = j;
                                }
                        }
                }
 
-               public Parameters (Parameter [] parameters, bool has_arglist) :
+               public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
                        this (parameters)
                {
                        this.has_arglist = has_arglist;
                }
                
-               public static Parameters CreateFullyResolved (Parameter p, Type type)
+               public static ParametersCompiled CreateFullyResolved (Parameter p, Type type)
                {
-                       return new Parameters (new Parameter [] { p }, new Type [] { type });
+                       return new ParametersCompiled (new Parameter [] { p }, new Type [] { type });
                }
                
-               public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types)
+               public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, Type[] types)
                {
-                       return new Parameters (parameters, types);
+                       return new ParametersCompiled (parameters, types);
                }
 
-               public static Parameters MergeGenerated (Parameters userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
+               public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
                {
                        return MergeGenerated (userParams, checkConflicts,
                                new Parameter [] { compilerParams },
@@ -916,7 +955,7 @@ namespace Mono.CSharp {
                //
                // Use this method when you merge compiler generated parameters with user parameters
                //
-               public static Parameters MergeGenerated (Parameters userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
+               public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
                {
                        Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
                        userParams.FixedParameters.CopyTo(all_params, 0);
@@ -947,45 +986,34 @@ namespace Mono.CSharp {
                                ++last_filled;
                        }
                        
-                       Parameters parameters = new Parameters (all_params, all_types);
+                       ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
                        parameters.has_params = userParams.has_params;
                        return parameters;
                }
 
-               /// <summary>
-               ///    Returns the paramenter information based on the name
-               /// </summary>
-               public Parameter GetParameterByName (string name, out int idx)
+               protected virtual void ErrorDuplicateName (Parameter p)
                {
-                       idx = 0;
-
-                       if (Count == 0)
-                               return null;
-
-                       int i = 0;
-
-                       foreach (Parameter par in FixedParameters){
-                               if (par.Name == name){
-                                       idx = i;
-                                       return par;
-                               }
-                               i++;
-                       }
-                       return null;
+                       Report.Error (100, p.Location, "The parameter name `{0}' is a duplicate", p.Name);
                }
 
-               public Parameter GetParameterByName (string name)
+               /// <summary>
+               ///    Returns the parameter information based on the name
+               /// </summary>
+               public int GetParameterIndexByName (string name)
                {
-                       int idx;
+                       for (int idx = 0; idx < Count; ++idx) {
+                               if (parameters [idx].Name == name)
+                                       return idx;
+                       }
 
-                       return GetParameterByName (name, out idx);
+                       return -1;
                }
-               
+
                public bool Resolve (IResolveContext ec)
                {
                        if (types != null)
                                return true;
-
+                       
                        types = new Type [Count];
                        
                        bool ok = true;
@@ -1036,37 +1064,6 @@ namespace Mono.CSharp {
                        }
                }
 
-#if MS_COMPATIBLE
-               public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
-               {
-                       Parameters p = 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 = types[i].GetGenericArguments ();
-                                       for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
-                                               if (gen_arguments[ii].IsGenericParameter) {
-                                                       Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
-                                                       gen_arguments_open[ii] = t;
-                                               } else
-                                                       gen_arguments_open[ii] = gen_arguments[ii];
-                                       }
-
-                                       p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
-                                       continue;
-                               }
-
-                               if (types[i].IsGenericParameter) {
-                                       Type gen_argument = argTypes[types[i].GenericParameterPosition];
-                                       p.types[i] = gen_argument;
-                                       continue;
-                               }
-                       }
-
-                       return p;
-               }
-#endif
-
                public void VerifyClsCompliance ()
                {
                        foreach (Parameter p in FixedParameters)
@@ -1097,16 +1094,15 @@ namespace Mono.CSharp {
                                "[]", initializers, loc);
                }
 
-               public Parameters Clone ()
+               public ParametersCompiled 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;
+                       ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
+
+                       p.parameters = new IParameterData [parameters.Length];
+                       for (int i = 0; i < Count; ++i)
+                               p.parameters [i] = this [i].Clone ();
+
+                       return p;
                }
        }
 }