예제 #1
0
        /// <summary>
        /// Produces a rule for the specified Action for the given arguments.
        /// 
        /// The default implementation can produce rules for standard .NET types.  Languages should
        /// override this and provide any custom behavior they need and fallback to the default
        /// implementation if no custom behavior is required.
        /// </summary>
        protected override void MakeRule(OldDynamicAction action, object[] args, RuleBuilder rule) {
            ContractUtils.RequiresNotNull(action, "action");
            ContractUtils.RequiresNotNull(args, "args");

            object[] extracted;
            CodeContext callerContext = ExtractCodeContext(args, out extracted);

            ContractUtils.RequiresNotNull(callerContext, "callerContext");

            switch (action.Kind) {
                case DynamicActionKind.GetMember:
                    new GetMemberBinderHelper(callerContext, (OldGetMemberAction)action, extracted, rule).MakeNewRule();
                    return;
                case DynamicActionKind.SetMember:
                    new SetMemberBinderHelper(callerContext, (OldSetMemberAction)action, extracted, rule).MakeNewRule();
                    return;
                case DynamicActionKind.DeleteMember:
                    new DeleteMemberBinderHelper(callerContext, (OldDeleteMemberAction)action, extracted, rule).MakeRule();
                    return;
                case DynamicActionKind.ConvertTo:
                    new ConvertToBinderHelper(callerContext, (OldConvertToAction)action, extracted, rule).MakeRule();
                    return;
                default:
                    throw new NotImplementedException(action.ToString());
            }
        }
예제 #2
0
 internal Expression Bind(OldDynamicAction action, object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel) {
     var builder = new RuleBuilder(parameters, returnLabel);
     MakeRule(action, args, builder);
     if (builder.Target != null) {
         return builder.CreateRule();
     }
     return null;
 }
예제 #3
0
 public Expression GetBoundPythonValue(RuleBuilder builder, ActionBinder binder, PythonType accessing) {
     return Ast.Call(
         typeof(PythonOps).GetMethod("SlotGetValue"),
         builder.Context,
         Ast.Constant(GetSlot(), typeof(PythonTypeSlot)),
         Ast.Constant(null),
         Ast.Constant(accessing)
     );
 }
예제 #4
0
        // 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;
        }
예제 #5
0
        public virtual Expression Bind(OldDynamicAction action, object[] args, ReadOnlyCollection <ParameterExpression> parameters, LabelTarget returnLabel)
        {
            var builder = new RuleBuilder(parameters, returnLabel);

            MakeRule(action, args, builder);
            if (builder.Target != null)
            {
                return(builder.CreateRule());
            }
            return(null);
        }
예제 #6
0
        public virtual ErrorInfo MakeEventValidation(RuleBuilder rule, MemberGroup members)
        {
            EventTracker ev = (EventTracker)members[0];

            // handles in place addition of events - this validates the user did the right thing.
            return(ErrorInfo.FromValueNoError(
                       Expression.Call(
                           typeof(ScriptingRuntimeHelpers).GetMethod("SetEvent"),
                           Expression.Constant(ev),
                           rule.Parameters[1]
                           )
                       ));
        }
예제 #7
0
        public override Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel) {
            ContractUtils.RequiresNotNull(args, "args");
            CodeContext cc = ExtractCodeContext(ref args);
            ContractUtils.Requires(args.Length > 0);
            IOldDynamicObject ido = args[0] as IOldDynamicObject;
            ContractUtils.RequiresNotNull(ido, "args");

            OldCallAction ca = OldCallAction.Make(cc.LanguageContext.Binder, _args);
            var builder = new RuleBuilder(parameters, returnLabel);
            if (!ido.GetRule(ca, cc, args, builder)) {
                throw new InvalidOperationException("Cannot perform call.");
            }

            return builder.CreateRule();
        }
예제 #8
0
        /// <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();
            }
        }
