private Expression GenerateComplexCall(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>();
GenerateComplexArgList(objx, context, _args, out exprs, out sbParams, out sbInits, out sbTransfers);
Expression[] argExprs = ClrExtensions.ArrayInsert<Expression>(target, exprs);
Type returnType = HasClrType ? ClrType : typeof(object);
// TODO: Get rid of Default
InvokeMemberBinder binder = new ClojureInvokeMemberBinder(ClojureContext.Default,_methodName, argExprs.Length, IsStaticCall);
//DynamicExpression dyn = Expression.Dynamic(binder, returnType, argExprs);
DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), argExprs);
//if (context.Mode == CompilerMode.File)
if ( context.DynInitHelper != null )
call = context.DynInitHelper.ReduceDyn(dyn);
else
call = dyn;
if (returnType == typeof(void))
call = Expression.Block(call, Expression.Default(typeof(object)));
else
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;
}