private MetaObject MakeMethodIndexRule(string oper, MetaObject[] args) { MethodInfo[] defaults = GetMethodsFromDefaults(args[0].LimitType.GetDefaultMembers(), oper); if (defaults.Length != 0) { MethodBinder binder = MethodBinder.MakeBinder( this, oper == StandardOperators.GetItem ? "get_Item" : "set_Item", defaults); MetaObject[] selfWithArgs = args; ParameterExpression arg2 = null; if (oper == StandardOperators.SetItem) { Debug.Assert(args.Length >= 2); // need to save arg2 in a temp because it's also our result arg2 = Ast.Variable(args[2].Expression.Type, "arg2Temp"); args[2] = new MetaObject( Ast.Assign(arg2, args[2].Expression), args[2].Restrictions ); } BindingTarget target = binder.MakeBindingTarget(CallTypes.ImplicitInstance, selfWithArgs); Restrictions restrictions = Restrictions.Combine(args); if (target.Success) { if (oper == StandardOperators.GetItem) { return(new MetaObject( target.MakeExpression(), restrictions.Merge(Restrictions.Combine(target.RestrictedArguments)) )); } else { return(new MetaObject( Ast.Block( new ParameterExpression[] { arg2 }, target.MakeExpression(), arg2 ), restrictions.Merge(Restrictions.Combine(target.RestrictedArguments)) )); } } return(MakeError( MakeInvalidParametersError(target), restrictions )); } return(null); }
private MetaObject TryNumericComparison(OperatorInfo info, MetaObject[] args) { MethodInfo[] targets = FilterNonMethods( args[0].LimitType, GetMember(OldDoOperationAction.Make(this, info.Operator), args[0].LimitType, "Compare") ); if (targets.Length > 0) { MethodBinder mb = MethodBinder.MakeBinder(this, targets[0].Name, targets); BindingTarget target = mb.MakeBindingTarget(CallTypes.None, args); if (target.Success) { Expression call = AstUtils.Convert(target.MakeExpression(), typeof(int)); switch (info.Operator) { case Operators.GreaterThan: call = Ast.GreaterThan(call, Ast.Constant(0)); break; case Operators.LessThan: call = Ast.LessThan(call, Ast.Constant(0)); break; case Operators.GreaterThanOrEqual: call = Ast.GreaterThanOrEqual(call, Ast.Constant(0)); break; case Operators.LessThanOrEqual: call = Ast.LessThanOrEqual(call, Ast.Constant(0)); break; case Operators.Equals: call = Ast.Equal(call, Ast.Constant(0)); break; case Operators.NotEquals: call = Ast.NotEqual(call, Ast.Constant(0)); break; case Operators.Compare: break; } return(new MetaObject( call, Restrictions.Combine(target.RestrictedArguments) )); } } return(null); }
private MetaObject CallWorker(ParameterBinder parameterBinder, IList <MethodBase> targets, IList <MetaObject> args, CallSignature signature, CallTypes callType, Restrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) { ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder"); ContractUtils.RequiresNotNullItems(args, "args"); ContractUtils.RequiresNotNullItems(targets, "targets"); ContractUtils.RequiresNotNull(restrictions, "restrictions"); MetaObject[] finalArgs; SymbolId[] argNames; if (callType == CallTypes.ImplicitInstance) { GetArgumentNamesAndTypes(signature, ArrayUtils.RemoveFirst(args), out argNames, out finalArgs); finalArgs = ArrayUtils.Insert(args[0], finalArgs); } else { GetArgumentNamesAndTypes(signature, args, out argNames, out finalArgs); } // attempt to bind to an individual method MethodBinder binder = MethodBinder.MakeBinder( this, name ?? GetTargetName(targets), targets, argNames, minLevel, maxLevel); target = binder.MakeBindingTarget(callType, finalArgs); if (target.Success) { // if we succeed make the target for the rule return(new MetaObject( target.MakeExpression(parameterBinder), restrictions.Merge(MakeSplatTests(callType, signature, args).Merge(Restrictions.Combine(target.RestrictedArguments))) )); } // make an error rule return(MakeInvalidParametersRule(callType, signature, this, args, restrictions, target)); }