KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xalan > internal > 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.1.2.2 2006/10/05 17:10:31 spericas Exp $
18  */

19
20 package com.sun.org.apache.xalan.internal.xsltc.compiler;
21
22 import java.util.Vector JavaDoc;
23
24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
25 import com.sun.org.apache.bcel.internal.generic.Instruction;
26 import com.sun.org.apache.bcel.internal.generic.InstructionList;
27 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
28 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
29 import com.sun.org.apache.bcel.internal.generic.NEW;
30 import com.sun.org.apache.bcel.internal.generic.PUSH;
31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSetType;
35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
37 import com.sun.org.apache.xml.internal.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     /**
68      * Disable this variable/parameter
69      */

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

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

86     public void removeReference(VariableRefBase vref) {
87     _refs.remove(vref);
88     }
89
90     /**
91      * Map this variable to a register
92      */

93     public void mapRegister(MethodGenerator methodGen) {
94         if (_local == null) {
95             final InstructionList il = methodGen.getInstructionList();
96         final String JavaDoc name = getEscapedName(); // TODO: namespace ?
97
final com.sun.org.apache.bcel.internal.generic.Type varType = _type.toJCType();
98             _local = methodGen.addLocalVariable2(name, varType, il.getEnd());
99         }
100     }
101
102     /**
103      * Remove the mapping of this variable to a register.
104      * Called when we leave the AST scope of the variable's declaration
105      */

106     public void unmapRegister(MethodGenerator methodGen) {
107     if (_refs.isEmpty() && (_local != null)) {
108         _local.setEnd(methodGen.getInstructionList().getEnd());
109         methodGen.removeLocalVariable(_local);
110         _refs = null;
111         _local = null;
112     }
113     }
114
115     /**
116      * Returns an instruction for loading the value of this variable onto
117      * the JVM stack.
118      */

119     public Instruction loadInstruction() {
120     final Instruction instr = _loadInstruction;
121     if (_loadInstruction == null) {
122         _loadInstruction = _type.LOAD(_local.getIndex());
123         }
124     return _loadInstruction;
125     }
126
127     /**
128      * Returns an instruction for storing a value from the JVM stack
129      * into this variable.
130      */

131     public Instruction storeInstruction() {
132     final Instruction instr = _storeInstruction;
133     if (_storeInstruction == null) {
134         _storeInstruction = _type.STORE(_local.getIndex());
135         }
136     return _storeInstruction;
137     }
138
139     /**
140      * Returns the expression from this variable's select attribute (if any)
141      */

142     public Expression getExpression() {
143     return(_select);
144     }
145
146     /**
147      * Display variable as single string
148      */

149     public String JavaDoc toString() {
150     return("variable("+_name+")");
151     }
152
153     /**
154      * Display variable in a full AST dump
155      */

156     public void display(int indent) {
157     indent(indent);
158     System.out.println("Variable " + _name);
159     if (_select != null) {
160         indent(indent + IndentIncrement);
161         System.out.println("select " + _select.toString());
162     }
163     displayContents(indent + IndentIncrement);
164     }
165
166     /**
167      * Returns the type of the variable
168      */

169     public Type getType() {
170     return _type;
171     }
172
173     /**
174      * Returns the name of the variable or parameter as it will occur in the
175      * compiled translet.
176      */

177     public QName getName() {
178     return _name;
179     }
180
181     /**
182      * Returns the escaped qname of the variable or parameter
183      */

184     public String JavaDoc getEscapedName() {
185     return _escapedName;
186     }
187
188     /**
189      * Set the name of the variable or paremeter. Escape all special chars.
190      */

191     public void setName(QName name) {
192     _name = name;
193     _escapedName = Util.escape(name.getStringRep());
194     }
195
196     /**
197      * Returns the true if the variable is local
198      */

199     public boolean isLocal() {
200     return _isLocal;
201     }
202
203     /**
204      * Parse the contents of the <xsl:decimal-format> element.
205      */

206     public void parseContents(Parser parser) {
207     // Get the 'name attribute
208
String JavaDoc name = getAttribute("name");
209
210         if (name.length() > 0) {
211             if (!XMLChar.isValidQName(name)) {
212                 ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
213                 parser.reportError(Constants.ERROR, err);
214             }
215         setName(parser.getQNameIgnoreDefaultNs(name));
216         }
217         else
218         reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name");
219
220     // Check whether variable/param of the same name is already in scope
221
VariableBase other = parser.lookupVariable(_name);
222     if ((other != null) && (other.getParent() == getParent())) {
223         reportError(this, parser, ErrorMsg.VARIABLE_REDEF_ERR, name);
224     }
225     
226     select = getAttribute("select");
227     if (select.length() > 0) {
228         _select = getParser().parseExpression(this, "select", null);
229         if (_select.isDummy()) {
230         reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
231         return;
232         }
233     }
234
235     // Children must be parsed first -> static scoping
236
parseChildren(parser);
237     }
238
239     /**
240      * Compile the value of the variable, which is either in an expression in
241      * a 'select' attribute, or in the variable elements body
242      */

243     public void translateValue(ClassGenerator classGen,
244                    MethodGenerator methodGen) {
245     // Compile expression is 'select' attribute if present
246
if (_select != null) {
247         _select.translate(classGen, methodGen);
248         // Create a CachedNodeListIterator for select expressions
249
// in a variable or parameter.
250
if (_select.getType() instanceof NodeSetType) {
251             final ConstantPoolGen cpg = classGen.getConstantPool();
252             final InstructionList il = methodGen.getInstructionList();
253             
254             final int initCNI = cpg.addMethodref(CACHED_NODE_LIST_ITERATOR_CLASS,
255                         "<init>",
256                         "("
257                         +NODE_ITERATOR_SIG
258                         +")V");
259             il.append(new NEW(cpg.addClass(CACHED_NODE_LIST_ITERATOR_CLASS)));
260             il.append(DUP_X1);
261             il.append(SWAP);
262
263             il.append(new INVOKESPECIAL(initCNI));
264         }
265         _select.startIterator(classGen, methodGen);
266     }
267     // If not, compile result tree from parameter body if present.
268
else if (hasContents()) {
269         compileResultTree(classGen, methodGen);
270     }
271     // If neither are present then store empty string in variable
272
else {
273         final ConstantPoolGen cpg = classGen.getConstantPool();
274         final InstructionList il = methodGen.getInstructionList();
275         il.append(new PUSH(cpg, Constants.EMPTYSTRING));
276     }
277     }
278
279 }
280
Popular Tags