GetBlock() публичный Метод

public GetBlock ( ) : Proc
Результат IronRuby.Builtins.Proc
Пример #1
0
        private static Type[] /*!*/ GetSignatureToMatch(CallArguments /*!*/ args, bool includeSelf, bool selfIsInstance)
        {
            var result = new List <Type>(args.ExplicitArgumentCount);

            // self (instance):
            if (includeSelf && selfIsInstance)
            {
                result.Add(CompilerHelpers.GetType(args.Target));
            }

            // block:
            if (args.Signature.HasBlock)
            {
                // use None to let binder know that [NotNull]BlockParam is not applicable
                result.Add(args.GetBlock() != null ? typeof(BlockParam) : typeof(Null));
            }
            else
            {
                result.Add(typeof(MissingBlockParam));
            }

            // self (non-instance):
            if (includeSelf && !selfIsInstance)
            {
                result.Add(CompilerHelpers.GetType(args.Target));
            }

            // simple args:
            for (int i = 0; i < args.SimpleArgumentCount; i++)
            {
                result.Add(CompilerHelpers.GetType(args.GetSimpleArgument(i)));
            }

            // splat arg:
            if (args.Signature.HasSplattedArgument)
            {
                object splattedArg = args.GetSplattedArgument();

                var list = splattedArg as List <object>;
                if (list != null)
                {
                    foreach (object obj in list)
                    {
                        result.Add(CompilerHelpers.GetType(obj));
                    }
                }
                else
                {
                    result.Add(CompilerHelpers.GetType(splattedArg));
                }
            }

            // rhs arg:
            if (args.Signature.HasRhsArgument)
            {
                result.Add(CompilerHelpers.GetType(args.GetRhsArgument()));
            }

            return(result.ToArray());
        }
Пример #2
0
        /// <summary>
        /// Resolves an library method overload and builds call expression.
        /// The resulting expression on meta-builder doesn't handle block control flow yet.
        /// </summary>
        internal static void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name,
                                             IList <MethodBase> /*!*/ overloads, bool includeSelf, bool selfIsInstance)
        {
            var bindingTarget = ResolveOverload(name, overloads, args, includeSelf, selfIsInstance);

            if (bindingTarget.Success)
            {
                bool calleeHasBlockParam = HasBlockParameter(bindingTarget.Method);

                // Allocates a variable holding BlockParam. At runtime the BlockParam is created with a new RFC instance that
                // identifies the library method frame as a proc-converter target of a method unwinder triggered by break from a block.
                //
                // NOTE: We check for null block here -> test fore that fact is added in MakeActualArgs
                if (metaBuilder.BfcVariable == null && args.Signature.HasBlock && args.GetBlock() != null && calleeHasBlockParam)
                {
                    metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
                }

                var actualArgs       = MakeActualArgs(metaBuilder, args, includeSelf, selfIsInstance, calleeHasBlockParam, true);
                var parameterBinder  = new RubyParameterBinder(args.RubyContext.Binder, args.MetaContext.Expression, args.Signature.HasScope);
                var targetExpression = bindingTarget.MakeExpression(parameterBinder, actualArgs);

                metaBuilder.Result = targetExpression;
            }
            else
            {
                metaBuilder.SetError(
                    Methods.MakeInvalidArgumentTypesError.OpCall(Ast.Constant(name))
                    );
            }
        }
        // Creates actual/normalized arguments: inserts self, expands splats, and inserts rhs arg.
        // Adds any restrictions/conditions applied to the arguments to the given meta-builder.
        protected override ActualArguments CreateActualArguments(IList <DynamicMetaObject> namedArgs, IList <string> argNames, int preSplatLimit, int postSplatLimit)
        {
            var result = new List <DynamicMetaObject>();

            // self (instance):
            if (_callConvention == SelfCallConvention.SelfIsInstance)
            {
                result.Add(_args.MetaTarget);
            }

            if (_args.Signature.HasBlock)
            {
                if (_args.GetBlock() == null)
                {
                    // the user explicitly passed nil as a block arg:
                    result.Add(NullMetaBlockParam);
                }
                else
                {
                    // pass BlockParam:
                    if (_metaBuilder.BfcVariable == null)
                    {
                        // we add temporary even though we might not us it if the calee doesn't have block param arg:
                        _metaBuilder.BfcVariable = _metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
                    }
                    result.Add(new DynamicMetaObject(_metaBuilder.BfcVariable, BindingRestrictions.Empty));
                }
            }
            else
            {
                // no block passed into a method with a BlockParam:
                result.Add(MissingBlockParam.Meta.Instance);
            }

            // self (parameter):
            if (_callConvention == SelfCallConvention.SelfIsParameter)
            {
                result.Add(_args.MetaTarget);
            }

            // the next argument is the first one for which we use restrictions coming from overload resolution:
            _firstRestrictedArg = result.Count;

            // hidden args: block, self
            int hidden = _callConvention == SelfCallConvention.NoSelf ? 1 : 2;

            return(CreateActualArguments(result, _metaBuilder, _args, hidden, preSplatLimit, postSplatLimit, out _lastSplattedArg, out _list, out _listVariable));
        }
