String coercedType = TypeCoercer.coerceToNumber(boxedType);
if (TypeCoercer.typeIsNull(coercedType))
{
// null always coerces to 0L on this operator
return new IntegerLiteralType(0L);
}
// JSP.2.3.5.4, step 2 if BigDecimal or BigInteger, then can't be
// literal and retains type
if (TypeConstants.TYPE_BIG_DOUBLE.equals(coercedType))
{
return new ValueType(TypeConstants.TYPE_BIG_DOUBLE, IAssignable.ASSIGNMENT_TYPE_RHS);
}
else if (TypeConstants.TYPE_BIG_INTEGER.equals(coercedType))
{
return new ValueType(TypeConstants.TYPE_BIG_INTEGER, IAssignable.ASSIGNMENT_TYPE_RHS);
}
if (TypeCoercer.typeIsString(type.getSignature()))
{
// if it's string and we have the value, we can determine for
// sure whether or not it's coercable to a number
// per JSP.2.3.5.4 step 3
if (type instanceof StringLiteralType)
{
String literalValue = ((LiteralType)type).getLiteralValue();
if (literalValue.indexOf('.') > -1
|| literalValue.indexOf('e') > -1
|| literalValue.indexOf('E') > -1)
{
// if it coerces to double, then it's a double
Number value = ((LiteralType)type).coerceToNumber(Double.class);
return new FloatLiteralType(-1 * value.doubleValue());
}
// if it coerces to long, then it's a long
Number value = ((LiteralType)type).coerceToNumber(Long.class);
return new IntegerLiteralType(-1 * value.longValue());
}
// otherwise, just return a long typed value
return new ValueType(Signature.SIG_LONG, IAssignable.ASSIGNMENT_TYPE_RHS);
}
// JSP.2.3.5.4
// big integer and big decimal retain type
// all numeric types retain type
if (TypeCoercer.typeIsNumeric(boxedType))
{
// integer and float literals are special because -1 or -1.0
// is syntically minusOp(1) and minusOp(1.0)
if (type instanceof IntegerLiteralType)
{
return new IntegerLiteralType(-1 * ((IntegerLiteralType)type).coerceToNumber(Long.class).longValue());
}
else if (type instanceof FloatLiteralType)
{
return new FloatLiteralType(-1 * ((FloatLiteralType)type).coerceToNumber(Double.class).doubleValue());
}