1 package net.sf.saxon.expr; 2 import net.sf.saxon.om.NamePool; 3 import net.sf.saxon.trans.StaticError; 4 import net.sf.saxon.trans.XPathException; 5 import net.sf.saxon.type.ItemType; 6 import net.sf.saxon.value.Value; 7 8 import java.io.PrintStream ; 9 import java.util.Arrays ; 10 import java.util.Iterator ; 11 12 15 16 public abstract class FunctionCall extends ComputedExpression { 17 18 21 22 private int nameCode; 23 24 28 29 protected Expression[] argument; 30 31 34 35 public final void setFunctionNameCode(int nc) { 36 nameCode = nc; 37 } 38 39 43 44 public final int getFunctionNameCode() { 45 return nameCode; 46 } 47 48 51 52 public final int getNumberOfArguments() { 53 return argument.length; 54 } 55 56 59 60 public void setArguments(Expression[] args) { 61 argument = args; 62 for (int a=0; a<args.length; a++) { 63 adoptChildExpression(args[a]); 64 } 65 } 66 67 71 72 public Expression simplify(StaticContext env) throws XPathException { 73 return simplifyArguments(env); 74 } 75 76 81 82 protected final Expression simplifyArguments(StaticContext env) throws XPathException { 83 for (int i=0; i<argument.length; i++) { 84 Expression exp = argument[i].simplify(env); 85 if (exp != argument[i]) { 86 adoptChildExpression(exp); 87 argument[i] = exp; 88 } 89 } 90 return this; 91 } 92 93 98 99 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 100 boolean fixed = true; 101 for (int i=0; i<argument.length; i++) { 102 Expression exp = argument[i].typeCheck(env, contextItemType); 103 if (exp != argument[i]) { 104 adoptChildExpression(exp); 105 argument[i] = exp; 106 } 107 if (!(argument[i] instanceof Value)) { 108 fixed = false; 109 } 110 } 111 checkArguments(env); 112 if (fixed) { 113 return preEvaluate(env); 114 } else { 115 return this; 116 } 117 } 118 119 136 137 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 138 boolean fixed = true; 139 for (int i=0; i<argument.length; i++) { 140 Expression exp = argument[i].optimize(opt, env, contextItemType); 141 if (exp != argument[i]) { 142 adoptChildExpression(exp); 143 argument[i] = exp; 144 } 145 if (!(argument[i] instanceof Value)) { 146 fixed = false; 147 } 148 } 149 checkArguments(env); 150 if (fixed) { 151 return preEvaluate(env); 152 } else { 153 return this; 154 } 155 } 156 157 161 162 public Expression preEvaluate(StaticContext env) throws XPathException { 163 return ExpressionTool.eagerEvaluate(this, null); 164 } 165 166 169 170 public Expression promote(PromotionOffer offer) throws XPathException { 171 Expression exp = offer.accept(this); 172 if (exp != null) { 173 return exp; 174 } else { 175 if (offer.action != PromotionOffer.UNORDERED) { 176 for (int i=0; i<argument.length; i++) { 177 argument[i] = doPromotion(argument[i], offer); 178 } 179 } 180 return this; 181 } 182 } 183 184 188 189 protected abstract void checkArguments(StaticContext env) throws XPathException; 190 191 199 200 protected int checkArgumentCount(int min, int max, StaticContext env) throws XPathException { 201 int numArgs = argument.length; 202 if (min==max && numArgs != min) { 203 throw new StaticError("Function " + getDisplayName(env.getNamePool()) + " must have " 204 + min + pluralArguments(min), 205 ExpressionTool.getLocator(this)); 206 } 207 if (numArgs < min) { 208 throw new StaticError("Function " + getDisplayName(env.getNamePool()) + " must have at least " 209 + min + pluralArguments(min), 210 ExpressionTool.getLocator(this)); 211 } 212 if (numArgs > max) { 213 throw new StaticError("Function " + getDisplayName(env.getNamePool()) + " must have no more than " 214 + max + pluralArguments(max), 215 ExpressionTool.getLocator(this)); 216 } 217 return numArgs; 218 } 219 220 223 224 private static String pluralArguments(int num) { 225 if (num==1) return " argument"; 226 return " arguments"; 227 } 228 229 232 233 public Iterator iterateSubExpressions() { 234 return Arrays.asList(argument).iterator(); 235 } 236 237 240 241 public final String getDisplayName(NamePool pool) { 242 return pool.getDisplayName(getFunctionNameCode()); 243 } 244 245 public void display(int level, NamePool pool, PrintStream out) { 246 out.println(ExpressionTool.indent(level) + "function " + getDisplayName(pool)); 247 for (int a=0; a<argument.length; a++) { 248 argument[a].display(level+1, pool, out); 249 } 250 } 251 252 } 253 254 | Popular Tags |