private DynamicMetaObject TryMakeBindingTarget(OverloadResolverFactory resolverFactory, MethodInfo[] targets, DynamicMetaObject[] args, BindingRestrictions restrictions) { var resolver = resolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None); BindingTarget target = resolver.ResolveOverload(targets[0].Name, targets, NarrowingLevel.None, NarrowingLevel.All); if (target.Success) { return(new DynamicMetaObject( target.MakeExpression(), restrictions.Merge(target.RestrictedArguments.GetAllRestrictions()) )); } return(null); }
private DynamicMetaObject MakeMetaMethodCall(CallSignature signature, OverloadResolverFactory resolverFactory, TargetInfo targetInfo) { BindingRestrictions restrictions = BindingRestrictions.Combine(targetInfo.Arguments).Merge(targetInfo.Restrictions); if (targetInfo.Instance != null) { restrictions = targetInfo.Instance.Restrictions.Merge(restrictions); } DynamicMetaObject[] args; CallTypes callType; if (targetInfo.Instance != null) { args = ArrayUtils.Insert(targetInfo.Instance, targetInfo.Arguments); callType = CallTypes.ImplicitInstance; } else { args = targetInfo.Arguments; callType = CallTypes.None; } return CallMethod(resolverFactory.CreateOverloadResolver(args, signature, callType), targetInfo.Targets, restrictions); }
private DynamicMetaObject TryNumericComparison(OperatorInfo info, OverloadResolverFactory resolverFactory, DynamicMetaObject[] args) { MethodInfo[] targets = FilterNonMethods( args[0].GetLimitType(), GetMember( MemberRequestKind.Operation, args[0].GetLimitType(), "Compare" ) ); if (targets.Length > 0) { var resolver = resolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None); BindingTarget target = resolver.ResolveOverload(targets[0].Name, targets, NarrowingLevel.None, NarrowingLevel.All); if (target.Success) { Expression call = AstUtils.Convert(target.MakeExpression(), typeof(int)); switch (info.Operator) { case ExpressionType.GreaterThan: call = Expression.GreaterThan(call, AstUtils.Constant(0)); break; case ExpressionType.LessThan: call = Expression.LessThan(call, AstUtils.Constant(0)); break; case ExpressionType.GreaterThanOrEqual: call = Expression.GreaterThanOrEqual(call, AstUtils.Constant(0)); break; case ExpressionType.LessThanOrEqual: call = Expression.LessThanOrEqual(call, AstUtils.Constant(0)); break; case ExpressionType.Equal: call = Expression.Equal(call, AstUtils.Constant(0)); break; case ExpressionType.NotEqual: call = Expression.NotEqual(call, AstUtils.Constant(0)); break; } return(new DynamicMetaObject( call, target.RestrictedArguments.GetAllRestrictions() )); } } 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); }
/// <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: #if CLR2 t = typeof(MSC::System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType); #else t = typeof(System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType); #endif 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); }
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); }