import { Opcodes } from "./Opcodes" ; author Eric Bruneton
 *  author Chris Nokleberg
  export class Type { /**
    * The sort of the <tt>void</tt> type. See  {@link #getSort getSort} .
     static readonly VOID : number = 0 ; /**
     * The sort of the <tt>boolean</tt> type. See  {@link #getSort getSort} .
      static readonly BOOLEAN : number = 1 ; /**
     * The sort of the <tt>char</tt> type. See  {@link #getSort getSort} .
      static readonly CHAR : number = 2 ; /**
     * The sort of the <tt>byte</tt> type. See  {@link #getSort getSort} .
      static readonly BYTE : number = 3 ; /**
     * The sort of the <tt>short</tt> type. See  {@link #getSort getSort} .
      static readonly SHORT : number = 4 ; /**
     * The sort of the <tt>int</tt> type. See  {@link #getSort getSort} .
      static readonly INT : number = 5 ; /**
     * The sort of the <tt>float</tt> type. See  {@link #getSort getSort} .
      static readonly FLOAT : number = 6 ; /**
     * The sort of the <tt>long</tt> type. See  {@link #getSort getSort} .
      static readonly LONG : number = 7 ; /**
     * The sort of the <tt>double</tt> type. See  {@link #getSort getSort} .
      static readonly DOUBLE : number = 8 ; /**
     * The sort of array reference types. See  {@link #getSort getSort} .
      static readonly ARRAY : number = 9 ; /**
     * The sort of object reference types. See  {@link #getSort getSort} .
      static readonly OBJECT : number = 10 ; /**
     * The sort of method types. See  {@link #getSort getSort} .
      static readonly METHOD : number = 11 ; /**
     * The <tt>void</tt> type.
     */ static readonly VOID_TYPE : Type = new Type ( Type . VOID , null , ( ( "V" ) . charCodeAt ( 0 ) << 24 ) | ( 5 << 16 ) , 1 ) ; /**
     * The <tt>boolean</tt> type.
     */ static readonly BOOLEAN_TYPE : Type = new Type ( Type . BOOLEAN , null , ( ( "Z" ) . charCodeAt ( 0 ) << 24 ) | ( 5 << 8 ) | 1 , 1 ) ; /**
     * The <tt>char</tt> type.
     */ static readonly CHAR_TYPE : Type = new Type ( Type . CHAR , null , ( ( "C" ) . charCodeAt ( 0 ) << 24 ) | ( 6 << 8 ) | 1 , 1 ) ; /**
     * The <tt>byte</tt> type.
     */ static readonly BYTE_TYPE : Type = new Type ( Type . BYTE , null , ( ( "B" ) . charCodeAt ( 0 ) << 24 ) | ( 5 << 8 ) | 1 , 1 ) ; /**
     * The <tt>short</tt> type.
     */ static readonly SHORT_TYPE : Type = new Type ( Type . SHORT , null , ( ( "S" ) . charCodeAt ( 0 ) << 24 ) | ( 7 << 8 ) | 1 , 1 ) ; /**
     * The <tt>int</tt> type.
     */ static readonly INT_TYPE : Type = new Type ( Type . INT , null , ( ( "I" ) . charCodeAt ( 0 ) << 24 ) | 1 , 1 ) ; /**
     * The <tt>float</tt> type.
     */ static readonly FLOAT_TYPE : Type = new Type ( Type . FLOAT , null , ( ( "F" ) . charCodeAt ( 0 ) << 24 ) | ( 2 << 16 ) | ( 2 << 8 ) | 1 , 1 ) ; /**
     * The <tt>long</tt> type.
     */ static readonly LONG_TYPE : Type = new Type ( Type . LONG , null , ( ( "J" ) . charCodeAt ( 0 ) << 24 ) | ( 1 << 16 ) | ( 1 << 8 ) | 2 , 1 ) ; /**
     * The <tt>double</tt> type.
     */ static readonly DOUBLE_TYPE : Type = new Type ( Type . DOUBLE , null , ( ( "D" ) . charCodeAt ( 0 ) << 24 ) | ( 3 << 16 ) | ( 3 << 8 ) | 2 , 1 ) ; /**
     * The sort of this Java type.
     *
     *  {@link #VOID VOID} ,  {@link #BOOLEAN BOOLEAN} ,  {@link #CHAR CHAR} ,
     *  {@link #BYTE BYTE} ,  {@link #SHORT SHORT} ,  {@link #INT INT} ,
     *  {@link #FLOAT FLOAT} ,  {@link #LONG LONG} ,  {@link #DOUBLE DOUBLE} ,
     *  {@link #ARRAY ARRAY} ,  {@link #OBJECT OBJECT} or  {@link #METHOD
 * METHOD}.
      readonly sort : number ; /**
     * A buffer containing the internal name of this Java type. This field is
     * only used for reference types.
     */ private buf : string ; /**
     * The offset of the internal name of this Java type in  {@link #buf buf} or,
     * for primitive types, the size, descriptor and getOpcode offsets for this
     * type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset
     * for IALOAD or IASTORE, byte 3 the offset for all other instructions).
      private off : number ; /**
     * The length of the internal name of this Java type.
     */ private len : number ; param sort param buf param off param len constructor ( sort , buf , off , len ) { this . sort = 0 ; this . off = 0 ; this . len = 0 ; this . sort = sort ; this . buf = buf ?? "" ; this . off = off ; this . len = len ; } param internalName return static getObjectType ( internalName ) { return new Type ( internalName [ 0 ] === "[" ? Type . ARRAY : Type . OBJECT , internalName , 0 , internalName . length ) ; } param methodDescriptor return static getMethodType ( methodDescriptor ) { return Type . getType ( methodDescriptor , 0 ) ; } param methodDescriptor return static getArgumentTypes ( methodDescriptor ) { let off = 1 ; let size = 0 ; while ( ( true ) ) { let car = methodDescriptor [ off ++ ] ; if ( car === ")" ) { break ; } else if ( car === "L" ) { while ( ( methodDescriptor [ off ++ ] !== ";" ) ) { } ; ++ size ; } else if ( car !== "[" ) { ++ size ; } } ; let args = new Array ( size ) ; off = 1 ; size = 0 ; while ( ( methodDescriptor [ off ] !== ")" ) ) { args [ size ] = Type . getType ( methodDescriptor , off ) ; off += args [ size ] . len + ( args [ size ] . sort === Type . OBJECT ? 2 : 0 ) ; size += 1 ; } ; return args ; } param desc return static getArgumentsAndReturnSizes ( desc ) { let n = 1 ; let c = 1 ; while ( ( true ) ) { let car = desc . charAt ( c ++ ) ; if ( car === ")" ) { car = desc . charAt ( c ) ; return n << 2 | ( car === "V" ? 0 : ( car === "D" || car === "J" ? 2 : 1 ) ) ; } else if ( car === "L" ) { while ( ( desc . charAt ( c ++ ) !== ";" ) ) { } ; n += 1 ; } else if ( car === "[" ) { while ( ( ( car = desc . charAt ( c ) ) === "[" ) ) { ++ c ; } ; if ( car === "D" || car === "J" ) { n -= 1 ; } } else if ( car === "D" || car === "J" ) { n += 2 ; } else { n += 1 ; } } ; return 0 ; } param buf param off return static getType ( str , off = 0 ) { let len ; let buf = "" . concat ( str ) ; switch ( buf [ off ] ) { case "V" : return Type . VOID_TYPE ; case "Z" : return Type . BOOLEAN_TYPE ; case "C" : return Type . CHAR_TYPE ; case "B" : return Type . BYTE_TYPE ; case "S" : return Type . SHORT_TYPE ; case "I" : return Type . INT_TYPE ; case "F" : return Type . FLOAT_TYPE ; case "J" : return Type . LONG_TYPE ; case "D" : return Type . DOUBLE_TYPE ; case "[" : len = 1 ; while ( ( buf [ off + len ] === "[" ) ) { ++ len ; } ; if ( buf [ off + len ] === "L" ) { ++ len ; while ( ( buf [ off + len ] !== ";" ) ) { ++ len ; } ; } return new Type ( Type . ARRAY , buf , off , len + 1 ) ; case "L" : len = 1 ; while ( ( buf [ off + len ] !== ";" ) ) { ++ len ; } ; return new Type ( Type . OBJECT , buf , off + 1 , len - 1 ) ; default : return new Type ( Type . METHOD , buf , off , buf . length - off ) ; } } return get internalName ( ) : string { return this . buf . substr ( this . off , this . len ) ; } param buf getDescriptor ( buf = "" ) { if ( this . sort == Type . OBJECT ) { buf += ( "L" ) ; for ( let i = 0 ; i < this . len ; i ++ ) { buf += this . buf [ i + this . off ] ; } buf += ( ";" ) ; } else { for ( let i = 0 ; i < this . len ; i ++ ) { buf += this . buf [ i + this . off ] ; } } } return get size ( ) : number { return this . buf == null ? ( this . off & 255 ) : 1 ; } param o return equals ( o ) { if ( this === o ) { return true ; } if ( ! ( o != null && o instanceof Type ) ) { return false ; } let t = o ; if ( this . sort !== t . sort ) { return false ; } if ( this . sort >= Type . ARRAY ) { if ( this . len !== t . len ) { return false ; } for ( let i = this . off , j = t . off , end = i + this . len ; i < end ; i ++ , j ++ ) { if ( this . buf [ i ] !== t . buf [ j ] ) { return false ; } } } return true ; } return hashCode ( ) { let hc = 13 * this . sort ; if ( this . sort >= Type . ARRAY ) { for ( let i = this . off , end = i + this . len ; i < end ; i ++ ) { hc = 17 * ( hc + ( this . buf [ i ] ) . charCodeAt ( 0 ) ) ; } } return hc ; } return toString ( ) { return this . getDescriptor ( ) ; } }