clojure.lang.CljCompiler.Ast.MethodExpr.GenerateComplexArgList C# (CSharp) Метод

GenerateComplexArgList() статический приватный Метод

static private GenerateComplexArgList ( ObjExpr objx, GenContext context, List args, List &argExprs, List &sbParams, List &sbInits, List &sbTransfers ) : void
objx ObjExpr
context GenContext
args List
argExprs List
sbParams List
sbInits List
sbTransfers List
Результат void
        internal static void GenerateComplexArgList(
            ObjExpr objx,
            GenContext context,
            List<HostArg> args,
            out List<Expression> argExprs,
            out List<ParameterExpression> sbParams,
            out  List<Expression> sbInits,
            out List<Expression> sbTransfers)
        {
            argExprs = new List<Expression>(args.Count);
            sbParams = new List<ParameterExpression>();
            sbInits = new List<Expression>();
            sbTransfers = new List<Expression>();

            BindingFlags cflags = BindingFlags.Public | BindingFlags.Instance;

            foreach (HostArg ha in args)
            {
                Expr e = ha.ArgExpr;
                Type argType = e.HasClrType ? (e.ClrType ?? typeof(Object)) : typeof(Object);

                switch (ha.ParamType)
                {
                    case HostArg.ParameterType.ByRef:
                        {
            #if CLR2
                            Type sbType = typeof(MSC::System.Runtime.CompilerServices.StrongBox<>).MakeGenericType(argType);
            #else
                            Type sbType = typeof(System.Runtime.CompilerServices.StrongBox<>).MakeGenericType(argType);
            #endif

                            ParameterExpression sbParam = Expression.Parameter(sbType, String.Format("__sb_{0}", sbParams.Count));
                            //ConstructorInfo[] cinfos = sbType.GetConstructors();
                            Expression sbInit1 =
                                Expression.Assign(
                                    sbParam,
                                    Expression.New(
                                        sbType.GetConstructor(cflags, null, new Type[] { argType }, null),
                                        Expression.Convert(ha.LocalBinding.ParamExpression,argType)));
                            Expression sbXfer = Expression.Assign(ha.LocalBinding.ParamExpression, Expression.Field(sbParam, "Value"));
                            sbParams.Add(sbParam);
                            sbInits.Add(sbInit1);
                            sbTransfers.Add(sbXfer);
                            argExprs.Add(sbParam);
                        }
                        break;
                    case HostArg.ParameterType.Standard:
                        argExprs.Add(e.GenCode(RHC.Expression, objx, context));
                        break;

                    default:
                        throw Util.UnreachableCode();
                }
            }
        }

Usage Example

Пример #1
0
        // TODO: See if it is worth removing the code duplication with MethodExp.GenDlr.

        private Expression GenerateComplexCall(RHC rhc, ObjExpr objx, GenContext context)
        {
            Expression call;

            Expression target = GenTargetExpression(objx, context);

            List <Expression>          exprs       = new List <Expression>(_args.Count);
            List <ParameterExpression> sbParams    = new List <ParameterExpression>();
            List <Expression>          sbInits     = new List <Expression>();
            List <Expression>          sbTransfers = new List <Expression>();

            MethodExpr.GenerateComplexArgList(objx, context, _args, out exprs, out sbParams, out sbInits, out sbTransfers);

            Expression[] argExprs = ClrExtensions.ArrayInsert <Expression>(target, exprs);


            Type returnType = this.ClrType;
            Type stubType   = Compiler.CompileStubOrigClassVar.isBound ? (Type)Compiler.CompileStubOrigClassVar.deref() : null;

            if (returnType == stubType)
            {
                returnType = objx.BaseType;
            }

            // TODO: get rid of Default
            CreateInstanceBinder binder = new ClojureCreateInstanceBinder(ClojureContext.Default, _args.Count);
            DynamicExpression    dyn    = Expression.Dynamic(binder, typeof(object), argExprs);

            // I'd like to use returnType in place of typeof(object) in the previous,
            // But I can't override ReturnType in DefaultCreateInstanceBinder and this causes an error.
            // Look for the conversion below.

            //if (context.Mode == CompilerMode.File)
            if (context.DynInitHelper != null)
            {
                call = context.DynInitHelper.ReduceDyn(dyn);
            }
            else
            {
                call = dyn;
            }

            call = Expression.Convert(call, returnType);

            if (sbParams.Count > 0)
            {
                // We have ref/out params.  Construct the complicated call;

                ParameterExpression   callValParam = Expression.Parameter(returnType, "__callVal");
                ParameterExpression[] allParams    = ClrExtensions.ArrayInsert <ParameterExpression>(callValParam, sbParams);

                call = Expression.Block(
                    returnType,
                    allParams,
                    Expression.Block(sbInits),
                    Expression.Assign(callValParam, call),
                    Expression.Block(sbTransfers),
                    callValParam);
            }

            return(call);
        }