CreateMetaObject() 개인적인 메소드

private CreateMetaObject ( DynamicMetaObjectBinder action ) : DynamicMetaObject
action System.Dynamic.DynamicMetaObjectBinder
리턴 System.Dynamic.DynamicMetaObject
예제 #1
0
        public override MetaObject /*!*/ Bind(MetaObject /*!*/ context, MetaObject /*!*/[] /*!*/ args)
        {
            var mo = new MetaObjectBuilder();

            SetRule(mo, new CallArguments(context, args, Signature));
            return(mo.CreateMetaObject(this, context, args));
        }
예제 #2
0
            public override DynamicMetaObject /*!*/ FallbackInvoke(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args,
                                                                   DynamicMetaObject errorSuggestion)
            {
                // Used in combination with GetMember to compose InvokeMember operation.
                // Gets here only if the target is not a callable meta-object.

                var metaBuilder = new MetaObjectBuilder(this, target, args);
                var callArgs    = new CallArguments(_context, target, args, CallInfo);

                metaBuilder.AddTypeRestriction(target.GetLimitType(), target.Expression);

                RubyOverloadResolver.NormalizeArguments(metaBuilder, callArgs, 0, 0);
                if (!metaBuilder.Error)
                {
                    // no arguments => just return the target:
                    metaBuilder.Result = target.Expression;
                }
                else
                {
                    // any arguments found (expected none):
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return(metaBuilder.CreateMetaObject(this));
            }
예제 #3
0
            public override DynamicMetaObject /*!*/ FallbackGetMember(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion)
            {
#if !SILVERLIGHT
                DynamicMetaObject result;
                if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetMember(this, target, out result))
                {
                    return(result);
                }
#endif

                var metaBuilder = new MetaObjectBuilder(target);
                var callArgs    = new CallArguments(_context, target, DynamicMetaObject.EmptyMetaObjects, _CallInfo);

                // See InvokeMember binder for explanation.
                bool tryAlternateBinding = _unmangled != null && errorSuggestion == null;

                if (!RubyCallAction.BuildAccess(metaBuilder, _originalName ?? Name, callArgs, errorSuggestion == null && !tryAlternateBinding, true))
                {
                    Debug.Assert(errorSuggestion != null || tryAlternateBinding);
                    if (tryAlternateBinding)
                    {
                        metaBuilder.SetMetaResult(target.BindGetMember(_unmangled), true);
                    }
                    else
                    {
                        // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions:
                        metaBuilder.SetMetaResult(errorSuggestion, false);
                    }
                }

                return(metaBuilder.CreateMetaObject(this));
            }
예제 #4
0
            public override DynamicMetaObject /*!*/ FallbackGetMember(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion)
            {
                if (_unmangled != null)
                {
                    // TODO: errorSuggestion?
                    return(_unmangled.Bind(target, DynamicMetaObject.EmptyMetaObjects));
                }

#if !SILVERLIGHT
                DynamicMetaObject result;
                if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetMember(this, target, out result))
                {
                    return(result);
                }
#endif

                var metaBuilder = new MetaObjectBuilder(target);
                var callArgs    = new CallArguments(_context, target, DynamicMetaObject.EmptyMetaObjects, _CallInfo);

                if (!RubyCallAction.BuildAccess(metaBuilder, _originalName ?? Name, callArgs, errorSuggestion == null, true))
                {
                    Debug.Assert(errorSuggestion != null);
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return(metaBuilder.CreateMetaObject(this));
            }
예제 #5
0
        public override MetaObject /*!*/ Bind(MetaObject /*!*/ context, MetaObject /*!*/[] /*!*/ args)
        {
            var mo = new MetaObjectBuilder();

            Bind(mo, _methodName, new CallArguments(context, args, _signature));
            return(mo.CreateMetaObject(this, context, args));
        }
