* Perform type analysis
*/
public Expression typeCheck(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException {
final TypeHierarchy th = visitor.getConfiguration().getTypeHierarchy();
if (state >= 2) {
// we've already done the main analysis, and we don't want to do it again because
// decisions on sorting get upset. But we have new information, namely the contextItemType,
// so we use that to check that it's a node
setStartExpression(visitor.typeCheck(start, contextItemType));
setStepExpression(visitor.typeCheck(step, start.getItemType(th)));
return this;
}
state = 2;
setStartExpression(visitor.typeCheck(start, contextItemType));
// The first operand must be of type node()*
RoleLocator role0 = new RoleLocator(RoleLocator.BINARY_EXPR, "/", 0, null);
role0.setSourceLocator(this);
role0.setErrorCode("XPTY0019");
setStartExpression(
TypeChecker.staticTypeCheck(start, SequenceType.NODE_SEQUENCE, false, role0, visitor));
// Now check the second operand
setStepExpression(visitor.typeCheck(step, start.getItemType(th)));
// We distinguish three cases for the second operand: either it is known statically to deliver
// nodes only (a traditional path expression), or it is known statically to deliver atomic values
// only (a simple mapping expression), or we don't yet know.
ItemType stepType = step.getItemType(th);
if (th.isSubType(stepType, Type.NODE_TYPE)) {
if ((step.getSpecialProperties() & StaticProperty.NON_CREATIVE) != 0) {
// A traditional path expression