/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package javassist.bytecode;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javassist.CtClass;

Constant pool table.
/** * Constant pool table. */
public final class ConstPool { LongVector items; int numOfItems; int thisClassInfo; Map<ConstInfo,ConstInfo> itemsCache;
CONSTANT_Class
/** * <code>CONSTANT_Class</code> */
public static final int CONST_Class = ClassInfo.tag;
CONSTANT_Fieldref
/** * <code>CONSTANT_Fieldref</code> */
public static final int CONST_Fieldref = FieldrefInfo.tag;
CONSTANT_Methodref
/** * <code>CONSTANT_Methodref</code> */
public static final int CONST_Methodref = MethodrefInfo.tag;
CONSTANT_InterfaceMethodref
/** * <code>CONSTANT_InterfaceMethodref</code> */
public static final int CONST_InterfaceMethodref = InterfaceMethodrefInfo.tag;
CONSTANT_String
/** * <code>CONSTANT_String</code> */
public static final int CONST_String = StringInfo.tag;
CONSTANT_Integer
/** * <code>CONSTANT_Integer</code> */
public static final int CONST_Integer = IntegerInfo.tag;
CONSTANT_Float
/** * <code>CONSTANT_Float</code> */
public static final int CONST_Float = FloatInfo.tag;
CONSTANT_Long
/** * <code>CONSTANT_Long</code> */
public static final int CONST_Long = LongInfo.tag;
CONSTANT_Double
/** * <code>CONSTANT_Double</code> */
public static final int CONST_Double = DoubleInfo.tag;
CONSTANT_NameAndType
/** * <code>CONSTANT_NameAndType</code> */
public static final int CONST_NameAndType = NameAndTypeInfo.tag;
CONSTANT_Utf8
/** * <code>CONSTANT_Utf8</code> */
public static final int CONST_Utf8 = Utf8Info.tag;
CONSTANT_MethodHandle
/** * <code>CONSTANT_MethodHandle</code> */
public static final int CONST_MethodHandle = MethodHandleInfo.tag;
CONSTANT_MethodHandle
/** * <code>CONSTANT_MethodHandle</code> */
public static final int CONST_MethodType = MethodTypeInfo.tag;
CONSTANT_Dynamic
/** * <code>CONSTANT_Dynamic</code> */
public static final int CONST_Dynamic = DynamicInfo.tag;
CONSTANT_InvokeDynamic
/** * <code>CONSTANT_InvokeDynamic</code> */
public static final int CONST_InvokeDynamic = InvokeDynamicInfo.tag;
CONSTANT_Module
/** * <code>CONSTANT_Module</code> */
public static final int CONST_Module = ModuleInfo.tag;
CONSTANT_Package
/** * <code>CONSTANT_Package</code> */
public static final int CONST_Package = PackageInfo.tag;
Represents the class using this constant pool table.
/** * Represents the class using this constant pool table. */
public static final CtClass THIS = null;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_getField = 1;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_getStatic = 2;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_putField = 3;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_putStatic = 4;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_invokeVirtual = 5;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_invokeStatic = 6;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_invokeSpecial = 7;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_newInvokeSpecial = 8;
reference_kind of CONSTANT_MethodHandle_info.
/** * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. */
public static final int REF_invokeInterface = 9;
Constructs a constant pool table.
Params:
  • thisclass – the name of the class using this constant pool table
/** * Constructs a constant pool table. * * @param thisclass the name of the class using this constant * pool table */
public ConstPool(String thisclass) { items = new LongVector(); itemsCache = null; numOfItems = 0; addItem0(null); // index 0 is reserved by the JVM. thisClassInfo = addClassInfo(thisclass); }
Constructs a constant pool table from the given byte stream.
Params:
  • in – byte stream.
/** * Constructs a constant pool table from the given byte stream. * * @param in byte stream. */
public ConstPool(DataInputStream in) throws IOException { itemsCache = null; thisClassInfo = 0; /* read() initializes items and numOfItems, and do addItem(null). */ read(in); } void prune() { itemsCache = null; }
Returns the number of entries in this table.
/** * Returns the number of entries in this table. */
public int getSize() { return numOfItems; }
Returns the name of the class using this constant pool table.
/** * Returns the name of the class using this constant pool table. */
public String getClassName() { return getClassInfo(thisClassInfo); }
Returns the index of CONSTANT_Class_info structure specifying the class using this constant pool table.
/** * Returns the index of <code>CONSTANT_Class_info</code> structure * specifying the class using this constant pool table. */
public int getThisClassInfo() { return thisClassInfo; } void setThisClassInfo(int i) { thisClassInfo = i; } ConstInfo getItem(int n) { return items.elementAt(n); }
Returns the tag field of the constant pool table entry at the given index.
Returns:either CONST_Class, CONST_Fieldref, CONST_Methodref, or ...
/** * Returns the <code>tag</code> field of the constant pool table * entry at the given index. * * @return either <code>CONST_Class</code>, <code>CONST_Fieldref</code>, * <code>CONST_Methodref</code>, or ... */
public int getTag(int index) { return getItem(index).getTag(); }
Reads CONSTANT_Class_info structure at the given index.
See Also:
Returns: a fully-qualified class or interface name specified by name_index. If the type is an array type, this method returns an encoded name like [Ljava.lang.Object; (note that the separators are not slashes but dots).
/** * Reads <code>CONSTANT_Class_info</code> structure * at the given index. * * @return a fully-qualified class or interface name specified * by <code>name_index</code>. If the type is an array * type, this method returns an encoded name like * <code>[Ljava.lang.Object;</code> (note that the separators * are not slashes but dots). * @see javassist.ClassPool#getCtClass(String) */
public String getClassInfo(int index) { ClassInfo c = (ClassInfo)getItem(index); if (c == null) return null; return Descriptor.toJavaName(getUtf8Info(c.name)); }
Reads CONSTANT_Class_info structure at the given index.
See Also:
Returns: the descriptor of the type specified by name_index.
Since:3.15
/** * Reads <code>CONSTANT_Class_info</code> structure * at the given index. * * @return the descriptor of the type specified * by <code>name_index</code>. * @see javassist.ClassPool#getCtClass(String) * @since 3.15 */
public String getClassInfoByDescriptor(int index) { ClassInfo c = (ClassInfo)getItem(index); if (c == null) return null; String className = getUtf8Info(c.name); if (className.charAt(0) == '[') return className; return Descriptor.of(className); }
Reads the name_index field of the CONSTANT_NameAndType_info structure at the given index.
/** * Reads the <code>name_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * at the given index. */
public int getNameAndTypeName(int index) { NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index); return ntinfo.memberName; }
Reads the descriptor_index field of the CONSTANT_NameAndType_info structure at the given index.
/** * Reads the <code>descriptor_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * at the given index. */
public int getNameAndTypeDescriptor(int index) { NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index); return ntinfo.typeDescriptor; }
Reads the class_index field of the CONSTANT_Fieldref_info, CONSTANT_Methodref_info, or CONSTANT_Interfaceref_info, structure at the given index.
Since:3.6
/** * Reads the <code>class_index</code> field of the * <code>CONSTANT_Fieldref_info</code>, * <code>CONSTANT_Methodref_info</code>, * or <code>CONSTANT_Interfaceref_info</code>, * structure at the given index. * * @since 3.6 */
public int getMemberClass(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); return minfo.classIndex; }
Reads the name_and_type_index field of the CONSTANT_Fieldref_info, CONSTANT_Methodref_info, or CONSTANT_Interfaceref_info, structure at the given index.
Since:3.6
/** * Reads the <code>name_and_type_index</code> field of the * <code>CONSTANT_Fieldref_info</code>, * <code>CONSTANT_Methodref_info</code>, * or <code>CONSTANT_Interfaceref_info</code>, * structure at the given index. * * @since 3.6 */
public int getMemberNameAndType(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); return minfo.nameAndTypeIndex; }
Reads the class_index field of the CONSTANT_Fieldref_info structure at the given index.
/** * Reads the <code>class_index</code> field of the * <code>CONSTANT_Fieldref_info</code> structure * at the given index. */
public int getFieldrefClass(int index) { FieldrefInfo finfo = (FieldrefInfo)getItem(index); return finfo.classIndex; }
Reads the class_index field of the CONSTANT_Fieldref_info structure at the given index.
Returns:the name of the class at that class_index.
/** * Reads the <code>class_index</code> field of the * <code>CONSTANT_Fieldref_info</code> structure * at the given index. * * @return the name of the class at that <code>class_index</code>. */
public String getFieldrefClassName(int index) { FieldrefInfo f = (FieldrefInfo)getItem(index); if (f == null) return null; return getClassInfo(f.classIndex); }
Reads the name_and_type_index field of the CONSTANT_Fieldref_info structure at the given index.
/** * Reads the <code>name_and_type_index</code> field of the * <code>CONSTANT_Fieldref_info</code> structure * at the given index. */
public int getFieldrefNameAndType(int index) { FieldrefInfo finfo = (FieldrefInfo)getItem(index); return finfo.nameAndTypeIndex; }
Reads the name_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_Fieldref_info.
Returns: the name of the field.
/** * Reads the <code>name_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to a <code>CONSTANT_Fieldref_info</code>. * @return the name of the field. */
public String getFieldrefName(int index) { FieldrefInfo f = (FieldrefInfo)getItem(index); if (f == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex); if(n == null) return null; return getUtf8Info(n.memberName); }
Reads the descriptor_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_Fieldref_info.
Returns: the type descriptor of the field.
/** * Reads the <code>descriptor_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to a <code>CONSTANT_Fieldref_info</code>. * @return the type descriptor of the field. */
public String getFieldrefType(int index) { FieldrefInfo f = (FieldrefInfo)getItem(index); if (f == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex); if(n == null) return null; return getUtf8Info(n.typeDescriptor); }
Reads the class_index field of the CONSTANT_Methodref_info structure at the given index.
/** * Reads the <code>class_index</code> field of the * <code>CONSTANT_Methodref_info</code> structure * at the given index. */
public int getMethodrefClass(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); return minfo.classIndex; }
Reads the class_index field of the CONSTANT_Methodref_info structure at the given index.
Returns:the name of the class at that class_index.
/** * Reads the <code>class_index</code> field of the * <code>CONSTANT_Methodref_info</code> structure * at the given index. * * @return the name of the class at that <code>class_index</code>. */
public String getMethodrefClassName(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); if (minfo == null) return null; return getClassInfo(minfo.classIndex); }
Reads the name_and_type_index field of the CONSTANT_Methodref_info structure at the given index.
/** * Reads the <code>name_and_type_index</code> field of the * <code>CONSTANT_Methodref_info</code> structure * at the given index. */
public int getMethodrefNameAndType(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); return minfo.nameAndTypeIndex; }
Reads the name_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_Methodref_info.
Returns: the name of the method.
/** * Reads the <code>name_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to a <code>CONSTANT_Methodref_info</code>. * @return the name of the method. */
public String getMethodrefName(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); if (minfo == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); if(n == null) return null; return getUtf8Info(n.memberName); }
Reads the descriptor_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_Methodref_info.
Returns: the descriptor of the method.
/** * Reads the <code>descriptor_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to a <code>CONSTANT_Methodref_info</code>. * @return the descriptor of the method. */
public String getMethodrefType(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); if (minfo == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); if(n == null) return null; return getUtf8Info(n.typeDescriptor); }
Reads the class_index field of the CONSTANT_InterfaceMethodref_info structure at the given index.
/** * Reads the <code>class_index</code> field of the * <code>CONSTANT_InterfaceMethodref_info</code> structure * at the given index. */
public int getInterfaceMethodrefClass(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); return minfo.classIndex; }
Reads the class_index field of the CONSTANT_InterfaceMethodref_info structure at the given index.
Returns:the name of the class at that class_index.
/** * Reads the <code>class_index</code> field of the * <code>CONSTANT_InterfaceMethodref_info</code> structure * at the given index. * * @return the name of the class at that <code>class_index</code>. */
public String getInterfaceMethodrefClassName(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); return getClassInfo(minfo.classIndex); }
Reads the name_and_type_index field of the CONSTANT_InterfaceMethodref_info structure at the given index.
/** * Reads the <code>name_and_type_index</code> field of the * <code>CONSTANT_InterfaceMethodref_info</code> structure * at the given index. */
public int getInterfaceMethodrefNameAndType(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); return minfo.nameAndTypeIndex; }
Reads the name_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_InterfaceMethodref_info.
Returns: the name of the method.
/** * Reads the <code>name_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to * a <code>CONSTANT_InterfaceMethodref_info</code>. * @return the name of the method. */
public String getInterfaceMethodrefName(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); if (minfo == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); if(n == null) return null; return getUtf8Info(n.memberName); }
Reads the descriptor_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_InterfaceMethodref_info.
Returns: the descriptor of the method.
/** * Reads the <code>descriptor_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to * a <code>CONSTANT_InterfaceMethodref_info</code>. * @return the descriptor of the method. */
public String getInterfaceMethodrefType(int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); if (minfo == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); if(n == null) return null; return getUtf8Info(n.typeDescriptor); }
Reads CONSTANT_Integer_info, _Float_info, _Long_info, _Double_info, or _String_info structure. These are used with the LDC instruction.
Returns:a String value or a wrapped primitive-type value.
/** * Reads <code>CONSTANT_Integer_info</code>, <code>_Float_info</code>, * <code>_Long_info</code>, <code>_Double_info</code>, or * <code>_String_info</code> structure. * These are used with the LDC instruction. * * @return a <code>String</code> value or a wrapped primitive-type * value. */
public Object getLdcValue(int index) { ConstInfo constInfo = this.getItem(index); Object value = null; if (constInfo instanceof StringInfo) value = this.getStringInfo(index); else if (constInfo instanceof FloatInfo) value = Float.valueOf(getFloatInfo(index)); else if (constInfo instanceof IntegerInfo) value = Integer.valueOf(getIntegerInfo(index)); else if (constInfo instanceof LongInfo) value = Long.valueOf(getLongInfo(index)); else if (constInfo instanceof DoubleInfo) value = Double.valueOf(getDoubleInfo(index)); return value; }
Reads CONSTANT_Integer_info structure at the given index.
Returns:the value specified by this entry.
/** * Reads <code>CONSTANT_Integer_info</code> structure * at the given index. * * @return the value specified by this entry. */
public int getIntegerInfo(int index) { IntegerInfo i = (IntegerInfo)getItem(index); return i.value; }
Reads CONSTANT_Float_info structure at the given index.
Returns:the value specified by this entry.
/** * Reads <code>CONSTANT_Float_info</code> structure * at the given index. * * @return the value specified by this entry. */
public float getFloatInfo(int index) { FloatInfo i = (FloatInfo)getItem(index); return i.value; }
Reads CONSTANT_Long_info structure at the given index.
Returns:the value specified by this entry.
/** * Reads <code>CONSTANT_Long_info</code> structure * at the given index. * * @return the value specified by this entry. */
public long getLongInfo(int index) { LongInfo i = (LongInfo)getItem(index); return i.value; }
Reads CONSTANT_Double_info structure at the given index.
Returns:the value specified by this entry.
/** * Reads <code>CONSTANT_Double_info</code> structure * at the given index. * * @return the value specified by this entry. */
public double getDoubleInfo(int index) { DoubleInfo i = (DoubleInfo)getItem(index); return i.value; }
Reads CONSTANT_String_info structure at the given index.
Returns:the string specified by string_index.
/** * Reads <code>CONSTANT_String_info</code> structure * at the given index. * * @return the string specified by <code>string_index</code>. */
public String getStringInfo(int index) { StringInfo si = (StringInfo)getItem(index); return getUtf8Info(si.string); }
Reads CONSTANT_utf8_info structure at the given index.
Returns:the string specified by this entry.
/** * Reads <code>CONSTANT_utf8_info</code> structure * at the given index. * * @return the string specified by this entry. */
public String getUtf8Info(int index) { Utf8Info utf = (Utf8Info)getItem(index); return utf.string; }
Reads the reference_kind field of the CONSTANT_MethodHandle_info structure at the given index.
See Also:
Since:3.17
/** * Reads the <code>reference_kind</code> field of the * <code>CONSTANT_MethodHandle_info</code> structure * at the given index. * * @see #REF_getField * @see #REF_getStatic * @see #REF_invokeInterface * @see #REF_invokeSpecial * @see #REF_invokeStatic * @see #REF_invokeVirtual * @see #REF_newInvokeSpecial * @see #REF_putField * @see #REF_putStatic * @since 3.17 */
public int getMethodHandleKind(int index) { MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index); return mhinfo.refKind; }
Reads the reference_index field of the CONSTANT_MethodHandle_info structure at the given index.
Since:3.17
/** * Reads the <code>reference_index</code> field of the * <code>CONSTANT_MethodHandle_info</code> structure * at the given index. * * @since 3.17 */
public int getMethodHandleIndex(int index) { MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index); return mhinfo.refIndex; }
Reads the descriptor_index field of the CONSTANT_MethodType_info structure at the given index.
Since:3.17
/** * Reads the <code>descriptor_index</code> field of the * <code>CONSTANT_MethodType_info</code> structure * at the given index. * * @since 3.17 */
public int getMethodTypeInfo(int index) { MethodTypeInfo mtinfo = (MethodTypeInfo)getItem(index); return mtinfo.descriptor; }
Reads the bootstrap_method_attr_index field of the CONSTANT_InvokeDynamic_info structure at the given index.
Since:3.17
/** * Reads the <code>bootstrap_method_attr_index</code> field of the * <code>CONSTANT_InvokeDynamic_info</code> structure * at the given index. * * @since 3.17 */
public int getInvokeDynamicBootstrap(int index) { InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); return iv.bootstrap; }
Reads the name_and_type_index field of the CONSTANT_InvokeDynamic_info structure at the given index.
Since:3.17
/** * Reads the <code>name_and_type_index</code> field of the * <code>CONSTANT_InvokeDynamic_info</code> structure * at the given index. * * @since 3.17 */
public int getInvokeDynamicNameAndType(int index) { InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); return iv.nameAndType; }
Reads the descriptor_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_InvokeDynamic_info.
Returns: the descriptor of the bootstrap method.
Since:3.17
/** * Reads the <code>descriptor_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to a <code>CONSTANT_InvokeDynamic_info</code>. * @return the descriptor of the bootstrap method. * @since 3.17 */
public String getInvokeDynamicType(int index) { InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); if (iv == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType); if(n == null) return null; return getUtf8Info(n.typeDescriptor); }
Reads the bootstrap_method_attr_index field of the CONSTANT_Dynamic_info structure at the given index.
Since:3.26
/** * Reads the <code>bootstrap_method_attr_index</code> field of the * <code>CONSTANT_Dynamic_info</code> structure * at the given index. * * @since 3.26 */
public int getDynamicBootstrap(int index) { DynamicInfo iv = (DynamicInfo)getItem(index); return iv.bootstrap; }
Reads the name_and_type_index field of the CONSTANT_Dynamic_info structure at the given index.
Since:3.26
/** * Reads the <code>name_and_type_index</code> field of the * <code>CONSTANT_Dynamic_info</code> structure * at the given index. * * @since 3.26 */
public int getDynamicNameAndType(int index) { DynamicInfo iv = (DynamicInfo)getItem(index); return iv.nameAndType; }
Reads the descriptor_index field of the CONSTANT_NameAndType_info structure indirectly specified by the given index.
Params:
  • index – an index to a CONSTANT_Dynamic_info.