예제 #6
0
            internal static DynamicMetaObject FallbackInvokeMember(IInteropBinder /*!*/ binder, string /*!*/ methodName, CallInfo /*!*/ callInfo,
                                                                   DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, DynamicMetaObject errorSuggestion, InvokeMember alternateBinder)
            {
                var metaBuilder = new MetaObjectBuilder(binder, target, args);
                var callArgs    = new CallArguments(binder.Context, target, args, callInfo);

                //
                // If we are called with no errorSuggestion we attempt to bind the alternate name since the current binding failed
                // (unless we successfully bind to a COM object method or Ruby/CLR method defined on the target meta-object).
                // If we already have an errorSuggestion we use it as it represents a valid binding and no alternate name lookups are thus necessary.
                //
                // For example, DynamicObject InvokeMember calls our FallbackInvokeMember 4 times:
                //
                // 1) binder.fallback(..., errorSuggestion: null)
                //    -> DynamicObject.BindInvokeMember(altBinder)
                //       2) altBinder.fallback(..., errorSuggestion: null)
                //          -> [[ error ]]
                //
                //       3) altBinder.fallback(..., errorSuggestion: [[
                //                                                     TryInvokeMember(altName, out result)
                //                                                       ? result
                //                                                       : TryGetMember(altName, out result)
                //                                                           ? altBinder.FallbackInvoke(result)
                //                                                           : [[ error ]]
                //                                                   ]])
                //          -> errorSuggestion
                //
                // 4) binder.fallback(..., errorSuggestion: [[
                //                                            TryInvokeMember(name, out result)
                //                                              ? result
                //                                              : TryGetMember(name, out result)
                //                                                  ? binder.FallbackInvoke(result)
                //                                                    TryInvokeMember(altName, out result)
                //                                                      ? result
                //                                                      : TryGetMember(altName, out result)
                //                                                          ? altBinder.FallbackInvoke(result)
                //                                                          : [[ error ]]
                //
                //                                          ]])
                // -> errorSuggestion
                //
                bool tryAlternateBinding = alternateBinder != null && errorSuggestion == null;

                if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, errorSuggestion == null && !tryAlternateBinding, true))
                {
                    Debug.Assert(errorSuggestion != null || tryAlternateBinding);
                    if (tryAlternateBinding)
                    {
                        metaBuilder.SetMetaResult(target.BindInvokeMember(alternateBinder, args), true);
                    }
                    else
                    {
                        // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions:
                        metaBuilder.SetMetaResult(errorSuggestion, false);
                    }
                }

                return(metaBuilder.CreateMetaObject((DynamicMetaObjectBinder)binder));
            }
예제 #7
0
        public override DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ scopeOrContextOrTarget, DynamicMetaObject/*!*/[]/*!*/ args) {
            var callArgs = new CallArguments(_context, scopeOrContextOrTarget, args, Signature);
            var metaBuilder = new MetaObjectBuilder(this, args);

            if (IsForeignMetaObject(callArgs.MetaTarget)) {
                return InteropBind(metaBuilder, callArgs);
            } 

            Build(metaBuilder, callArgs, true);
            return metaBuilder.CreateMetaObject(this);
        }
예제 #8
0
        public override DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, DynamicMetaObject/*!*/[]/*!*/ args) {
            var callArgs = new CallArguments(context, args, Signature);
            
            // TODO: COM interop
            if (IsForeignMetaObject(callArgs.MetaTarget)) {
                return InteropBind(callArgs);
            }

            var metaBuilder = new MetaObjectBuilder();
            Build(metaBuilder, callArgs);
            return metaBuilder.CreateMetaObject(this);
        }
예제 #9
0
            public static DynamicMetaObject/*!*/ Bind(RubyContext/*!*/ context, InvokeBinder/*!*/ binder,
                RubyMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, Action<MetaObjectBuilder, CallArguments>/*!*/ buildInvoke) {

                RubyCallSignature callSignature;
                if (RubyCallSignature.TryCreate(binder.CallInfo, out callSignature)) {
                    return binder.FallbackInvoke(target, args);
                }

                var metaBuilder = new MetaObjectBuilder();
                buildInvoke(metaBuilder, new CallArguments(target.CreateMetaContext(), target, args, callSignature));
                return metaBuilder.CreateMetaObject(binder);
            }
