langtools/src/jdk.compiler/share/classes/com/sun/tools/classfile/ConstantPool.java
changeset 30848 c275389a3680
parent 30842 b02fa8bb730c
parent 30847 9385b9c8506b
child 30849 fcfa8eb95c23
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/classfile/ConstantPool.java	Thu May 28 16:13:55 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,914 +0,0 @@
-/*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.classfile;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-
-/**
- * See JVMS, section 4.5.
- *
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own risk.
- *  This code and its internal interfaces are subject to change or
- *  deletion without notice.</b>
- */
-public class ConstantPool {
-
-    public static class InvalidIndex extends ConstantPoolException {
-        private static final long serialVersionUID = -4350294289300939730L;
-        InvalidIndex(int index) {
-            super(index);
-        }
-
-        @Override
-        public String getMessage() {
-            // i18n
-            return "invalid index #" + index;
-        }
-    }
-
-    public static class UnexpectedEntry extends ConstantPoolException {
-        private static final long serialVersionUID = 6986335935377933211L;
-        UnexpectedEntry(int index, int expected_tag, int found_tag) {
-            super(index);
-            this.expected_tag = expected_tag;
-            this.found_tag = found_tag;
-        }
-
-        @Override
-        public String getMessage() {
-            // i18n?
-            return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
-        }
-
-        public final int expected_tag;
-        public final int found_tag;
-    }
-
-    public static class InvalidEntry extends ConstantPoolException {
-        private static final long serialVersionUID = 1000087545585204447L;
-        InvalidEntry(int index, int tag) {
-            super(index);
-            this.tag = tag;
-        }
-
-        @Override
-        public String getMessage() {
-            // i18n?
-            return "unexpected tag at #" + index + ": " + tag;
-        }
-
-        public final int tag;
-    }
-
-    public static class EntryNotFound extends ConstantPoolException {
-        private static final long serialVersionUID = 2885537606468581850L;
-        EntryNotFound(Object value) {
-            super(-1);
-            this.value = value;
-        }
-
-        @Override
-        public String getMessage() {
-            // i18n?
-            return "value not found: " + value;
-        }
-
-        public final Object value;
-    }
-
-    public static final int CONSTANT_Utf8 = 1;
-    public static final int CONSTANT_Integer = 3;
-    public static final int CONSTANT_Float = 4;
-    public static final int CONSTANT_Long = 5;
-    public static final int CONSTANT_Double = 6;
-    public static final int CONSTANT_Class = 7;
-    public static final int CONSTANT_String = 8;
-    public static final int CONSTANT_Fieldref = 9;
-    public static final int CONSTANT_Methodref = 10;
-    public static final int CONSTANT_InterfaceMethodref = 11;
-    public static final int CONSTANT_NameAndType = 12;
-    public static final int CONSTANT_MethodHandle = 15;
-    public static final int CONSTANT_MethodType = 16;
-    public static final int CONSTANT_InvokeDynamic = 18;
-
-    public static enum RefKind {
-        REF_getField(1, "getfield"),
-        REF_getStatic(2, "getstatic"),
-        REF_putField(3, "putfield"),
-        REF_putStatic(4, "putstatic"),
-        REF_invokeVirtual(5, "invokevirtual"),
-        REF_invokeStatic(6, "invokestatic"),
-        REF_invokeSpecial(7, "invokespecial"),
-        REF_newInvokeSpecial(8, "newinvokespecial"),
-        REF_invokeInterface(9, "invokeinterface");
-
-        public final int tag;
-        public final String name;
-
-        RefKind(int tag, String name) {
-            this.tag = tag;
-            this.name = name;
-        }
-
-        static RefKind getRefkind(int tag) {
-            switch(tag) {
-                case 1:
-                    return REF_getField;
-                case 2:
-                    return REF_getStatic;
-                case 3:
-                    return REF_putField;
-                case 4:
-                    return REF_putStatic;
-                case 5:
-                    return REF_invokeVirtual;
-                case 6:
-                    return REF_invokeStatic;
-                case 7:
-                    return REF_invokeSpecial;
-                case 8:
-                    return REF_newInvokeSpecial;
-                case 9:
-                    return REF_invokeInterface;
-                default:
-                    return null;
-            }
-        }
-    }
-
-    ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
-        int count = cr.readUnsignedShort();
-        pool = new CPInfo[count];
-        for (int i = 1; i < count; i++) {
-            int tag = cr.readUnsignedByte();
-            switch (tag) {
-            case CONSTANT_Class:
-                pool[i] = new CONSTANT_Class_info(this, cr);
-                break;
-
-            case CONSTANT_Double:
-                pool[i] = new CONSTANT_Double_info(cr);
-                i++;
-                break;
-
-            case CONSTANT_Fieldref:
-                pool[i] = new CONSTANT_Fieldref_info(this, cr);
-                break;
-
-            case CONSTANT_Float:
-                pool[i] = new CONSTANT_Float_info(cr);
-                break;
-
-            case CONSTANT_Integer:
-                pool[i] = new CONSTANT_Integer_info(cr);
-                break;
-
-            case CONSTANT_InterfaceMethodref:
-                pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
-                break;
-
-            case CONSTANT_InvokeDynamic:
-                pool[i] = new CONSTANT_InvokeDynamic_info(this, cr);
-                break;
-
-            case CONSTANT_Long:
-                pool[i] = new CONSTANT_Long_info(cr);
-                i++;
-                break;
-
-            case CONSTANT_MethodHandle:
-                pool[i] = new CONSTANT_MethodHandle_info(this, cr);
-                break;
-
-            case CONSTANT_MethodType:
-                pool[i] = new CONSTANT_MethodType_info(this, cr);
-                break;
-
-            case CONSTANT_Methodref:
-                pool[i] = new CONSTANT_Methodref_info(this, cr);
-                break;
-
-            case CONSTANT_NameAndType:
-                pool[i] = new CONSTANT_NameAndType_info(this, cr);
-                break;
-
-            case CONSTANT_String:
-                pool[i] = new CONSTANT_String_info(this, cr);
-                break;
-
-            case CONSTANT_Utf8:
-                pool[i] = new CONSTANT_Utf8_info(cr);
-                break;
-
-            default:
-                throw new InvalidEntry(i, tag);
-            }
-        }
-    }
-
-    public ConstantPool(CPInfo[] pool) {
-        this.pool = pool;
-    }
-
-    public int size() {
-        return pool.length;
-    }
-
-    public int byteLength() {
-        int length = 2;
-        for (int i = 1; i < size(); ) {
-            CPInfo cpInfo = pool[i];
-            length += cpInfo.byteLength();
-            i += cpInfo.size();
-        }
-        return length;
-    }
-
-    public CPInfo get(int index) throws InvalidIndex {
-        if (index <= 0 || index >= pool.length)
-            throw new InvalidIndex(index);
-        CPInfo info = pool[index];
-        if (info == null) {
-            // this occurs for indices referencing the "second half" of an
-            // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
-            throw new InvalidIndex(index);
-        }
-        return pool[index];
-    }
-
-    private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
-        CPInfo info = get(index);
-        if (info.getTag() != expected_type)
-            throw new UnexpectedEntry(index, expected_type, info.getTag());
-        return info;
-    }
-
-    public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
-        return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
-    }
-
-    public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
-        return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
-    }
-
-    public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
-        return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
-    }
-
-    public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
-        return getUTF8Info(index).value;
-    }
-
-    public int getUTF8Index(String value) throws EntryNotFound {
-        for (int i = 1; i < pool.length; i++) {
-            CPInfo info = pool[i];
-            if (info instanceof CONSTANT_Utf8_info &&
-                    ((CONSTANT_Utf8_info) info).value.equals(value))
-                return i;
-        }
-        throw new EntryNotFound(value);
-    }
-
-    public Iterable<CPInfo> entries() {
-        return new Iterable<CPInfo>() {
-            public Iterator<CPInfo> iterator() {
-                return new Iterator<CPInfo>() {
-
-                    public boolean hasNext() {
-                        return next < pool.length;
-                    }
-
-                    public CPInfo next() {
-                        current = pool[next];
-                        switch (current.getTag()) {
-                            case CONSTANT_Double:
-                            case CONSTANT_Long:
-                                next += 2;
-                                break;
-                            default:
-                                next += 1;
-                        }
-                        return current;
-                    }
-
-                    public void remove() {
-                        throw new UnsupportedOperationException();
-                    }
-
-                    private CPInfo current;
-                    private int next = 1;
-
-                };
-            }
-        };
-    }
-
-    private CPInfo[] pool;
-
-    public interface Visitor<R,P> {
-        R visitClass(CONSTANT_Class_info info, P p);
-        R visitDouble(CONSTANT_Double_info info, P p);
-        R visitFieldref(CONSTANT_Fieldref_info info, P p);
-        R visitFloat(CONSTANT_Float_info info, P p);
-        R visitInteger(CONSTANT_Integer_info info, P p);
-        R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
-        R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);
-        R visitLong(CONSTANT_Long_info info, P p);
-        R visitNameAndType(CONSTANT_NameAndType_info info, P p);
-        R visitMethodref(CONSTANT_Methodref_info info, P p);
-        R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);
-        R visitMethodType(CONSTANT_MethodType_info info, P p);
-        R visitString(CONSTANT_String_info info, P p);
-        R visitUtf8(CONSTANT_Utf8_info info, P p);
-    }
-
-    public static abstract class CPInfo {
-        CPInfo() {
-            this.cp = null;
-        }
-
-        CPInfo(ConstantPool cp) {
-            this.cp = cp;
-        }
-
-        public abstract int getTag();
-
-        /** The number of slots in the constant pool used by this entry.
-         * 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */
-        public int size() {
-            return 1;
-        }
-
-        public abstract int byteLength();
-
-        public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
-
-        protected final ConstantPool cp;
-    }
-
-    public static abstract class CPRefInfo extends CPInfo {
-        protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
-            super(cp);
-            this.tag = tag;
-            class_index = cr.readUnsignedShort();
-            name_and_type_index = cr.readUnsignedShort();
-        }
-
-        protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
-            super(cp);
-            this.tag = tag;
-            this.class_index = class_index;
-            this.name_and_type_index = name_and_type_index;
-        }
-
-        public int getTag() {
-            return tag;
-        }
-
-        public int byteLength() {
-            return 5;
-        }
-
-        public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
-            return cp.getClassInfo(class_index);
-        }
-
-        public String getClassName() throws ConstantPoolException {
-            return cp.getClassInfo(class_index).getName();
-        }
-
-        public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
-            return cp.getNameAndTypeInfo(name_and_type_index);
-        }
-
-        public final int tag;
-        public final int class_index;
-        public final int name_and_type_index;
-    }
-
-    public static class CONSTANT_Class_info extends CPInfo {
-        CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp);
-            name_index = cr.readUnsignedShort();
-        }
-
-        public CONSTANT_Class_info(ConstantPool cp, int name_index) {
-            super(cp);
-            this.name_index = name_index;
-        }
-
-        public int getTag() {
-            return CONSTANT_Class;
-        }
-
-        public int  byteLength() {
-            return 3;
-        }
-
-        /**
-         * Get the raw value of the class referenced by this constant pool entry.
-         * This will either be the name of the class, in internal form, or a
-         * descriptor for an array class.
-         * @return the raw value of the class
-         */
-        public String getName() throws ConstantPoolException {
-            return cp.getUTF8Value(name_index);
-        }
-
-        /**
-         * If this constant pool entry identifies either a class or interface type,
-         * or a possibly multi-dimensional array of a class of interface type,
-         * return the name of the class or interface in internal form. Otherwise,
-         * (i.e. if this is a possibly multi-dimensional array of a primitive type),
-         * return null.
-         * @return the base class or interface name
-         */
-        public String getBaseName() throws ConstantPoolException {
-            String name = getName();
-            if (name.startsWith("[")) {
-                int index = name.indexOf("[L");
-                if (index == -1)
-                    return null;
-                return name.substring(index + 2, name.length() - 1);
-            } else
-                return name;
-        }
-
-        public int getDimensionCount() throws ConstantPoolException {
-            String name = getName();
-            int count = 0;
-            while (name.charAt(count) == '[')
-                count++;
-            return count;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_Class_info[name_index: " + name_index + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitClass(this, data);
-        }
-
-        public final int name_index;
-    }
-
-    public static class CONSTANT_Double_info extends CPInfo {
-        CONSTANT_Double_info(ClassReader cr) throws IOException {
-            value = cr.readDouble();
-        }
-
-        public CONSTANT_Double_info(double value) {
-            this.value = value;
-        }
-
-        public int getTag() {
-            return CONSTANT_Double;
-        }
-
-        public int  byteLength() {
-            return 9;
-        }
-
-        @Override
-        public int size() {
-            return 2;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_Double_info[value: " + value + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitDouble(this, data);
-        }
-
-        public final double value;
-    }
-
-    public static class CONSTANT_Fieldref_info extends CPRefInfo {
-        CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp, cr, CONSTANT_Fieldref);
-        }
-
-        public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
-            super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitFieldref(this, data);
-        }
-    }
-
-    public static class CONSTANT_Float_info extends CPInfo {
-        CONSTANT_Float_info(ClassReader cr) throws IOException {
-            value = cr.readFloat();
-        }
-
-        public CONSTANT_Float_info(float value) {
-            this.value = value;
-        }
-
-        public int getTag() {
-            return CONSTANT_Float;
-        }
-
-        public int byteLength() {
-            return 5;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_Float_info[value: " + value + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitFloat(this, data);
-        }
-
-        public final float value;
-    }
-
-    public static class CONSTANT_Integer_info extends CPInfo {
-        CONSTANT_Integer_info(ClassReader cr) throws IOException {
-            value = cr.readInt();
-        }
-
-        public CONSTANT_Integer_info(int value) {
-            this.value = value;
-        }
-
-        public int getTag() {
-            return CONSTANT_Integer;
-        }
-
-        public int byteLength() {
-            return 5;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_Integer_info[value: " + value + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitInteger(this, data);
-        }
-
-        public final int value;
-    }
-
-    public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
-        CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp, cr, CONSTANT_InterfaceMethodref);
-        }
-
-        public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
-            super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitInterfaceMethodref(this, data);
-        }
-    }
-
-    public static class CONSTANT_InvokeDynamic_info extends CPInfo {
-        CONSTANT_InvokeDynamic_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp);
-            bootstrap_method_attr_index = cr.readUnsignedShort();
-            name_and_type_index = cr.readUnsignedShort();
-        }
-
-        public CONSTANT_InvokeDynamic_info(ConstantPool cp, int bootstrap_method_index, int name_and_type_index) {
-            super(cp);
-            this.bootstrap_method_attr_index = bootstrap_method_index;
-            this.name_and_type_index = name_and_type_index;
-        }
-
-        public int getTag() {
-            return CONSTANT_InvokeDynamic;
-        }
-
-        public int byteLength() {
-            return 5;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_InvokeDynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitInvokeDynamic(this, data);
-        }
-
-        public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
-            return cp.getNameAndTypeInfo(name_and_type_index);
-        }
-
-        public final int bootstrap_method_attr_index;
-        public final int name_and_type_index;
-    }
-
-    public static class CONSTANT_Long_info extends CPInfo {
-        CONSTANT_Long_info(ClassReader cr) throws IOException {
-            value = cr.readLong();
-        }
-
-        public CONSTANT_Long_info(long value) {
-            this.value = value;
-        }
-
-        public int getTag() {
-            return CONSTANT_Long;
-        }
-
-        @Override
-        public int size() {
-            return 2;
-        }
-
-        public int byteLength() {
-            return 9;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_Long_info[value: " + value + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitLong(this, data);
-        }
-
-        public final long value;
-    }
-
-    public static class CONSTANT_MethodHandle_info extends CPInfo {
-        CONSTANT_MethodHandle_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp);
-            reference_kind =  RefKind.getRefkind(cr.readUnsignedByte());
-            reference_index = cr.readUnsignedShort();
-        }
-
-        public CONSTANT_MethodHandle_info(ConstantPool cp, RefKind ref_kind, int member_index) {
-            super(cp);
-            this.reference_kind = ref_kind;
-            this.reference_index = member_index;
-        }
-
-        public int getTag() {
-            return CONSTANT_MethodHandle;
-        }
-
-        public int byteLength() {
-            return 4;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_MethodHandle_info[ref_kind: " + reference_kind + ", member_index: " + reference_index + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitMethodHandle(this, data);
-        }
-
-        public CPRefInfo getCPRefInfo() throws ConstantPoolException {
-            int expected = CONSTANT_Methodref;
-            int actual = cp.get(reference_index).getTag();
-            // allow these tag types also:
-            switch (actual) {
-                case CONSTANT_Fieldref:
-                case CONSTANT_InterfaceMethodref:
-                    expected = actual;
-            }
-            return (CPRefInfo) cp.get(reference_index, expected);
-        }
-
-        public final RefKind reference_kind;
-        public final int reference_index;
-    }
-
-    public static class CONSTANT_MethodType_info extends CPInfo {
-        CONSTANT_MethodType_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp);
-            descriptor_index = cr.readUnsignedShort();
-        }
-
-        public CONSTANT_MethodType_info(ConstantPool cp, int signature_index) {
-            super(cp);
-            this.descriptor_index = signature_index;
-        }
-
-        public int getTag() {
-            return CONSTANT_MethodType;
-        }
-
-        public int byteLength() {
-            return 3;
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_MethodType_info[signature_index: " + descriptor_index + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitMethodType(this, data);
-        }
-
-        public String getType() throws ConstantPoolException {
-            return cp.getUTF8Value(descriptor_index);
-        }
-
-        public final int descriptor_index;
-    }
-
-    public static class CONSTANT_Methodref_info extends CPRefInfo {
-        CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp, cr, CONSTANT_Methodref);
-        }
-
-        public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
-            super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitMethodref(this, data);
-        }
-    }
-
-    public static class CONSTANT_NameAndType_info extends CPInfo {
-        CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp);
-            name_index = cr.readUnsignedShort();
-            type_index = cr.readUnsignedShort();
-        }
-
-        public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
-            super(cp);
-            this.name_index = name_index;
-            this.type_index = type_index;
-        }
-
-        public int getTag() {
-            return CONSTANT_NameAndType;
-        }
-
-        public int byteLength() {
-            return 5;
-        }
-
-        public String getName() throws ConstantPoolException {
-            return cp.getUTF8Value(name_index);
-        }
-
-        public String getType() throws ConstantPoolException {
-            return cp.getUTF8Value(type_index);
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitNameAndType(this, data);
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";
-        }
-
-        public final int name_index;
-        public final int type_index;
-    }
-
-    public static class CONSTANT_String_info extends CPInfo {
-        CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {
-            super(cp);
-            string_index = cr.readUnsignedShort();
-        }
-
-        public CONSTANT_String_info(ConstantPool cp, int string_index) {
-            super(cp);
-            this.string_index = string_index;
-        }
-
-        public int getTag() {
-            return CONSTANT_String;
-        }
-
-        public int byteLength() {
-            return 3;
-        }
-
-        public String getString() throws ConstantPoolException {
-            return cp.getUTF8Value(string_index);
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitString(this, data);
-        }
-
-        @Override
-        public String toString() {
-            return "CONSTANT_String_info[class_index: " + string_index + "]";
-        }
-
-        public final int string_index;
-    }
-
-    public static class CONSTANT_Utf8_info extends CPInfo {
-        CONSTANT_Utf8_info(ClassReader cr) throws IOException {
-            value = cr.readUTF();
-        }
-
-        public CONSTANT_Utf8_info(String value) {
-            this.value = value;
-        }
-
-        public int getTag() {
-            return CONSTANT_Utf8;
-        }
-
-        public int byteLength() {
-            class SizeOutputStream extends OutputStream {
-                @Override
-                public void write(int b) {
-                    size++;
-                }
-                int size;
-            }
-            SizeOutputStream sizeOut = new SizeOutputStream();
-            DataOutputStream out = new DataOutputStream(sizeOut);
-            try { out.writeUTF(value); } catch (IOException ignore) { }
-            return 1 + sizeOut.size;
-        }
-
-        @Override
-        public String toString() {
-            if (value.length() < 32 && isPrintableAscii(value))
-                return "CONSTANT_Utf8_info[value: \"" + value + "\"]";
-            else
-                return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";
-        }
-
-        static boolean isPrintableAscii(String s) {
-            for (int i = 0; i < s.length(); i++) {
-                char c = s.charAt(i);
-                if (c < 32 || c >= 127)
-                    return false;
-            }
-            return true;
-        }
-
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitUtf8(this, data);
-        }
-
-        public final String value;
-    }
-
-}