Returns: the descriptor of the bootstrap method.
Since:3.26
/** * Reads the <code>descriptor_index</code> field of the * <code>CONSTANT_NameAndType_info</code> structure * indirectly specified by the given index. * * @param index an index to a <code>CONSTANT_Dynamic_info</code>. * @return the descriptor of the bootstrap method. * @since 3.26 */
public String getDynamicType(int index) { DynamicInfo iv = (DynamicInfo)getItem(index); if (iv == null) return null; NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType); if(n == null) return null; return getUtf8Info(n.typeDescriptor); }
Reads the name_index field of the CONSTANT_Module_info structure at the given index.
Returns:the module name at name_index.
Since:3.22
/** * Reads the <code>name_index</code> field of the * <code>CONSTANT_Module_info</code> structure at the given index. * * @return the module name at <code>name_index</code>. * @since 3.22 */
public String getModuleInfo(int index) { ModuleInfo mi = (ModuleInfo)getItem(index); return getUtf8Info(mi.name); }
Reads the name_index field of the CONSTANT_Package_info structure at the given index.
Returns:the package name at name_index. It is a slash- separated name such as com/oracle/net.
Since:3.22
/** * Reads the <code>name_index</code> field of the * <code>CONSTANT_Package_info</code> structure at the given index. * * @return the package name at <code>name_index</code>. It is a slash- * separated name such as com/oracle/net. * @since 3.22 */
public String getPackageInfo(int index) { PackageInfo mi = (PackageInfo)getItem(index); return getUtf8Info(mi.name); }
Determines whether CONSTANT_Methodref_info structure at the given index represents the constructor of the given class.
Returns: the descriptor_index specifying the type descriptor of the that constructor. If it is not that constructor, isConstructor() returns 0.
/** * Determines whether <code>CONSTANT_Methodref_info</code> * structure at the given index represents the constructor * of the given class. * * @return the <code>descriptor_index</code> specifying * the type descriptor of the that constructor. * If it is not that constructor, * <code>isConstructor()</code> returns 0. */
public int isConstructor(String classname, int index) { return isMember(classname, MethodInfo.nameInit, index); }
Determines whether CONSTANT_Methodref_info, CONSTANT_Fieldref_info, or CONSTANT_InterfaceMethodref_info structure at the given index represents the member with the specified name and declaring class.
Params:
  • classname – the class declaring the member
  • membername – the member name
  • index – the index into the constant pool table
