--- old/langtools/src/jdk.compiler/share/classes/com/sun/tools/classfile/ConstantPool.java 2015-05-26 21:42:19.507832824 -0700
+++ /dev/null 2015-04-26 22:05:36.465433038 -0700
@@ -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.
- *
- *
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.
- */
-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 entries() {
- return new Iterable() {
- public Iterator iterator() {
- return new Iterator() {
-
- 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 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor visitor, D data) {
- return visitor.visitUtf8(this, data);
- }
-
- public final String value;
- }
-
-}
--- /dev/null 2015-04-26 22:05:36.465433038 -0700
+++ new/langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ConstantPool.java 2015-05-26 21:42:19.331832822 -0700
@@ -0,0 +1,914 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+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 entries() {
+ return new Iterable() {
+ public Iterator iterator() {
+ return new Iterator() {
+
+ 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 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor visitor, D data) {
+ return visitor.visitUtf8(this, data);
+ }
+
+ public final String value;
+ }
+
+}