001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License. 
016     *
017     */
018    package org.apache.bcel.classfile;
019    
020    import java.io.DataInput;
021    import java.io.DataOutputStream;
022    import java.io.IOException;
023    import java.io.Serializable;
024    
025    import org.apache.bcel.Constants;
026    
027    /**
028     * This class represents a local variable within a method. It contains its
029     * scope, name, signature and index on the method's frame.
030     *
031     * @version $Id: LocalVariable.java 1152072 2011-07-29 01:54:05Z dbrosius $
032     * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
033     * @see     LocalVariableTable
034     */
035    public final class LocalVariable implements Constants, Cloneable, Node, Serializable {
036    
037        private static final long serialVersionUID = -51081099265972179L;
038        private int start_pc; // Range in which the variable is valid
039        private int length;
040        private int name_index; // Index in constant pool of variable name
041        private int signature_index; // Index of variable signature
042        private int index; /* Variable is `index'th local variable on
043         * this method's frame.
044         */
045        private ConstantPool constant_pool;
046    
047    
048        /**
049         * Initialize from another object. Note that both objects use the same
050         * references (shallow copy). Use copy() for a physical copy.
051         */
052        public LocalVariable(LocalVariable c) {
053            this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(),
054                    c.getConstantPool());
055        }
056    
057    
058        /**
059         * Construct object from file stream.
060         * @param file Input stream
061         * @throws IOException
062         */
063        LocalVariable(DataInput file, ConstantPool constant_pool) throws IOException {
064            this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
065                    .readUnsignedShort(), file.readUnsignedShort(), constant_pool);
066        }
067    
068    
069        /**
070         * @param start_pc Range in which the variable
071         * @param length ... is valid
072         * @param name_index Index in constant pool of variable name
073         * @param signature_index Index of variable's signature
074         * @param index Variable is `index'th local variable on the method's frame
075         * @param constant_pool Array of constants
076         */
077        public LocalVariable(int start_pc, int length, int name_index, int signature_index, int index,
078                ConstantPool constant_pool) {
079            this.start_pc = start_pc;
080            this.length = length;
081            this.name_index = name_index;
082            this.signature_index = signature_index;
083            this.index = index;
084            this.constant_pool = constant_pool;
085        }
086    
087    
088        /**
089         * Called by objects that are traversing the nodes of the tree implicitely
090         * defined by the contents of a Java class. I.e., the hierarchy of methods,
091         * fields, attributes, etc. spawns a tree of objects.
092         *
093         * @param v Visitor object
094         */
095        public void accept( Visitor v ) {
096            v.visitLocalVariable(this);
097        }
098    
099    
100        /**
101         * Dump local variable to file stream in binary format.
102         *
103         * @param file Output file stream
104         * @throws IOException
105         */
106        public final void dump( DataOutputStream file ) throws IOException {
107            file.writeShort(start_pc);
108            file.writeShort(length);
109            file.writeShort(name_index);
110            file.writeShort(signature_index);
111            file.writeShort(index);
112        }
113    
114    
115        /**
116         * @return Constant pool used by this object.
117         */
118        public final ConstantPool getConstantPool() {
119            return constant_pool;
120        }
121    
122    
123        /**
124         * @return Variable is valid within getStartPC() .. getStartPC()+getLength()
125         */
126        public final int getLength() {
127            return length;
128        }
129    
130    
131        /**
132         * @return Variable name.
133         */
134        public final String getName() {
135            ConstantUtf8 c;
136            c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8);
137            return c.getBytes();
138        }
139    
140    
141        /**
142         * @return Index in constant pool of variable name.
143         */
144        public final int getNameIndex() {
145            return name_index;
146        }
147    
148    
149        /**
150         * @return Signature.
151         */
152        public final String getSignature() {
153            ConstantUtf8 c;
154            c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8);
155            return c.getBytes();
156        }
157    
158    
159        /**
160         * @return Index in constant pool of variable signature.
161         */
162        public final int getSignatureIndex() {
163            return signature_index;
164        }
165    
166    
167        /**
168         * @return index of register where variable is stored
169         */
170        public final int getIndex() {
171            return index;
172        }
173    
174    
175        /**
176         * @return Start of range where he variable is valid
177         */
178        public final int getStartPC() {
179            return start_pc;
180        }
181    
182    
183        /**
184         * @param constant_pool Constant pool to be used for this object.
185         */
186        public final void setConstantPool( ConstantPool constant_pool ) {
187            this.constant_pool = constant_pool;
188        }
189    
190    
191        /**
192         * @param length the length of this local variable
193         */
194        public final void setLength( int length ) {
195            this.length = length;
196        }
197    
198    
199        /**
200         * @param name_index the index into the constant pool for the name of this variable
201         */
202        public final void setNameIndex( int name_index ) {
203            this.name_index = name_index;
204        }
205    
206    
207        /**
208         * @param signature_index the index into the constant pool for the signature of this variable
209         */
210        public final void setSignatureIndex( int signature_index ) {
211            this.signature_index = signature_index;
212        }
213    
214    
215        /**
216         * @param index the index in the local variable table of this variable
217         */
218        public final void setIndex( int index ) {
219            this.index = index;
220        }
221    
222    
223        /**
224         * @param start_pc Specify range where the local variable is valid.
225         */
226        public final void setStartPC( int start_pc ) {
227            this.start_pc = start_pc;
228        }
229    
230    
231        /**
232         * @return string representation.
233         */
234        @Override
235        public final String toString() {
236            String name = getName(), signature = Utility.signatureToString(getSignature());
237            return "LocalVariable(start_pc = " + start_pc + ", length = " + length + ", index = "
238                    + index + ":" + signature + " " + name + ")";
239        }
240    
241    
242        /**
243         * @return deep copy of this object
244         */
245        public LocalVariable copy() {
246            try {
247                return (LocalVariable) clone();
248            } catch (CloneNotSupportedException e) {
249            }
250            return null;
251        }
252    }