Returns: the descriptor_index specifying the type descriptor of that member. If it is not that member, isMember() returns 0.
/** * Determines whether <code>CONSTANT_Methodref_info</code>, * <code>CONSTANT_Fieldref_info</code>, or * <code>CONSTANT_InterfaceMethodref_info</code> structure * at the given index represents the member with the specified * name and declaring class. * * @param classname the class declaring the member * @param membername the member name * @param index the index into the constant pool table * * @return the <code>descriptor_index</code> specifying * the type descriptor of that member. * If it is not that member, * <code>isMember()</code> returns 0. */
public int isMember(String classname, String membername, int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); if (getClassInfo(minfo.classIndex).equals(classname)) { NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); if (getUtf8Info(ntinfo.memberName).equals(membername)) return ntinfo.typeDescriptor; } return 0; // false }
Determines whether CONSTANT_Methodref_info, CONSTANT_Fieldref_info, or CONSTANT_InterfaceMethodref_info structure at the given index has the name and the descriptor given as the arguments.
Params:
  • membername – the member name
  • desc – the descriptor of the member.
  • index – the index into the constant pool table
Returns: the name of the target class specified by the ..._info structure at index. Otherwise, null if that structure does not match the given member name and descriptor.
/** * Determines whether <code>CONSTANT_Methodref_info</code>, * <code>CONSTANT_Fieldref_info</code>, or * <code>CONSTANT_InterfaceMethodref_info</code> structure * at the given index has the name and the descriptor * given as the arguments. * * @param membername the member name * @param desc the descriptor of the member. * @param index the index into the constant pool table * * @return the name of the target class specified by * the <code>..._info</code> structure * at <code>index</code>. * Otherwise, null if that structure does not * match the given member name and descriptor. */
public String eqMember(String membername, String desc, int index) { MemberrefInfo minfo = (MemberrefInfo)getItem(index); NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); if (getUtf8Info(ntinfo.memberName).equals(membername) && getUtf8Info(ntinfo.typeDescriptor).equals(desc)) return getClassInfo(minfo.classIndex); return null; // false } private int addItem0(ConstInfo info) { items.addElement(info); return numOfItems++; } private int addItem(ConstInfo info) { if (itemsCache == null) itemsCache = makeItemsCache(items); ConstInfo found = itemsCache.get(info); if (found != null) return found.index; items.addElement(info); itemsCache.put(info, info); return numOfItems++; }
Copies the n-th item in this ConstPool object into the destination ConstPool object. The class names that the item refers to are renamed according to the given map.
Params:
  • n – the n-th item
  • dest – destination constant pool table
  • classnames – the map or null.
