@Override public final Expr comp(final QueryContext ctx) throws QueryException { if (!test.comp(ctx)) return Empty.SEQ; // leaf flag indicates that a context node can be replaced by a text() step final Data data = ctx.data(); ctx.leaf = data != null && test.test == Name.NAME && test.type != NodeType.ATT && axis.down && data.meta.uptodate && data.nspaces.size() == 0; if (ctx.leaf) { final Stats s = data.tagindex.stat(data.tagindex.id(((NameTest) test).ln)); ctx.leaf = s != null && s.leaf; } // as predicates will not necessarily start from the document node, // the context item type is temporarily generalized final Type ct = ctx.value != null ? ctx.value.type : null; if (ct == NodeType.DOC) ctx.value.type = NodeType.NOD; final Expr e = super.comp(ctx); if (ct == NodeType.DOC) ctx.value.type = ct; ctx.leaf = false; // return optimized step / don't re-optimize step if (e != this || e instanceof IterStep) return e; // no numeric predicates.. use simple iterator if (!uses(Use.POS)) return new IterStep(input, axis, test, preds); // don't re-optimize step if (this instanceof IterPosStep) return this; // use iterator for simple numeric predicate return useIterator() ? new IterPosStep(this) : this; }