/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.ir.transform.statement;
import gw.internal.gosu.parser.statements.MapAssignmentStatement;
import gw.lang.ir.IRStatement;
import gw.lang.ir.IRExpression;
import gw.internal.gosu.ir.transform.ExpressionTransformer;
import gw.internal.gosu.ir.transform.TopLevelTransformationContext;
import gw.lang.reflect.TypeSystem;
import gw.lang.reflect.java.JavaTypes;
import java.util.AbstractMap;
import java.util.Map;
/**
*/
public class MapAssignmentStatementTransformer extends AbstractStatementTransformer<MapAssignmentStatement>
{
public static IRStatement compile( TopLevelTransformationContext cc, MapAssignmentStatement stmt )
{
MapAssignmentStatementTransformer gen = new MapAssignmentStatementTransformer( cc, stmt );
return gen.compile();
}
private MapAssignmentStatementTransformer( TopLevelTransformationContext cc, MapAssignmentStatement stmt )
{
super( cc, stmt );
}
@Override
protected IRStatement compile_impl()
{
// Push the Map value
IRExpression root = ExpressionTransformer.compile( _stmt().getMapAccessExpression().getRootExpression(), _cc() );
// Null check
// Label endLabel = new Label();
// mv.visitInsn( Opcodes.DUP );
// Label nullLabel = new Label();
// mv.visitJumpInsn( Opcodes.IFNULL, nullLabel );
// Call Map.put( k, v )
Class clsMap = getMapType();
IRExpression key = ExpressionTransformer.compile( _stmt().getMapAccessExpression().getKeyExpression(), _cc() );
IRExpression value = ExpressionTransformer.compile( _stmt().getExpression(), _cc() );
IRExpression putCall = callMethod( clsMap, "put", new Class[]{Object.class, Object.class},
root,
exprList( key, value ) );
return buildMethodCall( putCall );
// mv.visitInsn( Opcodes.POP ); // put returns a value, so it must be popped
// mv.visitJumpInsn( Opcodes.GOTO, endLabel );
// Throw exception for null map
// mv.visitLabel( nullLabel );
// mv.visitInsn( Opcodes.POP );
// pushConstant( "Null reference for map." );
// callStaticMethod( EvaluationException.class, "create", String.class );
// mv.visitInsn( Opcodes.ATHROW );
//
// mv.visitLabel( endLabel );
}
private Class getMapType()
{
Class clsMap;
if( JavaTypes.getJreType(AbstractMap.class).isAssignableFrom( _stmt().getMapAccessExpression().getRootExpression().getType() ) )
{
// Use class instead of interface i.e., invokevirtual is faster than invokeinterface
clsMap = AbstractMap.class;
}
else
{
clsMap = Map.class;
}
return clsMap;
}}