1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.util.Vector ; 23 24 import org.apache.bcel.generic.ConstantPoolGen; 25 import org.apache.bcel.generic.INVOKEINTERFACE; 26 import org.apache.bcel.generic.INVOKESPECIAL; 27 import org.apache.bcel.generic.INVOKEVIRTUAL; 28 import org.apache.bcel.generic.InstructionList; 29 import org.apache.bcel.generic.NEW; 30 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 31 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 32 import org.apache.xalan.xsltc.compiler.util.Type; 33 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 34 import org.apache.xalan.xsltc.dom.Axis; 35 import org.apache.xml.dtm.DTM; 36 37 41 final class UnionPathExpr extends Expression { 42 43 private final Expression _pathExpr; 44 private final Expression _rest; 45 private boolean _reverse = false; 46 47 private Expression[] _components; 49 50 public UnionPathExpr(Expression pathExpr, Expression rest) { 51 _pathExpr = pathExpr; 52 _rest = rest; 53 } 54 55 public void setParser(Parser parser) { 56 super.setParser(parser); 57 final Vector components = new Vector (); 59 flatten(components); 60 final int size = components.size(); 61 _components = (Expression[])components.toArray(new Expression[size]); 62 for (int i = 0; i < size; i++) { 63 _components[i].setParser(parser); 64 _components[i].setParent(this); 65 if (_components[i] instanceof Step) { 66 final Step step = (Step)_components[i]; 67 final int axis = step.getAxis(); 68 final int type = step.getNodeType(); 69 if ((axis == Axis.ATTRIBUTE) || (type == DTM.ATTRIBUTE_NODE)) { 71 _components[i] = _components[0]; 72 _components[0] = step; 73 } 74 if (Axis.isReverse[axis]) _reverse = true; 76 } 77 } 78 if (getParent() instanceof Expression) _reverse = false; 80 } 81 82 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 83 final int length = _components.length; 84 for (int i = 0; i < length; i++) { 85 if (_components[i].typeCheck(stable) != Type.NodeSet) { 86 _components[i] = new CastExpr(_components[i], Type.NodeSet); 87 } 88 } 89 return _type = Type.NodeSet; 90 } 91 92 public String toString() { 93 return "union(" + _pathExpr + ", " + _rest + ')'; 94 } 95 96 private void flatten(Vector components) { 97 components.addElement(_pathExpr); 98 if (_rest != null) { 99 if (_rest instanceof UnionPathExpr) { 100 ((UnionPathExpr)_rest).flatten(components); 101 } 102 else { 103 components.addElement(_rest); 104 } 105 } 106 } 107 108 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 109 final ConstantPoolGen cpg = classGen.getConstantPool(); 110 final InstructionList il = methodGen.getInstructionList(); 111 112 final int init = cpg.addMethodref(UNION_ITERATOR_CLASS, 113 "<init>", 114 "("+DOM_INTF_SIG+")V"); 115 final int iter = cpg.addMethodref(UNION_ITERATOR_CLASS, 116 ADD_ITERATOR, 117 ADD_ITERATOR_SIG); 118 119 il.append(new NEW(cpg.addClass(UNION_ITERATOR_CLASS))); 121 il.append(DUP); 122 il.append(methodGen.loadDOM()); 123 il.append(new INVOKESPECIAL(init)); 124 125 final int length = _components.length; 127 for (int i = 0; i < length; i++) { 128 _components[i].translate(classGen, methodGen); 129 il.append(new INVOKEVIRTUAL(iter)); 130 } 131 132 if (_reverse) { 134 final int order = cpg.addInterfaceMethodref(DOM_INTF, 135 ORDER_ITERATOR, 136 ORDER_ITERATOR_SIG); 137 il.append(methodGen.loadDOM()); 138 il.append(SWAP); 139 il.append(methodGen.loadContextNode()); 140 il.append(new INVOKEINTERFACE(order, 3)); 141 142 } 143 } 144 } 145 | Popular Tags |