예제 #10
0
        private DynamicMetaObject InteropBind(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            // TODO: argument count limit depends on the binder!

            // TODO: pass block as the last (before RHS arg?) parameter/ignore block if args not accepting block:
            var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, Int32.MaxValue);

            if (!metaBuilder.Error)
            {
                MethodInfo postConverter;
                var        interopBinder = GetInteropBinder(args.RubyContext, normalizedArgs, out postConverter);
                if (interopBinder != null)
                {
                    Type resultType;
                    var  result = interopBinder.Bind(args.MetaTarget, ArrayUtils.MakeArray(normalizedArgs));

                    metaBuilder.SetMetaResult(result, args);
                    if (postConverter != null)
                    {
                        // TODO: do better?
                        var paramType = postConverter.GetParameters()[0].ParameterType;

                        metaBuilder.Result = Ast.Call(null, postConverter, AstUtils.Convert(metaBuilder.Result, paramType));
                        resultType         = postConverter.ReturnType;
                    }
                    else
                    {
                        resultType = interopBinder.ReturnType;
                    }

                    return(metaBuilder.CreateMetaObject(interopBinder, resultType));
                }
                else
                {
                    // interop protocol not supported for this binder -> ignore IDO and treat it as a CLR object:
                    return(null);
                }
            }
            return(metaBuilder.CreateMetaObject(this));
        }
예제 #11
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));
        }
예제 #12
0
            internal static DynamicMetaObject FallbackInvokeMember(IInteropBinder /*!*/ binder, string /*!*/ methodName, CallInfo /*!*/ callInfo,
                                                                   DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, DynamicMetaObject errorSuggestion)
            {
                var metaBuilder = new MetaObjectBuilder(binder, target, args);
                var callArgs    = new CallArguments(binder.Context, target, args, callInfo);

                if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, errorSuggestion == null, true))
                {
                    Debug.Assert(errorSuggestion != null);
                    // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions:
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return(metaBuilder.CreateMetaObject((DynamicMetaObjectBinder)binder));
            }
예제 #13
0
            public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, GetIndexBinder /*!*/ binder,
                                                       DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ indexes,
                                                       Func <DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject> /*!*/ fallback)
            {
                Debug.Assert(fallback != null);

                var callArgs    = new CallArguments(context, target, indexes, RubyCallSignature.Interop(indexes.Length));
                var metaBuilder = new MetaObjectBuilder(target, indexes);

                if (!RubyCallAction.BuildCall(metaBuilder, "[]", callArgs, false, false))
                {
                    metaBuilder.SetMetaResult(fallback(target, indexes), false);
                }

                return(metaBuilder.CreateMetaObject(binder));
            }
예제 #14
0
            public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, SetMemberBinder /*!*/ binder, DynamicMetaObject /*!*/ target,
                                                       DynamicMetaObject /*!*/ value, Func <DynamicMetaObject, DynamicMetaObject, DynamicMetaObject> /*!*/ fallback)
            {
                Debug.Assert(fallback != null);

                var args        = new[] { value };
                var callArgs    = new CallArguments(context, target, args, RubyCallSignature.Interop(1));
                var metaBuilder = new MetaObjectBuilder(target, args);

                if (!RubyCallAction.BuildCall(metaBuilder, binder.Name + "=", callArgs, false, false))
                {
                    metaBuilder.SetMetaResult(fallback(target, value), false);
                }

                return(metaBuilder.CreateMetaObject(binder));
            }
예제 #15
0
            public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, GetMemberBinder /*!*/ binder, DynamicMetaObject /*!*/ target,
                                                       Func <DynamicMetaObject, DynamicMetaObject> /*!*/ fallback)
            {
                Debug.Assert(fallback != null);

                var callArgs    = new CallArguments(context, target, DynamicMetaObject.EmptyMetaObjects, RubyCallSignature.Interop(0));
                var metaBuilder = new MetaObjectBuilder(target);

                if (!RubyCallAction.BuildAccess(metaBuilder, binder.Name, callArgs, false, false))
                {
                    // TODO: error suggestion?
                    metaBuilder.SetMetaResult(fallback(target), false);
                }

                return(metaBuilder.CreateMetaObject(binder));
            }
