*/
public Expression typeCheck(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException {
final Configuration config = visitor.getConfiguration();
final TypeHierarchy th = config.getTypeHierarchy();
if (Literal.isEmptySequence(operand0)) {
return new Literal(DoubleValue.NaN);
}
if (Literal.isEmptySequence(operand1)) {
return new Literal(DoubleValue.NaN);
}
Expression oldOp0 = operand0;
Expression oldOp1 = operand1;
operand0 = visitor.typeCheck(operand0, contextItemType);
operand1 = visitor.typeCheck(operand1, contextItemType);
SequenceType atomicType = SequenceType.OPTIONAL_ATOMIC;
RoleLocator role0 = new RoleLocator(RoleLocator.BINARY_EXPR, Token.tokens[operator], 0);
//role0.setSourceLocator(this);
operand0 = TypeChecker.staticTypeCheck(operand0, atomicType, true, role0, visitor);
RoleLocator role1 = new RoleLocator(RoleLocator.BINARY_EXPR, Token.tokens[operator], 1);
//role1.setSourceLocator(this);
operand1 = TypeChecker.staticTypeCheck(operand1, atomicType, true, role1, visitor);
final ItemType itemType0 = operand0.getItemType(th);
if (itemType0 instanceof EmptySequenceTest) {
return Literal.makeLiteral(DoubleValue.NaN);
}
AtomicType type0 = (AtomicType) itemType0.getPrimitiveItemType();
final ItemType itemType1 = operand1.getItemType(th);
if (itemType1 instanceof EmptySequenceTest) {
return Literal.makeLiteral(DoubleValue.NaN);
}
AtomicType type1 = (AtomicType)itemType1.getPrimitiveItemType();
// If both operands are integers, use integer arithmetic and convert the result to a double
if (th.isSubType(type0, BuiltInAtomicType.INTEGER) &&
th.isSubType(type1, BuiltInAtomicType.INTEGER) &&
(operator == Token.PLUS || operator == Token.MINUS || operator == Token.MULT)) {
ArithmeticExpression arith = new ArithmeticExpression(operand0, operator, operand1);
arith.simplified = true;
NumberFn n = (NumberFn)SystemFunction.makeSystemFunction("number", new Expression[]{arith});
return n.typeCheck(visitor, contextItemType);