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.ALOAD; 25 import com.sun.org.apache.bcel.internal.generic.ASTORE; 26 import com.sun.org.apache.bcel.internal.generic.BranchHandle; 27 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 28 import com.sun.org.apache.bcel.internal.generic.GOTO; 29 import com.sun.org.apache.bcel.internal.generic.IFGT; 30 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 31 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 32 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 33 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; 34 import com.sun.org.apache.bcel.internal.generic.InstructionList; 35 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 36 import com.sun.org.apache.bcel.internal.generic.NEW; 37 import com.sun.org.apache.bcel.internal.generic.PUSH; 38 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 39 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.StringType; 41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 44 45 49 final class KeyCall extends FunctionCall { 50 51 54 private Expression _name; 55 56 59 private Expression _value; 60 61 64 private Type _valueType; 66 69 private QName _resolvedQName = null; 70 71 83 public KeyCall(QName fname, Vector arguments) { 84 super(fname, arguments); 85 switch(argumentCount()) { 86 case 1: 87 _name = null; 88 _value = argument(0); 89 break; 90 case 2: 91 _name = argument(0); 92 _value = argument(1); 93 break; 94 default: 95 _name = _value = null; 96 break; 97 } 98 } 99 111 public void addParentDependency() { 112 if (_resolvedQName == null) return; 114 115 SyntaxTreeNode node = this; 116 while (node != null && node instanceof TopLevelElement == false) { 117 node = node.getParent(); 118 } 119 120 TopLevelElement parent = (TopLevelElement) node; 121 if (parent != null) { 122 parent.addDependency(getSymbolTable().getKey(_resolvedQName)); 123 } 124 } 125 132 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 133 final Type returnType = super.typeCheck(stable); 134 135 if (_name != null) { 138 final Type nameType = _name.typeCheck(stable); 139 140 if (_name instanceof LiteralExpr) { 141 final LiteralExpr literal = (LiteralExpr) _name; 142 _resolvedQName = 143 getParser().getQNameIgnoreDefaultNs(literal.getValue()); 144 } 145 else if (nameType instanceof StringType == false) { 146 _name = new CastExpr(_name, Type.String); 147 } 148 } 149 150 _valueType = _value.typeCheck(stable); 158 159 if (_valueType != Type.NodeSet && _valueType != Type.String) 160 { 161 _value = new CastExpr(_value, Type.String); 162 } 163 addParentDependency(); 165 166 return returnType; 167 } 168 169 180 public void translate(ClassGenerator classGen, 181 MethodGenerator methodGen) { 182 final ConstantPoolGen cpg = classGen.getConstantPool(); 183 final InstructionList il = methodGen.getInstructionList(); 184 185 final int getNodeHandle = cpg.addInterfaceMethodref(DOM_INTF, 186 "getNodeHandle", 187 "(I)"+NODE_SIG); 188 189 final int dupInit = cpg.addMethodref(DUP_FILTERED_ITERATOR, 192 "<init>", 193 "("+NODE_ITERATOR_SIG+")V"); 194 195 il.append(new NEW(cpg.addClass(DUP_FILTERED_ITERATOR))); 196 il.append(DUP); 197 translateCall(classGen, methodGen); 198 il.append(new INVOKESPECIAL(dupInit)); 199 200 } 201 202 207 private void translateCall(ClassGenerator classGen, 208 MethodGenerator methodGen) { 209 210 final ConstantPoolGen cpg = classGen.getConstantPool(); 211 final InstructionList il = methodGen.getInstructionList(); 212 213 final int getNodeValue = cpg.addInterfaceMethodref(DOM_INTF, 215 GET_NODE_VALUE, 216 "(I)"+STRING_SIG); 217 218 final int getKeyIndex = cpg.addMethodref(TRANSLET_CLASS, 220 "getKeyIndex", 221 "(Ljava/lang/String;)"+ 222 KEY_INDEX_SIG); 223 224 final int lookupId = cpg.addMethodref(KEY_INDEX_CLASS, 226 "lookupId", 227 "(Ljava/lang/Object;)V"); 228 final int lookupKey = cpg.addMethodref(KEY_INDEX_CLASS, 229 "lookupKey", 230 "(Ljava/lang/Object;)V"); 231 232 final int merge = cpg.addMethodref(KEY_INDEX_CLASS, 234 "merge", 235 "("+KEY_INDEX_SIG+")V"); 236 237 final int indexConstructor = cpg.addMethodref(TRANSLET_CLASS, 239 "createKeyIndex", 240 "()"+KEY_INDEX_SIG); 241 242 final int keyDom = cpg.addMethodref(XSLT_PACKAGE + ".dom.KeyIndex", 244 "setDom", 245 "("+DOM_INTF_SIG+")V"); 246 247 248 final LocalVariableGen returnIndex = 250 methodGen.addLocalVariable("returnIndex", 251 Util.getJCRefType(KEY_INDEX_SIG), 252 il.getEnd(), null); 253 254 final LocalVariableGen searchIndex = 256 methodGen.addLocalVariable("searchIndex", 257 Util.getJCRefType(KEY_INDEX_SIG), 258 il.getEnd(), null); 259 260 if (_valueType == Type.NodeSet) { 264 il.append(methodGen.loadCurrentNode()); 266 il.append(methodGen.loadIterator()); 267 268 _value.translate(classGen, methodGen); 270 _value.startIterator(classGen, methodGen); 271 il.append(methodGen.storeIterator()); 272 273 il.append(classGen.loadTranslet()); 275 il.append(new INVOKEVIRTUAL(indexConstructor)); 276 il.append(DUP); 277 il.append(methodGen.loadDOM()); 278 il.append(new INVOKEVIRTUAL(keyDom)); 279 il.append(new ASTORE(returnIndex.getIndex())); 280 281 il.append(classGen.loadTranslet()); 283 if (_name == null) { 284 il.append(new PUSH(cpg,"##id")); 285 } 286 else if (_resolvedQName != null) { 287 il.append(new PUSH(cpg, _resolvedQName.toString())); 288 } 289 else { 290 _name.translate(classGen, methodGen); 291 } 292 293 il.append(new INVOKEVIRTUAL(getKeyIndex)); 294 il.append(new ASTORE(searchIndex.getIndex())); 295 296 298 final BranchHandle nextNode = il.append(new GOTO(null)); 301 final InstructionHandle loop = il.append(NOP); 302 303 il.append(new ALOAD(returnIndex.getIndex())); 305 306 il.append(new ALOAD(searchIndex.getIndex())); 308 il.append(DUP); 309 il.append(methodGen.loadDOM()); 310 il.append(methodGen.loadCurrentNode()); 311 il.append(new INVOKEINTERFACE(getNodeValue, 2)); 312 if (_name == null) { 313 il.append(new INVOKEVIRTUAL(lookupId)); 314 } 315 else { 316 il.append(new INVOKEVIRTUAL(lookupKey)); 317 } 318 319 il.append(new INVOKEVIRTUAL(merge)); 321 322 nextNode.setTarget(il.append(methodGen.loadIterator())); 324 il.append(methodGen.nextNode()); 325 il.append(DUP); 326 il.append(methodGen.storeCurrentNode()); 327 il.append(new IFGT(loop)); 328 329 331 il.append(methodGen.storeIterator()); 333 il.append(methodGen.storeCurrentNode()); 334 335 il.append(new ALOAD(returnIndex.getIndex())); 337 } 338 else { 341 il.append(classGen.loadTranslet()); 344 if (_name == null) { 345 il.append(new PUSH(cpg,"##id")); 346 } 347 else if (_resolvedQName != null) { 348 il.append(new PUSH(cpg, _resolvedQName.toString())); 349 } 350 else { 351 _name.translate(classGen, methodGen); 352 } 353 il.append(new INVOKEVIRTUAL(getKeyIndex)); 354 355 il.append(DUP); 358 359 _value.translate(classGen, methodGen); 360 361 if (_name == null) { 362 il.append(new INVOKEVIRTUAL(lookupId)); 363 } 364 else { 365 il.append(new INVOKEVIRTUAL(lookupKey)); 366 } 367 } 368 } 369 } 370 | Popular Tags |