te.loc = loc;
+ var dep = te.type.GetMissingDependencies ();
+ if (dep != null) {
+ ImportedTypeDefinition.Error_MissingDependency (ec.Compiler, dep, loc);
+ }
+
//
// Obsolete checks cannot be done when resolving base context as they
// require type dependecies to be set but we are just resolving them
UnsafeError (rc, loc);
}
+ var dep = member.GetMissingDependencies ();
+ if (dep != null) {
+ ImportedTypeDefinition.Error_MissingDependency (rc.Compiler, dep, loc);
+ }
+
if (!rc.IsObsolete) {
ObsoleteAttribute oa = member.GetAttributeObsolete ();
if (oa != null)
if (IsStatic) {
if (InstanceExpression != null) {
if (InstanceExpression is TypeExpr) {
- ObsoleteAttribute oa = InstanceExpression.Type.GetAttributeObsolete ();
- if (oa != null && !rc.IsObsolete) {
- AttributeTester.Report_ObsoleteMessage (oa, InstanceExpression.GetSignatureForError (), loc, rc.Report);
- }
+ var t = InstanceExpression.Type;
+ do {
+ ObsoleteAttribute oa = t.GetAttributeObsolete ();
+ if (oa != null && !rc.IsObsolete) {
+ AttributeTester.Report_ObsoleteMessage (oa, t.GetSignatureForError (), loc, rc.Report);
+ }
+
+ t = t.DeclaringType;
+ } while (t != null);
} else {
var runtime_expr = InstanceExpression as RuntimeValueExpression;
if (runtime_expr == null || !runtime_expr.IsSuggestionOnly) {
static int BetterExpressionConversion (ResolveContext ec, Argument a, TypeSpec p, TypeSpec q)
{
TypeSpec argument_type = a.Type;
+
+ //
+ // If argument is an anonymous function
+ //
if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) {
//
- // Uwrap delegate from Expression<T>
+ // p and q are delegate types or expression tree types
//
- if (p.GetDefinition () == TypeManager.expression_type) {
+ if (p.GetDefinition () == TypeManager.expression_type || q.GetDefinition () == TypeManager.expression_type) {
+ if (q.MemberDefinition != p.MemberDefinition) {
+ return 0;
+ }
+
+ //
+ // Uwrap delegate from Expression<T>
+ //
+ q = TypeManager.GetTypeArguments (q)[0];
p = TypeManager.GetTypeArguments (p)[0];
}
- if (q.GetDefinition () == TypeManager.expression_type) {
- q = TypeManager.GetTypeArguments (q)[0];
+
+ var p_m = Delegate.GetInvokeMethod (ec.Compiler, p);
+ var q_m = Delegate.GetInvokeMethod (ec.Compiler, q);
+
+ //
+ // With identical parameter lists
+ //
+ if (!TypeSpecComparer.Equals (p_m.Parameters.Types,q_m.Parameters.Types))
+ return 0;
+
+ p = p_m.ReturnType;
+ q = q_m.ReturnType;
+
+ //
+ // if p is void returning, and q has a return type Y, then C2 is the better conversion.
+ //
+ if (p == TypeManager.void_type) {
+ return q != TypeManager.void_type ? 2 : 0;
}
- p = Delegate.GetInvokeMethod (ec.Compiler, p).ReturnType;
- q = Delegate.GetInvokeMethod (ec.Compiler, q).ReturnType;
- if (p == TypeManager.void_type && q != TypeManager.void_type)
- return 2;
- if (q == TypeManager.void_type && p != TypeManager.void_type)
- return 1;
+ //
+ // if p has a return type Y, and q is void returning, then C1 is the better conversion.
+ //
+ if (q == TypeManager.void_type) {
+ return p != TypeManager.void_type ? 1: 0;
+ }
} else {
if (argument_type == p)
return 1;
//
int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, IParametersMember pm, ref bool params_expanded_form, ref bool dynamicArgument, ref TypeSpec returnType)
{
+ // Parameters of most-derived type used mainly for named and optional parameters
var pd = pm.Parameters;
+
+ // Used for params modifier only, that's legacy of C# 1.0 which uses base type for
+ // params modifier instead of most-derived type
+ var cpd = ((IParametersMember) candidate).Parameters;
int param_count = pd.Count;
int optional_count = 0;
int score;
return int.MaxValue - 10000 + args_gap - optional_count;
// Readjust expected number when params used
- if (pd.HasParams) {
+ if (cpd.HasParams) {
optional_count--;
if (arg_count < param_count)
param_count--;
return int.MaxValue - 10000 + args_gap;
}
} else if (arg_count != param_count) {
- if (!pd.HasParams)
+ if (!cpd.HasParams)
return int.MaxValue - 10000 + args_gap;
if (arg_count < param_count - 1)
return int.MaxValue - 10000 + args_gap;
Argument temp;
if (index >= param_count) {
// When using parameters which should not be available to the user
- if ((pd.FixedParameters[index].ModFlags & Parameter.Modifier.PARAMS) == 0)
+ if ((cpd.FixedParameters[index].ModFlags & Parameter.Modifier.PARAMS) == 0)
break;
arguments.Add (null);
//
// 1. Handle generic method using type arguments when specified or type inference
//
+ TypeSpec[] ptypes;
var ms = candidate as MethodSpec;
if (ms != null && ms.IsGeneric) {
// Setup constraint checker for probing only
}
candidate = ms;
-
+ ptypes = ms.Parameters.Types;
} else {
if (type_arguments != null)
return int.MaxValue - 15000;
+
+ ptypes = cpd.Types;
}
//
//
Parameter.Modifier p_mod = 0;
TypeSpec pt = null;
- TypeSpec[] ptypes = ((IParametersMember) candidate).Parameters.Types;
for (int i = 0; i < arg_count; i++) {
Argument a = arguments[i];
}
if (p_mod != Parameter.Modifier.PARAMS) {
- p_mod = pd.FixedParameters[i].ModFlags;
+ p_mod = (pd.FixedParameters[i].ModFlags & ~Parameter.Modifier.PARAMS) | (cpd.FixedParameters[i].ModFlags & Parameter.Modifier.PARAMS);
pt = ptypes [i];
} else if (!params_expanded_form) {
params_expanded_form = true;
//
// When params parameter has no argument it will be provided later if the method is the best candidate
//
- if (arg_count + 1 == pd.Count && (pd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
+ if (arg_count + 1 == pd.Count && (cpd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
params_expanded_form = true;
//
if (oa != null && !rc.IsObsolete)
AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report);
+ var dep = best_candidate.GetMissingDependencies ();
+ if (dep != null) {
+ ImportedTypeDefinition.Error_MissingDependency (rc.Compiler, dep, loc);
+ }
+
best_candidate.MemberDefinition.SetIsUsed ();
args = best_candidate_args;
// For candidates which match on parameters count report more details about incorrect arguments
//
if (pm != null) {
- int unexpanded_count = pm.Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count;
+ int unexpanded_count = ((IParametersMember) best_candidate).Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count;
if (pm.Parameters.Count == arg_count || params_expanded || unexpanded_count == arg_count) {
// Reject any inaccessible member
if (!best_candidate.IsAccessible (rc.CurrentType) || !best_candidate.DeclaringType.IsAccessible (rc.CurrentType)) {