1 package net.sf.saxon.expr; 2 import net.sf.saxon.om.NamePool; 3 import net.sf.saxon.trans.DynamicError; 4 import net.sf.saxon.trans.XPathException; 5 import net.sf.saxon.type.ItemType; 6 import net.sf.saxon.value.Cardinality; 7 import net.sf.saxon.value.Value; 8 9 import java.io.PrintStream ; 10 import java.util.Iterator ; 11 12 16 17 public abstract class BinaryExpression extends ComputedExpression { 18 19 protected Expression operand0; 20 protected Expression operand1; 21 protected int operator; 23 29 30 public BinaryExpression(Expression p0, int op, Expression p1) { 31 this.operator = op; 32 operand0 = p0; 33 operand1 = p1; 34 adoptChildExpression(p0); 35 adoptChildExpression(p1); 36 } 37 38 42 43 public Expression simplify(StaticContext env) throws XPathException { 44 operand0 = operand0.simplify(env); 45 operand1 = operand1.simplify(env); 46 return this; 47 } 48 49 53 54 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 55 operand0 = operand0.typeCheck(env, contextItemType); 56 operand1 = operand1.typeCheck(env, contextItemType); 57 try { 59 if ((operand0 instanceof Value) && (operand1 instanceof Value)) { 60 return ExpressionTool.eagerEvaluate(this, null); 61 } 62 } catch (DynamicError err) { 63 } 66 return this; 67 } 68 69 86 87 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 88 operand0 = operand0.optimize(opt, env, contextItemType); 89 operand1 = operand1.optimize(opt, env, contextItemType); 90 try { 92 if ((operand0 instanceof Value) && (operand1 instanceof Value)) { 93 return ExpressionTool.eagerEvaluate(this, null); 94 } 95 } catch (DynamicError err) { 96 } 99 return this; 100 } 101 102 103 106 107 public Expression promote(PromotionOffer offer) throws XPathException { 108 Expression exp = offer.accept(this); 109 if (exp != null) { 110 return exp; 111 } else { 112 if (offer.action != PromotionOffer.UNORDERED) { 113 operand0 = doPromotion(operand0, offer); 114 operand1 = doPromotion(operand1, offer); 115 } 116 return this; 117 } 118 } 119 120 123 124 public Iterator iterateSubExpressions() { 125 return new PairIterator(operand0, operand1); 126 } 127 128 131 132 public int getOperator() { 133 return operator; 134 } 135 136 139 140 public Expression[] getOperands() { 141 Expression[] ops = {operand0, operand1}; 142 return ops; 143 } 144 145 149 150 public int computeCardinality() { 151 if (Cardinality.allowsZero(operand0.getCardinality()) || 152 Cardinality.allowsZero(operand1.getCardinality())) { 153 return StaticProperty.ALLOWS_ZERO_OR_ONE; 154 } else { 155 return StaticProperty.EXACTLY_ONE; 156 } 157 } 158 159 164 165 public int computeSpecialProperties() { 166 int p = super.computeSpecialProperties(); 167 return p | StaticProperty.NON_CREATIVE; 168 } 169 170 protected static boolean isCommutative(int operator) { 171 return (operator == Token.AND || 172 operator == Token.OR || 173 operator == Token.UNION || 174 operator == Token.INTERSECT || 175 operator == Token.PLUS || 176 operator == Token.MULT || 177 operator == Token.EQUALS || 178 operator == Token.FEQ || 179 operator == Token.NE || 180 operator == Token.FNE 181 ); 182 } 183 184 192 protected static boolean isInverse(int op1, int op2) { 193 return op1 != op2 && op1 == Token.inverse(op2); 194 } 195 196 199 200 public boolean equals(Object other) { 201 if (other instanceof BinaryExpression) { 202 BinaryExpression b = (BinaryExpression)other; 203 if (operator == b.operator) { 204 if (operand0.equals(b.operand0) && 205 operand1.equals(b.operand1)) { 206 return true; 207 } 208 if (isCommutative(operator) && 209 operand0.equals(b.operand1) && 210 operand1.equals(b.operand0)) { 211 return true; 212 } 213 } 214 if (isInverse(operator, b.operator) && 215 operand0.equals(b.operand1) && 216 operand1.equals(b.operand0)) { 217 return true; 218 } 219 } 221 return false; 222 } 223 224 228 229 public int hashCode() { 230 int op = Math.min(operator, Token.inverse(operator)); 233 return ("BinaryExpression " + op).hashCode() 234 ^ operand0.hashCode() 235 ^ operand1.hashCode(); 236 } 237 238 241 242 public void display(int level, NamePool pool, PrintStream out) { 243 out.println(ExpressionTool.indent(level) + "operator " + displayOperator()); 244 operand0.display(level+1, pool, out); 245 operand1.display(level+1, pool, out); 246 } 247 248 protected String displayOperator() { 249 return Token.tokens[operator]; 250 } 251 252 } 253 254 | Popular Tags |