codeowners update
[mono.git] / mcs / mcs / parameter.cs
index d95363c774c62b9aae16f0aa55624622b9911009..2bd2a498a919444a5862a395038f7d42e5500862 100644 (file)
@@ -142,6 +142,9 @@ namespace Mono.CSharp {
        }
 
        public class ParamsParameter : Parameter {
+
+               bool ParamsAttributeEmit;
+
                public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
                        base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
                {
@@ -158,13 +161,18 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       var mc = ec as MemberCore;
+                       ParamsAttributeEmit = mc == null || (mc.ModFlags & Modifiers.OVERRIDE) == 0;
+
                        return parameter_type;
                }
 
                public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
                {
                        base.ApplyAttributes (mb, cb, index, pa);
-                       pa.ParamArray.EmitAttribute (builder);
+
+                       if (ParamsAttributeEmit)
+                               pa.ParamArray.EmitAttribute (builder);
                }
        }
 
@@ -222,8 +230,7 @@ namespace Mono.CSharp {
                        CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath
                }
 
-               static readonly string[] attribute_targets = new string[] { "param" };
-               static readonly string[] attribute_targets_primary = new string[] { "param", "field" };
+               static readonly string[] attribute_targets = new [] { "param" };
 
                FullNamedExpression texpr;
                Modifier modFlags;