Пример #4
0
        private static Type[]/*!*/ GetSignatureToMatch(CallArguments/*!*/ args, bool includeSelf, bool selfIsInstance) {
            var result = new List<Type>(args.ExplicitArgumentCount);

            // self (instance):
            if (includeSelf && selfIsInstance) {
                result.Add(CompilerHelpers.GetType(args.Target));
            }

            // block:
            if (args.Signature.HasBlock) {
                // use None to let binder know that [NotNull]BlockParam is not applicable
                result.Add(args.GetBlock() != null ? typeof(BlockParam) : typeof(Null));
            } else {
                result.Add(typeof(MissingBlockParam));
            }

            // self (non-instance):
            if (includeSelf && !selfIsInstance) {
                result.Add(CompilerHelpers.GetType(args.Target));
            }

            // simple args:
            for (int i = 0; i < args.SimpleArgumentCount; i++) {
                result.Add(CompilerHelpers.GetType(args.GetSimpleArgument(i)));
            }

            // splat arg:
            if (args.Signature.HasSplattedArgument) {
                object splattedArg = args.GetSplattedArgument();
                
                var list = splattedArg as List<object>;
                if (list != null) {
                    foreach (object obj in list) {
                        result.Add(CompilerHelpers.GetType(obj));
                    }
                } else {
                    result.Add(CompilerHelpers.GetType(splattedArg));
                }
            }

            // rhs arg:
            if (args.Signature.HasRhsArgument) {
                result.Add(CompilerHelpers.GetType(args.GetRhsArgument()));
            }

            return result.ToArray();
        }