Returns:the index of the copied item into the destination ClassPool.
/** * Copies the n-th item in this ConstPool object into the destination * ConstPool object. * The class names that the item refers to are renamed according * to the given map. * * @param n the <i>n</i>-th item * @param dest destination constant pool table * @param classnames the map or null. * @return the index of the copied item into the destination ClassPool. */
public int copy(int n, ConstPool dest, Map<String,String> classnames) { if (n == 0) return 0; ConstInfo info = getItem(n); return info.copy(this, dest, classnames); } int addConstInfoPadding() { return addItem0(new ConstInfoPadding(numOfItems)); }
Adds a new CONSTANT_Class_info structure.

This also adds a CONSTANT_Utf8_info structure for storing the class name.

Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Class_info</code> structure. * * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure * for storing the class name. * * @return the index of the added entry. */
public int addClassInfo(CtClass c) { if (c == THIS) return thisClassInfo; else if (!c.isArray()) return addClassInfo(c.getName()); else { // an array type is recorded in the hashtable with // the key "[L<classname>;" instead of "<classname>". // // note: toJvmName(toJvmName(c)) is equal to toJvmName(c). return addClassInfo(Descriptor.toJvmName(c)); } }
Adds a new CONSTANT_Class_info structure.

This also adds a CONSTANT_Utf8_info structure for storing the class name.

Params:
  • qname – a fully-qualified class name (or the JVM-internal representation of that name).
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Class_info</code> structure. * * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure * for storing the class name. * * @param qname a fully-qualified class name * (or the JVM-internal representation of that name). * @return the index of the added entry. */
public int addClassInfo(String qname) { int utf8 = addUtf8Info(Descriptor.toJvmName(qname)); return addItem(new ClassInfo(utf8, numOfItems)); }
Adds a new CONSTANT_NameAndType_info structure.

This also adds CONSTANT_Utf8_info structures.

Params:
  • name – name_index
  • type – descriptor_index
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_NameAndType_info</code> structure. * * <p>This also adds <code>CONSTANT_Utf8_info</code> structures. * * @param name <code>name_index</code> * @param type <code>descriptor_index</code> * @return the index of the added entry. */
public int addNameAndTypeInfo(String name, String type) { return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type)); }
Adds a new CONSTANT_NameAndType_info structure.
Params:
  • name – name_index
  • type – descriptor_index
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_NameAndType_info</code> structure. * * @param name <code>name_index</code> * @param type <code>descriptor_index</code> * @return the index of the added entry. */
public int addNameAndTypeInfo(int name, int type) { return addItem(new NameAndTypeInfo(name, type, numOfItems)); }
Adds a new CONSTANT_Fieldref_info structure.

This also adds a new CONSTANT_NameAndType_info structure.

Params:
  • classInfo – class_index
  • name – name_index of CONSTANT_NameAndType_info.
  • type – descriptor_index of CONSTANT_NameAndType_info.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Fieldref_info</code> structure. * * <p>This also adds a new <code>CONSTANT_NameAndType_info</code> * structure. * * @param classInfo <code>class_index</code> * @param name <code>name_index</code> * of <code>CONSTANT_NameAndType_info</code>. * @param type <code>descriptor_index</code> * of <code>CONSTANT_NameAndType_info</code>. * @return the index of the added entry. */
public int addFieldrefInfo(int classInfo, String name, String type) { int nt = addNameAndTypeInfo(name, type); return addFieldrefInfo(classInfo, nt); }
Adds a new CONSTANT_Fieldref_info structure.
Params:
  • classInfo – class_index
  • nameAndTypeInfo – name_and_type_index.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Fieldref_info</code> structure. * * @param classInfo <code>class_index</code> * @param nameAndTypeInfo <code>name_and_type_index</code>. * @return the index of the added entry. */
public int addFieldrefInfo(int classInfo, int nameAndTypeInfo) { return addItem(new FieldrefInfo(classInfo, nameAndTypeInfo, numOfItems)); }
Adds a new CONSTANT_Methodref_info structure.

This also adds a new CONSTANT_NameAndType_info structure.

Params:
  • classInfo – class_index
  • name – name_index of CONSTANT_NameAndType_info.
  • type – descriptor_index of CONSTANT_NameAndType_info.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Methodref_info</code> structure. * * <p>This also adds a new <code>CONSTANT_NameAndType_info</code> * structure. * * @param classInfo <code>class_index</code> * @param name <code>name_index</code> * of <code>CONSTANT_NameAndType_info</code>. * @param type <code>descriptor_index</code> * of <code>CONSTANT_NameAndType_info</code>. * @return the index of the added entry. */