예제 #16
0
            public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, string /*!*/ methodName, CallInfo /*!*/ callInfo,
                                                       DynamicMetaObjectBinder /*!*/ binder, DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args,
                                                       Func <DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject> /*!*/ fallback)
            {
                Debug.Assert(fallback != null);

                var callArgs    = new CallArguments(context, target, args, RubyCallSignature.Interop(callInfo.ArgumentCount));
                var metaBuilder = new MetaObjectBuilder(target, args);

                if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, false, false))
                {
                    // TODO: error suggestion?
                    metaBuilder.SetMetaResult(fallback(target, args), false);
                }
                return(metaBuilder.CreateMetaObject(binder));
            }
예제 #17
0
            public static DynamicMetaObject /*!*/ Bind(InvokeBinder /*!*/ binder,
                                                       RubyMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, Action <MetaObjectBuilder, CallArguments> /*!*/ buildInvoke)
            {
                RubyCallSignature callSignature;

                if (RubyCallSignature.TryCreate(binder.CallInfo, out callSignature))
                {
                    return(binder.FallbackInvoke(target, args));
                }

                var callArgs    = new CallArguments(target.CreateMetaContext(), target, args, callSignature);
                var metaBuilder = new MetaObjectBuilder(target, args);

                buildInvoke(metaBuilder, callArgs);
                return(metaBuilder.CreateMetaObject(binder));
            }
예제 #18
0
            public override MetaObject/*!*/ BindInvoke(InvokeBinder/*!*/ action, MetaObject/*!*/[]/*!*/ args) {
                RubyCallSignature callSignature;
                if (RubyCallSignature.TryCreate(action.Arguments, out callSignature)) {
                    return action.FallbackInvoke(this, args);
                }

                var context = new MetaObject(
                    Methods.GetContextFromProc.OpCall(AstUtils.Convert(Expression, typeof(Proc))),
                    Restrictions.Empty,
                    RubyOps.GetContextFromProc((Proc)Value)
                );

                var metaBuilder = new MetaObjectBuilder();
                Proc.SetCallActionRule(metaBuilder, new CallArguments(context, this, args, callSignature), true);
                return metaBuilder.CreateMetaObject(action, args);
            }
예제 #19
0
        public override DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ scopeOrContextOrTargetOrArgArray, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Ruby: " + GetType().Name + Signature.ToString() + ": Bind");

            var callArgs    = new CallArguments(_context, scopeOrContextOrTargetOrArgArray, args, Signature);
            var metaBuilder = new MetaObjectBuilder(this, args);

            DynamicMetaObject interopBinding;

            if (IsForeignMetaObject(callArgs.MetaTarget) && (interopBinding = InteropBind(metaBuilder, callArgs)) != null)
            {
                return(interopBinding);
            }

            Build(metaBuilder, callArgs, true);
            return(metaBuilder.CreateMetaObject(this));
        }
예제 #20
0
        public static DynamicMetaObject TryBind(RubyContext/*!*/ context, CreateInstanceBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args) {
            Assert.NotNull(context, binder, target, args);
            
            var metaBuilder = new MetaObjectBuilder();

            RubyCallAction.Bind(metaBuilder, "new", 
                new CallArguments(
                    new DynamicMetaObject(AstUtils.Constant(context), BindingRestrictions.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, DynamicMetaObject.EmptyMetaObjects);
        }
예제 #21
0
        public static DynamicMetaObject TryBind(RubyContext/*!*/ context, InvokeMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args) {
            Assert.NotNull(context, target);

            var metaBuilder = new MetaObjectBuilder();
            
            RubyCallAction.Bind(metaBuilder, binder.Name,
                new CallArguments(
                    new DynamicMetaObject(AstUtils.Constant(context), BindingRestrictions.Empty, context),
                    target, 
                    args, 
                    RubyCallSignature.Simple(binder.CallInfo.ArgumentCount)
                )
            );

            // TODO: we should return null if we fail, we need to throw exception for now:
            return metaBuilder.CreateMetaObject(binder, DynamicMetaObject.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));
        }
예제 #23
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));
        }
