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)); }
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)); }
/// <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))); }