public int addMethodrefInfo(int classInfo, String name, String type) { int nt = addNameAndTypeInfo(name, type); return addMethodrefInfo(classInfo, nt); }
Adds a new CONSTANT_Methodref_info structure.
Params:
  • classInfo – class_index
  • nameAndTypeInfo – name_and_type_index.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Methodref_info</code> structure. * * @param classInfo <code>class_index</code> * @param nameAndTypeInfo <code>name_and_type_index</code>. * @return the index of the added entry. */
public int addMethodrefInfo(int classInfo, int nameAndTypeInfo) { return addItem(new MethodrefInfo(classInfo, nameAndTypeInfo, numOfItems)); }
Adds a new CONSTANT_InterfaceMethodref_info structure.

This also adds a new CONSTANT_NameAndType_info structure.

Params:
  • classInfo – class_index
  • name – name_index of CONSTANT_NameAndType_info.
  • type – descriptor_index of CONSTANT_NameAndType_info.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_InterfaceMethodref_info</code> * structure. * * <p>This also adds a new <code>CONSTANT_NameAndType_info</code> * structure. * * @param classInfo <code>class_index</code> * @param name <code>name_index</code> * of <code>CONSTANT_NameAndType_info</code>. * @param type <code>descriptor_index</code> * of <code>CONSTANT_NameAndType_info</code>. * @return the index of the added entry. */
public int addInterfaceMethodrefInfo(int classInfo, String name, String type) { int nt = addNameAndTypeInfo(name, type); return addInterfaceMethodrefInfo(classInfo, nt); }
Adds a new CONSTANT_InterfaceMethodref_info structure.
Params:
  • classInfo – class_index
  • nameAndTypeInfo – name_and_type_index.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_InterfaceMethodref_info</code> * structure. * * @param classInfo <code>class_index</code> * @param nameAndTypeInfo <code>name_and_type_index</code>. * @return the index of the added entry. */
public int addInterfaceMethodrefInfo(int classInfo, int nameAndTypeInfo) { return addItem(new InterfaceMethodrefInfo(classInfo, nameAndTypeInfo, numOfItems)); }
Adds a new CONSTANT_String_info structure.

