/**
 * A constant pool item. Constant pool items can be created with the 'newXXX'
 * methods in the  ClassWriter class.
 *
 *  author Eric Bruneton
  import { ClassWriter } from "./ClassWriter" ; import { floatToIntBits , doubleToLongBits } from "./bits" ; import Long from "long" ; export class Item { /**
     * Index of this item in the constant pool.
     */ index : number ; /**
     * Type of this constant pool item. A single class is used to represent all
     * constant pool item types, in order to minimize the bytecode size of this
     * package. The value of this field is one of  ClassWriter ,
     *  ClassWriter ,  ClassWriter ,
     *  ClassWriter ,  ClassWriter ,
     *  ClassWriter ,  ClassWriter ,
     *  ClassWriter ,  ClassWriter ,
     *  ClassWriter ,  ClassWriter ,
     *  ClassWriter ,  ClassWriter .
     *
     * MethodHandle constant 9 variations are stored using a range of 9 values
     * from  ClassWriter + 1 to
     *  ClassWriter + 9.
     *
     * Special Item types are used for Items that are stored in the ClassWriter
     *  ClassWriter , instead of the constant pool, in order to
     * avoid clashes with normal constant pool items in the ClassWriter constant
     * pool's hash table. These special item types are
     *  ClassWriter ,  ClassWriter and
     *  ClassWriter .
      type ! : number ; /**
     * Value of this item, for an integer item.
     */ intVal : number = 0 ; /**
     * Value of this item, for a long item.
     */ longVal : Long = Long . fromInt ( 0 ) ; /**
     * First part of the value of this item, for items that do not hold a
     * primitive value.
     */ strVal1 : string = "" ; /**
     * Second part of the value of this item, for items that do not hold a
     * primitive value.
     */ strVal2 : string = "" ; /**
     * Third part of the value of this item, for items that do not hold a
     * primitive value.
     */ strVal3 : string = "" ; /**
     * The hash code value of this constant pool item.
     */ __hashCode ! : number ; /**
     * Link to another constant pool item, used for collision lists in the
     * constant pool's hash table.
     */ next : Item | null = null ; param index param i public constructor ( index , i ? ) { this . index = index ; if ( i ) { this . index = index ; this . type = i . type ; this . intVal = i . intVal ; this . longVal = i . longVal ; this . strVal1 = i . strVal1 ; this . strVal2 = i . strVal2 ; this . strVal3 = i . strVal3 ; this . __hashCode = i . __hashCode ; } } param intVal set$int ( intVal ) { this . type = ClassWriter . INT ; this . intVal = intVal ; this . __hashCode = 2147483647 & ( this . type + intVal ) ; } param longVal set$long ( longVal ) { this . type = ClassWriter . LONG ; this . longVal = longVal ; this . __hashCode = 2147483647 & ( this . type + ( longVal . getLowBits ( ) ) ) ; } param floatVal set$float ( floatVal ) { this . type = ClassWriter . FLOAT ; this . intVal = floatToIntBits ( floatVal ) ; this . __hashCode = 2147483647 & ( this . type + ( floatVal | 0 ) ) ; } param doubleVal set$double ( doubleVal ) { this . type = ClassWriter . DOUBLE ; this . longVal = doubleToLongBits ( doubleVal ) ; this . __hashCode = 2147483647 & ( this . type + ( doubleVal | 0 ) ) ; } param type param strVal1 param strVal2 param strVal3 public set ( type , strVal1 ? , strVal2 ? , strVal3 ? ) { this . type = type ; this . strVal1 = strVal1 ?? "" ; this . strVal2 = strVal2 ?? "" ; this . strVal3 = strVal3 ?? "" ; switch ( type ) { case ClassWriter . CLASS : this . intVal = 0 ; case ClassWriter . UTF8 : case ClassWriter . STR : case ClassWriter . MTYPE : case ClassWriter . TYPE_NORMAL : this . __hashCode = 0x7FFFFFFF & ( type + str_hash ( this . strVal1 ) ) ; return ; case ClassWriter . NAME_TYPE : { this . __hashCode = 0x7FFFFFFF & ( type + str_hash ( this . strVal1 ) * str_hash ( this . strVal2 ) ) ; return ; } default : this . __hashCode = 0x7FFFFFFF & ( type + str_hash ( this . strVal1 ) * str_hash ( this . strVal2 ) * str_hash ( this . strVal3 ) ) ; } } param name param desc param bsmIndex setInvkDynItem ( name , desc , bsmIndex ) { this . type = ClassWriter . INDY ; this . longVal = Long . fromInt ( bsmIndex ) ; this . strVal1 = name ; this . strVal2 = desc ; this . __hashCode = 2147483647 & ( ClassWriter . INDY + bsmIndex * ( < any > this . strVal1 . toString ( ) ) * ( < any > this . strVal2 . toString ( ) ) ) ; } param position param hashCode setPosHash ( position , hashCode ) { this . type = ClassWriter . BSM ; this . intVal = position ; this . __hashCode = hashCode ; } /**
     * Indicates if the given item is equal to this one. <i>This method assumes
     * that the two items have the same  {@link #type} </i>.
     *
     *  param i the item to be compared to this one. Both items must have the
     * same  {@link #type} .
     *  return isEqualTo ( i ) { switch ( ( this . type ) ) { case ClassWriter . UTF8 : case ClassWriter . STR : case ClassWriter . CLASS : case ClassWriter . MTYPE : case ClassWriter . TYPE_NORMAL : return ( i . strVal1 === this . strVal1 ) ; case ClassWriter . TYPE_MERGED : case ClassWriter . LONG : case ClassWriter . DOUBLE : return i . longVal === this . longVal ; case ClassWriter . INT : case ClassWriter . FLOAT : return i . intVal === this . intVal ; case ClassWriter . TYPE_UNINIT : return i . intVal === this . intVal && ( i . strVal1 === this . strVal1 ) ; case ClassWriter . NAME_TYPE : return ( i . strVal1 === this . strVal1 ) && ( i . strVal2 === this . strVal2 ) ; case ClassWriter . INDY : { return i . longVal === this . longVal && ( i . strVal1 === this . strVal1 ) && ( i . strVal2 === this . strVal2 ) ; } ; default : return ( i . strVal1 === this . strVal1 ) && ( i . strVal2 === this . strVal2 ) && ( i . strVal3 === this . strVal3 ) ; } } } function str_hash ( str ) { let hash = 0 ; if ( str . length == 0 ) { return hash ; } for ( let i = 0 ; i < str . length ; i ++ ) { let char = str . charCodeAt ( i ) ; hash = ( ( hash << 5 ) - hash ) + char ; hash = hash & hash ; } return hash ; }