1 package net.sf.saxon.expr; 2 import net.sf.saxon.om.Item; 3 import net.sf.saxon.om.NamePool; 4 import net.sf.saxon.om.SequenceIterator; 5 import net.sf.saxon.trans.XPathException; 6 import net.sf.saxon.type.ItemType; 7 import net.sf.saxon.type.SchemaType; 8 import net.sf.saxon.type.Type; 9 import net.sf.saxon.value.BooleanValue; 10 import net.sf.saxon.value.Cardinality; 11 import net.sf.saxon.value.Value; 12 import net.sf.saxon.value.EmptySequence; 13 import net.sf.saxon.instruct.TailCallReturner; 14 import net.sf.saxon.instruct.TailCall; 15 16 import java.io.PrintStream ; 17 import java.util.ArrayList ; 18 import java.util.Iterator ; 19 20 21 25 26 public class IfExpression extends ComputedExpression implements TailCallReturner { 27 28 private Expression condition; 29 private Expression thenExp; 30 private Expression elseExp; 31 32 35 36 public IfExpression(Expression condition, Expression thenExp, Expression elseExp) { 37 this.condition = condition; 38 this.thenExp = thenExp; 39 this.elseExp = elseExp; 40 adoptChildExpression(condition); 41 adoptChildExpression(thenExp); 42 adoptChildExpression(elseExp); 43 } 44 45 public Expression getCondition() { 46 return condition; 47 } 48 49 public Expression getThenExpression() { 50 return thenExp; 51 } 52 53 public Expression getElseExpression() { 54 return elseExp; 55 } 56 57 public void setCondition(Expression exp) { 58 condition = exp; 59 adoptChildExpression(exp); 60 } 61 62 public void setThenExpression(Expression exp) { 63 thenExp = exp; 64 adoptChildExpression(exp); 65 } 66 67 70 71 public Expression simplify(StaticContext env) throws XPathException { 72 73 condition = condition.simplify(env); 74 75 if (condition instanceof Value) { 76 return (condition.effectiveBooleanValue(null) ? thenExp.simplify(env) : elseExp.simplify(env)); 77 } 78 thenExp = thenExp.simplify(env); 79 elseExp = elseExp.simplify(env); 80 return this; 81 } 82 83 86 87 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 88 condition = condition.typeCheck(env, contextItemType); 89 if (condition instanceof BooleanValue) { 94 if (((BooleanValue)condition).getBooleanValue()) { 95 return thenExp.typeCheck(env, contextItemType); 96 } else { 97 return elseExp.typeCheck(env, contextItemType); 98 } 99 } else { 100 thenExp = thenExp.typeCheck(env, contextItemType); 101 elseExp = elseExp.typeCheck(env, contextItemType); 102 adoptChildExpression(condition); 103 adoptChildExpression(thenExp); 104 adoptChildExpression(elseExp); 105 return this; 106 } 107 } 108 109 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 110 condition = condition.optimize(opt, env, contextItemType); 111 thenExp = thenExp.optimize(opt, env, contextItemType); 112 elseExp = elseExp.optimize(opt, env, contextItemType); 113 return this; 114 } 115 116 117 120 121 public Expression promote(PromotionOffer offer) throws XPathException { 122 Expression exp = offer.accept(this); 123 if (exp != null) { 124 return exp; 125 } else { 126 condition = doPromotion(condition, offer); 130 131 if (offer.action == PromotionOffer.UNORDERED || 133 offer.action == PromotionOffer.INLINE_VARIABLE_REFERENCES || 134 offer.action == PromotionOffer.REPLACE_CURRENT) { 135 thenExp = doPromotion(thenExp, offer); 136 elseExp = doPromotion(elseExp, offer); 137 } 138 return this; 139 } 140 } 141 142 145 146 public Iterator iterateSubExpressions() { 147 ArrayList a = new ArrayList (3); 148 a.add(condition); 149 a.add(thenExp); 150 a.add(elseExp); 151 return a.iterator(); 152 } 153 154 157 158 public boolean markTailFunctionCalls() { 159 boolean a = ExpressionTool.markTailFunctionCalls(thenExp); 160 boolean b = ExpressionTool.markTailFunctionCalls(elseExp); 161 return a || b; 162 } 163 164 171 172 public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException { 173 thenExp.checkPermittedContents(parentType, env, whole); 174 elseExp.checkPermittedContents(parentType, env, whole); 175 } 176 177 181 182 public Item evaluateItem(XPathContext context) throws XPathException { 183 if (condition.effectiveBooleanValue(context)) { 184 return thenExp.evaluateItem(context); 185 } else { 186 return elseExp.evaluateItem(context); 187 } 188 } 189 190 194 195 public SequenceIterator iterate(XPathContext context) throws XPathException { 196 if (condition.effectiveBooleanValue(context)) { 197 return thenExp.iterate(context); 198 } else { 199 return elseExp.iterate(context); 200 } 201 } 202 203 207 208 public void process(XPathContext context) throws XPathException { 209 if (condition.effectiveBooleanValue(context)) { 210 thenExp.process(context); 211 } else { 212 elseExp.process(context); 213 } 214 } 215 216 227 228 public TailCall processLeavingTail(XPathContext context) throws XPathException { 229 if (condition.effectiveBooleanValue(context)) { 230 if (thenExp instanceof TailCallReturner) { 231 return ((TailCallReturner)thenExp).processLeavingTail(context); 232 } else { 233 thenExp.process(context); 234 return null; 235 } 236 } else { 237 if (elseExp instanceof TailCallReturner) { 238 return ((TailCallReturner)elseExp).processLeavingTail(context); 239 } else { 240 elseExp.process(context); 241 return null; 242 } 243 } 244 } 245 246 247 250 251 public ItemType getItemType() { 252 return Type.getCommonSuperType(thenExp.getItemType(), elseExp.getItemType()); 253 } 254 255 258 259 public int computeCardinality() { 260 return Cardinality.union(thenExp.getCardinality(), elseExp.getCardinality()); 261 } 262 263 268 269 public int computeSpecialProperties() { 270 if (thenExp instanceof EmptySequence) { 272 return elseExp.getSpecialProperties(); 273 } 274 if (elseExp instanceof EmptySequence) { 275 return thenExp.getSpecialProperties(); 276 } 277 return thenExp.getSpecialProperties() & elseExp.getSpecialProperties(); 279 } 280 281 284 285 public void display(int level, NamePool pool, PrintStream out) { 286 out.println(ExpressionTool.indent(level) + "if ("); 287 condition.display(level+1, pool, out); 288 out.println(ExpressionTool.indent(level) + "then"); 289 thenExp.display(level+1, pool, out); 290 out.println(ExpressionTool.indent(level) + "else"); 291 elseExp.display(level+1, pool, out); 292 } 293 294 } 295 296 297 298 | Popular Tags |