IronRuby.Runtime.Calls.ArgsBuilder.AddCallArguments C# (CSharp) Method

AddCallArguments() public method

public AddCallArguments ( MetaObjectBuilder metaBuilder, CallArguments args ) : void
metaBuilder MetaObjectBuilder
args CallArguments
return void
        public void AddCallArguments(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
            _callArguments = args;

            // calculate actual argument count:
            _actualArgumentCount = args.SimpleArgumentCount;
            if (args.Signature.HasSplattedArgument) {
                var splattedArg = args.GetSplattedMetaArgument();
                metaBuilder.AddSplattedArgumentTest((IList)splattedArg.Value, splattedArg.Expression, out _listLength, out _listVariable);
                _actualArgumentCount += _listLength;
            }
            if (args.Signature.HasRhsArgument) {
                _actualArgumentCount++;
            }

            // check:
            if (HasTooFewArguments) {
                metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount);
                return;
            }

            if (HasTooManyArguments) {
                metaBuilder.SetWrongNumberOfArgumentsError(_actualArgumentCount, _mandatoryParamCount);
                return;
            }

            bool isSplatted;

            // leading mandatory:
            for (int i = 0; i < _leadingMandatoryParamCount; i++) {
                _arguments[LeadingMandatoryIndex + i] = GetArgument(i, out isSplatted);
            }

            // trailing mandatory:
            for (int i = 0; i < TrailingMandatoryCount; i++) {
                _arguments[TrailingMandatoryIndex + i] = GetArgument(_actualArgumentCount - TrailingMandatoryCount + i, out isSplatted);
            }

            int start = _leadingMandatoryParamCount;
            int end = _actualArgumentCount - TrailingMandatoryCount;

            // optional:
            for (int i = 0; i < _optionalParamCount; i++) {
                _arguments[OptionalParameterIndex + i] = (start < end) ? GetArgument(start++, out isSplatted) : Ast.Field(null, Fields.DefaultArgument);
            }

            // unsplat:
            if (_hasUnsplatParameter) {
                Expression array;
                if (args.Signature.HasSplattedArgument) {
                    // simple:
                    var argsToUnsplat = new List<Expression>();
                    while (start < end) {
                        var arg = GetArgument(start, out isSplatted);
                        if (isSplatted) {
                            break;
                        }
                        argsToUnsplat.Add(AstUtils.Box(arg));
                        start++;
                    }
                    array = Methods.MakeArrayOpCall(argsToUnsplat);
                    
                    int rangeStart = start - args.SimpleArgumentCount;
                    int rangeLength = Math.Min(end - start, _listLength - rangeStart);

                    // splatted:
                    if (rangeLength > 0) {
                        array = Methods.AddSubRange.OpCall(array, _listVariable, Ast.Constant(rangeStart), Ast.Constant(rangeLength));
                        start += rangeLength;
                    }

                    // rhs:
                    while (start < end) {
                        array = Methods.AddItem.OpCall(array, AstUtils.Box(GetArgument(start, out isSplatted)));
                        start++;
                    }
                } else {
                    var argsToUnsplat = new List<Expression>(end - start);
                    while (start < end) {
                        argsToUnsplat.Add(AstUtils.Box(GetArgument(start++, out isSplatted)));
                    }
                    array = Methods.MakeArrayOpCall(argsToUnsplat);
                }

                _arguments[UnsplatParameterIndex] = array;
            }

            _callArguments = null;
            _listVariable = null;
            Debug.Assert(CollectionUtils.TrueForAll(_arguments, (e) => e != null));
        }
    }

Usage Example

Beispiel #1
0
        internal override void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name)
        {
            Assert.NotNull(metaBuilder, args, name);

            // 2 implicit args: self, block
            var argsBuilder = new ArgsBuilder(2, Parameters.Mandatory.Length, Parameters.LeadingMandatoryCount, Parameters.Optional.Length, Parameters.Unsplat != null);

            argsBuilder.SetImplicit(0, AstUtils.Box(args.TargetExpression));
            argsBuilder.SetImplicit(1, args.Signature.HasBlock ? AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)) : AstFactory.NullOfProc);
            argsBuilder.AddCallArguments(metaBuilder, args);

            if (metaBuilder.Error)
            {
                return;
            }

            // box explicit arguments:
            var boxedArguments = argsBuilder.GetArguments();

            for (int i = 2; i < boxedArguments.Length; i++)
            {
                boxedArguments[i] = AstUtils.Box(boxedArguments[i]);
            }

            var method = GetDelegate();

            if (method.GetType() == ParamsArrayDelegateType)
            {
                // Func<object, Proc, object[], object>
                metaBuilder.Result = AstFactory.CallDelegate(method, new[] {
                    boxedArguments[0],
                    boxedArguments[1],
                    Ast.NewArrayInit(typeof(object), ArrayUtils.ShiftLeft(boxedArguments, 2))
                });
            }
            else
            {
                metaBuilder.Result = AstFactory.CallDelegate(method, boxedArguments);
            }
        }
All Usage Examples Of IronRuby.Runtime.Calls.ArgsBuilder::AddCallArguments