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