@@ -234,7 +241,6 @@ namespace Mono.CSharp {
                protected int idx;
                public bool HasAddressTaken;
 
-               Constructor primary_constructor;
                TemporaryVariableReference expr_tree_variable;
 
                HoistedParameter hoisted_variant;
@@ -309,7 +315,7 @@ namespace Mono.CSharp {
 
                public override string[] ValidAttributeTargets {
                        get {
-                               return primary_constructor != null ? attribute_targets_primary : attribute_targets;
+                               return attribute_targets;
                        }
                }
 
@@ -317,12 +323,6 @@ namespace Mono.CSharp {
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
-                       if (a.Target == AttributeTargets.Field) {
-                               var field = MemberCache.FindMember (primary_constructor.Spec.DeclaringType, MemberFilter.Field (name, parameter_type), BindingRestriction.DeclaredOnly);
-                               ((Field)field.MemberDefinition).ApplyAttributeBuilder (a, ctor, cdata, pa);
-                               return;
-                       }
-
                        if (a.Type == pa.In && ModFlags == Modifier.OUT) {
                                a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
                                return;
@@ -379,6 +379,15 @@ namespace Mono.CSharp {
                        return member.IsAccessibleAs (parameter_type);
                }
 
+               bool IsValidCallerContext (MemberCore memberContext)
+               {
+                       var m = memberContext as Method;
+                       if (m != null)
+                               return !m.IsPartialImplementation;
+
+                       return true;
+               }
+
                // <summary>
                //   Resolve is used in method definitions
                // </summary>
@@ -390,10 +399,6 @@ namespace Mono.CSharp {
                        if (attributes != null)
                                attributes.AttachTo (this, rc);
 
-                       var ctor = rc.CurrentMemberDefinition as Constructor;
-                       if (ctor != null && ctor.IsPrimaryConstructor)
-                               primary_constructor = ctor;
-
                        parameter_type = texpr.ResolveAsType (rc);
                        if (parameter_type == null)
                                return null;
@@ -428,6 +433,7 @@ namespace Mono.CSharp {
                {
                        var pa = rc.Module.PredefinedAttributes;
                        TypeSpec caller_type;
+                       Attribute callerMemberName = null, callerFilePath = null;
 
                        foreach (var attr in attributes.Attrs) {
                                var atype = attr.ResolveTypeForComparison ();
@@ -442,18 +448,31 @@ namespace Mono.CSharp {
                                                        caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
                                        }
 
+                                       if (!IsValidCallerContext (rc.CurrentMemberDefinition)) {
+                                               rc.Report.Warning (4026, 1, attr.Location,
+                                                       "The CallerMemberName applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments",
+                                                       name);
+                                       }
+
                                        modFlags |= Modifier.CallerMemberName;
+                                       callerMemberName = attr;
                                        continue;
                                }
 
                                if (atype == pa.CallerLineNumberAttribute) {
                                        caller_type = rc.BuiltinTypes.Int;
-                                       if (caller_type != parameter_type && !Convert.ImplicitNumericConversionExists (caller_type, parameter_type)) {
+                                       if (caller_type != parameter_type && !Convert.ImplicitStandardConversionExists (new IntConstant (caller_type, int.MaxValue, Location.Null), parameter_type)) {
                                                rc.Report.Error (4017, attr.Location,
-                                                       "The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
+                                                       "The CallerLineNumberAttribute attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
                                                        caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
                                        }
 
+                                       if (!IsValidCallerContext (rc.CurrentMemberDefinition)) {
+                                               rc.Report.Warning (4024, 1, attr.Location,
+                                                       "The CallerLineNumberAttribute applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments",
+                                                       name);
+                                       }
+
                                        modFlags |= Modifier.CallerLineNumber;
                                        continue;
                                }
@@ -466,10 +485,40 @@ namespace Mono.CSharp {
                                                        caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
                                        }
 
+                                       if (!IsValidCallerContext (rc.CurrentMemberDefinition)) {
+                                               rc.Report.Warning (4025, 1, attr.Location,
+                                                       "The CallerFilePath applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments",
+                                                       name);
+                                       }
+
                                        modFlags |= Modifier.CallerFilePath;
+                                       callerFilePath = attr;
                                        continue;
                                }
                        }
+
+                       if ((modFlags & Modifier.CallerLineNumber) != 0) {
+                               if (callerMemberName != null) {
+                                       rc.Report.Warning (7081, 1, callerMemberName.Location,
+                                               "The CallerMemberNameAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerLineNumberAttribute",
+                                               Name);
+                               }
+
+                               if (callerFilePath != null) {
+                                       rc.Report.Warning (7082, 1, callerFilePath.Location,
+                                               "The CallerFilePathAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerLineNumberAttribute",
+                                               name);
+                               }
+                       }
+
+                       if ((modFlags & Modifier.CallerMemberName) != 0) {
+                               if (callerFilePath != null) {
+                                       rc.Report.Warning (7080, 1, callerFilePath.Location,
+                                               "The CallerMemberNameAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerFilePathAttribute",
+                                               name);
+                               }
+
+                       }
                }
 
                public void ResolveDefaultValue (ResolveContext rc)
@@ -522,7 +571,8 @@ namespace Mono.CSharp {
 
                                if (TypeSpecComparer.IsEqual (default_expr.Type, parameter_type) ||
                                        (default_expr is NullConstant && TypeSpec.IsReferenceType (parameter_type) && !parameter_type.IsGenericParameter) ||
-                                       parameter_type.BuiltinType == BuiltinTypeSpec.Type.Object) {
+                                       parameter_type.BuiltinType == BuiltinTypeSpec.Type.Object ||
+                                       parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
                                        return;
                                }
 
@@ -676,6 +726,10 @@ namespace Mono.CSharp {
                                } else if (parameter_type.HasDynamicElement) {
                                        pa.Dynamic.EmitAttribute (builder, parameter_type, Location);
                                }
+
+                               if (parameter_type.HasNamedTupleElement) {
+                                       pa.TupleElementNames.EmitAttribute (builder, parameter_type, Location);
+                               }
                        }
                }
 
@@ -736,6 +790,11 @@ namespace Mono.CSharp {
                        return new TypeExpression (p_type, location);
                }
 
+               public void SetIndex (int index)
+               {
+                       idx = index;
+               }
+
                public void Warning_UselessOptionalParameter (Report Report)
                {
                        Report.Warning (1066, 1, Location,
@@ -912,6 +971,19 @@ namespace Mono.CSharp {
                        return sb.ToString ();
                }
 
+               public static bool HasSameParameterDefaults (AParametersCollection a, AParametersCollection b)
+               {
+                       if (a == null)
+                               return b == null;
+
+                       for (int i = 0; i < a.Count; ++i) {
+                               if (a.FixedParameters [i].HasDefaultValue != b.FixedParameters [i].HasDefaultValue)
+                                       return false;
+                       }
+
+                       return true;
+               }
+
                public bool HasArglist {
                        get { return has_arglist; }
                }
@@ -1098,6 +1170,23 @@ namespace Mono.CSharp {
                        return new ParametersCompiled (parameters, types);
                }
 
+               public static ParametersCompiled Prefix (ParametersCompiled parameters, Parameter p, TypeSpec type)
+               {
+                       var ptypes = new TypeSpec [parameters.Count + 1];
+                       ptypes [0] = type;
+                       Array.Copy (parameters.Types, 0, ptypes, 1, parameters.Count);
+
+                       var param = new Parameter [ptypes.Length];
+                       param [0] = p;
+                       for (int i = 0; i < parameters.Count; ++i) {
+                               var pi = parameters [i];
+                               param [i + 1] = pi;
+                               pi.SetIndex (i + 1);
+                       }
+
+                       return ParametersCompiled.CreateFullyResolved (param, ptypes);
+               }
+
                //
                // TODO: This does not fit here, it should go to different version of AParametersCollection
                // as the underlying type is not Parameter and some methods will fail to cast
@@ -1259,6 +1348,9 @@ namespace Mono.CSharp {
                        for (int i = 0; i < parameters.Length; ++i) {
                                Parameter p = (Parameter) parameters [i];
 
+                               if (p.Type != null)
+                                       p.Type.CheckObsoleteness (m, p.Location);
+
                                //
                                // Try not to enter default values resolution if there are is not any default value possible
                                //
@@ -1355,10 +1447,12 @@ namespace Mono.CSharp {
 
                        expr = Child;
 
-                       if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsDefaultStruct))) {
-                               rc.Report.Error (1736, Location,
-                                       "The expression being assigned to optional parameter `{0}' must be a constant or default value",
-                                       p.Name);
+                       if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsGeneratedStructConstructor))) {
+                               if (!(expr is ErrorExpression)) {
+                                       rc.Report.Error (1736, Location,
+                                               "The expression being assigned to optional parameter `{0}' must be a constant or default value",
+                                               p.Name);
+                               }
 
                                return;
                        }