예제 #9
0
        /// <summary>
        /// Produces a rule for the specified Action for the given arguments.
        ///
        /// The default implementation can produce rules for standard .NET types.  Languages should
        /// override this and provide any custom behavior they need and fallback to the default
        /// implementation if no custom behavior is required.
        /// </summary>
        protected override void MakeRule(OldDynamicAction action, object[] args, RuleBuilder rule)
        {
            ContractUtils.RequiresNotNull(action, "action");
            ContractUtils.RequiresNotNull(args, "args");

            object[]    extracted;
            CodeContext callerContext = ExtractCodeContext(args, out extracted);

            ContractUtils.RequiresNotNull(callerContext, "callerContext");

            switch (action.Kind)
            {
            case DynamicActionKind.Call:
                new CallBinderHelper <OldCallAction>(callerContext, (OldCallAction)action, extracted, rule).MakeRule();
                return;

            case DynamicActionKind.GetMember:
                new GetMemberBinderHelper(callerContext, (OldGetMemberAction)action, extracted, rule).MakeNewRule();
                return;

            case DynamicActionKind.SetMember:
                new SetMemberBinderHelper(callerContext, (OldSetMemberAction)action, extracted, rule).MakeNewRule();
                return;

            case DynamicActionKind.CreateInstance:
                new CreateInstanceBinderHelper(callerContext, (OldCreateInstanceAction)action, extracted, rule).MakeRule();
                return;

            case DynamicActionKind.DoOperation:
                new DoOperationBinderHelper(callerContext, (OldDoOperationAction)action, extracted, rule).MakeRule();
                return;

            case DynamicActionKind.DeleteMember:
                new DeleteMemberBinderHelper(callerContext, (OldDeleteMemberAction)action, extracted, rule).MakeRule();
                return;

            case DynamicActionKind.ConvertTo:
                new ConvertToBinderHelper(callerContext, (OldConvertToAction)action, extracted, rule).MakeRule();
                return;

            default:
                throw new NotImplementedException(action.ToString());
            }
        }
예제 #10
0
        public override Expression Bind(object[] args, ReadOnlyCollection <ParameterExpression> parameters, LabelTarget returnLabel)
        {
            ContractUtils.RequiresNotNull(args, "args");
            CodeContext cc = ExtractCodeContext(ref args);

            ContractUtils.Requires(args.Length > 0);
            IOldDynamicObject ido = args[0] as IOldDynamicObject;

            ContractUtils.RequiresNotNull(ido, "args");

            OldCallAction ca      = OldCallAction.Make(cc.LanguageContext.Binder, _args);
            var           builder = new RuleBuilder(parameters, returnLabel);

            if (!ido.GetRule(ca, cc, args, builder))
            {
                throw new InvalidOperationException("Cannot perform call.");
            }

            return(builder.CreateRule());
        }
예제 #11
0
        public MemberBinderHelper(CodeContext context, TActionKind action, object[] args, RuleBuilder rule)
            : base(context, action)
        {
            ContractUtils.RequiresNotNull(args, "args");
            if (args.Length == 0)
            {
                throw new ArgumentException("args must have at least one member");
            }

            _args = args;

            _target = args[0];
            if (CompilerHelpers.IsStrongBox(_target))
            {
                _strongBoxType = _target.GetType();
                _target        = ((IStrongBox)_target).Value;
            }

            _rule = rule;
        }
예제 #12
0
 /// <summary>
 /// Produces a rule for the specified Action for the given arguments.
 /// </summary>
 /// <param name="action">The Action that is being performed.</param>
 /// <param name="args">The arguments to the action as provided from the call site at runtime.</param>
 /// <param name="rule">The rule builder that will hold the result</param>
 protected abstract void MakeRule(OldDynamicAction action, object[] args, RuleBuilder rule);
예제 #13
0
 /// <summary>
 /// Produces a rule for the specified Action for the given arguments.
 /// </summary>
 /// <param name="action">The Action that is being performed.</param>
 /// <param name="args">The arguments to the action as provided from the call site at runtime.</param>
 /// <param name="rule">The rule builder that will hold the result</param>
 protected abstract void MakeRule(OldDynamicAction action, object[] args, RuleBuilder rule);
예제 #14
0
 /// <summary>
 /// Provides a way for the binder to provide a custom error message when lookup fails.  Just
 /// doing this for the time being until we get a more robust error return mechanism.
 /// </summary>
 public virtual Expression MakeUndeletableMemberError(RuleBuilder rule, Type type, string name) {
     return MakeReadOnlyMemberError(rule, type, name);
 }
예제 #15
0
        public virtual ErrorInfo MakeEventValidation(RuleBuilder rule, MemberGroup members) {
            EventTracker ev = (EventTracker)members[0];

            // handles in place addition of events - this validates the user did the right thing.
            return ErrorInfo.FromValueNoError(
                Expression.Call(
                    typeof(ScriptingRuntimeHelpers).GetMethod("SetEvent"),
                    AstUtils.Constant(ev),
                    rule.Parameters[1]
                )
            );
        }
