Boo.Lang.Compiler.Steps.ImplementICallableOnCallableDefinitions.ImplementByRefICallableCall C# (CSharp) Method

ImplementByRefICallableCall() private method

private ImplementByRefICallableCall ( Method call, InternalCallableType type, ClassDefinition node, CallableSignature signature, int byRefCount ) : void
call Boo.Lang.Compiler.Ast.Method
type Boo.Lang.Compiler.TypeSystem.InternalCallableType
node Boo.Lang.Compiler.Ast.ClassDefinition
signature Boo.Lang.Compiler.TypeSystem.CallableSignature
byRefCount int
return void
        void ImplementByRefICallableCall(
            Method call,
            InternalCallableType type,
            ClassDefinition node,
            CallableSignature signature,
            int byRefCount)
        {
            MethodInvocationExpression mie = CreateInvokeInvocation(type);
            IParameter[] parameters = signature.Parameters;
            ReferenceExpression args = CodeBuilder.CreateReference(call.Parameters[0]);
            InternalLocal[] temporaries = new InternalLocal[byRefCount];

            int byRefIndex = 0;
            for (int i=0; i<parameters.Length; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(args.CloneNode(), i);

                IParameter parameter = parameters[i];
                if (parameter.IsByRef)
                {
                    IType tempType = parameter.Type;
                    if (tempType.IsByRef)
                    {
                        tempType = tempType.GetElementType();
                    }
                    temporaries[byRefIndex] = CodeBuilder.DeclareLocal(call,
                                "__temp_" + parameter.Name,
                                tempType);

                    call.Body.Add(
                        CodeBuilder.CreateAssignment(
                        CodeBuilder.CreateReference(temporaries[byRefIndex]),
                            CodeBuilder.CreateCast(
                                tempType,
                                slice)));

                    mie.Arguments.Add(
                        CodeBuilder.CreateReference(
                            temporaries[byRefIndex]));

                    ++byRefIndex;
                }
                else
                {
                    mie.Arguments.Add(slice);
                }
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
                PropagateByRefParameterChanges(call, parameters, temporaries);
            }
            else
            {
                InternalLocal invokeReturnValue = CodeBuilder.DeclareLocal(call,
                            "__returnValue", signature.ReturnType);
                call.Body.Add(
                    CodeBuilder.CreateAssignment(
                        CodeBuilder.CreateReference(invokeReturnValue),
                        mie));
                PropagateByRefParameterChanges(call, parameters, temporaries);
                call.Body.Add(
                    new ReturnStatement(
                        CodeBuilder.CreateReference(invokeReturnValue)));
            }
        }