/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser.expressions; import gw.internal.gosu.parser.ParserBase; import gw.lang.parser.IGosuParser; import gw.lang.parser.expressions.IConditionalExpression; import gw.lang.reflect.IMethodInfo; import gw.lang.reflect.IType; import gw.lang.reflect.java.JavaTypes; import gw.config.CommonServices; /** * The base class for conditional expressions with logical operators e.g., && || ==. * Models conditional expressions by encapsulating the left and right hand side * operands. */ public abstract class ConditionalExpression extends BinaryExpression implements IConditionalExpression { private IMethodInfo _override; /** * Base constructor sets type to BooleanType. */ public ConditionalExpression() { setType( JavaTypes.pBOOLEAN() ); } public IMethodInfo getOverride() { return _override; } public void setOverride( IMethodInfo overrideMi ) { _override = overrideMi; } public boolean isCompileTimeConstant() { return getLHS().isCompileTimeConstant() && getRHS().isCompileTimeConstant(); } public static int compareNumbers( Object lhsValue, Object rhsValue, IType lhsType, IType rhsType ) { if( JavaTypes.IDIMENSION().isAssignableFrom( lhsType ) && JavaTypes.COMPARABLE().isAssignableFrom( lhsType ) ) { // The dimension is explicitly comparable. Enable relational operator overloading via compareTo(). //noinspection unchecked return ((Comparable)lhsValue).compareTo( rhsValue ); } lhsType = ParserBase.resolveType( lhsType, '>', rhsType ); try { DimensionOperandResolver customNumberResolver = DimensionOperandResolver.resolve( lhsType, '>', lhsType, lhsValue, rhsType, rhsValue ); lhsType = customNumberResolver.getRawNumberType(); lhsValue = customNumberResolver.getLhsValue(); rhsValue = customNumberResolver.getRhsValue(); if( lhsType == JavaTypes.BIG_DECIMAL() ) { return CommonServices.getCoercionManager().makeBigDecimalFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeBigDecimalFrom( rhsValue ) ); } if( lhsType == JavaTypes.BIG_INTEGER() ) { return CommonServices.getCoercionManager().makeBigIntegerFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeBigIntegerFrom( rhsValue ) ); } if( lhsType == JavaTypes.INTEGER() || lhsType == JavaTypes.pINT() ) { return CommonServices.getCoercionManager().makeIntegerFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeIntegerFrom( rhsValue ) ); } if( lhsType == JavaTypes.LONG() || lhsType == JavaTypes.pLONG() ) { return CommonServices.getCoercionManager().makeLongFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeLongFrom( rhsValue ) ); } if( lhsType == JavaTypes.DOUBLE() || lhsType == JavaTypes.pDOUBLE() ) { return CommonServices.getCoercionManager().makeDoubleFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeDoubleFrom( rhsValue ) ); } if( lhsType == JavaTypes.FLOAT() || lhsType == JavaTypes.pFLOAT() ) { float f1 = CommonServices.getCoercionManager().makePrimitiveFloatFrom( lhsValue ); float f2 = CommonServices.getCoercionManager().makePrimitiveFloatFrom( rhsValue ); return f1 > f2 ? 1 : f1 < f2 ? -1 : 0; } if( lhsType == JavaTypes.SHORT() || lhsType == JavaTypes.pSHORT() ) { return CommonServices.getCoercionManager().makeIntegerFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeIntegerFrom( rhsValue ) ); } if( lhsType == JavaTypes.BYTE() || lhsType == JavaTypes.pBYTE() ) { return CommonServices.getCoercionManager().makeIntegerFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeIntegerFrom( rhsValue ) ); } } catch( NumberFormatException nfe ) { rhsValue = IGosuParser.ZERO; } return CommonServices.getCoercionManager().makeDoubleFrom( lhsValue ).compareTo( CommonServices.getCoercionManager().makeDoubleFrom( rhsValue ) ); } @Override public IType getType() { return JavaTypes.pBOOLEAN(); } @Override protected IType getTypeImpl() { return JavaTypes.pBOOLEAN(); } }