public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) { if (target.HasValue && target.Value == null) { return(errorSuggestion ?? new DynamicMetaObject( Expression.Throw( Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }), Expression.Constant(String.Format("Cannot call {0} method named {1} on nil", _isStatic ? "static" : "instance", this.Name))), typeof(object)), BindingRestrictions.GetInstanceRestriction(target.Expression, null))); } Type typeToUse = _isStatic && target.Value is Type ? (Type)target.Value : target.LimitType; IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(args.Length + (_isStatic ? 0 : 1)); if (!_isStatic) { argsPlus.Add(target); } foreach (DynamicMetaObject arg in args) { argsPlus.Add(arg); } OverloadResolverFactory factory = _context.SharedOverloadResolverFactory; DefaultOverloadResolver res = factory.CreateOverloadResolver(argsPlus, new CallSignature(args.Length), _isStatic ? CallTypes.None : CallTypes.ImplicitInstance); BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Public | (_isStatic ? BindingFlags.Static : BindingFlags.Instance); IList <MethodBase> methods = new List <MethodBase>(typeToUse.GetMethods(flags).Where <MethodBase>(x => x.Name == Name && x.GetParameters().Length == args.Length)); if (methods.Count > 0) { BindingTarget bt; DynamicMetaObject dmo = _context.Binder.CallMethod( res, methods, target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args))), Name, NarrowingLevel.None, NarrowingLevel.All, out bt); dmo = DynUtils.MaybeBoxReturnValue(dmo); //; Console.WriteLine(dmo.Expression.DebugView); return(dmo); } return(errorSuggestion ?? new DynamicMetaObject( Expression.Throw( Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }), Expression.Constant(String.Format("No matching member {0} taking {1} args for {2}", this.Name, args.Length, typeToUse.Name))), typeof(object)), target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args))))); }
public override DynamicMetaObject FallbackCreateInstance(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) { Type typeToUse = target.Value is Type ? (Type)target.Value : target.LimitType; IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(args.Length); foreach (DynamicMetaObject arg in args) { argsPlus.Add(arg); } OverloadResolverFactory factory = _context.SharedOverloadResolverFactory; DefaultOverloadResolver res = factory.CreateOverloadResolver(argsPlus, new CallSignature(args.Length), CallTypes.None); BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; IList <MethodBase> methods = new List <MethodBase>(typeToUse.GetConstructors(flags).Where <MethodBase>(x => x.GetParameters().Length == args.Length)); if (methods.Count > 0) { BindingTarget bt; DynamicMetaObject dmo = _context.Binder.CallMethod(res, methods, BindingRestrictions.Empty, "_ctor", NarrowingLevel.None, NarrowingLevel.All, out bt); dmo = DynUtils.MaybeBoxReturnValue(dmo); return(dmo); } return(errorSuggestion ?? new DynamicMetaObject( Expression.Throw( Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }), Expression.Constant("Cannot find constructor matching args")), typeof(object)), target.Restrictions.Merge(BindingRestrictions.Combine(args)))); }
/// <summary> /// Select matching method from list based on args. /// </summary> /// <param name="targetType"></param> /// <param name="args"></param> /// <param name="methods"></param> /// <param name="methodName"></param> /// <param name="isStatic"></param> /// <returns></returns> private static MethodBase GetMatchingMethodAux(Type targetType, IList <HostArg> args, IList <MethodBase> methods, string methodName, bool isStatic) { int argCount = args.Count; if (methods.Count == 0) { return(null); } if (methods.Count == 1) { return(methods[0]); } IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(argCount + (isStatic ? 0 : 1)); if (!isStatic) { argsPlus.Add(new DynamicMetaObject(Expression.Default(targetType), BindingRestrictions.Empty)); } foreach (HostArg ha in args) { Expr e = ha.ArgExpr; Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object); Type t; switch (ha.ParamType) { case HostArg.ParameterType.ByRef: t = typeof(System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType); break; case HostArg.ParameterType.Standard: t = argType; break; default: throw Util.UnreachableCode(); } argsPlus.Add(new DynamicMetaObject(Expression.Default(t), BindingRestrictions.Empty)); } // TODO: See if we can get rid of .Default OverloadResolverFactory factory = ClojureContext.Default.SharedOverloadResolverFactory; DefaultOverloadResolver res = factory.CreateOverloadResolver(argsPlus, new CallSignature(argCount), isStatic ? CallTypes.None : CallTypes.ImplicitInstance); BindingTarget bt = res.ResolveOverload(methodName, methods, NarrowingLevel.None, NarrowingLevel.All); if (bt.Success) { return(bt.Overload.ReflectionInfo); } return(null); }
private static MethodBase GetMatchingMethodAux(Type targetType, object[] actualArgs, IList <MethodBase> methods, string methodName, bool isStatic) { int argCount = actualArgs.Length; if (methods.Count == 0) { return(null); } if (methods.Count == 1) { return(methods[0]); } IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(argCount + (isStatic ? 0 : 1)); if (!isStatic) { argsPlus.Add(new DynamicMetaObject(Expression.Default(targetType), BindingRestrictions.Empty)); } foreach (object arg in actualArgs) { argsPlus.Add(new DynamicMetaObject(Expression.Default(arg.GetType()), BindingRestrictions.Empty, arg)); } OverloadResolverFactory factory = ClojureContext.Default.SharedOverloadResolverFactory; DefaultOverloadResolver res = factory.CreateOverloadResolver(argsPlus, new CallSignature(argCount), isStatic ? CallTypes.None : CallTypes.ImplicitInstance); BindingTarget bt = res.ResolveOverload(methodName, methods, NarrowingLevel.None, NarrowingLevel.All); if (bt.Success) { return(bt.Overload.ReflectionInfo); } return(null); }
protected Expression GenDlrForMethod(ObjExpr objx, GenContext context) { if (_method.DeclaringType == (Type)Compiler.CompileStubOrigClassVar.deref()) { _method = FindEquivalentMethod(_method, objx.BaseType); } int argCount = _args.Count; IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(argCount + (IsStaticCall ? 0 : 1)); if (!IsStaticCall) { argsPlus.Add(new DynamicMetaObject(Expression.Convert(GenTargetExpression(objx, context), _method.DeclaringType), BindingRestrictions.Empty)); } List <int> refPositions = new List <int>(); ParameterInfo[] methodParms = _method.GetParameters(); for (int i = 0; i < argCount; i++) { HostArg ha = _args[i]; Expr e = ha.ArgExpr; Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object); //Type t; switch (ha.ParamType) { case HostArg.ParameterType.ByRef: refPositions.Add(i); argsPlus.Add(new DynamicMetaObject(HostExpr.GenUnboxArg(GenTypedArg(objx, context, argType, e), methodParms[i].ParameterType.GetElementType()), BindingRestrictions.Empty)); break; case HostArg.ParameterType.Standard: Type ptype = methodParms[i].ParameterType; if (ptype.IsGenericParameter) { ptype = argType; } Expression typedArg = GenTypedArg(objx, context, ptype, e); argsPlus.Add(new DynamicMetaObject(typedArg, BindingRestrictions.Empty)); break; default: throw Util.UnreachableCode(); } } // TODO: get rid of use of Default OverloadResolverFactory factory = ClojureContext.Default.SharedOverloadResolverFactory; DefaultOverloadResolver res = factory.CreateOverloadResolver(argsPlus, new CallSignature(argCount), IsStaticCall ? CallTypes.None : CallTypes.ImplicitInstance); List <MethodBase> methods = new List <MethodBase>(); methods.Add(_method); BindingTarget bt = res.ResolveOverload(_methodName, methods, NarrowingLevel.None, NarrowingLevel.All); if (!bt.Success) { throw new ArgumentException("Conflict in argument matching. -- Internal error."); } Expression call = bt.MakeExpression(); if (refPositions.Count > 0) { ParameterExpression resultParm = Expression.Parameter(typeof(Object[])); List <Expression> stmts = new List <Expression>(refPositions.Count + 2); stmts.Add(Expression.Assign(resultParm, call)); // TODO: Fold this into the loop above foreach (int i in refPositions) { HostArg ha = _args[i]; Expr e = ha.ArgExpr; Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object); stmts.Add(Expression.Assign(_args[i].LocalBinding.ParamExpression, Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(i + 1)), argType))); } Type returnType = HasClrType ? ClrType : typeof(object); stmts.Add(Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(0)), returnType)); call = Expression.Block(new ParameterExpression[] { resultParm }, stmts); } call = _arithmeticRewriter.Visit(call); return(call); }