/** * Get a 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. */ public int computeHashCode() { // Ensure that an operator and its inverse get the same hash code, // so that (A lt B) has the same hash code as (B gt A) int op = Math.min(operator, Token.inverse(operator)); return ("BinaryExpression " + op).hashCode() ^ getLhsExpression().hashCode() ^ getRhsExpression().hashCode(); }
/** * Get a 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. */ public int computeHashCode() { // Ensure that an operator and its inverse get the same hash code, // so that (A lt B) has the same hash code as (B gt A) int op = Math.min(operator, Token.inverse(operator)); return ("BinaryExpression " + op).hashCode() ^ getLhsExpression().hashCode() ^ getRhsExpression().hashCode(); }
if (getLhsExpression() instanceof BinaryExpression && ((BinaryExpression) getLhsExpression()).operator == operator) { ((BinaryExpression) getLhsExpression()).flattenExpression(list); } else { int h = getLhsExpression().hashCode(); list.add(getLhsExpression()); int i = list.size() - 1; while (i > 0 && h > list.get(i - 1).hashCode()) { list.set(i, list.get(i - 1)); list.set(i - 1, getLhsExpression()); i--;
if (getLhsExpression() instanceof BinaryExpression && ((BinaryExpression) getLhsExpression()).operator == operator) { ((BinaryExpression) getLhsExpression()).flattenExpression(list); } else { int h = getLhsExpression().hashCode(); list.add(getLhsExpression()); int i = list.size() - 1; while (i > 0 && h > list.get(i - 1).hashCode()) { list.set(i, list.get(i - 1)); list.set(i - 1, getLhsExpression()); i--;
/** * Mark an expression as being "flattened". This is a collective term that includes extracting the * string value or typed value, or operations such as simple value construction that concatenate text * nodes before atomizing. The implication of all of these is that although the expression might * return nodes, the identity of the nodes has no significance. This is called during type checking * of the parent expression. * * @param flattened set to true if the result of the expression is atomized or otherwise turned into * an atomic value */ public void setFlattened(boolean flattened) { getLhsExpression().setFlattened(flattened); getRhsExpression().setFlattened(flattened); }
/** * Mark an expression as being "flattened". This is a collective term that includes extracting the * string value or typed value, or operations such as simple value construction that concatenate text * nodes before atomizing. The implication of all of these is that although the expression might * return nodes, the identity of the nodes has no significance. This is called during type checking * of the parent expression. * * @param flattened set to true if the result of the expression is atomized or otherwise turned into * an atomic value */ public void setFlattened(boolean flattened) { getLhsExpression().setFlattened(flattened); getRhsExpression().setFlattened(flattened); }
/** * Represent the expression as a string. The resulting string will be a valid XPath 3.0 expression * with no dependencies on namespace bindings other than the binding of the prefix "xs" to the XML Schema * namespace. * * @return the expression as a string in XPath 3.0 syntax */ public String toString() { return ExpressionTool.parenthesize(getLhsExpression()) + " " + displayOperator() + " " + ExpressionTool.parenthesize(getRhsExpression()); }
/** * Represent the expression as a string. The resulting string will be a valid XPath 3.0 expression * with no dependencies on namespace bindings other than the binding of the prefix "xs" to the XML Schema * namespace. * * @return the expression as a string in XPath 3.0 syntax */ public String toString() { return ExpressionTool.parenthesize(getLhsExpression()) + " " + displayOperator() + " " + ExpressionTool.parenthesize(getRhsExpression()); }
@Override public String toShortString() { return parenthesize(getLhsExpression()) + " " + displayOperator() + " " + parenthesize(getRhsExpression()); }
@Override public String toShortString() { return parenthesize(getLhsExpression()) + " " + displayOperator() + " " + parenthesize(getRhsExpression()); }
/** * Is this expression the same as another expression? */ public boolean equals(Object other) { if (other instanceof BinaryExpression && hasCompatibleStaticContext((Expression)other)) { BinaryExpression b = (BinaryExpression) other; Expression lhs1 = getLhsExpression(); Expression rhs1 = getRhsExpression(); Expression lhs2 = b.getLhsExpression(); Expression rhs2 = b.getRhsExpression(); if (operator == b.operator) { if (lhs1.isEqual(lhs2) && rhs1.isEqual(rhs2)) { return true; } if (isCommutative(operator) && lhs1.isEqual(rhs2) && rhs1.isEqual(lhs2)) { return true; } if (isAssociative(operator) && pairwiseEqual(flattenExpression(new ArrayList<>(4)), b.flattenExpression(new ArrayList<>(4)))) { return true; } } return isInverse(operator, b.operator) && lhs1.isEqual(rhs2) && rhs1.isEqual(lhs2); } return false; }
/** * Is this expression the same as another expression? */ public boolean equals(Object other) { if (other instanceof BinaryExpression && hasCompatibleStaticContext((Expression)other)) { BinaryExpression b = (BinaryExpression) other; Expression lhs1 = getLhsExpression(); Expression rhs1 = getRhsExpression(); Expression lhs2 = b.getLhsExpression(); Expression rhs2 = b.getRhsExpression(); if (operator == b.operator) { if (lhs1.isEqual(lhs2) && rhs1.isEqual(rhs2)) { return true; } if (isCommutative(operator) && lhs1.isEqual(rhs2) && rhs1.isEqual(lhs2)) { return true; } if (isAssociative(operator) && pairwiseEqual(flattenExpression(new ArrayList<>(4)), b.flattenExpression(new ArrayList<>(4)))) { return true; } } return isInverse(operator, b.operator) && lhs1.isEqual(rhs2) && rhs1.isEqual(lhs2); } return false; }
/** * Determine the static cardinality. Default implementation returns [0..1] if either operand * can be empty, or [1..1] otherwise, provided that the arguments are of atomic type. This * caveat is necessary because the method can be called before type-checking, and a node * or array with cardinality [1..n] might be atomized to an empty sequence. */ public int computeCardinality() { Expression lhs = getLhsExpression(); Expression rhs = getRhsExpression(); if (!Cardinality.allowsZero(lhs.getCardinality()) && lhs.getItemType() instanceof AtomicType && !Cardinality.allowsZero(rhs.getCardinality()) && rhs.getItemType() instanceof AtomicType) { return StaticProperty.EXACTLY_ONE; } else { return StaticProperty.ALLOWS_ZERO_OR_ONE; } }
/** * Determine the static cardinality. Default implementation returns [0..1] if either operand * can be empty, or [1..1] otherwise, provided that the arguments are of atomic type. This * caveat is necessary because the method can be called before type-checking, and a node * or array with cardinality [1..n] might be atomized to an empty sequence. */ public int computeCardinality() { Expression lhs = getLhsExpression(); Expression rhs = getRhsExpression(); if (!Cardinality.allowsZero(lhs.getCardinality()) && lhs.getItemType() instanceof AtomicType && !Cardinality.allowsZero(rhs.getCardinality()) && rhs.getItemType() instanceof AtomicType) { return StaticProperty.EXACTLY_ONE; } else { return StaticProperty.ALLOWS_ZERO_OR_ONE; } }
/** * Diagnostic print of expression structure. The abstract expression tree * is written to the supplied output destination. * * @param out the output destination for the displayed expression tree */ public void export(ExpressionPresenter out) throws XPathException { out.startElement(tag(), this); out.emitAttribute("op", displayOperator()); explainExtraAttributes(out); getLhsExpression().export(out); getRhsExpression().export(out); out.endElement(); }
/** * Diagnostic print of expression structure. The abstract expression tree * is written to the supplied output destination. * * @param out the output destination for the displayed expression tree */ public void export(ExpressionPresenter out) throws XPathException { out.startElement(tag(), this); out.emitAttribute("op", displayOperator()); explainExtraAttributes(out); getLhsExpression().export(out); getRhsExpression().export(out); out.endElement(); }
/** * Type-check the expression. Default implementation for binary operators that accept * any kind of operand */ /*@NotNull*/ public Expression typeCheck(ExpressionVisitor visitor, ContextItemStaticInfo contextInfo) throws XPathException { resetLocalStaticProperties(); lhs.typeCheck(visitor, contextInfo); rhs.typeCheck(visitor, contextInfo); // if both operands are known, pre-evaluate the expression try { if ((getLhsExpression() instanceof Literal) && (getRhsExpression() instanceof Literal)) { GroundedValue<?> v = evaluateItem(visitor.getStaticContext().makeEarlyEvaluationContext()).materialize(); return Literal.makeLiteral(v, this); } } catch (XPathException err) { // if early evaluation fails, suppress the error: the value might // not be needed at run-time } return this; }
/** * Type-check the expression. Default implementation for binary operators that accept * any kind of operand */ /*@NotNull*/ public Expression typeCheck(ExpressionVisitor visitor, ContextItemStaticInfo contextInfo) throws XPathException { resetLocalStaticProperties(); lhs.typeCheck(visitor, contextInfo); rhs.typeCheck(visitor, contextInfo); // if both operands are known, pre-evaluate the expression try { if ((getLhsExpression() instanceof Literal) && (getRhsExpression() instanceof Literal)) { GroundedValue<?> v = evaluateItem(visitor.getStaticContext().makeEarlyEvaluationContext()).materialize(); return Literal.makeLiteral(v, this); } } catch (XPathException err) { // if early evaluation fails, suppress the error: the value might // not be needed at run-time } return this; }
if ((getLhsExpression() instanceof Literal) && (getRhsExpression() instanceof Literal)) { Item<?> item = evaluateItem(visitor.getStaticContext().makeEarlyEvaluationContext()); if (item != null) {
if ((getLhsExpression() instanceof Literal) && (getRhsExpression() instanceof Literal)) { Item<?> item = evaluateItem(visitor.getStaticContext().makeEarlyEvaluationContext()); if (item != null) {