private bool MakeGetMemberRule(OldGetMemberAction action, CodeContext context, RuleBuilder rule) { object value; if (TryGetValue(action.Name, out value)) { Debug.Assert(value is MemberTracker); MemberTracker memValue = (MemberTracker)value; rule.MakeTest(typeof(NamespaceTracker)); rule.AddTest( Expression.Equal( Expression.Property( Expression.Convert(rule.Parameters[0], typeof(NamespaceTracker)), typeof(NamespaceTracker).GetProperty("Id") ), Expression.Constant(Id) ) ); Expression target = context.LanguageContext.Binder.ReturnMemberTracker(memValue.DeclaringType, memValue); rule.Target = rule.MakeReturn(context.LanguageContext.Binder, target); return(true); } return(false); }
/// <summary> /// Internal helper to produce the actual expression used for the error when emitting /// the error into a rule. /// </summary> public Expression MakeErrorForRule(RuleBuilder rule, ActionBinder binder) { switch (_kind) { case ErrorInfoKind.Error: rule.IsError = true; return(rule.MakeReturn(binder, _value)); case ErrorInfoKind.Success: return(rule.MakeReturn(binder, _value)); case ErrorInfoKind.Exception: return(rule.MakeError(_value)); default: throw new InvalidOperationException(); } }
// This can produce a IsCallable rule that returns the immutable constant isCallable. // Beware that objects can have a mutable callable property. Eg, in Python, assign or delete the __call__ attribute. public static bool MakeIsCallableRule(CodeContext context, object self, bool isCallable, RuleBuilder rule) { rule.MakeTest(CompilerHelpers.GetType(self)); rule.Target = rule.MakeReturn( context.LanguageContext.Binder, Ast.Constant(isCallable) ); return true; }
private void MakeMethodBaseRule(MethodBase[] targets) { Type[] argTypes; // will not include implicit instance argument (if any) SymbolId[] argNames; // will include ArgumentKind.Dictionary keyword names GetArgumentNamesAndTypes(out argNames, out argTypes); Type[] bindingArgs = argTypes; // will include instance argument (if any) CallTypes callType = CallTypes.None; if (_instance != null) { bindingArgs = ArrayUtils.Insert(InstanceType, argTypes); callType = CallTypes.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, argNames, NarrowingLevel.None, _maxLevel); BindingTarget bt = binder.MakeBindingTarget(callType, bindingArgs); if (bt.Success) { // if we succeed make the target for the rule MethodBase target = bt.Method; MethodInfo targetMethod = target as MethodInfo; if (targetMethod != null) { target = CompilerHelpers.GetCallableMethod(targetMethod, Binder.PrivateBinding); } Expression[] exprargs = FinishTestForCandidate(bt.ArgumentTests, argTypes); _rule.Target = _rule.MakeReturn( Binder, bt.MakeExpression(_rule, exprargs)); } else { // make an error rule MakeInvalidParametersRule(bt); } }
// This can produce a IsCallable rule that returns the immutable constant isCallable. // Beware that objects can have a mutable callable property. Eg, in Python, assign or delete the __call__ attribute. public static bool MakeIsCallableRule(CodeContext context, object self, bool isCallable, RuleBuilder rule) { rule.MakeTest(CompilerHelpers.GetType(self)); rule.Target = rule.MakeReturn( context.LanguageContext.Binder, Ast.Constant(isCallable) ); return(true); }
/// <summary> /// Helper to produce a rule when no conversion is required (the strong type of the expression /// input matches the type we're converting to) /// </summary> private void MakePerfectMatchTarget() { _rule.Target = _rule.MakeReturn(Binder, _rule.Parameters[0]); }
private bool TryNumericComparison(OperatorInfo info) { MethodInfo[] targets = FilterNonMethods(_types[0], Binder.GetMember(Action, _types[0], "Compare")); if (targets.Length > 0) { MethodBinder mb = MethodBinder.MakeBinder(Binder, targets[0].Name, targets); BindingTarget target = mb.MakeBindingTarget(CallTypes.None, _types); if (target.Success) { Expression call = Ast.Convert(target.MakeExpression(_rule, _rule.Parameters), 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; } _rule.Target = _rule.MakeReturn(Binder, call); return(true); } } return(false); }
/// <summary> /// Internal helper to produce the actual expression used for the error when emitting /// the error into a rule. /// </summary> public Expression MakeErrorForRule(RuleBuilder rule, ActionBinder binder) { switch (_kind) { case ErrorInfoKind.Error: rule.IsError = true; return rule.MakeReturn(binder, _value); case ErrorInfoKind.Success: return rule.MakeReturn(binder, _value); case ErrorInfoKind.Exception: return rule.MakeError(_value); default: throw new InvalidOperationException(); } }
private bool MakeGetMemberRule(OldGetMemberAction action, CodeContext context, RuleBuilder rule) { object value; if (TryGetValue(action.Name, out value)) { Debug.Assert(value is MemberTracker); MemberTracker memValue = (MemberTracker)value; rule.MakeTest(typeof(NamespaceTracker)); rule.AddTest( Expression.Equal( Expression.Property( Expression.Convert(rule.Parameters[0], typeof(NamespaceTracker)), typeof(NamespaceTracker).GetProperty("Id") ), AstUtils.Constant(Id) ) ); Expression target = context.LanguageContext.Binder.ReturnMemberTracker(memValue.DeclaringType, memValue); rule.Target = rule.MakeReturn(context.LanguageContext.Binder, target); return true; } return false; }