Пример #5
0
        public static Expression[]/*!*/ MakeActualArgs(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args,
            bool includeSelf, bool selfIsInstance, bool calleeHasBlockParam, bool injectMissingBlockParam) {

            var actualArgs = new List<Expression>(args.ExplicitArgumentCount);

            // self (instance):
            if (includeSelf && selfIsInstance) {
                // test already added by method resolver
                Debug.Assert(args.TargetExpression != null);
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            Proc block = null;
            Expression blockExpression = null;

            // block test - we need to test for a block regardless of whether it is actually passed to the method or not
            // since the information that the block is not null is used for overload resolution.
            if (args.Signature.HasBlock) {
                block = args.GetBlock();
                blockExpression = args.GetBlockExpression();

                if (block == null) {
                    metaBuilder.AddRestriction(Ast.Equal(blockExpression, Ast.Constant(null)));
                } else {
                    // don't need to test the exact type of the Proc since the code is subclass agnostic:
                    metaBuilder.AddRestriction(Ast.NotEqual(blockExpression, Ast.Constant(null)));
                }
            }

            // block:
            if (calleeHasBlockParam) {
                if (args.Signature.HasBlock) {
                    if (block == null) {
                        // the user explicitly passed nil as a block arg:
                        actualArgs.Add(Ast.Constant(null));
                    } else {
                        // pass BlockParam:
                        Debug.Assert(metaBuilder.BfcVariable != null);
                        actualArgs.Add(metaBuilder.BfcVariable);
                    }
                } else {
                    // no block passed into a method with a BlockParam:
                    actualArgs.Add(Ast.Constant(null));
                }
            } else if (injectMissingBlockParam) {
                // no block passed into a method w/o a BlockParam (we still need to fill the missing block argument):
                actualArgs.Add(Ast.Constant(null));
            }

            // self (non-instance):
            if (includeSelf && !selfIsInstance) {
                // test already added by method resolver
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            // simple arguments:
            for (int i = 0; i < args.SimpleArgumentCount; i++) {
                var value = args.GetSimpleArgument(i);
                var expr = args.GetSimpleArgumentExpression(i);

                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            // splat argument:
            int listLength;
            ParameterExpression listVariable;
            if (args.Signature.HasSplattedArgument) {
                object splattedArg = args.GetSplattedArgument();
                Expression splattedArgExpression = args.GetSplattedArgumentExpression();

                if (metaBuilder.AddSplattedArgumentTest(splattedArg, splattedArgExpression, out listLength, out listVariable)) {

                    // AddTestForListArg only returns 'true' if the argument is a List<object>
                    var list = (List<object>)splattedArg;

                    // get arguments, add tests
                    for (int j = 0; j < listLength; j++) {
                        var value = list[j];
                        var expr = Ast.Call(listVariable, typeof(List<object>).GetMethod("get_Item"), Ast.Constant(j));

                        metaBuilder.AddObjectTypeCondition(value, expr);
                        AddArgument(actualArgs, value, expr);
                    }

                } else {
                    // argument is not an array => add the argument itself:
                    AddArgument(actualArgs, splattedArg, splattedArgExpression);
                }
            }

            // rhs argument:
            if (args.Signature.HasRhsArgument) {
                var value = args.GetRhsArgument();
                var expr = args.GetRhsArgumentExpression();

                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            return actualArgs.ToArray();
        }
Пример #6
0
        /// <summary>
        /// Resolves an library method overload and builds call expression.
        /// The resulting expression on meta-builder doesn't handle block control flow yet.
        /// </summary>
        internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name, 
            IList<MethodBase>/*!*/ overloads, bool includeSelf, bool selfIsInstance) {

            var bindingTarget = ResolveOverload(name, overloads, args, includeSelf, selfIsInstance);
            if (bindingTarget.Success) {
                bool calleeHasBlockParam = HasBlockParameter(bindingTarget.Method);

                // Allocates a variable holding BlockParam. At runtime the BlockParam is created with a new RFC instance that
                // identifies the library method frame as a proc-converter target of a method unwinder triggered by break from a block.
                //
                // NOTE: We check for null block here -> test fore that fact is added in MakeActualArgs
                if (metaBuilder.BfcVariable == null && args.Signature.HasBlock && args.GetBlock() != null && calleeHasBlockParam) {
                    metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
                }

                var actualArgs = MakeActualArgs(metaBuilder, args, includeSelf, selfIsInstance, calleeHasBlockParam, true);
                var parameterBinder = new RubyParameterBinder(args.RubyContext.Binder, args.MetaContext.Expression, args.Signature.HasScope);
                var targetExpression = bindingTarget.MakeExpression(parameterBinder, actualArgs);

                metaBuilder.Result = targetExpression;
            } else {
                metaBuilder.SetError(
                    Methods.MakeInvalidArgumentTypesError.OpCall(Ast.Constant(name))
                );
            }
        }
Пример #7
0
        public static Expression[] /*!*/ MakeActualArgs(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args,
                                                        bool includeSelf, bool selfIsInstance, bool calleeHasBlockParam, bool injectMissingBlockParam)
        {
            var actualArgs = new List <Expression>(args.ExplicitArgumentCount);

            // self (instance):
            if (includeSelf && selfIsInstance)
            {
                // test already added by method resolver
                Debug.Assert(args.TargetExpression != null);
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            Proc       block           = null;
            Expression blockExpression = null;

            // block test - we need to test for a block regardless of whether it is actually passed to the method or not
            // since the information that the block is not null is used for overload resolution.
            if (args.Signature.HasBlock)
            {
                block           = args.GetBlock();
                blockExpression = args.GetBlockExpression();

                if (block == null)
                {
                    metaBuilder.AddRestriction(Ast.Equal(blockExpression, Ast.Constant(null)));
                }
                else
                {
                    // don't need to test the exact type of the Proc since the code is subclass agnostic:
                    metaBuilder.AddRestriction(Ast.NotEqual(blockExpression, Ast.Constant(null)));
                }
            }

            // block:
            if (calleeHasBlockParam)
            {
                if (args.Signature.HasBlock)
                {
                    if (block == null)
                    {
                        // the user explicitly passed nil as a block arg:
                        actualArgs.Add(Ast.Constant(null));
                    }
                    else
                    {
                        // pass BlockParam:
                        Debug.Assert(metaBuilder.BfcVariable != null);
                        actualArgs.Add(metaBuilder.BfcVariable);
                    }
                }
                else
                {
                    // no block passed into a method with a BlockParam:
                    actualArgs.Add(Ast.Constant(null));
                }
            }
            else if (injectMissingBlockParam)
            {
                // no block passed into a method w/o a BlockParam (we still need to fill the missing block argument):
                actualArgs.Add(Ast.Constant(null));
            }

            // self (non-instance):
            if (includeSelf && !selfIsInstance)
            {
                // test already added by method resolver
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            // simple arguments:
            for (int i = 0; i < args.SimpleArgumentCount; i++)
            {
                var value = args.GetSimpleArgument(i);
                var expr  = args.GetSimpleArgumentExpression(i);

                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            // splat argument:
            int listLength;
            ParameterExpression listVariable;

            if (args.Signature.HasSplattedArgument)
            {
                object     splattedArg           = args.GetSplattedArgument();
                Expression splattedArgExpression = args.GetSplattedArgumentExpression();

                if (metaBuilder.AddSplattedArgumentTest(splattedArg, splattedArgExpression, out listLength, out listVariable))
                {
                    // AddTestForListArg only returns 'true' if the argument is a List<object>
                    var list = (List <object>)splattedArg;

                    // get arguments, add tests
                    for (int j = 0; j < listLength; j++)
                    {
                        var value = list[j];
                        var expr  = Ast.Call(listVariable, typeof(List <object>).GetMethod("get_Item"), Ast.Constant(j));

                        metaBuilder.AddObjectTypeCondition(value, expr);
                        AddArgument(actualArgs, value, expr);
                    }
                }
                else
                {
                    // argument is not an array => add the argument itself:
                    AddArgument(actualArgs, splattedArg, splattedArgExpression);
                }
            }

            // rhs argument:
            if (args.Signature.HasRhsArgument)
            {
                var value = args.GetRhsArgument();
                var expr  = args.GetRhsArgumentExpression();

                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            return(actualArgs.ToArray());
        }
Пример #8
0
        // TODO: OBSOLETE
        private static Expression[]/*!*/ MakeActualArgs(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args,
            SelfCallConvention callConvention, bool calleeHasBlockParam, bool injectMissingBlockParam) {

            var actualArgs = new List<Expression>();

            // self (instance):
            if (callConvention == SelfCallConvention.SelfIsInstance) {
                // test already added by method resolver
                Debug.Assert(args.TargetExpression != null);
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            // block:
            if (calleeHasBlockParam) {
                if (args.Signature.HasBlock) {
                    if (args.GetBlock() == null) {
                        // the user explicitly passed nil as a block arg:
                        actualArgs.Add(AstUtils.Constant(null));
                    } else {
                        // pass BlockParam:
                        Debug.Assert(metaBuilder.BfcVariable != null);
                        actualArgs.Add(metaBuilder.BfcVariable);
                    }
                } else {
                    // no block passed into a method with a BlockParam:
                    actualArgs.Add(AstUtils.Constant(null));
                }
            } else if (injectMissingBlockParam) {
                // no block passed into a method w/o a BlockParam (we still need to fill the missing block argument):
                actualArgs.Add(AstUtils.Constant(null));
            }

            // self (non-instance):
            if (callConvention == SelfCallConvention.SelfIsParameter) {
                // test already added by method resolver
                AddArgument(actualArgs, args.Target, args.TargetExpression);
            }

            // simple arguments:
            for (int i = 0; i < args.SimpleArgumentCount; i++) {
                var value = args.GetSimpleArgument(i);
                var expr = args.GetSimpleArgumentExpression(i);

                // TODO: overload-resolution restrictions
                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            // splat argument:
            int listLength;
            ParameterExpression listVariable;
            if (args.Signature.HasSplattedArgument) {
                object splattedArg = args.GetSplattedArgument();
                Expression splattedArgExpression = args.GetSplattedArgumentExpression();

                if (metaBuilder.AddSplattedArgumentTest(splattedArg, splattedArgExpression, out listLength, out listVariable)) {

                    // AddTestForListArg only returns 'true' if the argument is a List<object>
                    var list = (List<object>)splattedArg;

                    // get arguments, add tests
                    for (int j = 0; j < listLength; j++) {
                        var value = list[j];
                        var expr = Ast.Call(listVariable, typeof(List<object>).GetMethod("get_Item"), AstUtils.Constant(j));

                        // TODO: overload-resolution restrictions
                        metaBuilder.AddObjectTypeCondition(value, expr);
                        AddArgument(actualArgs, value, expr);
                    }

                } else {
                    // argument is not an array => add the argument itself:
                    AddArgument(actualArgs, splattedArg, splattedArgExpression);
                }
            }

            // rhs argument:
            if (args.Signature.HasRhsArgument) {
                var value = args.GetRhsArgument();
                var expr = args.GetRhsArgumentExpression();

                // TODO: overload-resolution restrictions
                metaBuilder.AddObjectTypeRestriction(value, expr);
                AddArgument(actualArgs, value, expr);
            }

            return actualArgs.ToArray();
        }