View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  package org.apache.bcel.classfile;
19  
20  import java.io.DataInput;
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.bcel.Const;
25  import org.apache.bcel.Constants;
26  
27  /**
28   * This class represents a local variable within a method. It contains its
29   * scope, name, signature and index on the method's frame.  It is used both
30   * to represent an element of the LocalVariableTable as well as an element
31   * of the LocalVariableTypeTable.  The nomenclature used here may be a bit confusing;
32   * while the two items have the same layout in a class file, a LocalVariableTable
33   * attribute contains a descriptor_index, not a signatureIndex.  The
34   * LocalVariableTypeTable attribute does have a signatureIndex.
35   * @see org.apache.bcel.classfile.Utility for more details on the difference.
36   *
37   * @see     LocalVariableTable
38   * @see     LocalVariableTypeTable
39   */
40  public final class LocalVariable implements Cloneable, Node, Constants {
41  
42      private int startPc; // Range in which the variable is valid
43      private int length;
44      private int nameIndex; // Index in constant pool of variable name
45      // Technically, a decscriptor_index for a local variable table entry
46      // and a signatureIndex for a local variable type table entry.
47      private int signatureIndex; // Index of variable signature
48      private int index; /* Variable is index'th local variable on
49       * this method's frame.
50       */
51      private ConstantPool constantPool;
52      private int origIndex; // never changes; used to match up with LocalVariableTypeTable entries
53  
54  
55      /**
56       * Initializes from another LocalVariable. Note that both objects use the same
57       * references (shallow copy). Use copy() for a physical copy.
58       *
59       * @param localVariable Another LocalVariable.
60       */
61      public LocalVariablecalVariable.html#LocalVariable">LocalVariable(final LocalVariable localVariable) {
62          this(localVariable.getStartPC(), localVariable.getLength(), localVariable.getNameIndex(),
63                  localVariable.getSignatureIndex(), localVariable.getIndex(), localVariable.getConstantPool());
64          this.origIndex = localVariable.getOrigIndex();
65      }
66  
67      /**
68       * Constructs object from file stream.
69       * @param file Input stream
70       * @throws IOException
71       */
72      LocalVariable(final DataInput file, final ConstantPool constant_pool) throws IOException {
73          this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
74                  .readUnsignedShort(), file.readUnsignedShort(), constant_pool);
75      }
76  
77  
78      /**
79       * @param startPc Range in which the variable
80       * @param length ... is valid
81       * @param nameIndex Index in constant pool of variable name
82       * @param signatureIndex Index of variable's signature
83       * @param index Variable is `index'th local variable on the method's frame
84       * @param constantPool Array of constants
85       */
86      public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index,
87              final ConstantPool constantPool) {
88          this.startPc = startPc;
89          this.length = length;
90          this.nameIndex = nameIndex;
91          this.signatureIndex = signatureIndex;
92          this.index = index;
93          this.constantPool = constantPool;
94          this.origIndex = index;
95      }
96  
97  
98      /**
99       * @param startPc Range in which the variable
100      * @param length ... is valid
101      * @param nameIndex Index in constant pool of variable name
102      * @param signatureIndex Index of variable's signature
103      * @param index Variable is `index'th local variable on the method's frame
104      * @param constantPool Array of constants
105      * @param origIndex Variable is `index'th local variable on the method's frame prior to any changes
106      */
107     public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index,
108             final ConstantPool constantPool, final int origIndex) {
109         this.startPc = startPc;
110         this.length = length;
111         this.nameIndex = nameIndex;
112         this.signatureIndex = signatureIndex;
113         this.index = index;
114         this.constantPool = constantPool;
115         this.origIndex = origIndex;
116     }
117 
118 
119     /**
120      * Called by objects that are traversing the nodes of the tree implicitely
121      * defined by the contents of a Java class. I.e., the hierarchy of methods,
122      * fields, attributes, etc. spawns a tree of objects.
123      *
124      * @param v Visitor object
125      */
126     @Override
127     public void accept( final Visitor v ) {
128         v.visitLocalVariable(this);
129     }
130 
131 
132     /**
133      * Dumps local variable to file stream in binary format.
134      *
135      * @param dataOutputStream Output file stream
136      * @exception IOException if an I/O error occurs.
137      * @see java.io.FilterOutputStream#out
138      */
139     public void dump(final DataOutputStream dataOutputStream) throws IOException {
140         dataOutputStream.writeShort(startPc);
141         dataOutputStream.writeShort(length);
142         dataOutputStream.writeShort(nameIndex);
143         dataOutputStream.writeShort(signatureIndex);
144         dataOutputStream.writeShort(index);
145     }
146 
147     /**
148      * @return Constant pool used by this object.
149      */
150     public ConstantPool getConstantPool() {
151         return constantPool;
152     }
153 
154 
155     /**
156      * @return Variable is valid within getStartPC() .. getStartPC()+getLength()
157      */
158     public int getLength() {
159         return length;
160     }
161 
162 
163     /**
164      * @return Variable name.
165      */
166     public String getName() {
167         ConstantUtf8 c;
168         c = (ConstantUtf8) constantPool.getConstant(nameIndex, Const.CONSTANT_Utf8);
169         return c.getBytes();
170     }
171 
172 
173     /**
174      * @return Index in constant pool of variable name.
175      */
176     public int getNameIndex() {
177         return nameIndex;
178     }
179 
180 
181     /**
182      * @return Signature.
183      */
184     public String getSignature() {
185         ConstantUtf8 c;
186         c = (ConstantUtf8) constantPool.getConstant(signatureIndex, Const.CONSTANT_Utf8);
187         return c.getBytes();
188     }
189 
190 
191     /**
192      * @return Index in constant pool of variable signature.
193      */
194     public int getSignatureIndex() {
195         return signatureIndex;
196     }
197 
198 
199     /**
200      * @return index of register where variable is stored
201      */
202     public int getIndex() {
203         return index;
204     }
205 
206 
207     /**
208      * @return index of register where variable was originally stored
209      */
210     public int getOrigIndex() {
211         return origIndex;
212     }
213 
214 
215     /**
216      * @return Start of range where the variable is valid
217      */
218     public int getStartPC() {
219         return startPc;
220     }
221 
222 
223     /*
224      * Helper method shared with LocalVariableTypeTable
225      */
226     String toStringShared( final boolean typeTable ) {
227         final String name = getName();
228         final String signature = Utility.signatureToString(getSignature(), false);
229         final String label = "LocalVariable" + (typeTable ? "Types" : "" );
230         return label + "(startPc = " + startPc + ", length = " + length + ", index = "
231                 + index + ":" + signature + " " + name + ")";
232     }
233 
234 
235     /**
236      * @param constantPool Constant pool to be used for this object.
237      */
238     public void setConstantPool( final ConstantPool constantPool ) {
239         this.constantPool = constantPool;
240     }
241 
242 
243     /**
244      * @param length the length of this local variable
245      */
246     public void setLength( final int length ) {
247         this.length = length;
248     }
249 
250 
251     /**
252      * @param nameIndex the index into the constant pool for the name of this variable
253      */
254     public void setNameIndex( final int nameIndex ) { // TODO unused
255         this.nameIndex = nameIndex;
256     }
257 
258 
259     /**
260      * @param signatureIndex the index into the constant pool for the signature of this variable
261      */
262     public void setSignatureIndex( final int signatureIndex ) { // TODO unused
263         this.signatureIndex = signatureIndex;
264     }
265 
266 
267     /**
268      * @param index the index in the local variable table of this variable
269      */
270     public void setIndex( final int index ) { // TODO unused
271         this.index = index;
272     }
273 
274 
275     /**
276      * @param startPc Specify range where the local variable is valid.
277      */
278     public void setStartPC( final int startPc ) { // TODO unused
279         this.startPc = startPc;
280     }
281 
282 
283     /**
284      * @return string representation.
285      */
286     @Override
287     public String toString() {
288         return toStringShared(false);
289     }
290 
291 
292     /**
293      * @return deep copy of this object
294      */
295     public LocalVariable copy() {
296         try {
297             return (LocalVariable) clone();
298         } catch (final CloneNotSupportedException e) {
299             // TODO should this throw?
300         }
301         return null;
302     }
303 }