/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.ir.transform.expression; import gw.internal.gosu.ir.transform.ExpressionTransformer; import gw.internal.gosu.ir.transform.TopLevelTransformationContext; import gw.internal.gosu.runtime.GosuRuntimeMethods; import gw.lang.ir.IRExpression; import gw.lang.ir.IRSymbol; import gw.lang.ir.statement.IRSyntheticStatement; import gw.lang.parser.expressions.ITypeOfExpression; import gw.lang.reflect.java.IJavaType; import gw.lang.reflect.java.JavaTypes; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.IType; import gw.lang.reflect.java.JavaTypes; /** */ public class TypeOfTransformer extends AbstractExpressionTransformer<ITypeOfExpression> { public static IRExpression compile( TopLevelTransformationContext cc, ITypeOfExpression expr ) { TypeOfTransformer gen = new TypeOfTransformer( cc, expr ); return gen.compile(); } private TypeOfTransformer( TopLevelTransformationContext cc, ITypeOfExpression expr ) { super( cc, expr ); } protected IRExpression compile_impl() { IType rhsType = _expr().getExpression().getType(); IRExpression rhs = ExpressionTransformer.compile( _expr().getExpression(), _cc() ); if( rhsType.isPrimitive() ) { // We evaluate the RHS, but just pop it off and push on the type since we know it statically return buildComposite( new IRSyntheticStatement( rhs ), pushType( rhsType ) ); } else { // If it's not a primitive, we want to short-circuit to "void" if the expression is null, and otherwise to call // TypeSystem.getFromObject, so we end up with code that looks like: // temp = rhs // (temp == null ? TypeSystem.getByFullName( "void" ) : TypeSystem.getFromObject( temp) ) IRSymbol temp = _cc().makeAndIndexTempSymbol( rhs.getType() ); return buildComposite( buildAssignment( temp, rhs ), buildNullCheckTernary( identifier( temp ), pushType( JavaTypes.pVOID() ), callStaticMethod( GosuRuntimeMethods.class, "typeof", new Class[]{ Object.class }, exprList( identifier( temp ) ) ) ) ); } } }