1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import org.apache.bcel.generic.ConstantPoolGen; 23 import org.apache.bcel.generic.INVOKEINTERFACE; 24 import org.apache.bcel.generic.INVOKESPECIAL; 25 import org.apache.bcel.generic.INVOKEVIRTUAL; 26 import org.apache.bcel.generic.InstructionList; 27 import org.apache.bcel.generic.NEW; 28 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 29 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 30 import org.apache.xalan.xsltc.compiler.util.Type; 31 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 32 import org.apache.xalan.xsltc.dom.Axis; 33 import org.apache.xml.dtm.DTM; 34 35 39 final class ParentLocationPath extends RelativeLocationPath { 40 private Expression _step; 41 private final RelativeLocationPath _path; 42 private Type stype; 43 private boolean _orderNodes = false; 44 private boolean _axisMismatch = false; 45 46 public ParentLocationPath(RelativeLocationPath path, Expression step) { 47 _path = path; 48 _step = step; 49 _path.setParent(this); 50 _step.setParent(this); 51 52 if (_step instanceof Step) { 53 _axisMismatch = checkAxisMismatch(); 54 } 55 } 56 57 public void setAxis(int axis) { 58 _path.setAxis(axis); 59 } 60 61 public int getAxis() { 62 return _path.getAxis(); 63 } 64 65 public RelativeLocationPath getPath() { 66 return(_path); 67 } 68 69 public Expression getStep() { 70 return(_step); 71 } 72 73 public void setParser(Parser parser) { 74 super.setParser(parser); 75 _step.setParser(parser); 76 _path.setParser(parser); 77 } 78 79 public String toString() { 80 return "ParentLocationPath(" + _path + ", " + _step + ')'; 81 } 82 83 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 84 stype = _step.typeCheck(stable); 85 _path.typeCheck(stable); 86 87 if (_axisMismatch) enableNodeOrdering(); 88 89 return _type = Type.NodeSet; 90 } 91 92 public void enableNodeOrdering() { 93 SyntaxTreeNode parent = getParent(); 94 if (parent instanceof ParentLocationPath) 95 ((ParentLocationPath)parent).enableNodeOrdering(); 96 else { 97 _orderNodes = true; 98 } 99 } 100 101 106 public boolean checkAxisMismatch() { 107 108 int left = _path.getAxis(); 109 int right = ((Step)_step).getAxis(); 110 111 if (((left == Axis.ANCESTOR) || (left == Axis.ANCESTORORSELF)) && 112 ((right == Axis.CHILD) || 113 (right == Axis.DESCENDANT) || 114 (right == Axis.DESCENDANTORSELF) || 115 (right == Axis.PARENT) || 116 (right == Axis.PRECEDING) || 117 (right == Axis.PRECEDINGSIBLING))) 118 return true; 119 120 if ((left == Axis.CHILD) && 121 (right == Axis.ANCESTOR) || 122 (right == Axis.ANCESTORORSELF) || 123 (right == Axis.PARENT) || 124 (right == Axis.PRECEDING)) 125 return true; 126 127 if ((left == Axis.DESCENDANT) || (left == Axis.DESCENDANTORSELF)) 128 return true; 129 130 if (((left == Axis.FOLLOWING) || (left == Axis.FOLLOWINGSIBLING)) && 131 ((right == Axis.FOLLOWING) || 132 (right == Axis.PARENT) || 133 (right == Axis.PRECEDING) || 134 (right == Axis.PRECEDINGSIBLING))) 135 return true; 136 137 if (((left == Axis.PRECEDING) || (left == Axis.PRECEDINGSIBLING)) && 138 ((right == Axis.DESCENDANT) || 139 (right == Axis.DESCENDANTORSELF) || 140 (right == Axis.FOLLOWING) || 141 (right == Axis.FOLLOWINGSIBLING) || 142 (right == Axis.PARENT) || 143 (right == Axis.PRECEDING) || 144 (right == Axis.PRECEDINGSIBLING))) 145 return true; 146 147 if ((right == Axis.FOLLOWING) && (left == Axis.CHILD)) { 148 if (_path instanceof Step) { 153 int type = ((Step)_path).getNodeType(); 154 if (type == DTM.ATTRIBUTE_NODE) return true; 155 } 156 } 157 158 return false; 159 } 160 161 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 162 final ConstantPoolGen cpg = classGen.getConstantPool(); 163 final InstructionList il = methodGen.getInstructionList(); 164 165 final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS, 167 "<init>", 168 "(" 169 +NODE_ITERATOR_SIG 170 +NODE_ITERATOR_SIG 171 +")V"); 172 il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS))); 173 il.append(DUP); 174 175 _path.translate(classGen, methodGen); _step.translate(classGen, methodGen); 178 179 il.append(new INVOKESPECIAL(initSI)); 181 182 Expression stp = _step; 184 if (stp instanceof ParentLocationPath) 185 stp = ((ParentLocationPath)stp).getStep(); 186 187 if ((_path instanceof Step) && (stp instanceof Step)) { 188 final int path = ((Step)_path).getAxis(); 189 final int step = ((Step)stp).getAxis(); 190 if ((path == Axis.DESCENDANTORSELF && step == Axis.CHILD) || 191 (path == Axis.PRECEDING && step == Axis.PARENT)) { 192 final int incl = cpg.addMethodref(NODE_ITERATOR_BASE, 193 "includeSelf", 194 "()" + NODE_ITERATOR_SIG); 195 il.append(new INVOKEVIRTUAL(incl)); 196 } 197 } 198 199 205 if (_orderNodes) { 206 final int order = cpg.addInterfaceMethodref(DOM_INTF, 207 ORDER_ITERATOR, 208 ORDER_ITERATOR_SIG); 209 il.append(methodGen.loadDOM()); 210 il.append(SWAP); 211 il.append(methodGen.loadContextNode()); 212 il.append(new INVOKEINTERFACE(order, 3)); 213 } 214 } 215 } 216 | Popular Tags |