public bool VerifyArgumentsCompat(ResolveContext ec, ref Arguments arguments, int arg_count, MethodSpec method, bool chose_params_expanded, bool may_fail, Location loc) { AParametersCollection pd = method.Parameters; int param_count = GetApplicableParametersCount (method, pd); int errors = ec.Report.Errors; Parameter.Modifier p_mod = 0; TypeSpec pt = null; int a_idx = 0, a_pos = 0; Argument a = null; ArrayInitializer params_initializers = null; bool has_unsafe_arg = method.ReturnType.IsPointer; for (; a_idx < arg_count; a_idx++, ++a_pos) { a = arguments [a_idx]; if (p_mod != Parameter.Modifier.PARAMS) { p_mod = pd.FixedParameters [a_idx].ModFlags; pt = pd.Types [a_idx]; has_unsafe_arg |= pt.IsPointer; if (p_mod == Parameter.Modifier.PARAMS) { if (chose_params_expanded) { params_initializers = new ArrayInitializer (arg_count - a_idx, a.Expr.Location); pt = TypeManager.GetElementType (pt); } } } // // Types have to be identical when ref or out modifer is used // if (a.Modifier != 0 || (p_mod & ~Parameter.Modifier.PARAMS) != 0) { if ((p_mod & ~Parameter.Modifier.PARAMS) != a.Modifier) break; if (!TypeManager.IsEqual (a.Expr.Type, pt)) break; continue; } else { NamedArgument na = a as NamedArgument; if (na != null) { int name_index = pd.GetParameterIndexByName (na.Name); if (name_index < 0 || name_index >= param_count) { if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType)) { ec.Report.SymbolRelatedToPreviousError (DeclaringType); ec.Report.Error (1746, na.Location, "The delegate `{0}' does not contain a parameter named `{1}'", TypeManager.CSharpName (DeclaringType), na.Name); } else { ec.Report.SymbolRelatedToPreviousError (best_candidate); ec.Report.Error (1739, na.Location, "The best overloaded method match for `{0}' does not contain a parameter named `{1}'", TypeManager.CSharpSignature (method), na.Name); } } else if (arguments[name_index] != a) { if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType)) ec.Report.SymbolRelatedToPreviousError (DeclaringType); else ec.Report.SymbolRelatedToPreviousError (best_candidate); ec.Report.Error (1744, na.Location, "Named argument `{0}' cannot be used for a parameter which has positional argument specified", na.Name); } } } if (a.Expr.Type == InternalType.Dynamic) continue; if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt)) break; Expression conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc); if (conv == null) break; // // Convert params arguments to an array initializer // if (params_initializers != null) { // we choose to use 'a.Expr' rather than 'conv' so that // we don't hide the kind of expression we have (esp. CompoundAssign.Helper) params_initializers.Add (a.Expr); arguments.RemoveAt (a_idx--); --arg_count; continue; } // Update the argument with the implicit conversion a.Expr = conv; } if (a_idx != arg_count) { if (!may_fail && ec.Report.Errors == errors) { if (CustomErrorHandler != null) CustomErrorHandler.NoExactMatch (ec, best_candidate); else Error_InvalidArguments (ec, loc, a_pos, method, a, pd, pt); } return false; } // // Fill not provided arguments required by params modifier // if (params_initializers == null && pd.HasParams && arg_count + 1 == param_count) { if (arguments == null) arguments = new Arguments (1); pt = pd.Types [param_count - 1]; pt = TypeManager.GetElementType (pt); has_unsafe_arg |= pt.IsPointer; params_initializers = new ArrayInitializer (0, loc); } // // Append an array argument with all params arguments // if (params_initializers != null) { arguments.Add (new Argument ( new ArrayCreation (new TypeExpression (pt, loc), "[]", params_initializers, loc).Resolve (ec))); arg_count++; } if (arg_count < param_count) { if (!may_fail) Error_ArgumentCountWrong (ec, arg_count); return false; } if (has_unsafe_arg && !ec.IsUnsafe) { if (!may_fail) UnsafeError (ec, loc); return false; } return true; }