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 TryMakeBindingTarget(MethodInfo[] targets, MetaObject[] args, Expression codeContext, Restrictions restrictions) { MethodBinder mb = MethodBinder.MakeBinder(this, targets[0].Name, targets); BindingTarget target = mb.MakeBindingTarget(CallTypes.None, args); if (target.Success) { return(new MetaObject( target.MakeExpression(new ParameterBinderWithCodeContext(this, codeContext)), restrictions.Merge(Restrictions.Combine(target.RestrictedArguments)) )); } return(null); }
private MetaObject TryMakeInvertedBindingTarget(MethodBase[] targets, MetaObject[] args) { MethodBinder mb = MethodBinder.MakeBinder(this, targets[0].Name, targets); MetaObject[] selfArgs = args; BindingTarget target = mb.MakeBindingTarget(CallTypes.None, selfArgs); if (target.Success) { return(new MetaObject( Ast.Not(target.MakeExpression()), Restrictions.Combine(target.RestrictedArguments) )); } 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)); }
private bool MakeDefaultMemberRule(Operators oper) { if (_types[0].IsArray) { if (Binder.CanConvertFrom(_types[1], typeof(int), NarrowingLevel.All)) { if (oper == Operators.GetItem) { _rule.SetTarget(_rule.MakeReturn(Binder, Ast.ArrayIndex( Param0, ConvertIfNeeded(Param1, typeof(int)) ) )); } else { _rule.SetTarget(_rule.MakeReturn(Binder, Ast.AssignArrayIndex( Param0, ConvertIfNeeded(Param1, typeof(int)), ConvertIfNeeded(Param2, _types[0].GetElementType()) ) )); } return(true); } } MethodInfo[] defaults = GetMethodsFromDefaults(_types[0].GetDefaultMembers(), oper); if (defaults.Length != 0) { MethodBinder binder = MethodBinder.MakeBinder(Binder, oper == Operators.GetItem ? "get_Item" : "set_Item", defaults, BinderType.Normal); MethodCandidate cand = binder.MakeBindingTarget(CallType.ImplicitInstance, _types); if (cand != null) { if (oper == Operators.GetItem) { _rule.SetTarget(_rule.MakeReturn(Binder, cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types))); } else { _rule.SetTarget(_rule.MakeReturn(Binder, Ast.Comma(0, _rule.Parameters[2], cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types) ) )); } } else { _rule.SetTarget(Binder.MakeInvalidParametersError(binder, Action, CallType.None, defaults, _rule, _args)); } return(true); } return(false); }
private void MakeMethodBaseRule(MethodBase[] targets) { Type[] testTypes, argTypes; SymbolId[] argNames; //If an instance is explicitly passed in as an argument, ignore it. //Calls that need an instance will pick it up from the bound objects //passed in or the rule. CallType can differentiate between the type //of call during method binding. int instanceIndex = Action.Signature.IndexOf(ArgumentKind.Instance); if (instanceIndex > -1) { _args = ArrayUtils.RemoveAt(_args, instanceIndex + 1); } GetArgumentNamesAndTypes(out argNames, out argTypes); Type[] bindingArgs = argTypes; CallType callType = CallType.None; if (_instance != null) { bindingArgs = ArrayUtils.Insert(_instance.Type, argTypes); callType = CallType.ImplicitInstance; } if (_reversedOperator && bindingArgs.Length >= 2) { // we swap the arguments before binding, and swap back before calling. ArrayUtils.SwapLastTwo(bindingArgs); if (argNames.Length >= 2) { ArrayUtils.SwapLastTwo(argNames); } } // attempt to bind to an individual method MethodBinder binder = MethodBinder.MakeBinder(Binder, GetTargetName(targets), targets, GetBinderType(targets), argNames); MethodCandidate cand = binder.MakeBindingTarget(callType, bindingArgs, out testTypes); if (cand != null) { // if we succeed make the target for the rule MethodBase target = cand.Target.Method; MethodInfo targetMethod = target as MethodInfo; if (targetMethod != null) { target = CompilerHelpers.GetCallableMethod(targetMethod); } if (!MakeActionOnCallRule(target)) { Expression[] exprargs = FinishTestForCandidate(testTypes, argTypes); _rule.SetTarget(_rule.MakeReturn( Binder, cand.Target.MakeExpression(Binder, _rule, exprargs, testTypes))); } } else { // make an error rule MakeInvalidParametersRule(binder, callType, targets); } }