Пример #1
0
        public static MetaObject TryBind(RubyContext /*!*/ context, GetMemberBinder /*!*/ binder, MetaObject /*!*/ target)
        {
            Assert.NotNull(context, target);
            var metaBuilder       = new MetaObjectBuilder();
            var contextExpression = Ast.Constant(context);

            metaBuilder.AddTargetTypeTest(target.Value, target.Expression, context, contextExpression);

            RubyMemberInfo method = context.ResolveMethod(target.Value, binder.Name, true).InvalidateSitesOnOverride();

            if (method != null && RubyModule.IsMethodVisible(method, false))
            {
                // we need to create a bound member:
                metaBuilder.Result = Ast.Constant(new RubyMethod(target.Value, method, binder.Name));
            }
            else
            {
                // TODO:
                // We need to throw an exception if we don't find method_missing so that our version update optimization works:
                // This limits interop with other languages.
                //
                // class B           CLR type with method 'foo'
                // class C < B       Ruby class
                // x = C.new
                //
                // 1. x.GET("foo") from Ruby
                //    No method found or CLR method found -> fallback to Python
                //    Python might see its method foo or might just fallback to .NET,
                //    in any case it will add rule [1] with restriction on type of C w/o Ruby version check.
                // 2. B.define_method("foo")
                //    This doesn't update C due to the optimization (there is no overridden method foo in C).
                // 3. x.GET("foo") from Ruby
                //    This will not invoke the binder since the rule [1] is still valid.
                //
                object symbol = SymbolTable.StringToId(binder.Name);
                RubyCallAction.BindToMethodMissing(metaBuilder, binder.Name,
                                                   new CallArguments(
                                                       new MetaObject(contextExpression, Restrictions.Empty, context),
                                                       new[] {
                    target,
                    new MetaObject(Ast.Constant(symbol), Restrictions.Empty, symbol)
                },
                                                       RubyCallSignature.Simple(1)
                                                       ),
                                                   method != null
                                                   );
            }

            // TODO: we should return null if we fail, we need to throw exception for now:
            return(metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects));
        }
Пример #2
0
        public static MetaObject TryBind(RubyContext /*!*/ context, InvokeMemberBinder /*!*/ binder, MetaObject /*!*/ target, MetaObject /*!*/[] /*!*/ args)
        {
            Assert.NotNull(context, target);

            var metaBuilder = new MetaObjectBuilder();

            RubyCallAction.Bind(metaBuilder, binder.Name,
                                new CallArguments(
                                    new MetaObject(Ast.Constant(context), Restrictions.Empty, context),
                                    target,
                                    args,
                                    RubyCallSignature.Simple(binder.Arguments.Count)
                                    )
                                );

            // TODO: we should return null if we fail, we need to throw exception for now:
            return(metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects));
        }
        public static MetaObject TryBind(RubyContext /*!*/ context, CreateInstanceBinder /*!*/ binder, MetaObject /*!*/ target, MetaObject /*!*/[] /*!*/ args)
        {
            Assert.NotNull(context, binder, target, args);

            var metaBuilder = new MetaObjectBuilder();

            RubyCallAction.Bind(metaBuilder, "new",
                                new CallArguments(
                                    new MetaObject(Ast.Constant(context), Restrictions.Empty, context),
                                    target,
                                    args,
                                    RubyCallSignature.Simple(args.Length)
                                    )
                                );

            // TODO: we should return null if we fail, we need to throw exception due to version update optimization:
            return(metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects));
        }
Пример #4
0
 /// <summary>
 /// Creates a runtime-bound call site binder.
 /// </summary>
 public static RubyCallAction /*!*/ Make(RubyContext /*!*/ context, string /*!*/ methodName, int argumentCount)
 {
     return(Make(context, methodName, RubyCallSignature.Simple(argumentCount)));
 }