예제 #24
0
            public override DynamicMetaObject/*!*/ BindInvoke(InvokeBinder/*!*/ action, DynamicMetaObject/*!*/[]/*!*/ args) {
                RubyCallSignature callSignature;
                if (RubyCallSignature.TryCreate(action.Arguments, out callSignature)) {
                    return action.FallbackInvoke(this, args);
                }

                var self = (RubyMethod)Value;

                var context = new DynamicMetaObject(
                    Methods.GetContextFromMethod.OpCall(AstUtils.Convert(Expression, typeof(RubyMethod))),
                    BindingRestrictions.Empty,
                    RubyOps.GetContextFromMethod(self)
                );

                var metaBuilder = new MetaObjectBuilder();
                Method.SetRuleForCall(metaBuilder, new CallArguments(context, this, args, callSignature));
                return metaBuilder.CreateMetaObject(action, args);
            }
예제 #25
0
            public override DynamicMetaObject /*!*/ FallbackConvert(DynamicMetaObject /*!*/ target, DynamicMetaObject errorSuggestion)
            {
#if !SILVERLIGHT
                DynamicMetaObject result;
                if (Microsoft.Scripting.ComInterop.ComBinder.TryConvert(this, target, out result))
                {
                    return(result);
                }
#endif
                var metaBuilder = new MetaObjectBuilder(this, target, DynamicMetaObject.EmptyMetaObjects);

                if (!GenericConversionAction.BuildConversion(metaBuilder, target, Ast.Constant(_context), Type, errorSuggestion == null))
                {
                    Debug.Assert(errorSuggestion != null);
                    // no conversion applicable so we didn't do any operation with arguments that would require restrictions converted to conditions:
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return(metaBuilder.CreateMetaObject(this));
            }
예제 #26
0
            public static DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ context, SetIndexBinder /*!*/ binder,
                                                       DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ indexes, DynamicMetaObject /*!*/ value,
                                                       Func <DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject, DynamicMetaObject> /*!*/ fallback)
            {
                Debug.Assert(fallback != null);

                var args     = ArrayUtils.Append(indexes, value);
                var callArgs = new CallArguments(context, target, args,
                                                 new RubyCallSignature(indexes.Length, RubyCallFlags.IsInteropCall | RubyCallFlags.HasRhsArgument)
                                                 );

                var metaBuilder = new MetaObjectBuilder(target, args);

                if (!RubyCallAction.BuildCall(metaBuilder, "[]=", callArgs, false, false))
                {
                    metaBuilder.SetMetaResult(fallback(target, indexes, value), false);
                }

                return(metaBuilder.CreateMetaObject(binder));
            }
예제 #27
0
            public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, GetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target, 
                Func<DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) {
                Debug.Assert(fallback != null);

                var callArgs = new CallArguments(context, target, DynamicMetaObject.EmptyMetaObjects, RubyCallSignature.Interop(0));
                var metaBuilder = new MetaObjectBuilder(target);

                if (!RubyCallAction.BuildAccess(metaBuilder, binder.Name, callArgs, false, false)) {
                    metaBuilder.SetMetaResult(fallback(target), false);
                }

                return metaBuilder.CreateMetaObject(binder);
            }
예제 #28
0
            public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, string/*!*/ methodName, CallInfo/*!*/ callInfo, 
                DynamicMetaObjectBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args,
                Func<DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject>/*!*/ fallback) {
                Debug.Assert(fallback != null);

                var callArgs = new CallArguments(context, target, args, RubyCallSignature.Interop(callInfo.ArgumentCount));
                var metaBuilder = new MetaObjectBuilder(target, args);

                if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, false, false)) {
                    metaBuilder.SetMetaResult(fallback(target, args), false);
                }
                return metaBuilder.CreateMetaObject(binder);
            }
