1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-2004 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 /* 21 * $Id: ParentPattern.java,v 1.2.4.1 2005/09/02 11:10:09 pvedula Exp $ 22 */ 23 24 package com.sun.org.apache.xalan.internal.xsltc.compiler; 25 26 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 27 import com.sun.org.apache.bcel.internal.generic.ILOAD; 28 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 29 import com.sun.org.apache.bcel.internal.generic.ISTORE; 30 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; 31 import com.sun.org.apache.bcel.internal.generic.InstructionList; 32 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 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.compiler.util.Util; 38 39 /** 40 * @author Jacek Ambroziak 41 * @author Santiago Pericas-Geertsen 42 */ 43 final class ParentPattern extends RelativePathPattern { 44 private final Pattern _left; 45 private final RelativePathPattern _right; 46 47 public ParentPattern(Pattern left, RelativePathPattern right) { 48 (_left = left).setParent(this); 49 (_right = right).setParent(this); 50 } 51 52 public void setParser(Parser parser) { 53 super.setParser(parser); 54 _left.setParser(parser); 55 _right.setParser(parser); 56 } 57 58 public boolean isWildcard() { 59 return false; 60 } 61 62 public StepPattern getKernelPattern() { 63 return _right.getKernelPattern(); 64 } 65 66 public void reduceKernelPattern() { 67 _right.reduceKernelPattern(); 68 } 69 70 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 71 _left.typeCheck(stable); 72 return _right.typeCheck(stable); 73 } 74 75 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 76 final ConstantPoolGen cpg = classGen.getConstantPool(); 77 final InstructionList il = methodGen.getInstructionList(); 78 final LocalVariableGen local = 79 methodGen.addLocalVariable2("ppt", 80 Util.getJCRefType(NODE_SIG), 81 null); 82 83 final com.sun.org.apache.bcel.internal.generic.Instruction loadLocal = 84 new ILOAD(local.getIndex()); 85 final com.sun.org.apache.bcel.internal.generic.Instruction storeLocal = 86 new ISTORE(local.getIndex()); 87 88 if (_right.isWildcard()) { 89 il.append(methodGen.loadDOM()); 90 il.append(SWAP); 91 } 92 else if (_right instanceof StepPattern) { 93 il.append(DUP); 94 local.setStart(il.append(storeLocal)); 95 96 _right.translate(classGen, methodGen); 97 98 il.append(methodGen.loadDOM()); 99 local.setEnd(il.append(loadLocal)); 100 } 101 else { 102 _right.translate(classGen, methodGen); 103 104 if (_right instanceof AncestorPattern) { 105 il.append(methodGen.loadDOM()); 106 il.append(SWAP); 107 } 108 } 109 110 final int getParent = cpg.addInterfaceMethodref(DOM_INTF, 111 GET_PARENT, 112 GET_PARENT_SIG); 113 il.append(new INVOKEINTERFACE(getParent, 2)); 114 115 final SyntaxTreeNode p = getParent(); 116 if (p == null || p instanceof Instruction || 117 p instanceof TopLevelElement) 118 { 119 _left.translate(classGen, methodGen); 120 } 121 else { 122 il.append(DUP); 123 InstructionHandle storeInst = il.append(storeLocal); 124 125 if (local.getStart() == null) { 126 local.setStart(storeInst); 127 } 128 129 _left.translate(classGen, methodGen); 130 131 il.append(methodGen.loadDOM()); 132 local.setEnd(il.append(loadLocal)); 133 } 134 135 methodGen.removeLocalVariable(local); 136 137 /* 138 * If _right is an ancestor pattern, backpatch _left false 139 * list to the loop that searches for more ancestors. 140 */ 141 if (_right instanceof AncestorPattern) { 142 final AncestorPattern ancestor = (AncestorPattern) _right; 143 _left.backPatchFalseList(ancestor.getLoopHandle()); // clears list 144 } 145 146 _trueList.append(_right._trueList.append(_left._trueList)); 147 _falseList.append(_right._falseList.append(_left._falseList)); 148 } 149 150 public String toString() { 151 return "Parent(" + _left + ", " + _right + ')'; 152 } 153 }