* arithmetic function to use if the types of operands are known an compile time.
*/
public Expression typeCheck(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException {
final TypeHierarchy th = visitor.getConfiguration().getTypeHierarchy();
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, false, role0, visitor);
final ItemType itemType0 = operand0.getItemType(th);
if (itemType0 instanceof EmptySequenceTest) {
return new Literal(EmptySequence.getInstance());
}
AtomicType type0 = (AtomicType) itemType0.getPrimitiveItemType();
if (type0.getFingerprint() == StandardNames.XS_UNTYPED_ATOMIC) {
operand0 = new UntypedAtomicConverter(operand0, BuiltInAtomicType.DOUBLE, true, role0);
type0 = BuiltInAtomicType.DOUBLE;
} else if (/*!(operand0 instanceof UntypedAtomicConverter)*/
(operand0.getSpecialProperties()&StaticProperty.NOT_UNTYPED) == 0 &&
th.relationship(type0, BuiltInAtomicType.UNTYPED_ATOMIC) != TypeHierarchy.DISJOINT) {
operand0 = new UntypedAtomicConverter(operand0, BuiltInAtomicType.DOUBLE, false, role0);
type0 = (AtomicType)operand0.getItemType(th);
}
// System.err.println("First operand"); operand0.display(10);
RoleLocator role1 = new RoleLocator(RoleLocator.BINARY_EXPR, Token.tokens[operator], 1);
//role1.setSourceLocator(this);
operand1 = TypeChecker.staticTypeCheck(operand1, atomicType, false, role1, visitor);
final ItemType itemType1 = operand1.getItemType(th);
if (itemType1 instanceof EmptySequenceTest) {
return new Literal(EmptySequence.getInstance());
}
AtomicType type1 = (AtomicType)itemType1.getPrimitiveItemType();
if (type1.getFingerprint() == StandardNames.XS_UNTYPED_ATOMIC) {
operand1 = new UntypedAtomicConverter(operand1, BuiltInAtomicType.DOUBLE, true, role1);
type1 = BuiltInAtomicType.DOUBLE;
} else if (/*!(operand1 instanceof UntypedAtomicConverter) &&*/
(operand1.getSpecialProperties()&StaticProperty.NOT_UNTYPED) == 0 &&
th.relationship(type1, BuiltInAtomicType.UNTYPED_ATOMIC) != TypeHierarchy.DISJOINT) {
operand1 = new UntypedAtomicConverter(operand1, BuiltInAtomicType.DOUBLE, false, role1);
type1 = (AtomicType)operand1.getItemType(th);
}
if (operand0 != oldOp0) {