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.
30   *
31   * @version $Id: LocalVariable.html 1018313 2017-09-18 09:03:04Z britter $
32   * @see     LocalVariableTable
33   */
34  public final class LocalVariable implements Cloneable, Node, Constants {
35  
36      private int start_pc; // Range in which the variable is valid
37      private int length;
38      private int name_index; // Index in constant pool of variable name
39      private int signature_index; // Index of variable signature
40      private int index; /* Variable is `index'th local variable on
41       * this method's frame.
42       */
43      private ConstantPool constant_pool;
44      private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries
45  
46  
47      /**
48       * Initialize from another object. Note that both objects use the same
49       * references (shallow copy). Use copy() for a physical copy.
50       */
51      public LocalVariable(final LocalVariable c) {
52          this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(),
53                  c.getConstantPool());
54          this.orig_index = c.getOrigIndex();
55      }
56  
57  
58      /**
59       * Construct object from file stream.
60       * @param file Input stream
61       * @throws IOException
62       */
63      LocalVariable(final DataInput file, final ConstantPool constant_pool) throws IOException {
64          this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
65                  .readUnsignedShort(), file.readUnsignedShort(), constant_pool);
66      }
67  
68  
69      /**
70       * @param start_pc Range in which the variable
71       * @param length ... is valid
72       * @param name_index Index in constant pool of variable name
73       * @param signature_index Index of variable's signature
74       * @param index Variable is `index'th local variable on the method's frame
75       * @param constant_pool Array of constants
76       */
77      public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index,
78              final ConstantPool constant_pool) {
79          this.start_pc = start_pc;
80          this.length = length;
81          this.name_index = name_index;
82          this.signature_index = signature_index;
83          this.index = index;
84          this.constant_pool = constant_pool;
85          this.orig_index = index;
86      }
87  
88  
89      /**
90       * @param start_pc Range in which the variable
91       * @param length ... is valid
92       * @param name_index Index in constant pool of variable name
93       * @param signature_index Index of variable's signature
94       * @param index Variable is `index'th local variable on the method's frame
95       * @param constant_pool Array of constants
96       * @param orig_index Variable is `index'th local variable on the method's frame prior to any changes
97       */
98      public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index,
99              final ConstantPool constant_pool, final int orig_index) {
100         this.start_pc = start_pc;
101         this.length = length;
102         this.name_index = name_index;
103         this.signature_index = signature_index;
104         this.index = index;
105         this.constant_pool = constant_pool;
106         this.orig_index = orig_index;
107     }
108 
109 
110     /**
111      * Called by objects that are traversing the nodes of the tree implicitely
112      * defined by the contents of a Java class. I.e., the hierarchy of methods,
113      * fields, attributes, etc. spawns a tree of objects.
114      *
115      * @param v Visitor object
116      */
117     @Override
118     public void accept( final Visitor v ) {
119         v.visitLocalVariable(this);
120     }
121 
122 
123     /**
124      * Dump local variable to file stream in binary format.
125      *
126      * @param file Output file stream
127      * @throws IOException
128      */
129     public final void dump( final DataOutputStream file ) throws IOException {
130         file.writeShort(start_pc);
131         file.writeShort(length);
132         file.writeShort(name_index);
133         file.writeShort(signature_index);
134         file.writeShort(index);
135     }
136 
137 
138     /**
139      * @return Constant pool used by this object.
140      */
141     public final ConstantPool getConstantPool() {
142         return constant_pool;
143     }
144 
145 
146     /**
147      * @return Variable is valid within getStartPC() .. getStartPC()+getLength()
148      */
149     public final int getLength() {
150         return length;
151     }
152 
153 
154     /**
155      * @return Variable name.
156      */
157     public final String getName() {
158         ConstantUtf8 c;
159         c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8);
160         return c.getBytes();
161     }
162 
163 
164     /**
165      * @return Index in constant pool of variable name.
166      */
167     public final int getNameIndex() {
168         return name_index;
169     }
170 
171 
172     /**
173      * @return Signature.
174      */
175     public final String getSignature() {
176         ConstantUtf8 c;
177         c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8);
178         return c.getBytes();
179     }
180 
181 
182     /**
183      * @return Index in constant pool of variable signature.
184      */
185     public final int getSignatureIndex() {
186         return signature_index;
187     }
188 
189 
190     /**
191      * @return index of register where variable is stored
192      */
193     public final int getIndex() {
194         return index;
195     }
196 
197 
198     /**
199      * @return index of register where variable was originally stored
200      */
201     public final int getOrigIndex() {
202         return orig_index;
203     }
204 
205 
206     /**
207      * @return Start of range where he variable is valid
208      */
209     public final int getStartPC() {
210         return start_pc;
211     }
212 
213 
214     /*
215      * Helper method shared with LocalVariableTypeTable
216      */
217     final String toStringShared( final boolean typeTable ) {
218         final String name = getName();
219         final String signature = Utility.signatureToString(getSignature(), false);
220         final String label = "LocalVariable" + (typeTable ? "Types" : "" );
221         return label + "(start_pc = " + start_pc + ", length = " + length + ", index = "
222                 + index + ":" + signature + " " + name + ")";
223     }
224 
225 
226     /**
227      * @param constant_pool Constant pool to be used for this object.
228      */
229     public final void setConstantPool( final ConstantPool constant_pool ) {
230         this.constant_pool = constant_pool;
231     }
232 
233 
234     /**
235      * @param length the length of this local variable
236      */
237     public final void setLength( final int length ) {
238         this.length = length;
239     }
240 
241 
242     /**
243      * @param name_index the index into the constant pool for the name of this variable
244      */
245     public final void setNameIndex( final int name_index ) { // TODO unused
246         this.name_index = name_index;
247     }
248 
249 
250     /**
251      * @param signature_index the index into the constant pool for the signature of this variable
252      */
253     public final void setSignatureIndex( final int signature_index ) { // TODO unused
254         this.signature_index = signature_index;
255     }
256 
257 
258     /**
259      * @param index the index in the local variable table of this variable
260      */
261     public final void setIndex( final int index ) { // TODO unused
262         this.index = index;
263     }
264 
265 
266     /**
267      * @param start_pc Specify range where the local variable is valid.
268      */
269     public final void setStartPC( final int start_pc ) { // TODO unused
270         this.start_pc = start_pc;
271     }
272 
273 
274     /**
275      * @return string representation.
276      */
277     @Override
278     public final String toString() {
279         return toStringShared(false);
280     }
281 
282 
283     /**
284      * @return deep copy of this object
285      */
286     public LocalVariable copy() {
287         try {
288             return (LocalVariable) clone();
289         } catch (final CloneNotSupportedException e) {
290             // TODO should this throw?
291         }
292         return null;
293     }
294 }