예제 #16
0
        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);
        }
예제 #17
0
 /// <summary>
 /// Provides a way for the binder to provide a custom error message when lookup fails.  Just
 /// doing this for the time being until we get a more robust error return mechanism.
 /// </summary>
 public virtual Expression MakeReadOnlyMemberError(RuleBuilder rule, Type type, string name) {
     return rule.MakeError(
         Expression.New(
             typeof(MissingMemberException).GetConstructor(new Type[] { typeof(string) }),
             AstUtils.Constant(name)
         )
     );
 }
예제 #18
0
 public CreateInstanceBinderHelper(CodeContext context, OldCreateInstanceAction action, object[] args, RuleBuilder rule)
     : base(context, action, args, rule)
 {
 }
예제 #19
0
        public override ErrorInfo MakeEventValidation(RuleBuilder rule, MemberGroup members) {
            EventTracker ev = (EventTracker)members[0];

            return ErrorInfo.FromValueNoError(
               Ast.Call(
                   typeof(PythonOps).GetMethod("SlotTrySetValue"),
                   rule.Context,
                   Ast.Constant(PythonTypeOps.GetReflectedEvent(ev)),
                   AstUtils.Convert(rule.Parameters[0], typeof(object)),
                   Ast.Constant(null, typeof(PythonType)),
                   AstUtils.Convert(rule.Parameters[1], typeof(object))
               )
            );
        }
예제 #20
0
 public CallBinderHelper(CodeContext context, TAction action, object[] args, RuleBuilder rule, IList <MethodBase> targets)
     : this(context, action, args, rule)
 {
     _targets  = ArrayUtils.ToArray(targets);
     _maxLevel = NarrowingLevel.All;
 }
예제 #21
0
 /// <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();
     }
 }
예제 #22
0
 public bool GetRule(OldDynamicAction action, CodeContext context, object[] args, RuleBuilder rule)
 {
     if (action.Kind == DynamicActionKind.GetMember)
     {
         return(MakeGetMemberRule((OldGetMemberAction)action, context, rule));
     }
     return(false);
 }
예제 #23
0
 public bool GetRule(OldDynamicAction action, CodeContext context, object[] args, RuleBuilder rule) {
     if (action.Kind == DynamicActionKind.GetMember) {
         return MakeGetMemberRule((OldGetMemberAction)action, context, rule);                
     }
     return false;
 }
예제 #24
0
        /// <summary>
        /// Gets an Expression which calls the binding target if the method binding succeeded.
        /// 
        /// Throws InvalidOperationException if the binding failed.
        /// 
        /// OBSOLETE
        /// </summary>
        public Expression MakeExpression(RuleBuilder rule, IList<Expression> parameters) {
            ContractUtils.RequiresNotNull(rule, "rule");

            if (_target == null) {
                throw new InvalidOperationException("An expression cannot be produced because the method binding was unsuccessful.");
            } 
            
            return MakeExpression(new ParameterBinderWithCodeContext(_target.Binder._binder, rule.Context), parameters);
        }
예제 #25
0
 /// <summary>
 /// Provides a way for the binder to provide a custom error message when lookup fails.  Just
 /// doing this for the time being until we get a more robust error return mechanism.
 /// </summary>
 public virtual Expression MakeUndeletableMemberError(RuleBuilder rule, Type type, string name)
 {
     return(MakeReadOnlyMemberError(rule, type, name));
 }
예제 #26
0
        private readonly RuleBuilder _rule;                         // the rule we're building and returning

        public DoOperationBinderHelper(CodeContext context, OldDoOperationAction action, object[] args, RuleBuilder rule)
            : base(context, action)
        {
            _args  = args;
            _types = CompilerHelpers.GetTypes(args);
            _rule  = rule;
            _rule.MakeTest(_types);
        }
예제 #27
0
        public ConvertToBinderHelper(CodeContext context, OldConvertToAction action, object[] args, RuleBuilder rule)
            : base(context, action)
        {
            ContractUtils.Requires(args.Length == 1, "can only convert single argument");

            _arg  = args[0];
            _rule = rule;
        }
예제 #28
0
        // 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);
        }
예제 #29
0
        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;
        }
예제 #30
0
 public DeleteMemberBinderHelper(CodeContext context, OldDeleteMemberAction action, object[] args, RuleBuilder rule)
     : base(context, action, args, rule)
 {
 }