operand0 = TypeChecker.staticTypeCheck(operand0, atomicType, true, role0, visitor);
final ItemType itemType0 = operand0.getItemType(th);
if (itemType0 instanceof EmptySequenceTest) {
return Literal.makeLiteral(DoubleValue.NaN);
}
AtomicType type0 = (AtomicType) itemType0.getPrimitiveItemType();
if (calculator == null) {
operand0 = createConversionCode(operand0, th, type0);
}
type0 = (AtomicType) operand0.getItemType(th).getPrimitiveItemType();
// System.err.println("First operand"); operand0.display(10);
RoleLocator role1 = new RoleLocator(RoleLocator.BINARY_EXPR, Token.tokens[operator], 1, null);
role1.setSourceLocator(this);
operand1 = TypeChecker.staticTypeCheck(operand1, atomicType, true, role1, visitor);
final ItemType itemType1 = operand1.getItemType(th);
if (itemType1 instanceof EmptySequenceTest) {
return Literal.makeLiteral(DoubleValue.NaN);
}
AtomicType type1 = (AtomicType)itemType1.getPrimitiveItemType();
if (calculator == null) {
operand1 = createConversionCode(operand1, th, type1);
}
type1 = (AtomicType) operand1.getItemType(th).getPrimitiveItemType();
if (operand0 != oldOp0) {
adoptChildExpression(operand0);
}
if (operand1 != oldOp1) {
adoptChildExpression(operand1);
}
if (operator == Token.NEGATE) {
if (operand1 instanceof Literal) {
Value v = ((Literal)operand1).getValue();
if (v instanceof NumericValue) {
return Literal.makeLiteral(((NumericValue)v).negate());
}
}
NegateExpression ne = new NegateExpression(operand1);
ne.setBackwardsCompatible(true);
return visitor.typeCheck(ne, contextItemType);
}
// Get a calculator to implement the arithmetic operation. If the types are not yet specifically known,
// we allow this to return an "ANY" calculator which defers the decision. However, we only allow this if
// at least one of the operand types is AnyAtomicType.
boolean mustResolve = !(type0.equals(BuiltInAtomicType.ANY_ATOMIC) || type1.equals(BuiltInAtomicType.ANY_ATOMIC));
calculator = Calculator.getCalculator(type0.getFingerprint(), type1.getFingerprint(),
ArithmeticExpression.mapOpCode(operator), mustResolve);
if (calculator == null) {
XPathException de = new XPathException("Arithmetic operator is not defined for arguments of types (" +
type0.getDescription() + ", " + type1.getDescription() + ")");
de.setLocator(this);
de.setErrorCode("XPTY0004");
throw de;
}