public virtual LinqExpression VisitInvoke(InvokeExpression call) { var resolved = ResolveMethod(null, call); if (resolved == null) { // Screw extension methods other than from Queryable and Enumerable resolved = ResolveMethod(typeof(Queryable), call); resolved = resolved ?? ResolveMethod(typeof(Enumerable), call); } if (resolved != null) { return resolved; } else { throw new NotSupportedException(call.ToString()); } }
private LinqExpression ResolveMethod(Type hostClass, InvokeExpression call) { throw new NotImplementedException(call.ToString()); // var isExtension = hostClass != null; // if (isExtension) // { // var args = new List<RelinqScriptExpression>(call.Args); // args.Insert(0, call.Target); // call = new InvokeExpression(call.Name, new ConstantExpression("null"), args); // } // // hostClass = hostClass ?? Visit(call.Target).Type; // var mis = isExtension ? // hostClass.GetMethods(BindingFlags.Static | BindingFlags.Public) : // // Only instance methods for non-extension invocations // hostClass.GetMethods(BindingFlags.Instance | BindingFlags.Public); // // var mrs = mis // .Where(mi => mi.Name == call.Name) // .Where(mi => !isExtension || mi.IsExtension()) // .Select(mi => new MethodResolution(mi, _closure, call)); // // // First pass matches formal and actual (a.k.a. "real") arguments using available types. // // While matching it also tries to infer generic arguments of the method. // // // // Since typeinfo in JS is quite often incomplete the following arguments will not be used // // for generic arguments inference: // // * Function-type parameters (tho matches arg count of an underlying delegate) // // * Object definitions (when used as func arguments they need type info in order to be inferred) // // // // Second pass iteratively applies // // var success = mrs.SingleOrDefault(mr => mr.Resolve(ResolutionPass.First) != false); // if (success != null) // { // success.Resolve(ResolutionPass.Second); // return success.ResolvedCall; // } // else // { // return null; // } }