/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.ir.transform.expression;
import gw.internal.gosu.parser.expressions.BlockInvocation;
import gw.lang.ir.IRElement;
import gw.lang.ir.IRExpression;
import gw.internal.gosu.ir.transform.ExpressionTransformer;
import gw.internal.gosu.ir.transform.TopLevelTransformationContext;
import gw.internal.gosu.compiler.FunctionClassUtil;
import gw.lang.ir.expression.IRCompositeExpression;
import gw.lang.parser.IExpression;
import gw.lang.reflect.IType;
import gw.lang.reflect.java.IJavaClassInfo;
import gw.lang.reflect.java.IJavaType;
import java.util.ArrayList;
import java.util.List;
public class BlockInvocationTransformer extends AbstractExpressionTransformer<BlockInvocation>
{
public static IRExpression compile( TopLevelTransformationContext cc, BlockInvocation expr )
{
BlockInvocationTransformer compiler = new BlockInvocationTransformer( cc, expr );
return compiler.compile();
}
private BlockInvocationTransformer( TopLevelTransformationContext cc, BlockInvocation expr )
{
super( cc, expr );
}
protected IRExpression compile_impl()
{
List<IRExpression> explicitArgs = boxArgs();
List<IRElement> callElements = handleNamedArgs( explicitArgs, _expr().getNamedArgOrder() );
IRExpression root = ExpressionTransformer.compile( _expr().getRoot(), _cc() );
IJavaType interfaceForArity = FunctionClassUtil.getFunctionInterfaceForArity(_expr().getArgs().size());
IRExpression call = callMethod(interfaceForArity.getBackingClassInfo(),
"invoke", FunctionClassUtil.getArgArrayForArity(_expr().getArgs().size()),
root, explicitArgs);
IType returnType = _expr().getType();
if( returnType.isPrimitive() )
{
call = unboxValueToType( returnType, call );
}
else
{
call = checkCast( returnType, call );
}
if( callElements.size() > 0 )
{
// Include temp var assignments so named args are evaluated in lexical order before the call
callElements.add( call );
call = new IRCompositeExpression( callElements );
}
return call;
}
private List<IRExpression> boxArgs()
{
List<IRExpression> irArgs = new ArrayList<IRExpression>();
for( IExpression arg : _expr().getArgs() )
{
IRExpression irArg = ExpressionTransformer.compile( arg, _cc() );
irArgs.add( boxValue( arg.getType(), irArg ) );
}
return irArgs;
}
}