예제 #29
0
            internal static DynamicMetaObject FallbackInvokeMember(IInteropBinder/*!*/ binder, string/*!*/ methodName, CallInfo/*!*/ callInfo,
                DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, DynamicMetaObject errorSuggestion) {

                var metaBuilder = new MetaObjectBuilder(binder, target, args);
                var callArgs = new CallArguments(binder.Context, target, args, callInfo);

                if (!RubyCallAction.BuildCall(metaBuilder, methodName, callArgs, errorSuggestion == null, true)) {
                    Debug.Assert(errorSuggestion != null);
                    // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions:
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return metaBuilder.CreateMetaObject((DynamicMetaObjectBinder)binder);
            }
예제 #30
0
 protected override DynamicMetaObject/*!*/ InteropBind(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
     metaBuilder.SetError(Ast.New(
         typeof(NotSupportedException).GetConstructor(new[] { typeof(string) }),
         Ast.Constant("Super call not supported on foreign meta-objects")
     ));
     return metaBuilder.CreateMetaObject(this);
 }
예제 #31
0
            public override DynamicMetaObject/*!*/ FallbackConvert(DynamicMetaObject/*!*/ target, DynamicMetaObject errorSuggestion) {
#if !SILVERLIGHT
                DynamicMetaObject result;
                if (Microsoft.Scripting.ComInterop.ComBinder.TryConvert(this, target, out result)) {
                    return result;
                }
#endif
                var metaBuilder = new MetaObjectBuilder(this, target, DynamicMetaObject.EmptyMetaObjects);

                if (!GenericConversionAction.BuildConversion(metaBuilder, target, Ast.Constant(_context), Type, errorSuggestion == null)) {
                    Debug.Assert(errorSuggestion != null);
                    // no conversion applicable so we didn't do any operation with arguments that would require restrictions converted to conditions:
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return metaBuilder.CreateMetaObject(this);
            }
예제 #32
0
        protected override DynamicMetaObject/*!*/ InteropBind(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
            // TODO: pass block as the last parameter (before RHS arg?):
            var normalizedArgs = RubyMethodGroupBase.NormalizeArguments(metaBuilder, args, SelfCallConvention.NoSelf, false, false);
            var callInfo = new CallInfo(normalizedArgs.Length);

            var interopBinder = GetInteropBinder(args.RubyContext, callInfo);
            var result = interopBinder.Bind(args.MetaTarget, normalizedArgs);
            metaBuilder.SetMetaResult(result, args);
            return metaBuilder.CreateMetaObject(interopBinder);
        }
예제 #33
0
        // TODO: convert binder
        internal static DynamicMetaObject TryBindCovertToDelegate(RubyMetaObject /*!*/ target, ConvertBinder /*!*/ binder, MethodInfo /*!*/ delegateFactory)
        {
            var metaBuilder = new MetaObjectBuilder(target);

            return(TryBuildConversionToDelegate(metaBuilder, target, binder.Type, delegateFactory) ? metaBuilder.CreateMetaObject(binder) : null);
        }
예제 #34
0
        public static DynamicMetaObject TryBind(RubyContext/*!*/ context, GetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target) {
            Assert.NotNull(context, target);
            var metaBuilder = new MetaObjectBuilder();
            var contextExpression = AstUtils.Constant(context);

            RubyClass targetClass = context.GetImmediateClassOf(target.Value);
            MethodResolutionResult method;
            RubyMemberInfo methodMissing = null;

            using (targetClass.Context.ClassHierarchyLocker()) {
                metaBuilder.AddTargetTypeTest(target.Value, targetClass, target.Expression, context, contextExpression);

                method = targetClass.ResolveMethodForSiteNoLock(binder.Name, RubyClass.IgnoreVisibility);
                if (method.Found) {
                    methodMissing = targetClass.ResolveMethodForSiteNoLock(Symbols.MethodMissing, RubyClass.IgnoreVisibility).Info;
                }
            }
            
            if (method.Found) {
                // we need to create a bound member:
                metaBuilder.Result = AstUtils.Constant(new RubyMethod(target.Value, method.Info, 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, 
                    new CallArguments(
                        new DynamicMetaObject(contextExpression, BindingRestrictions.Empty, context),
                        new[] { 
                            target,
                            new DynamicMetaObject(AstUtils.Constant(symbol), BindingRestrictions.Empty, symbol) 
                        },
                        RubyCallSignature.Simple(1)
                    ),
                    binder.Name,
                    methodMissing,
                    method.IncompatibleVisibility,
                    false
                );
            }

            // TODO: we should return null if we fail, we need to throw exception for now:
            return metaBuilder.CreateMetaObject(binder, DynamicMetaObject.EmptyMetaObjects);
        }
예제 #35
0
            public override DynamicMetaObject/*!*/ FallbackInvokeMember(DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args,
                DynamicMetaObject errorSuggestion) {

                var metaBuilder = new MetaObjectBuilder();
                var callArgs = new CallArguments(_context, target, args, CallInfo);

                if (!RubyCallAction.Build(metaBuilder, Name, callArgs, errorSuggestion == null)) {
                    Debug.Assert(errorSuggestion != null);
                    // method wasn't found so we didn't do any operation with arguments that would require restrictions converted to conditions:
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return metaBuilder.CreateMetaObject(this);
            }
예제 #36
0
            public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, GetIndexBinder/*!*/ binder, 
                DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ indexes,
                Func<DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject>/*!*/ fallback) {
                Debug.Assert(fallback != null);
                
                var callArgs = new CallArguments(context, target, indexes, RubyCallSignature.Interop(indexes.Length));
                var metaBuilder = new MetaObjectBuilder(target, indexes);

                if (!RubyCallAction.BuildCall(metaBuilder, "[]", callArgs, false, false)) {
                    metaBuilder.SetMetaResult(fallback(target, indexes), false);
                }

                return metaBuilder.CreateMetaObject(binder);
            }
예제 #37
0
 // TODO: convert binder
 internal static DynamicMetaObject TryBindCovertToDelegate(RubyMetaObject/*!*/ metaTarget, ConvertBinder/*!*/ binder, MethodInfo/*!*/ delegateFactory) {
     var metaBuilder = new MetaObjectBuilder();
     return TryBuildConversionToDelegate(metaBuilder, metaTarget, binder.Type, delegateFactory) ? metaBuilder.CreateMetaObject(binder) : null;
 }
예제 #38
0
            public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, GetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target, 
                Func<DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) {
                Debug.Assert(fallback != null);

                var metaBuilder = new MetaObjectBuilder();
                var callArgs = new CallArguments(context, target, DynamicMetaObject.EmptyMetaObjects, RubyCallSignature.Simple(0));
                
                RubyMemberInfo methodMissing;
                var method = RubyCallAction.Resolve(metaBuilder, binder.Name, callArgs, out methodMissing);

                if (method.Found) {
                    // create a bound member:
                    metaBuilder.Result = AstUtils.Constant(new RubyMethod(target.Value, method.Info, binder.Name));
                } else {
                    // TODO: support methodMissing
                    // we need to create a wrapper over methodMissing that has curried the method name and calls to methodMissing method:
                    return fallback(target);
                }

                return metaBuilder.CreateMetaObject(binder);
            }
예제 #39
0
            public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, SetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target,
                DynamicMetaObject/*!*/ value, Func<DynamicMetaObject, DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) {
                Debug.Assert(fallback != null);

                var args = new[] { value };
                var callArgs = new CallArguments(context, target, args, RubyCallSignature.Interop(1));
                var metaBuilder = new MetaObjectBuilder(target, args);

                if (!RubyCallAction.BuildCall(metaBuilder, binder.Name + "=", callArgs, false, false)) {
                    metaBuilder.SetMetaResult(fallback(target, value), false);
                }

                return metaBuilder.CreateMetaObject(binder);
            }
예제 #40
0
        private DynamicMetaObject/*!*/ InteropBind(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
            // TODO: argument count limit depends on the binder!

            // TODO: pass block as the last (before RHS arg?) parameter/ignore block if args not accepting block:
            var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, Int32.MaxValue);
            if (!metaBuilder.Error) {
                MethodInfo postConverter;
                var interopBinder = GetInteropBinder(args.RubyContext, normalizedArgs, out postConverter);
                if (interopBinder != null) {
                    Type resultType;
                    var result = interopBinder.Bind(args.MetaTarget, ArrayUtils.MakeArray(normalizedArgs));

                    metaBuilder.SetMetaResult(result, args);
                    if (postConverter != null) {
                        // TODO: do better?
                        var paramType = postConverter.GetParameters()[0].ParameterType;

                        metaBuilder.Result = Ast.Call(null, postConverter, AstUtils.Convert(metaBuilder.Result, paramType));
                        resultType = postConverter.ReturnType;
                    } else {
                        resultType = ((IInteropBinder)interopBinder).ResultType;
                    }

                    return metaBuilder.CreateMetaObject(interopBinder, resultType);
                } else {
                    metaBuilder.SetError(Ast.New(
                       typeof(NotSupportedException).GetConstructor(new[] { typeof(string) }),
                       Ast.Constant(String.Format("{0} not supported on foreign meta-objects", this))
                    ));
                }
            }
            return metaBuilder.CreateMetaObject(this);
        }
