KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > VariableBase


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: VariableBase.java,v 1.23 2004/02/24 02:57:28 zongaro Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import java.util.Vector JavaDoc;
23
24 import org.apache.bcel.generic.ConstantPoolGen;
25 import org.apache.bcel.generic.Instruction;
26 import org.apache.bcel.generic.InstructionList;
27 import org.apache.bcel.generic.INVOKESPECIAL;
28 import org.apache.bcel.generic.LocalVariableGen;
29 import org.apache.bcel.generic.NEW;
30 import org.apache.bcel.generic.PUSH;
31 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
32 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
33 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
34 import org.apache.xalan.xsltc.compiler.util.NodeSetType;
35 import org.apache.xalan.xsltc.compiler.util.Type;
36 import org.apache.xalan.xsltc.compiler.util.Util;
37 import org.apache.xml.utils.XMLChar;
38
39 /**
40  * @author Jacek Ambroziak
41  * @author Santiago Pericas-Geertsen
42  * @author Morten Jorgensen
43  * @author Erwin Bolwidt <ejb@klomp.org>
44  * @author John Howard <JohnH@schemasoft.com>
45  */

46 class VariableBase extends TopLevelElement {
47
48     protected QName _name; // The name of the variable.
49
protected String JavaDoc _escapedName; // The escaped qname of the variable.
50
protected Type _type; // The type of this variable.
51
protected boolean _isLocal; // True if the variable is local.
52
protected LocalVariableGen _local; // Reference to JVM variable
53
protected Instruction _loadInstruction; // Instruction to load JVM variable
54
protected Instruction _storeInstruction; // Instruction to load JVM variable
55
protected Expression _select; // Reference to variable expression
56
protected String JavaDoc select; // Textual repr. of variable expr.
57

58     // References to this variable (when local)
59
protected Vector JavaDoc _refs = new Vector JavaDoc(2);
60
61     // Dependencies to other variables/parameters (for globals only)
62
protected Vector JavaDoc _dependencies = null;
63
64     // Used to make sure parameter field is not added twice
65
protected boolean _ignore = false;
66
67     // Used to order top-level variables so that there are no forward references
68
protected int _weight = 0;
69
70     /**
71      * Disable this variable/parameter
72      */

73     public void disable() {
74     _ignore = true;
75     }
76
77     /**
78      * Add a reference to this variable. Called by VariableRef when an
79      * expression contains a reference to this variable.
80      */

81     public void addReference(VariableRefBase vref) {
82     _refs.addElement(vref);
83     }
84
85     /**
86      * Remove a reference to this variable. Called by VariableRef when this
87      * variable goes out of scope.
88      */

89     public void removeReference(VariableRefBase vref) {
90     _refs.remove(vref);
91     }
92
93     /**
94      *
95      */

96     public void addDependency(VariableBase other) {
97     if (_dependencies == null) {
98         _dependencies = new Vector JavaDoc();
99     }
100     if (!_dependencies.contains(other)) {
101         _dependencies.addElement(other);
102     }
103     }
104
105     /**
106      *
107      */

108     public Vector JavaDoc getDependencies() {
109     return _dependencies;
110     }
111
112     /**
113      * Map this variable to a register
114      */

115     public void mapRegister(MethodGenerator methodGen) {
116         if (_local == null) {
117             final InstructionList il = methodGen.getInstructionList();
118         final String JavaDoc name = getEscapedName(); // TODO: namespace ?
119
final org.apache.bcel.generic.Type varType = _type.toJCType();
120             _local = methodGen.addLocalVariable2(name, varType, il.getEnd());
121         }
122     }
123
124     /**
125      * Remove the mapping of this variable to a register.
126      * Called when we leave the AST scope of the variable's declaration
127      */

128     public void unmapRegister(MethodGenerator methodGen) {
129     if (_refs.isEmpty() && (_local != null)) {
130         _local.setEnd(methodGen.getInstructionList().getEnd());
131         methodGen.removeLocalVariable(_local);
132         _refs = null;
133         _local = null;
134     }
135     }
136
137     /**
138      * Returns an instruction for loading the value of this variable onto
139      * the JVM stack.
140      */

141     public Instruction loadInstruction() {
142     final Instruction instr = _loadInstruction;
143     if (_loadInstruction == null) {
144         _loadInstruction = _type.LOAD(_local.getIndex());
145         }
146     return _loadInstruction;
147     }
148
149     /**
150      * Returns an instruction for storing a value from the JVM stack
151      * into this variable.
152      */

153     public Instruction storeInstruction() {
154     final Instruction instr = _storeInstruction;
155     if (_storeInstruction == null) {
156         _storeInstruction = _type.STORE(_local.getIndex());
157         }
158     return _storeInstruction;
159     }
160
161     /**
162      * Returns the expression from this variable's select attribute (if any)
163      */

164     public Expression getExpression() {
165     return(_select);
166     }
167
168     /**
169      * Display variable as single string
170      */

171     public String JavaDoc toString() {
172     return("variable("+_name+")");
173     }
174
175     /**
176      * Display variable in a full AST dump
177      */

178     public void display(int indent) {
179     indent(indent);
180     System.out.println("Variable " + _name);
181     if (_select != null) {
182         indent(indent + IndentIncrement);
183         System.out.println("select " + _select.toString());
184     }
185     displayContents(indent + IndentIncrement);
186     }
187
188     /**
189      * Returns the type of the variable
190      */

191     public Type getType() {
192     return _type;
193     }
194
195     /**
196      * Returns the name of the variable or parameter as it will occur in the
197      * compiled translet.
198      */

199     public QName getName() {
200     return _name;
201     }
202
203     /**
204      * Returns the escaped qname of the variable or parameter
205      */

206     public String JavaDoc getEscapedName() {
207     return _escapedName;
208     }
209
210     /**
211      * Set the name of the variable or paremeter. Escape all special chars.
212      */

213     public void setName(QName name) {
214     _name = name;
215     _escapedName = Util.escape(name.getStringRep());
216     }
217
218     /**
219      * Returns the true if the variable is local
220      */

221     public boolean isLocal() {
222     return _isLocal;
223     }
224
225     /**
226      * Parse the contents of the <xsl:decimal-format> element.
227      */

228     public void parseContents(Parser parser) {
229     // Get the 'name attribute
230
String JavaDoc name = getAttribute("name");
231
232         if (name.length() > 0) {
233             if (!XMLChar.isValidQName(name)) {
234                 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
235                 parser.reportError(Constants.ERROR, err);
236             }
237         setName(parser.getQNameIgnoreDefaultNs(name));
238         }
239         else
240         reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name");
241
242     // Check whether variable/param of the same name is already in scope
243
VariableBase other = parser.lookupVariable(_name);
244     if ((other != null) && (other.getParent() == getParent())) {
245         reportError(this, parser, ErrorMsg.VARIABLE_REDEF_ERR, name);
246     }
247     
248     select = getAttribute("select");
249     if (select.length() > 0) {
250         _select = getParser().parseExpression(this, "select", null);
251         if (_select.isDummy()) {
252         reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
253         return;
254         }
255     }
256
257     // Children must be parsed first -> static scoping
258
parseChildren(parser);
259     }
260
261     /**
262      * Compile the value of the variable, which is either in an expression in
263      * a 'select' attribute, or in the variable elements body
264      */

265     public void translateValue(ClassGenerator classGen,
266                    MethodGenerator methodGen) {
267     // Compile expression is 'select' attribute if present
268
if (_select != null) {
269         _select.translate(classGen, methodGen);
270         // Create a CachedNodeListIterator for select expressions
271
// in a variable or parameter.
272
if (_select.getType() instanceof NodeSetType) {
273             final ConstantPoolGen cpg = classGen.getConstantPool();
274             final InstructionList il = methodGen.getInstructionList();
275             
276             final int initCNI = cpg.addMethodref(CACHED_NODE_LIST_ITERATOR_CLASS,
277                         "<init>",
278                         "("
279                         +NODE_ITERATOR_SIG
280                         +")V");
281             il.append(new NEW(cpg.addClass(CACHED_NODE_LIST_ITERATOR_CLASS)));
282             il.append(DUP_X1);
283             il.append(SWAP);
284
285             il.append(new INVOKESPECIAL(initCNI));
286         }
287         _select.startIterator(classGen, methodGen);
288     }
289     // If not, compile result tree from parameter body if present.
290
else if (hasContents()) {
291         compileResultTree(classGen, methodGen);
292     }
293     // If neither are present then store empty string in variable
294
else {
295         final ConstantPoolGen cpg = classGen.getConstantPool();
296         final InstructionList il = methodGen.getInstructionList();
297         il.append(new PUSH(cpg, Constants.EMPTYSTRING));
298     }
299     }
300
301 }
302
Popular Tags