public int computeCardinality() { if (singleton) { return StaticProperty.ALLOWS_ZERO_OR_ONE; } else { return super.computeCardinality(); } }
/** * Determine the special properties of this expression * * @return {@link StaticProperty#NO_NODES_NEWLY_CREATED}. */ public int computeSpecialProperties() { int p = super.computeSpecialProperties(); p &= ~StaticProperty.NODESET_PROPERTIES; return p | StaticProperty.NO_NODES_NEWLY_CREATED; }
/** * Is this expression the same as another expression? */ public boolean equals(Object other) { return super.equals(other) && requiredCardinality == ((CardinalityChecker) other).requiredCardinality; }
/** * The toString() method for an expression attempts to give a representation of the expression * in an XPath-like form, but there is no guarantee that the syntax will actually be true XPath. * In the case of XSLT instructions, the toString() method gives an abstracted view of the syntax */ public String toString() { return getExpressionName() + "(" + getBaseExpression() + ")"; }
/** * Perform optimisation of an expression and its subexpressions. * <p/> * <p>This method is called after all references to functions and variables have been resolved * to the declaration of the function or variable, and after all type checking has been done.</p> * * @param visitor an expresion visitor * @param contextItemType the static type of "." at the point where this expression is invoked. * The parameter is set to null if it is known statically that the context item will be undefined. * If the type of the context item is not known statically, the argument is set to * {@link net.sf.saxon.type.Type#ITEM_TYPE} * @return the original expression, rewritten if appropriate to optimize execution * @throws net.sf.saxon.trans.XPathException if an error is discovered during this phase * (typically a type error) */ public Expression optimize(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException { operand = visitor.optimize(operand, contextItemType); if (operand instanceof LastItemExpression || operand instanceof FirstItemExpression) { return operand; } return super.optimize(visitor, contextItemType); }
/** * Process the instruction, without returning any tail calls * * @param context The dynamic context, giving access to the current node, * the current variables, etc. */ public void process(XPathContext context) throws XPathException { Expression next = getBaseExpression(); int card = StaticProperty.ALLOWS_ZERO_OR_MORE; if (next instanceof CardinalityChecker) { card = ((CardinalityChecker) next).getRequiredCardinality(); next = ((CardinalityChecker) next).getBaseExpression(); } if ((next.getImplementationMethod() & PROCESS_METHOD) != 0 && !(requiredItemType instanceof DocumentNodeTest)) { Receiver out = context.getReceiver(); TypeCheckingFilter filter = new TypeCheckingFilter(out); filter.setRequiredType(requiredItemType, card, role, getLocation()); context.setReceiver(filter); next.process(context); filter.close(); context.setReceiver(out); } else { // Force pull-mode evaluation super.process(context); } }
/** * Perform optimisation of an expression and its subexpressions. * <p>This method is called after all references to functions and variables have been resolved * to the declaration of the function or variable, and after all type checking has been done.</p> * * @param visitor an expression visitor * @param contextInfo the static type of "." at the point where this expression is invoked. * The parameter is set to null if it is known statically that the context item will be undefined. * If the type of the context item is not known statically, the argument is set to * {@link net.sf.saxon.type.Type#ITEM_TYPE} * @return the original expression, rewritten if appropriate to optimize execution * @throws XPathException if an error is discovered during this phase * (typically a type error) */ /*@NotNull*/ public Expression optimize(ExpressionVisitor visitor, ContextItemStaticInfo contextInfo) throws XPathException { operand.optimize(visitor, contextInfo); // if the operand value is known, pre-evaluate the expression Expression base = getBaseExpression(); try { if (base instanceof Literal) { return Literal.makeLiteral( iterate(visitor.getStaticContext().makeEarlyEvaluationContext()).materialize(), this); } } catch (XPathException err) { // if early evaluation fails, suppress the error: the value might // not be needed at run-time } return this; }
/** * Diagnostic print of expression structure. The abstract expression tree * is written to the supplied output destination. */ public void export(ExpressionPresenter out) throws XPathException { String name = getExpressionName(); if (name == null) { out.startElement("unaryOperator", this); String op = displayOperator(out.getConfiguration()); if (op != null) { out.emitAttribute("op", op); } } else { out.startElement(name, this); } getBaseExpression().export(out); out.endElement(); }
/** * Is this expression the same as another expression? */ public boolean equals(/*@Nullable*/ Object other) { return other != null && this.getClass().equals(other.getClass()) && this.getBaseExpression().isEqual(((UnaryExpression) other).getBaseExpression()); }
/** * Diagnostic print of expression structure. The abstract expression tree * is written to the supplied output destination. */ public void explain(ExpressionPresenter out) { String name = displayExpressionName(); if (name == null) { out.startElement("unaryOperator"); String op = displayOperator(out.getConfiguration()); if (op != null) { out.emitAttribute("op", op); } } else { out.startElement(name); } operand.explain(out); out.endElement(); }
/** * Type-check the expression. Default implementation for unary operators that accept * any kind of operand */ public Expression typeCheck(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException { operand = visitor.typeCheck(operand, contextItemType); // if the operand value is known, pre-evaluate the expression try { if (operand instanceof Literal) { return Literal.makeLiteral(Value.asValue( SequenceExtent.makeSequenceExtent( iterate(visitor.getStaticContext().makeEarlyEvaluationContext())))); } //return (Value)ExpressionTool.eagerEvaluate(this, env.makeEarlyEvaluationContext()); } catch (XPathException err) { // if early evaluation fails, suppress the error: the value might // not be needed at run-time } return this; }
/** * get HashCode for comparing two expressions. Note that this hashcode gives the same * result for (A op B) and for (B op A), whether or not the operator is commutative. */ @Override public int computeHashCode() { return super.computeHashCode() ^ requiredCardinality; }
public UnaryExpression(Expression p0) { operand = p0; adoptChildExpression(p0); }
/** * Perform optimisation of an expression and its subexpressions. * <p/> * <p>This method is called after all references to functions and variables have been resolved * to the declaration of the function or variable, and after all type checking has been done.</p> * * @param visitor an expresion visitor * @param contextItemType the static type of "." at the point where this expression is invoked. * The parameter is set to null if it is known statically that the context item will be undefined. * If the type of the context item is not known statically, the argument is set to * {@link net.sf.saxon.type.Type#ITEM_TYPE} * @return the original expression, rewritten if appropriate to optimize execution * @throws XPathException if an error is discovered during this phase * (typically a type error) */ public Expression optimize(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException { operand = visitor.optimize(operand, contextItemType); // don't remove this expression just because the operand is known to be a singleton. // It might be that this expression was added to give early exit from evaluating the underlying expression // if (!Cardinality.allowsMany(operand.getCardinality())) { // ComputedExpression.setParentExpression(operand, getParentExpression()); // return operand; // } if (operand instanceof FirstItemExpression) { return operand; } return super.optimize(visitor, contextItemType); }
/** * Process the instruction, without returning any tail calls * * @param context The dynamic context, giving access to the current node, * the current variables, etc. */ public void process(XPathContext context) throws XPathException { Expression next = getBaseExpression(); int card = StaticProperty.ALLOWS_ZERO_OR_MORE; if (next instanceof CardinalityChecker) { card = ((CardinalityChecker) next).getRequiredCardinality(); next = ((CardinalityChecker) next).getBaseExpression(); } if ((next.getImplementationMethod() & PROCESS_METHOD) != 0 && !(requiredItemType instanceof DocumentNodeTest)) { Receiver out = context.getReceiver(); TypeCheckingFilter filter = new TypeCheckingFilter(out); filter.setRequiredType(requiredItemType, card, role, getLocation()); context.setReceiver(filter); next.process(context); filter.close(); context.setReceiver(out); } else { // Force pull-mode evaluation super.process(context); } }
/** * Type-check the expression. Default implementation for unary operators that accept * any kind of operand */ /*@NotNull*/ public Expression typeCheck(ExpressionVisitor visitor, ContextItemStaticInfo contextInfo) throws XPathException { operand.typeCheck(visitor, contextInfo); // if the operand value is known, pre-evaluate the expression try { if (getBaseExpression() instanceof Literal) { Expression e2 = Literal.makeLiteral( iterate(visitor.getStaticContext().makeEarlyEvaluationContext()).materialize(), this); ExpressionTool.copyLocationInfo(this, e2); return e2; } //return (Value)ExpressionTool.eagerEvaluate(this, env.makeEarlyEvaluationContext()); } catch (Exception err) { // if early evaluation fails, suppress the error: the value might // not be needed at run-time } return this; }
/** * Diagnostic print of expression structure. The abstract expression tree * is written to the supplied output destination. */ public void export(ExpressionPresenter out) throws XPathException { String name = getExpressionName(); if (name == null) { out.startElement("unaryOperator", this); String op = displayOperator(out.getConfiguration()); if (op != null) { out.emitAttribute("op", op); } } else { out.startElement(name, this); } getBaseExpression().export(out); out.endElement(); }
/** * The toString() method for an expression attempts to give a representation of the expression * in an XPath-like form, but there is no guarantee that the syntax will actually be true XPath. * In the case of XSLT instructions, the toString() method gives an abstracted view of the syntax */ public String toString() { return getExpressionName() + "(" + getBaseExpression() + ")"; }
/** * Is this expression the same as another expression? */ public boolean equals(/*@Nullable*/ Object other) { return other != null && this.getClass().equals(other.getClass()) && this.getBaseExpression().isEqual(((UnaryExpression) other).getBaseExpression()); }
/** * Diagnostic print of expression structure. The abstract expression tree * is written to the supplied output destination. */ public void explain(ExpressionPresenter out) { String name = displayExpressionName(); if (name == null) { out.startElement("unaryOperator"); String op = displayOperator(out.getConfiguration()); if (op != null) { out.emitAttribute("op", op); } } else { out.startElement(name); } operand.explain(out); out.endElement(); }