1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import java.util.Vector ; 23 24 import com.sun.org.apache.bcel.internal.generic.CHECKCAST; 25 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 26 import com.sun.org.apache.bcel.internal.generic.ICONST; 27 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 28 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 29 import com.sun.org.apache.bcel.internal.generic.InstructionList; 30 import com.sun.org.apache.bcel.internal.generic.NEW; 31 import com.sun.org.apache.bcel.internal.generic.PUSH; 32 import com.sun.org.apache.xalan.internal.xsltc.DOM; 33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 37 import com.sun.org.apache.xalan.internal.xsltc.dom.Axis; 38 import com.sun.org.apache.xml.internal.dtm.DTM; 39 40 45 final class Step extends RelativeLocationPath { 46 47 50 private int _axis; 51 52 55 private Vector _predicates; 56 57 62 private boolean _hadPredicates = false; 63 64 67 private int _nodeType; 68 69 public Step(int axis, int nodeType, Vector predicates) { 70 _axis = axis; 71 _nodeType = nodeType; 72 _predicates = predicates; 73 } 74 75 78 public void setParser(Parser parser) { 79 super.setParser(parser); 80 if (_predicates != null) { 81 final int n = _predicates.size(); 82 for (int i = 0; i < n; i++) { 83 final Predicate exp = (Predicate)_predicates.elementAt(i); 84 exp.setParser(parser); 85 exp.setParent(this); 86 } 87 } 88 } 89 90 93 public int getAxis() { 94 return _axis; 95 } 96 97 100 public void setAxis(int axis) { 101 _axis = axis; 102 } 103 104 107 public int getNodeType() { 108 return _nodeType; 109 } 110 111 114 public Vector getPredicates() { 115 return _predicates; 116 } 117 118 121 public void addPredicates(Vector predicates) { 122 if (_predicates == null) { 123 _predicates = predicates; 124 } 125 else { 126 _predicates.addAll(predicates); 127 } 128 } 129 130 135 private boolean hasParentPattern() { 136 final SyntaxTreeNode parent = getParent(); 137 return (parent instanceof ParentPattern || 138 parent instanceof ParentLocationPath || 139 parent instanceof UnionPathExpr || 140 parent instanceof FilterParentPath); 141 } 142 143 146 private boolean hasParentLocationPath() { 147 return getParent() instanceof ParentLocationPath; 148 } 149 150 153 private boolean hasPredicates() { 154 return _predicates != null && _predicates.size() > 0; 155 } 156 157 160 private boolean isPredicate() { 161 SyntaxTreeNode parent = this; 162 while (parent != null) { 163 parent = parent.getParent(); 164 if (parent instanceof Predicate) return true; 165 } 166 return false; 167 } 168 169 172 public boolean isAbbreviatedDot() { 173 return _nodeType == NodeTest.ANODE && _axis == Axis.SELF; 174 } 175 176 177 180 public boolean isAbbreviatedDDot() { 181 return _nodeType == NodeTest.ANODE && _axis == Axis.PARENT; 182 } 183 184 189 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 190 191 _hadPredicates = hasPredicates(); 194 195 if (isAbbreviatedDot()) { 199 _type = (hasParentPattern() || hasPredicates() || hasParentLocationPath()) ? 200 Type.NodeSet : Type.Node; 201 } 202 else { 203 _type = Type.NodeSet; 204 } 205 206 if (_predicates != null) { 208 final int n = _predicates.size(); 209 for (int i = 0; i < n; i++) { 210 final Expression pred = (Expression)_predicates.elementAt(i); 211 pred.typeCheck(stable); 212 } 213 } 214 215 return _type; 217 } 218 219 226 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 227 final ConstantPoolGen cpg = classGen.getConstantPool(); 228 final InstructionList il = methodGen.getInstructionList(); 229 230 if (hasPredicates()) { 231 translatePredicates(classGen, methodGen); 232 } else { 233 int star = 0; 234 String name = null; 235 final XSLTC xsltc = getParser().getXSLTC(); 236 237 if (_nodeType >= DTM.NTYPES) { 238 final Vector ni = xsltc.getNamesIndex(); 239 240 name = (String )ni.elementAt(_nodeType-DTM.NTYPES); 241 star = name.lastIndexOf('*'); 242 } 243 244 if (_axis == Axis.ATTRIBUTE && _nodeType != NodeTest.ATTRIBUTE 247 && _nodeType != NodeTest.ANODE && !hasParentPattern() 248 && star == 0) 249 { 250 int iter = cpg.addInterfaceMethodref(DOM_INTF, 251 "getTypedAxisIterator", 252 "(II)"+NODE_ITERATOR_SIG); 253 il.append(methodGen.loadDOM()); 254 il.append(new PUSH(cpg, Axis.ATTRIBUTE)); 255 il.append(new PUSH(cpg, _nodeType)); 256 il.append(new INVOKEINTERFACE(iter, 3)); 257 return; 258 } 259 260 SyntaxTreeNode parent = getParent(); 261 if (isAbbreviatedDot()) { 263 if (_type == Type.Node) { 264 il.append(methodGen.loadContextNode()); 266 } 267 else { 268 if (parent instanceof ParentLocationPath){ 269 int init = cpg.addMethodref(SINGLETON_ITERATOR, 271 "<init>", 272 "("+NODE_SIG+")V"); 273 il.append(new NEW(cpg.addClass(SINGLETON_ITERATOR))); 274 il.append(DUP); 275 il.append(methodGen.loadContextNode()); 276 il.append(new INVOKESPECIAL(init)); 277 } else { 278 int git = cpg.addInterfaceMethodref(DOM_INTF, 280 "getAxisIterator", 281 "(I)"+NODE_ITERATOR_SIG); 282 il.append(methodGen.loadDOM()); 283 il.append(new PUSH(cpg, _axis)); 284 il.append(new INVOKEINTERFACE(git, 2)); 285 } 286 } 287 return; 288 } 289 290 if ((parent instanceof ParentLocationPath) && 292 (parent.getParent() instanceof ParentLocationPath)) { 293 if ((_nodeType == NodeTest.ELEMENT) && (!_hadPredicates)) { 294 _nodeType = NodeTest.ANODE; 295 } 296 } 297 298 switch (_nodeType) { 300 case NodeTest.ATTRIBUTE: 301 _axis = Axis.ATTRIBUTE; 302 case NodeTest.ANODE: 303 int git = cpg.addInterfaceMethodref(DOM_INTF, 305 "getAxisIterator", 306 "(I)"+NODE_ITERATOR_SIG); 307 il.append(methodGen.loadDOM()); 308 il.append(new PUSH(cpg, _axis)); 309 il.append(new INVOKEINTERFACE(git, 2)); 310 break; 311 default: 312 if (star > 1) { 313 final String namespace; 314 if (_axis == Axis.ATTRIBUTE) 315 namespace = name.substring(0,star-2); 316 else 317 namespace = name.substring(0,star-1); 318 319 final int nsType = xsltc.registerNamespace(namespace); 320 final int ns = cpg.addInterfaceMethodref(DOM_INTF, 321 "getNamespaceAxisIterator", 322 "(II)"+NODE_ITERATOR_SIG); 323 il.append(methodGen.loadDOM()); 324 il.append(new PUSH(cpg, _axis)); 325 il.append(new PUSH(cpg, nsType)); 326 il.append(new INVOKEINTERFACE(ns, 3)); 327 break; 328 } 329 case NodeTest.ELEMENT: 330 final int ty = cpg.addInterfaceMethodref(DOM_INTF, 332 "getTypedAxisIterator", 333 "(II)"+NODE_ITERATOR_SIG); 334 il.append(methodGen.loadDOM()); 336 il.append(new PUSH(cpg, _axis)); 337 il.append(new PUSH(cpg, _nodeType)); 338 il.append(new INVOKEINTERFACE(ty, 3)); 339 340 break; 341 } 342 } 343 } 344 345 346 352 public void translatePredicates(ClassGenerator classGen, 353 MethodGenerator methodGen) { 354 final ConstantPoolGen cpg = classGen.getConstantPool(); 355 final InstructionList il = methodGen.getInstructionList(); 356 357 int idx = 0; 358 359 if (_predicates.size() == 0) { 360 translate(classGen, methodGen); 361 } 362 else { 363 final Predicate predicate = (Predicate)_predicates.lastElement(); 364 _predicates.remove(predicate); 365 366 if (predicate.isNodeValueTest()) { 374 Step step = predicate.getStep(); 375 376 il.append(methodGen.loadDOM()); 377 if (step.isAbbreviatedDot()) { 380 translate(classGen, methodGen); 381 il.append(new ICONST(DOM.RETURN_CURRENT)); 382 } 383 else { 386 ParentLocationPath path = new ParentLocationPath(this, step); 387 _parent = step._parent = path; 389 try { 390 path.typeCheck(getParser().getSymbolTable()); 391 } 392 catch (TypeCheckError e) { } 393 path.translate(classGen, methodGen); 394 il.append(new ICONST(DOM.RETURN_PARENT)); 395 } 396 predicate.translate(classGen, methodGen); 397 idx = cpg.addInterfaceMethodref(DOM_INTF, 398 GET_NODE_VALUE_ITERATOR, 399 GET_NODE_VALUE_ITERATOR_SIG); 400 il.append(new INVOKEINTERFACE(idx, 5)); 401 } 402 else if (predicate.isNthDescendant()) { 404 il.append(methodGen.loadDOM()); 405 il.append(new ICONST(predicate.getPosType())); 407 predicate.translate(classGen, methodGen); 408 il.append(new ICONST(0)); 409 idx = cpg.addInterfaceMethodref(DOM_INTF, 410 "getNthDescendant", 411 "(IIZ)"+NODE_ITERATOR_SIG); 412 il.append(new INVOKEINTERFACE(idx, 4)); 413 } 414 else if (predicate.isNthPositionFilter()) { 416 idx = cpg.addMethodref(NTH_ITERATOR_CLASS, 417 "<init>", 418 "("+NODE_ITERATOR_SIG+"I)V"); 419 il.append(new NEW(cpg.addClass(NTH_ITERATOR_CLASS))); 420 il.append(DUP); 421 translatePredicates(classGen, methodGen); predicate.translate(classGen, methodGen); 423 il.append(new INVOKESPECIAL(idx)); 424 } 425 else { 426 idx = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, 427 "<init>", 428 "(" 429 + NODE_ITERATOR_SIG 430 + CURRENT_NODE_LIST_FILTER_SIG 431 + NODE_SIG 432 + TRANSLET_SIG 433 + ")V"); 434 il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); 436 il.append(DUP); 437 translatePredicates(classGen, methodGen); predicate.translateFilter(classGen, methodGen); 439 440 il.append(methodGen.loadCurrentNode()); 441 il.append(classGen.loadTranslet()); 442 if (classGen.isExternal()) { 443 final String className = classGen.getClassName(); 444 il.append(new CHECKCAST(cpg.addClass(className))); 445 } 446 il.append(new INVOKESPECIAL(idx)); 447 } 448 } 449 } 450 451 454 public String toString() { 455 final StringBuffer buffer = new StringBuffer ("step(\""); 456 buffer.append(Axis.names[_axis]).append("\", ").append(_nodeType); 457 if (_predicates != null) { 458 final int n = _predicates.size(); 459 for (int i = 0; i < n; i++) { 460 final Predicate pred = (Predicate)_predicates.elementAt(i); 461 buffer.append(", ").append(pred.toString()); 462 } 463 } 464 return buffer.append(')').toString(); 465 } 466 } 467 | Popular Tags |