예제 #41
0
            public override DynamicMetaObject/*!*/ FallbackInvoke(DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, 
                DynamicMetaObject errorSuggestion) {

                // Used in combination with GetMember to compose InvokeMember operation.
                // Gets here only if the target is not a callable meta-object. 

                var metaBuilder = new MetaObjectBuilder(this, target, args);
                var callArgs = new CallArguments(_context, target, args, CallInfo);

                metaBuilder.AddTypeRestriction(target.GetLimitType(), target.Expression);

                var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, callArgs, 0, 0);
                if (!metaBuilder.Error) {
                    // no arguments => just return the target:
                    metaBuilder.Result = target.Expression;
                } else {
                    // any arguments found (expected none):
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }
                
                return metaBuilder.CreateMetaObject(this);
            }
예제 #42
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);
        }
예제 #43
0
            public override DynamicMetaObject/*!*/ FallbackGetMember(DynamicMetaObject/*!*/ target, DynamicMetaObject errorSuggestion) {
                if (_unmangled != null) {
                    // TODO: errorSuggestion?
                    return _unmangled.Bind(target, DynamicMetaObject.EmptyMetaObjects);
                }

#if !SILVERLIGHT
                DynamicMetaObject result;
                if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetMember(this, target, out result)) {
                    return result;
                }
