KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xalan > internal > xsltc > compiler > VariableRefBase


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: VariableRefBase.java,v 1.13 2004/02/16 22:25:10 minchau Exp $
18  */

19
20 package com.sun.org.apache.xalan.internal.xsltc.compiler;
21
22 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
23 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
24
25 /**
26  * @author Morten Jorgensen
27  * @author Santiago Pericas-Geertsen
28  */

29 class VariableRefBase extends Expression {
30
31     /**
32      * A reference to the associated variable.
33      */

34     protected VariableBase _variable;
35
36     /**
37      * A reference to the enclosing expression/instruction for which a
38      * closure is needed (Predicate, Number or Sort).
39      */

40     protected Closure _closure = null;
41
42     public VariableRefBase(VariableBase variable) {
43     _variable = variable;
44     variable.addReference(this);
45     }
46
47     public VariableRefBase() {
48     _variable = null;
49     }
50
51     /**
52      * Returns a reference to the associated variable
53      */

54     public VariableBase getVariable() {
55     return _variable;
56     }
57
58     /**
59      * If this variable reference is in a top-level element like
60      * another variable, param or key, add a dependency between
61      * that top-level element and the referenced variable. For
62      * example,
63      *
64      * <xsl:variable name="x" .../>
65      * <xsl:variable name="y" select="$x + 1"/>
66      * and assuming this class represents "$x", add a reference
67      * between variable y and variable x.
68      */

69     public void addParentDependency() {
70     SyntaxTreeNode node = this;
71         while (node != null && node instanceof TopLevelElement == false) {
72         node = node.getParent();
73     }
74         TopLevelElement parent = (TopLevelElement) node;
75         if (parent != null) {
76             VariableBase var = _variable;
77             if (_variable._ignore) {
78                 if (_variable instanceof Variable) {
79                     var = parent.getSymbolTable()
80                                 .lookupVariable(_variable._name);
81                 } else if (_variable instanceof Param) {
82                     var = parent.getSymbolTable().lookupParam(_variable._name);
83                 }
84              }
85              parent.addDependency(var);
86          }
87     }
88
89     /**
90      * Two variable references are deemed equal if they refer to the
91      * same variable.
92      */

93     public boolean equals(Object JavaDoc obj) {
94     try {
95         return (_variable == ((VariableRefBase) obj)._variable);
96     }
97     catch (ClassCastException JavaDoc e) {
98         return false;
99     }
100     }
101
102     /**
103      * Returns a string representation of this variable reference on the
104      * format 'variable-ref(<var-name>)'.
105      * @return Variable reference description
106      */

107     public String JavaDoc toString() {
108     return "variable-ref("+_variable.getName()+'/'+_variable.getType()+')';
109     }
110
111     public Type typeCheck(SymbolTable stable)
112     throws TypeCheckError
113     {
114     // Returned cached type if available
115
if (_type != null) return _type;
116
117     // Find nearest closure to add a variable reference
118
if (_variable.isLocal()) {
119         SyntaxTreeNode node = getParent();
120         do {
121         if (node instanceof Closure) {
122             _closure = (Closure) node;
123             break;
124         }
125         if (node instanceof TopLevelElement) {
126             break; // way up in the tree
127
}
128         node = node.getParent();
129         } while (node != null);
130
131         if (_closure != null) {
132         _closure.addVariable(this);
133         }
134     }
135
136         // Attempt to get the cached variable type
137
_type = _variable.getType();
138
139         // If that does not work we must force a type-check (this is normally
140
// only needed for globals in included/imported stylesheets
141
if (_type == null) {
142             _variable.typeCheck(stable);
143             _type = _variable.getType();
144         }
145        
146         // If in a top-level element, create dependency to the referenced var
147
addParentDependency();
148
149         // Return the type of the referenced variable
150
return _type;
151     }
152
153 }
154
Popular Tags