/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.ir.transform; import gw.internal.gosu.parser.DynamicFunctionSymbol; import gw.internal.gosu.parser.TypeVariableType; import gw.lang.ir.IRSymbol; import gw.lang.ir.IRType; import gw.lang.parser.Keyword; import gw.util.Stack; import java.util.List; /** */ public class FunctionBodyTransformationContext { public static final String TEMP_VAR_PREFIX = "*temp"; private int _tempVarCount = 0; private Stack<IRScope> _scopes; private ConstructorState _constructorState; protected TopLevelTransformationContext _context; private boolean _isStatic; public FunctionBodyTransformationContext(TopLevelTransformationContext context, boolean isStatic) { _context = context; _isStatic = isStatic; } private enum ConstructorState { PRE_SUPER, SUPER_INVOKED, CLEAR } public void updateSuperInvokedAfterLastExpressionCompiles() { if( _constructorState == ConstructorState.SUPER_INVOKED ) { _constructorState = ConstructorState.CLEAR; } } public boolean hasSuperBeenInvoked() { return _constructorState == ConstructorState.CLEAR; } public void markSuperInvoked() { _constructorState = ConstructorState.SUPER_INVOKED; } public IRSymbol makeAndIndexTempSymbol( IRType type ) { return makeAndIndexTempSymbol( null, type ); } public IRSymbol makeAndIndexTempSymbol( String strNameSuffix, IRType type ) { String strName = strNameSuffix != null ? TEMP_VAR_PREFIX + strNameSuffix : TEMP_VAR_PREFIX + _tempVarCount++; IRSymbol symbol = new IRSymbol( strName, type, true); _scopes.peek().addSymbol( symbol ); return symbol; } public String makeTempSymbolName( ) { String strName = TEMP_VAR_PREFIX + _tempVarCount; _tempVarCount ++; return strName; } public void pushScope( boolean bInitialInstanceMethodScope ) { if( _scopes == null ) { _scopes = new Stack<IRScope>(); } IRScope parent = _scopes.isEmpty() ? null : _scopes.peek(); _scopes.push( new IRScope( parent ) ); if( bInitialInstanceMethodScope ) { assert parent == null; _scopes.peek().addSymbol( Keyword.KW_this.getName(), _context.getIRTypeForCurrentClass() ); } } public void popScope() { _scopes.pop(); } public IRSymbol getTypeParamIndex( TypeVariableType type ) { return _scopes.peek().getSymbol( AbstractElementTransformer.TYPE_PARAM_PREFIX + type.getRelativeName() ); } public IRSymbol getSymbol(String symbolName) { IRSymbol symbol = _scopes.peek().getSymbol( symbolName ); if (symbol == null) { throw new IllegalStateException("No symbol found named " + symbolName); } return symbol; } public boolean hasSymbol(String symbolName) { return _scopes.peek().getSymbol( symbolName ) != null; } public void putSymbols(List<IRSymbol> symbols) { for (IRSymbol symbol : symbols) { putSymbol(symbol); } } public void putSymbol(IRSymbol symbol) { _scopes.peek().addSymbol(symbol); } public IRSymbol createSymbol(String name, IRType type) { return _scopes.peek().addSymbol(name, type); } public Stack<IRScope> getScopes() { return _scopes; } public boolean isBlockInvoke() { return false; } public DynamicFunctionSymbol getCurrentDFS() { return null; } public boolean isStatic() { return _isStatic; } }