Home | History | Annotate | Download | only in classfile
      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$
     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 }
    295