This also adds a new CONSTANT_Utf8_info structure.

Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_String_info</code> * structure. * * <p>This also adds a new <code>CONSTANT_Utf8_info</code> * structure. * * @return the index of the added entry. */
public int addStringInfo(String str) { int utf = addUtf8Info(str); return addItem(new StringInfo(utf, numOfItems)); }
Adds a new CONSTANT_Integer_info structure.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Integer_info</code> * structure. * * @return the index of the added entry. */
public int addIntegerInfo(int i) { return addItem(new IntegerInfo(i, numOfItems)); }
Adds a new CONSTANT_Float_info structure.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Float_info</code> * structure. * * @return the index of the added entry. */
public int addFloatInfo(float f) { return addItem(new FloatInfo(f, numOfItems)); }
Adds a new CONSTANT_Long_info structure.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Long_info</code> * structure. * * @return the index of the added entry. */
public int addLongInfo(long l) { int i = addItem(new LongInfo(l, numOfItems)); if (i == numOfItems - 1) // if not existing addConstInfoPadding(); return i; }
Adds a new CONSTANT_Double_info structure.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Double_info</code> * structure. * * @return the index of the added entry. */
public int addDoubleInfo(double d) { int i = addItem(new DoubleInfo(d, numOfItems)); if (i == numOfItems - 1) // if not existing addConstInfoPadding(); return i; }
Adds a new CONSTANT_Utf8_info structure.
Returns: the index of the added entry.
/** * Adds a new <code>CONSTANT_Utf8_info</code> * structure. * * @return the index of the added entry. */
public int addUtf8Info(String utf8) { return addItem(new Utf8Info(utf8, numOfItems)); }
Adds a new CONSTANT_MethodHandle_info structure.
Params:
Returns: the index of the added entry.
Since:3.17
/** * Adds a new <code>CONSTANT_MethodHandle_info</code> * structure. * * @param kind <code>reference_kind</code> * such as {@link #REF_invokeStatic <code>REF_invokeStatic</code>}. * @param index <code>reference_index</code>. * @return the index of the added entry. * * @since 3.17 */
public int addMethodHandleInfo(int kind, int index) { return addItem(new MethodHandleInfo(kind, index, numOfItems)); }
Adds a new CONSTANT_MethodType_info structure.
Params:
  • desc – descriptor_index.
Returns: the index of the added entry.
Since:3.17
/** * Adds a new <code>CONSTANT_MethodType_info</code> * structure. * * @param desc <code>descriptor_index</code>. * @return the index of the added entry. * * @since 3.17 */
public int addMethodTypeInfo(int desc) { return addItem(new MethodTypeInfo(desc, numOfItems)); }
Adds a new CONSTANT_InvokeDynamic_info structure.
Params:
  • bootstrap – bootstrap_method_attr_index.
  • nameAndType – name_and_type_index.
Returns: the index of the added entry.
Since:3.17
/** * Adds a new <code>CONSTANT_InvokeDynamic_info</code> * structure. * * @param bootstrap <code>bootstrap_method_attr_index</code>. * @param nameAndType <code>name_and_type_index</code>. * @return the index of the added entry. * * @since 3.17 */
public int addInvokeDynamicInfo(int bootstrap, int nameAndType) { return addItem(new InvokeDynamicInfo(bootstrap, nameAndType, numOfItems)); }
Adds a new CONSTANT_Dynamic_info structure.
Params:
  • bootstrap – bootstrap_method_attr_index.
  • nameAndType – name_and_type_index.
Returns:the index of the added entry.
Since:3.26
/** * Adds a new <code>CONSTANT_Dynamic_info</code> structure. * * @param bootstrap <code>bootstrap_method_attr_index</code>. * @param nameAndType <code>name_and_type_index</code>. * @return the index of the added entry. * @since 3.26 */
public int addDynamicInfo(int bootstrap, int nameAndType) { return addItem(new DynamicInfo(bootstrap, nameAndType, numOfItems)); }
Adds a new CONSTANT_Module_info
Params:
  • nameIndex – the index of the Utf8 entry.
Returns: the index of the added entry.
Since:3.22
/** * Adds a new <code>CONSTANT_Module_info</code> * @param nameIndex the index of the Utf8 entry. * @return the index of the added entry. * @since 3.22 */
public int addModuleInfo(int nameIndex) { return addItem(new ModuleInfo(nameIndex, numOfItems)); }
Adds a new CONSTANT_Package_info
Params:
  • nameIndex – the index of the Utf8 entry.
Returns: the index of the added entry.
Since:3.22
/** * Adds a new <code>CONSTANT_Package_info</code> * @param nameIndex the index of the Utf8 entry. * @return the index of the added entry. * @since 3.22 */
public int addPackageInfo(int nameIndex) { return addItem(new PackageInfo(nameIndex, numOfItems)); }
Get all the class names.
Returns:a set of class names (String objects).
/** * Get all the class names. * * @return a set of class names (<code>String</code> objects). */
public Set<String> getClassNames() { Set<String> result = new HashSet<String>(); LongVector v = items; int size = numOfItems; for (int i = 1; i < size; ++i) { String className = v.elementAt(i).getClassName(this); if (className != null) result.add(className); } return result; }
Replaces all occurrences of a class name.
Params:
  • oldName – the replaced name (JVM-internal representation).
  • newName – the substituted name (JVM-internal representation).
/** * Replaces all occurrences of a class name. * * @param oldName the replaced name (JVM-internal representation). * @param newName the substituted name (JVM-internal representation). */
public void renameClass(String oldName, String newName) { LongVector v = items; int size = numOfItems; for (int i = 1; i < size; ++i) { ConstInfo ci = v.elementAt(i); ci.renameClass(this, oldName, newName, itemsCache); } }
Replaces all occurrences of class names.
Params:
  • classnames – specifies pairs of replaced and substituted name.
/** * Replaces all occurrences of class names. * * @param classnames specifies pairs of replaced and substituted * name. */
public void renameClass(Map<String,String> classnames) { LongVector v = items; int size = numOfItems; for (int i = 1; i < size; ++i) { ConstInfo ci = v.elementAt(i); ci.renameClass(this, classnames, itemsCache); } } private void read(DataInputStream in) throws IOException { int n = in.readUnsignedShort(); items = new LongVector(n); numOfItems = 0; addItem0(null); // index 0 is reserved by the JVM. while (--n > 0) { // index 0 is reserved by JVM int tag = readOne(in); if ((tag == LongInfo.tag) || (tag == DoubleInfo.tag)) { addConstInfoPadding(); --n; } } } private static Map<ConstInfo,ConstInfo> makeItemsCache(LongVector items) { Map<ConstInfo,ConstInfo> cache = new HashMap<ConstInfo,ConstInfo>(); int i = 1; while (true) { ConstInfo info = items.elementAt(i++); if (info == null) break; cache.put(info, info); } return cache; } private int readOne(DataInputStream in) throws IOException { ConstInfo info; int tag = in.readUnsignedByte(); switch (tag) { case Utf8Info.tag : // 1 info = new Utf8Info(in, numOfItems); break; case IntegerInfo.tag : // 3 info = new IntegerInfo(in, numOfItems); break; case FloatInfo.tag : // 4 info = new FloatInfo(in, numOfItems); break; case LongInfo.tag : // 5 info = new LongInfo(in, numOfItems); break; case DoubleInfo.tag : // 6 info = new DoubleInfo(in, numOfItems); break; case ClassInfo.tag : // 7 info = new ClassInfo(in, numOfItems); break; case StringInfo.tag : // 8 info = new StringInfo(in, numOfItems); break; case FieldrefInfo.tag : // 9 info = new FieldrefInfo(in, numOfItems); break; case MethodrefInfo.tag : // 10 info = new MethodrefInfo(in, numOfItems); break; case InterfaceMethodrefInfo.tag : // 11 info = new InterfaceMethodrefInfo(in, numOfItems); break; case NameAndTypeInfo.tag : // 12 info = new NameAndTypeInfo(in, numOfItems); break; case MethodHandleInfo.tag : // 15 info = new MethodHandleInfo(in, numOfItems); break; case MethodTypeInfo.tag : // 16 info = new MethodTypeInfo(in, numOfItems); break; case DynamicInfo.tag : // 17 info = new DynamicInfo(in, numOfItems); break; case InvokeDynamicInfo.tag : // 18 info = new InvokeDynamicInfo(in, numOfItems); break; case ModuleInfo.tag : // 19 info = new ModuleInfo(in, numOfItems); break; case PackageInfo.tag : // 20 info = new PackageInfo(in, numOfItems); break; default : throw new IOException("invalid constant type: " + tag + " at " + numOfItems); } addItem0(info); return tag; }
Writes the contents of the constant pool table.
/** * Writes the contents of the constant pool table. */
public void write(DataOutputStream out) throws IOException { out.writeShort(numOfItems); LongVector v = items; int size = numOfItems; for (int i = 1; i < size; ++i) v.elementAt(i).write(out); }
Prints the contents of the constant pool table.
/** * Prints the contents of the constant pool table. */
public void print() { print(new PrintWriter(System.out, true)); }
Prints the contents of the constant pool table.
/** * Prints the contents of the constant pool table. */
public void print(PrintWriter out) { int size = numOfItems; for (int i = 1; i < size; ++i) { out.print(i); out.print(" "); items.elementAt(i).print(out); } } } abstract class ConstInfo { int index; public ConstInfo(int i) { index = i; } public abstract int getTag(); public String getClassName(ConstPool cp) { return null; } public void renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache) {} public void renameClass(ConstPool cp, Map<String,String> classnames, Map<ConstInfo,ConstInfo> cache) {} public abstract int copy(ConstPool src, ConstPool dest, Map<String, String> classnames); // ** classnames is a mapping between JVM names. public abstract void write(DataOutputStream out) throws IOException; public abstract void print(PrintWriter out); @Override public String toString() { ByteArrayOutputStream bout = new ByteArrayOutputStream(); PrintWriter out = new PrintWriter(bout); print(out); return bout.toString(); } } /* padding following DoubleInfo or LongInfo. */ class ConstInfoPadding extends ConstInfo { public ConstInfoPadding(int i) { super(i); } @Override public int getTag() { return 0; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addConstInfoPadding(); } @Override public void write(DataOutputStream out) throws IOException {} @Override public void print(PrintWriter out) { out.println("padding"); } } class ClassInfo extends ConstInfo { static final int tag = 7; int name; public ClassInfo(int className, int index) { super(index); name = className; } public ClassInfo(DataInputStream in, int index) throws IOException { super(index); name = in.readUnsignedShort(); } @Override public int hashCode() { return name; } @Override public boolean equals(Object obj) { return obj instanceof ClassInfo && ((ClassInfo)obj).name == name; } @Override public int getTag() { return tag; } @Override public String getClassName(ConstPool cp) { return cp.getUtf8Info(name); } @Override public void renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache) { String nameStr = cp.getUtf8Info(name); String newNameStr = null; if (nameStr.equals(oldName)) newNameStr = newName; else if (nameStr.charAt(0) == '[') { String s = Descriptor.rename(nameStr, oldName, newName); if (nameStr != s) newNameStr = s; } if (newNameStr != null) if (cache == null) name = cp.addUtf8Info(newNameStr); else { cache.remove(this); name = cp.addUtf8Info(newNameStr); cache.put(this, this); } } @Override public void renameClass(ConstPool cp, Map<String,String> map, Map<ConstInfo,ConstInfo> cache) { String oldName = cp.getUtf8Info(name); String newName = null; if (oldName.charAt(0) == '[') { String s = Descriptor.rename(oldName, map); if (oldName != s) newName = s; } else { String s = map.get(oldName); if (s != null && !s.equals(oldName)) newName = s; } if (newName != null) { if (cache == null) name = cp.addUtf8Info(newName); else { cache.remove(this); name = cp.addUtf8Info(newName); cache.put(this, this); } } } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { String classname = src.getUtf8Info(name); if (map != null) { String newname = map.get(classname); if (newname != null) classname = newname; } return dest.addClassInfo(classname); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(name); } @Override public void print(PrintWriter out) { out.print("Class #"); out.println(name); } } class NameAndTypeInfo extends ConstInfo { static final int tag = 12; int memberName; int typeDescriptor; public NameAndTypeInfo(int name, int type, int index) { super(index); memberName = name; typeDescriptor = type; } public NameAndTypeInfo(DataInputStream in, int index) throws IOException { super(index); memberName = in.readUnsignedShort(); typeDescriptor = in.readUnsignedShort(); } @Override public int hashCode() { return (memberName << 16) ^ typeDescriptor; } @Override public boolean equals(Object obj) { if (obj instanceof NameAndTypeInfo) { NameAndTypeInfo nti = (NameAndTypeInfo)obj; return nti.memberName == memberName && nti.typeDescriptor == typeDescriptor; } return false; } @Override public int getTag() { return tag; } @Override public void renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache) { String type = cp.getUtf8Info(typeDescriptor); String type2 = Descriptor.rename(type, oldName, newName); if (type != type2) if (cache == null) typeDescriptor = cp.addUtf8Info(type2); else { cache.remove(this); typeDescriptor = cp.addUtf8Info(type2); cache.put(this, this); } } @Override public void renameClass(ConstPool cp, Map<String,String> map, Map<ConstInfo,ConstInfo> cache) { String type = cp.getUtf8Info(typeDescriptor); String type2 = Descriptor.rename(type, map); if (type != type2) if (cache == null) typeDescriptor = cp.addUtf8Info(type2); else { cache.remove(this); typeDescriptor = cp.addUtf8Info(type2); cache.put(this, this); } } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { String mname = src.getUtf8Info(memberName); String tdesc = src.getUtf8Info(typeDescriptor); tdesc = Descriptor.rename(tdesc, map); return dest.addNameAndTypeInfo(dest.addUtf8Info(mname), dest.addUtf8Info(tdesc)); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(memberName); out.writeShort(typeDescriptor); } @Override public void print(PrintWriter out) { out.print("NameAndType #"); out.print(memberName); out.print(", type #"); out.println(typeDescriptor); } } abstract class MemberrefInfo extends ConstInfo { int classIndex; int nameAndTypeIndex; public MemberrefInfo(int cindex, int ntindex, int thisIndex) { super(thisIndex); classIndex = cindex; nameAndTypeIndex = ntindex; } public MemberrefInfo(DataInputStream in, int thisIndex) throws IOException { super(thisIndex); classIndex = in.readUnsignedShort(); nameAndTypeIndex = in.readUnsignedShort(); } @Override public int hashCode() { return (classIndex << 16) ^ nameAndTypeIndex; } @Override public boolean equals(Object obj) { if (obj instanceof MemberrefInfo) { MemberrefInfo mri = (MemberrefInfo)obj; return mri.classIndex == classIndex && mri.nameAndTypeIndex == nameAndTypeIndex && mri.getClass() == this.getClass(); } return false; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { int classIndex2 = src.getItem(classIndex).copy(src, dest, map); int ntIndex2 = src.getItem(nameAndTypeIndex).copy(src, dest, map); return copy2(dest, classIndex2, ntIndex2); } abstract protected int copy2(ConstPool dest, int cindex, int ntindex); @Override public void write(DataOutputStream out) throws IOException { out.writeByte(getTag()); out.writeShort(classIndex); out.writeShort(nameAndTypeIndex); } @Override public void print(PrintWriter out) { out.print(getTagName() + " #"); out.print(classIndex); out.print(", name&type #"); out.println(nameAndTypeIndex); } public abstract String getTagName(); } class FieldrefInfo extends MemberrefInfo { static final int tag = 9; public FieldrefInfo(int cindex, int ntindex, int thisIndex) { super(cindex, ntindex, thisIndex); } public FieldrefInfo(DataInputStream in, int thisIndex) throws IOException { super(in, thisIndex); } @Override public int getTag() { return tag; } @Override public String getTagName() { return "Field"; } @Override protected int copy2(ConstPool dest, int cindex, int ntindex) { return dest.addFieldrefInfo(cindex, ntindex); } } class MethodrefInfo extends MemberrefInfo { static final int tag = 10; public MethodrefInfo(int cindex, int ntindex, int thisIndex) { super(cindex, ntindex, thisIndex); } public MethodrefInfo(DataInputStream in, int thisIndex) throws IOException { super(in, thisIndex); } @Override public int getTag() { return tag; } @Override public String getTagName() { return "Method"; } @Override protected int copy2(ConstPool dest, int cindex, int ntindex) { return dest.addMethodrefInfo(cindex, ntindex); } } class InterfaceMethodrefInfo extends MemberrefInfo { static final int tag = 11; public InterfaceMethodrefInfo(int cindex, int ntindex, int thisIndex) { super(cindex, ntindex, thisIndex); } public InterfaceMethodrefInfo(DataInputStream in, int thisIndex) throws IOException { super(in, thisIndex); } @Override public int getTag() { return tag; } @Override public String getTagName() { return "Interface"; } @Override protected int copy2(ConstPool dest, int cindex, int ntindex) { return dest.addInterfaceMethodrefInfo(cindex, ntindex); } } class StringInfo extends ConstInfo { static final int tag = 8; int string; public StringInfo(int str, int index) { super(index); string = str; } public StringInfo(DataInputStream in, int index) throws IOException { super(index); string = in.readUnsignedShort(); } @Override public int hashCode() { return string; } @Override public boolean equals(Object obj) { return obj instanceof StringInfo && ((StringInfo)obj).string == string; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addStringInfo(src.getUtf8Info(string)); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(string); } @Override public void print(PrintWriter out) { out.print("String #"); out.println(string); } } class IntegerInfo extends ConstInfo { static final int tag = 3; int value; public IntegerInfo(int v, int index) { super(index); value = v; } public IntegerInfo(DataInputStream in, int index) throws IOException { super(index); value = in.readInt(); } @Override public int hashCode() { return value; } @Override public boolean equals(Object obj) { return obj instanceof IntegerInfo && ((IntegerInfo)obj).value == value; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addIntegerInfo(value); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeInt(value); } @Override public void print(PrintWriter out) { out.print("Integer "); out.println(value); } } class FloatInfo extends ConstInfo { static final int tag = 4; float value; public FloatInfo(float f, int index) { super(index); value = f; } public FloatInfo(DataInputStream in, int index) throws IOException { super(index); value = in.readFloat(); } @Override public int hashCode() { return Float.floatToIntBits(value); } @Override public boolean equals(Object obj) { return obj instanceof FloatInfo && ((FloatInfo)obj).value == value; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addFloatInfo(value); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeFloat(value); } @Override public void print(PrintWriter out) { out.print("Float "); out.println(value); } } class LongInfo extends ConstInfo { static final int tag = 5; long value; public LongInfo(long l, int index) { super(index); value = l; } public LongInfo(DataInputStream in, int index) throws IOException { super(index); value = in.readLong(); } @Override public int hashCode() { return (int)(value ^ (value >>> 32)); } @Override public boolean equals(Object obj) { return obj instanceof LongInfo && ((LongInfo)obj).value == value; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addLongInfo(value); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeLong(value); } @Override public void print(PrintWriter out) { out.print("Long "); out.println(value); } } class DoubleInfo extends ConstInfo { static final int tag = 6; double value; public DoubleInfo(double d, int index) { super(index); value = d; } public DoubleInfo(DataInputStream in, int index) throws IOException { super(index); value = in.readDouble(); } @Override public int hashCode() { long v = Double.doubleToLongBits(value); return (int)(v ^ (v >>> 32)); } @Override public boolean equals(Object obj) { return obj instanceof DoubleInfo && ((DoubleInfo)obj).value == value; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addDoubleInfo(value); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeDouble(value); } @Override public void print(PrintWriter out) { out.print("Double "); out.println(value); } } class Utf8Info extends ConstInfo { static final int tag = 1; String string; public Utf8Info(String utf8, int index) { super(index); string = utf8; } public Utf8Info(DataInputStream in, int index) throws IOException { super(index); string = in.readUTF(); } @Override public int hashCode() { return string.hashCode(); } @Override public boolean equals(Object obj) { return obj instanceof Utf8Info && ((Utf8Info)obj).string.equals(string); } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addUtf8Info(string); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeUTF(string); } @Override public void print(PrintWriter out) { out.print("UTF8 \""); out.print(string); out.println("\""); } } class MethodHandleInfo extends ConstInfo { static final int tag = 15; int refKind, refIndex; public MethodHandleInfo(int kind, int referenceIndex, int index) { super(index); refKind = kind; refIndex = referenceIndex; } public MethodHandleInfo(DataInputStream in, int index) throws IOException { super(index); refKind = in.readUnsignedByte(); refIndex = in.readUnsignedShort(); } @Override public int hashCode() { return (refKind << 16) ^ refIndex; } @Override public boolean equals(Object obj) { if (obj instanceof MethodHandleInfo) { MethodHandleInfo mh = (MethodHandleInfo)obj; return mh.refKind == refKind && mh.refIndex == refIndex; } return false; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addMethodHandleInfo(refKind, src.getItem(refIndex).copy(src, dest, map)); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeByte(refKind); out.writeShort(refIndex); } @Override public void print(PrintWriter out) { out.print("MethodHandle #"); out.print(refKind); out.print(", index #"); out.println(refIndex); } } class MethodTypeInfo extends ConstInfo { static final int tag = 16; int descriptor; public MethodTypeInfo(int desc, int index) { super(index); descriptor = desc; } public MethodTypeInfo(DataInputStream in, int index) throws IOException { super(index); descriptor = in.readUnsignedShort(); } @Override public int hashCode() { return descriptor; } @Override public boolean equals(Object obj) { if (obj instanceof MethodTypeInfo) return ((MethodTypeInfo)obj).descriptor == descriptor; return false; } @Override public int getTag() { return tag; } @Override public void renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache) { String desc = cp.getUtf8Info(descriptor); String desc2 = Descriptor.rename(desc, oldName, newName); if (desc != desc2) if (cache == null) descriptor = cp.addUtf8Info(desc2); else { cache.remove(this); descriptor = cp.addUtf8Info(desc2); cache.put(this, this); } } @Override public void renameClass(ConstPool cp, Map<String,String> map, Map<ConstInfo,ConstInfo> cache) { String desc = cp.getUtf8Info(descriptor); String desc2 = Descriptor.rename(desc, map); if (desc != desc2) if (cache == null) descriptor = cp.addUtf8Info(desc2); else { cache.remove(this); descriptor = cp.addUtf8Info(desc2); cache.put(this, this); } } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { String desc = src.getUtf8Info(descriptor); desc = Descriptor.rename(desc, map); return dest.addMethodTypeInfo(dest.addUtf8Info(desc)); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(descriptor); } @Override public void print(PrintWriter out) { out.print("MethodType #"); out.println(descriptor); } } class InvokeDynamicInfo extends ConstInfo { static final int tag = 18; int bootstrap, nameAndType; public InvokeDynamicInfo(int bootstrapMethod, int ntIndex, int index) { super(index); bootstrap = bootstrapMethod; nameAndType = ntIndex; } public InvokeDynamicInfo(DataInputStream in, int index) throws IOException { super(index); bootstrap = in.readUnsignedShort(); nameAndType = in.readUnsignedShort(); } @Override public int hashCode() { return (bootstrap << 16) ^ nameAndType; } @Override public boolean equals(Object obj) { if (obj instanceof InvokeDynamicInfo) { InvokeDynamicInfo iv = (InvokeDynamicInfo)obj; return iv.bootstrap == bootstrap && iv.nameAndType == nameAndType; } return false; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { return dest.addInvokeDynamicInfo(bootstrap, src.getItem(nameAndType).copy(src, dest, map)); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(bootstrap); out.writeShort(nameAndType); } @Override public void print(PrintWriter out) { out.print("InvokeDynamic #"); out.print(bootstrap); out.print(", name&type #"); out.println(nameAndType); } } class DynamicInfo extends ConstInfo { static final int tag = 17; int bootstrap, nameAndType; public DynamicInfo(int bootstrapMethod, int ntIndex, int index) { super(index); bootstrap = bootstrapMethod; nameAndType = ntIndex; } public DynamicInfo(DataInputStream in, int index) throws IOException { super(index); bootstrap = in.readUnsignedShort(); nameAndType = in.readUnsignedShort(); } @Override public int hashCode() { return (bootstrap << 16) ^ nameAndType; } @Override public boolean equals(Object obj) { if (obj instanceof DynamicInfo) { DynamicInfo iv = (DynamicInfo)obj; return iv.bootstrap == bootstrap && iv.nameAndType == nameAndType; } return false; } @Override public int getTag() { return tag; } @Override public int copy(ConstPool src, ConstPool dest, Map<String, String> map) { return dest.addDynamicInfo(bootstrap, src.getItem(nameAndType).copy(src, dest, map)); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(bootstrap); out.writeShort(nameAndType); } @Override public void print(PrintWriter out) { out.print("Dynamic #"); out.print(bootstrap); out.print(", name&type #"); out.println(nameAndType); } } class ModuleInfo extends ConstInfo { static final int tag = 19; int name; public ModuleInfo(int moduleName, int index) { super(index); name = moduleName; } public ModuleInfo(DataInputStream in, int index) throws IOException { super(index); name = in.readUnsignedShort(); } @Override public int hashCode() { return name; } @Override public boolean equals(Object obj) { return obj instanceof ModuleInfo && ((ModuleInfo)obj).name == name; } @Override public int getTag() { return tag; } public String getModuleName(ConstPool cp) { return cp.getUtf8Info(name); } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { String moduleName = src.getUtf8Info(name); int newName = dest.addUtf8Info(moduleName); return dest.addModuleInfo(newName); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(name); } @Override public void print(PrintWriter out) { out.print("Module #"); out.println(name); } } class PackageInfo extends ConstInfo { static final int tag = 20; int name; public PackageInfo(int moduleName, int index) { super(index); name = moduleName; } public PackageInfo(DataInputStream in, int index) throws IOException { super(index); name = in.readUnsignedShort(); } @Override public int hashCode() { return name; } @Override public boolean equals(Object obj) { return obj instanceof PackageInfo && ((PackageInfo)obj).name == name; } @Override public int getTag() { return tag; } public String getPackageName(ConstPool cp) { return cp.getUtf8Info(name); } @Override public int copy(ConstPool src, ConstPool dest, Map<String,String> map) { String packageName = src.getUtf8Info(name); int newName = dest.addUtf8Info(packageName); return dest.addModuleInfo(newName); } @Override public void write(DataOutputStream out) throws IOException { out.writeByte(tag); out.writeShort(name); } @Override public void print(PrintWriter out) { out.print("Package #"); out.println(name); } }