/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.ir.transform.expression;
import gw.internal.gosu.parser.expressions.TemplateStringLiteral;
import gw.lang.ir.IRExpression;
import gw.lang.ir.IRSymbol;
import gw.lang.ir.IRType;
import gw.lang.ir.IRStatement;
import gw.lang.ir.IRTypeConstants;
import gw.lang.ir.expression.IRStringLiteralExpression;
import gw.lang.ir.expression.IRMethodCallExpression;
import gw.lang.ir.expression.IRCompositeExpression;
import gw.lang.ir.statement.IRAssignmentStatement;
import gw.internal.gosu.ir.transform.TopLevelTransformationContext;
import gw.lang.parser.expressions.IProgram;
import gw.util.Stack;
import java.util.Collections;
/**
*/
public class TemplateStringLiteralTransformer extends AbstractExpressionTransformer<TemplateStringLiteral>
{
private static final ThreadLocal<Stack<IRSymbol>> SYMBOL_STACK = new ThreadLocal<Stack<IRSymbol>>();
public static IRExpression compile( TopLevelTransformationContext cc, TemplateStringLiteral expr )
{
TemplateStringLiteralTransformer compiler = new TemplateStringLiteralTransformer( cc, expr );
return compiler.compile();
}
private TemplateStringLiteralTransformer( TopLevelTransformationContext cc, TemplateStringLiteral expr )
{
super( cc, expr );
}
protected IRExpression compile_impl()
{
TemplateStringLiteral stringLiteral = _expr();
IProgram iProgram = stringLiteral.getProgram();
if( iProgram != null )
{
IRCompositeExpression template = new IRCompositeExpression();
IRType sbType = getDescriptor( StringBuilder.class );
IRSymbol symbol = _cc().makeAndIndexTempSymbol( sbType );
try
{
getThreadLocalStack().push( symbol );
// instantiate and store a string builder
IRAssignmentStatement sbAssignment = buildAssignment( symbol, buildNewExpression( sbType, Collections.<IRType>emptyList(), Collections.EMPTY_LIST ) );
template.addElement( sbAssignment );
sbAssignment.setImplicit( true );
// invoke the body
IRStatement templateBody = _cc().compile( iProgram.getMainStatement() );
template.addElement( templateBody );
templateBody.setImplicit( true );
// invoke toString on the string builder
IRMethodCallExpression toString = buildMethodCall( sbType, "toString", false, IRTypeConstants.STRING(), Collections.EMPTY_LIST, identifier( symbol ), Collections.EMPTY_LIST );
template.addElement( toString );
template.setImplicit( true );
return template;
}
finally
{
getThreadLocalStack().pop();
}
}
else
{
return new IRStringLiteralExpression( "Unsupported Template");
}
}
private static Stack<IRSymbol> getThreadLocalStack()
{
Stack<IRSymbol> symbolStack = SYMBOL_STACK.get();
if( symbolStack == null )
{
symbolStack = new Stack<IRSymbol>();
SYMBOL_STACK.set( symbolStack );
}
return symbolStack;
}
public static IRSymbol getCurrentTemplateSymbol()
{
return getThreadLocalStack().peek();
}
}