X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fparameter.cs;h=275f1013e8b9dfb533215ddeaeb466e4d4a8faf9;hb=631d194f74cdf9feb8684931805a813d3e6fb40a;hp=69ae1cf839f2a8da9cd5352f0b2fa11521f27a8f;hpb=3f3ef7225cbabdae584723e5d77974d2e1c67d6c;p=mono.git diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs index 69ae1cf839f..275f1013e8b 100644 --- a/mcs/mcs/parameter.cs +++ b/mcs/mcs/parameter.cs @@ -222,7 +222,7 @@ namespace Mono.CSharp { CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath } - static readonly string[] attribute_targets = new string[] { "param" }; + static readonly string[] attribute_targets = new [] { "param" }; FullNamedExpression texpr; Modifier modFlags; @@ -371,6 +371,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; + } + // // Resolve is used in method definitions // @@ -394,7 +403,7 @@ namespace Mono.CSharp { return null; } - TypeManager.CheckTypeVariance (parameter_type, + VarianceDecl.CheckTypeVariance (parameter_type, (modFlags & Parameter.Modifier.RefOutMask) != 0 ? Variance.None : Variance.Contravariant, rc); @@ -416,6 +425,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 (); @@ -430,18 +440,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; } @@ -454,10 +477,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) @@ -501,7 +554,7 @@ namespace Mono.CSharp { } else { rc.Report.Error (1909, default_expr.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'", - default_expr.Type.GetSignatureForError ()); ; + default_expr.Type.GetSignatureForError ()); } default_expr = null; @@ -510,7 +563,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; } @@ -635,7 +689,7 @@ namespace Mono.CSharp { if (OptAttributes != null) OptAttributes.Emit (); - if (HasDefaultValue) { + if (HasDefaultValue && default_expr.Type != null) { // // Emit constant values for true constants only, the other // constant-like expressions will rely on default value expression @@ -648,9 +702,9 @@ namespace Mono.CSharp { } else { builder.SetConstant (c.GetValue ()); } - } else if (default_expr.Type.IsStruct) { + } else if (default_expr.Type.IsStruct || default_expr.Type.IsGenericParameter) { // - // Handles special case where default expression is used with value-type + // Handles special case where default expression is used with value-type or type parameter // // void Foo (S s = default (S)) {} // @@ -724,6 +778,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, @@ -900,6 +959,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; } } @@ -972,10 +1044,18 @@ namespace Mono.CSharp { if (inflated_types[i] == expr.Type) continue; - if (expr is DefaultValueExpression) + var c = expr as Constant; + if (c != null) { + // + // It may fail we are inflating before type validation is done + // + c = Constant.ExtractConstantFromValue (inflated_types[i], c.GetValue (), expr.Location); + if (c == null) + expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location); + else + expr = c; + } else if (expr is DefaultValueExpression) expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location); - else if (expr is Constant) - expr = Constant.CreateConstantFromValue (inflated_types[i], ((Constant) expr).GetValue (), expr.Location); clone.FixedParameters[i] = new ParameterData (fp.Name, fp.ModFlags, expr); } @@ -1078,6 +1158,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 @@ -1239,6 +1336,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 // @@ -1325,23 +1425,22 @@ namespace Mono.CSharp { { } - protected override Expression DoResolve (ResolveContext rc) - { - return base.DoResolve (rc); - } - public void Resolve (ResolveContext rc, Parameter p) { var expr = Resolve (rc); - if (expr == null) + if (expr == null) { + this.expr = ErrorExpression.Instance; return; + } 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; } @@ -1378,6 +1477,8 @@ namespace Mono.CSharp { rc.Report.Error (1750, Location, "Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'", type.GetSignatureForError (), parameter_type.GetSignatureForError ()); + + this.expr = ErrorExpression.Instance; } public override object Accept (StructuralVisitor visitor)