/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser.expressions; import gw.internal.gosu.parser.TypeLord; import gw.lang.reflect.interval.ISequenceable; import gw.internal.gosu.ir.transform.AbstractElementTransformer; import gw.internal.gosu.parser.CannotExecuteGosuException; import gw.internal.gosu.parser.ErrorType; import gw.internal.gosu.parser.Expression; import gw.lang.parser.expressions.IIntervalExpression; import gw.lang.reflect.IType; import gw.lang.reflect.java.JavaTypes; /** * Represents an interval expression in the Gosu grammar: * <pre> * <i>interval-expression</i> * <bitshift-expression> * <interval-expression> <b>..</b> <bitshift-expression> * <interval-expression> <b>|..</b> <bitshift-expression> * <interval-expression> <b>..|</b> <bitshift-expression> * <interval-expression> <b>|..|</b> <bitshift-expression> * </pre> * <p/> * * @see gw.lang.parser.IGosuParser */ public final class IntervalExpression extends BinaryExpression implements IIntervalExpression { private boolean _bLeftClosed; private boolean _bRightClosed; public IntervalExpression( boolean bLeftClosed, boolean bRightClosed, Expression lhsExpr, Expression rhsExpr ) { _bLeftClosed = bLeftClosed; _bRightClosed = bRightClosed; setLHS( lhsExpr ); setRHS( rhsExpr ); setOperator( (bLeftClosed ? "" : "|") + ".." + (bRightClosed ? "" : "|") ); } public boolean isLeftClosed() { return _bLeftClosed; } public boolean isRightClosed() { return _bRightClosed; } public Object evaluate() { if( !isCompileTimeConstant() ) { return super.evaluate(); } throw new CannotExecuteGosuException(); } public static IType getIntervalType( IType type ) { if( AbstractElementTransformer.isIntType( type ) || AbstractElementTransformer.isBoxedIntType( type ) ) { return JavaTypes.INTEGER_INTERVAL(); } else if( type == JavaTypes.pLONG() || type == JavaTypes.LONG() ) { return JavaTypes.LONG_INTERVAL(); } else if( type == JavaTypes.BIG_INTEGER() ) { return JavaTypes.BIG_INTEGER_INTERVAL(); } else if( type == JavaTypes.pFLOAT() || type == JavaTypes.FLOAT() || type == JavaTypes.pDOUBLE() || type == JavaTypes.DOUBLE() || type == JavaTypes.BIG_DECIMAL() ) { return JavaTypes.BIG_DECIMAL_INTERVAL(); } else if( JavaTypes.DATE().isAssignableFrom( type ) ) { return JavaTypes.DATE_INTERVAL(); } else if( JavaTypes.getGosuType(ISequenceable.class ).isAssignableFrom( type ) ) { if( type instanceof ErrorType ) { return JavaTypes.SEQUENCEABLE_INTERVAL().getParameterizedType( type, JavaTypes.OBJECT(), JavaTypes.OBJECT() ); } IType parameterizedSequenceable = TypeLord.findParameterizedType( type, JavaTypes.getGosuType( ISequenceable.class ) ); return JavaTypes.SEQUENCEABLE_INTERVAL().getParameterizedType( type, parameterizedSequenceable.getTypeParameters()[1], parameterizedSequenceable.getTypeParameters()[2] ); } else { if( type instanceof ErrorType ) { return JavaTypes.COMPARABLE_INTERVAL().getParameterizedType( JavaTypes.OBJECT() ); } return JavaTypes.COMPARABLE_INTERVAL().getParameterizedType( type ); } } }