// 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);
}