private static IList<MethodData> FindBestMethods(ArgumentData target, IList<MethodInfo> methods, IList<ArgumentData> arguments, Type[] typeArgs) { if (methods.Count == 0) return Empty.Array<MethodData>(); var candidates = new List<MethodData>(); for (int index = 0; index < methods.Count; index++) { try { var methodInfo = methods[index]; var args = GetMethodArgs(methodInfo.IsExtensionMethod(), target, arguments); var methodData = TryInferMethod(methodInfo, args, typeArgs); if (methodData == null) continue; var parameters = methodInfo.GetParameters(); var optionalCount = parameters.Count(info => info.HasDefaultValue()); var requiredCount = parameters.Length - optionalCount; bool hasParams = false; if (parameters.Length != 0) { hasParams = parameters[parameters.Length - 1].IsDefined(typeof(ParamArrayAttribute), true); if (hasParams) requiredCount -= 1; } if (requiredCount > args.Count) continue; if (parameters.Length < args.Count && !hasParams) continue; var count = parameters.Length > args.Count ? args.Count : parameters.Length; bool valid = true; for (int i = 0; i < count; i++) { var arg = args[i]; if (!IsCompatible(parameters[i].ParameterType, arg.Node)) { valid = false; break; } } if (valid) candidates.Add(methodData); } catch { ; } } return candidates; }
internal static IList<ArgumentData> GetMethodArgs(bool isExtensionMethod, ArgumentData target, IList<ArgumentData> args) { if (!isExtensionMethod || target.IsTypeAccess) return args; var actualArgs = new List<ArgumentData> { target }; actualArgs.AddRange(args); return actualArgs; }