blob: eed075058c93469422485e919e754bbfbbc0bcd1 [file] [log] [blame]
ohair6c320662012-03-04 11:55:34 -08001/*
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
24package com.sun.org.apache.xalan.internal.xsltc.compiler;
25
26import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
27import com.sun.org.apache.bcel.internal.generic.ILOAD;
28import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
29import com.sun.org.apache.bcel.internal.generic.ISTORE;
30import com.sun.org.apache.bcel.internal.generic.InstructionList;
31import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
32import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
33import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
34import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
35import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
36import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
37
38/**
39 * @author Jacek Ambroziak
40 * @author Santiago Pericas-Geertsen
41 */
42final class ParentPattern extends RelativePathPattern {
43 private final Pattern _left;
44 private final RelativePathPattern _right;
45
46 public ParentPattern(Pattern left, RelativePathPattern right) {
47 (_left = left).setParent(this);
48 (_right = right).setParent(this);
49 }
50
51 public void setParser(Parser parser) {
52 super.setParser(parser);
53 _left.setParser(parser);
54 _right.setParser(parser);
55 }
56
57 public boolean isWildcard() {
58 return false;
59 }
60
61 public StepPattern getKernelPattern() {
62 return _right.getKernelPattern();
63 }
64
65 public void reduceKernelPattern() {
66 _right.reduceKernelPattern();
67 }
68
69 public Type typeCheck(SymbolTable stable) throws TypeCheckError {
70 _left.typeCheck(stable);
71 return _right.typeCheck(stable);
72 }
73
74 public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
75 final ConstantPoolGen cpg = classGen.getConstantPool();
76 final InstructionList il = methodGen.getInstructionList();
77 final LocalVariableGen local =
78 methodGen.addLocalVariable2("ppt",
79 Util.getJCRefType(NODE_SIG),
80 il.getEnd());
81
82 final com.sun.org.apache.bcel.internal.generic.Instruction loadLocal =
83 new ILOAD(local.getIndex());
84 final com.sun.org.apache.bcel.internal.generic.Instruction storeLocal =
85 new ISTORE(local.getIndex());
86
87 if (_right.isWildcard()) {
88 il.append(methodGen.loadDOM());
89 il.append(SWAP);
90 }
91 else if (_right instanceof StepPattern) {
92 il.append(DUP);
93 il.append(storeLocal);
94
95 _right.translate(classGen, methodGen);
96
97 il.append(methodGen.loadDOM());
98 local.setEnd(il.append(loadLocal));
99 }
100 else {
101 _right.translate(classGen, methodGen);
102
103 if (_right instanceof AncestorPattern) {
104 il.append(methodGen.loadDOM());
105 il.append(SWAP);
106 }
107 }
108
109 final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
110 GET_PARENT,
111 GET_PARENT_SIG);
112 il.append(new INVOKEINTERFACE(getParent, 2));
113
114 final SyntaxTreeNode p = getParent();
115 if (p == null || p instanceof Instruction ||
116 p instanceof TopLevelElement)
117 {
118 _left.translate(classGen, methodGen);
119 }
120 else {
121 il.append(DUP);
122 il.append(storeLocal);
123
124 _left.translate(classGen, methodGen);
125
126 il.append(methodGen.loadDOM());
127 local.setEnd(il.append(loadLocal));
128 }
129
130 methodGen.removeLocalVariable(local);
131
132 /*
133 * If _right is an ancestor pattern, backpatch _left false
134 * list to the loop that searches for more ancestors.
135 */
136 if (_right instanceof AncestorPattern) {
137 final AncestorPattern ancestor = (AncestorPattern) _right;
138 _left.backPatchFalseList(ancestor.getLoopHandle()); // clears list
139 }
140
141 _trueList.append(_right._trueList.append(_left._trueList));
142 _falseList.append(_right._falseList.append(_left._falseList));
143 }
144
145 public String toString() {
146 return "Parent(" + _left + ", " + _right + ')';
147 }
148}