Home | History | Annotate | Download | only in asm
      1 /***
      2  * ASM: a very small and fast Java bytecode manipulation framework
      3  * Copyright (c) 2000-2007 INRIA, France Telecom
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. Neither the name of the copyright holders nor the names of its
     15  *    contributors may be used to endorse or promote products derived from
     16  *    this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     28  * THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 package org.mockito.asm;
     31 
     32 /**
     33  * A constant pool item. Constant pool items can be created with the 'newXXX'
     34  * methods in the {@link ClassWriter} class.
     35  *
     36  * @author Eric Bruneton
     37  */
     38 final class Item {
     39 
     40     /**
     41      * Index of this item in the constant pool.
     42      */
     43     int index;
     44 
     45     /**
     46      * Type of this constant pool item. A single class is used to represent all
     47      * constant pool item types, in order to minimize the bytecode size of this
     48      * package. The value of this field is one of {@link ClassWriter#INT},
     49      * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
     50      * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
     51      * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
     52      * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
     53      * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}.
     54      *
     55      * Special Item types are used for Items that are stored in the ClassWriter
     56      * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
     57      * avoid clashes with normal constant pool items in the ClassWriter constant
     58      * pool's hash table. These special item types are
     59      * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
     60      * {@link ClassWriter#TYPE_MERGED}.
     61      */
     62     int type;
     63 
     64     /**
     65      * Value of this item, for an integer item.
     66      */
     67     int intVal;
     68 
     69     /**
     70      * Value of this item, for a long item.
     71      */
     72     long longVal;
     73 
     74     /**
     75      * First part of the value of this item, for items that do not hold a
     76      * primitive value.
     77      */
     78     String strVal1;
     79 
     80     /**
     81      * Second part of the value of this item, for items that do not hold a
     82      * primitive value.
     83      */
     84     String strVal2;
     85 
     86     /**
     87      * Third part of the value of this item, for items that do not hold a
     88      * primitive value.
     89      */
     90     String strVal3;
     91 
     92     /**
     93      * The hash code value of this constant pool item.
     94      */
     95     int hashCode;
     96 
     97     /**
     98      * Link to another constant pool item, used for collision lists in the
     99      * constant pool's hash table.
    100      */
    101     Item next;
    102 
    103     /**
    104      * Constructs an uninitialized {@link Item}.
    105      */
    106     Item() {
    107     }
    108 
    109     /**
    110      * Constructs an uninitialized {@link Item} for constant pool element at
    111      * given position.
    112      *
    113      * @param index index of the item to be constructed.
    114      */
    115     Item(final int index) {
    116         this.index = index;
    117     }
    118 
    119     /**
    120      * Constructs a copy of the given item.
    121      *
    122      * @param index index of the item to be constructed.
    123      * @param i the item that must be copied into the item to be constructed.
    124      */
    125     Item(final int index, final Item i) {
    126         this.index = index;
    127         type = i.type;
    128         intVal = i.intVal;
    129         longVal = i.longVal;
    130         strVal1 = i.strVal1;
    131         strVal2 = i.strVal2;
    132         strVal3 = i.strVal3;
    133         hashCode = i.hashCode;
    134     }
    135 
    136     /**
    137      * Sets this item to an integer item.
    138      *
    139      * @param intVal the value of this item.
    140      */
    141     void set(final int intVal) {
    142         this.type = ClassWriter.INT;
    143         this.intVal = intVal;
    144         this.hashCode = 0x7FFFFFFF & (type + intVal);
    145     }
    146 
    147     /**
    148      * Sets this item to a long item.
    149      *
    150      * @param longVal the value of this item.
    151      */
    152     void set(final long longVal) {
    153         this.type = ClassWriter.LONG;
    154         this.longVal = longVal;
    155         this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
    156     }
    157 
    158     /**
    159      * Sets this item to a float item.
    160      *
    161      * @param floatVal the value of this item.
    162      */
    163     void set(final float floatVal) {
    164         this.type = ClassWriter.FLOAT;
    165         this.intVal = Float.floatToRawIntBits(floatVal);
    166         this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
    167     }
    168 
    169     /**
    170      * Sets this item to a double item.
    171      *
    172      * @param doubleVal the value of this item.
    173      */
    174     void set(final double doubleVal) {
    175         this.type = ClassWriter.DOUBLE;
    176         this.longVal = Double.doubleToRawLongBits(doubleVal);
    177         this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
    178     }
    179 
    180     /**
    181      * Sets this item to an item that do not hold a primitive value.
    182      *
    183      * @param type the type of this item.
    184      * @param strVal1 first part of the value of this item.
    185      * @param strVal2 second part of the value of this item.
    186      * @param strVal3 third part of the value of this item.
    187      */
    188     void set(
    189         final int type,
    190         final String strVal1,
    191         final String strVal2,
    192         final String strVal3)
    193     {
    194         this.type = type;
    195         this.strVal1 = strVal1;
    196         this.strVal2 = strVal2;
    197         this.strVal3 = strVal3;
    198         switch (type) {
    199             case ClassWriter.UTF8:
    200             case ClassWriter.STR:
    201             case ClassWriter.CLASS:
    202             case ClassWriter.TYPE_NORMAL:
    203                 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
    204                 return;
    205             case ClassWriter.NAME_TYPE:
    206                 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
    207                         * strVal2.hashCode());
    208                 return;
    209                 // ClassWriter.FIELD:
    210                 // ClassWriter.METH:
    211                 // ClassWriter.IMETH:
    212             default:
    213                 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
    214                         * strVal2.hashCode() * strVal3.hashCode());
    215         }
    216     }
    217 
    218     /**
    219      * Indicates if the given item is equal to this one.
    220      *
    221      * @param i the item to be compared to this one.
    222      * @return <tt>true</tt> if the given item if equal to this one,
    223      *         <tt>false</tt> otherwise.
    224      */
    225     boolean isEqualTo(final Item i) {
    226         if (i.type == type) {
    227             switch (type) {
    228                 case ClassWriter.INT:
    229                 case ClassWriter.FLOAT:
    230                     return i.intVal == intVal;
    231                 case ClassWriter.TYPE_MERGED:
    232                 case ClassWriter.LONG:
    233                 case ClassWriter.DOUBLE:
    234                     return i.longVal == longVal;
    235                 case ClassWriter.UTF8:
    236                 case ClassWriter.STR:
    237                 case ClassWriter.CLASS:
    238                 case ClassWriter.TYPE_NORMAL:
    239                     return i.strVal1.equals(strVal1);
    240                 case ClassWriter.TYPE_UNINIT:
    241                     return i.intVal == intVal && i.strVal1.equals(strVal1);
    242                 case ClassWriter.NAME_TYPE:
    243                     return i.strVal1.equals(strVal1)
    244                             && i.strVal2.equals(strVal2);
    245                     // ClassWriter.FIELD:
    246                     // ClassWriter.METH:
    247                     // ClassWriter.IMETH:
    248                 default:
    249                     return i.strVal1.equals(strVal1)
    250                             && i.strVal2.equals(strVal2)
    251                             && i.strVal3.equals(strVal3);
    252             }
    253         }
    254         return false;
    255     }
    256 }
    257