#endif

                var metaBuilder = new MetaObjectBuilder(target);
                var callArgs = new CallArguments(_context, target, DynamicMetaObject.EmptyMetaObjects, _CallInfo);

                if (!RubyCallAction.BuildAccess(metaBuilder, _originalName ?? Name, callArgs, errorSuggestion == null, true)) {
                    Debug.Assert(errorSuggestion != null);
                    metaBuilder.SetMetaResult(errorSuggestion, false);
                }

                return metaBuilder.CreateMetaObject(this);
            }
예제 #44
0
            public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, SetIndexBinder/*!*/ binder,
                DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ indexes, DynamicMetaObject/*!*/ value,
                Func<DynamicMetaObject, DynamicMetaObject[], DynamicMetaObject, DynamicMetaObject>/*!*/ fallback) {
                Debug.Assert(fallback != null);

                var args = ArrayUtils.Append(indexes, value);
                var callArgs = new CallArguments(context, target, args,
                    new RubyCallSignature(indexes.Length, RubyCallFlags.IsInteropCall | RubyCallFlags.HasRhsArgument)
                );

                var metaBuilder = new MetaObjectBuilder(target, args);

                if (!RubyCallAction.BuildCall(metaBuilder, "[]=", callArgs, false, false)) {
                    metaBuilder.SetMetaResult(fallback(target, indexes, value), false);
                }

                return metaBuilder.CreateMetaObject(binder);
            }