src/share/classes/com/sun/tools/classfile/ConstantPool.java

Tue, 25 May 2010 15:54:51 -0700

author
ohair
date
Tue, 25 May 2010 15:54:51 -0700
changeset 554
9d9f26857129
parent 513
6e1e2738c530
child 581
f2fdd52e4e87
permissions
-rw-r--r--

6943119: Rebrand source copyright notices
Reviewed-by: darcy

jjg@46 1 /*
ohair@554 2 * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
jjg@46 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@46 4 *
jjg@46 5 * This code is free software; you can redistribute it and/or modify it
jjg@46 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
jjg@46 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
jjg@46 10 *
jjg@46 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@46 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@46 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@46 14 * version 2 for more details (a copy is included in the LICENSE file that
jjg@46 15 * accompanied this code).
jjg@46 16 *
jjg@46 17 * You should have received a copy of the GNU General Public License version
jjg@46 18 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@46 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@46 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
jjg@46 24 */
jjg@46 25
jjg@46 26 package com.sun.tools.classfile;
jjg@46 27
jjg@345 28 import java.io.DataOutputStream;
jjg@46 29 import java.io.IOException;
jjg@345 30 import java.io.OutputStream;
jjg@282 31 import java.util.Iterator;
jjg@46 32
jjg@46 33 /**
jjg@46 34 * See JVMS3, section 4.5.
jjg@46 35 *
jjg@46 36 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
jjg@46 37 * you write code that depends on this, you do so at your own risk.
jjg@46 38 * This code and its internal interfaces are subject to change or
jjg@46 39 * deletion without notice.</b>
jjg@46 40 */
jjg@46 41 public class ConstantPool {
jjg@46 42
jjg@513 43 public static class InvalidIndex extends ConstantPoolException {
jjg@198 44 private static final long serialVersionUID = -4350294289300939730L;
jjg@46 45 InvalidIndex(int index) {
jjg@46 46 super(index);
jjg@46 47 }
jjg@46 48
jjg@46 49 @Override
jjg@46 50 public String getMessage() {
jjg@46 51 // i18n
jjg@46 52 return "invalid index #" + index;
jjg@46 53 }
jjg@46 54 }
jjg@46 55
jjg@513 56 public static class UnexpectedEntry extends ConstantPoolException {
jjg@198 57 private static final long serialVersionUID = 6986335935377933211L;
jjg@46 58 UnexpectedEntry(int index, int expected_tag, int found_tag) {
jjg@46 59 super(index);
jjg@46 60 this.expected_tag = expected_tag;
jjg@46 61 this.found_tag = found_tag;
jjg@46 62 }
jjg@46 63
jjg@46 64 @Override
jjg@46 65 public String getMessage() {
jjg@46 66 // i18n?
jjg@46 67 return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
jjg@46 68 }
jjg@46 69
jjg@46 70 public final int expected_tag;
jjg@46 71 public final int found_tag;
jjg@46 72 }
jjg@46 73
jjg@513 74 public static class InvalidEntry extends ConstantPoolException {
jjg@198 75 private static final long serialVersionUID = 1000087545585204447L;
jjg@46 76 InvalidEntry(int index, int tag) {
jjg@46 77 super(index);
jjg@46 78 this.tag = tag;
jjg@46 79 }
jjg@46 80
jjg@46 81 @Override
jjg@46 82 public String getMessage() {
jjg@46 83 // i18n?
jjg@46 84 return "unexpected tag at #" + index + ": " + tag;
jjg@46 85 }
jjg@46 86
jjg@46 87 public final int tag;
jjg@46 88 }
jjg@46 89
jjg@513 90 public static class EntryNotFound extends ConstantPoolException {
jjg@198 91 private static final long serialVersionUID = 2885537606468581850L;
jjg@46 92 EntryNotFound(Object value) {
jjg@46 93 super(-1);
jjg@46 94 this.value = value;
jjg@46 95 }
jjg@46 96
jjg@46 97 @Override
jjg@46 98 public String getMessage() {
jjg@46 99 // i18n?
jjg@46 100 return "value not found: " + value;
jjg@46 101 }
jjg@46 102
jjg@46 103 public final Object value;
jjg@46 104 }
jjg@46 105
jjg@46 106 public static final int CONSTANT_Utf8 = 1;
jjg@46 107 public static final int CONSTANT_Integer = 3;
jjg@46 108 public static final int CONSTANT_Float = 4;
jjg@46 109 public static final int CONSTANT_Long = 5;
jjg@46 110 public static final int CONSTANT_Double = 6;
jjg@46 111 public static final int CONSTANT_Class = 7;
jjg@46 112 public static final int CONSTANT_String = 8;
jjg@46 113 public static final int CONSTANT_Fieldref = 9;
jjg@46 114 public static final int CONSTANT_Methodref = 10;
jjg@46 115 public static final int CONSTANT_InterfaceMethodref = 11;
jjg@46 116 public static final int CONSTANT_NameAndType = 12;
jjg@46 117
jjg@46 118 ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
jjg@46 119 int count = cr.readUnsignedShort();
jjg@46 120 pool = new CPInfo[count];
jjg@46 121 for (int i = 1; i < count; i++) {
jjg@46 122 int tag = cr.readUnsignedByte();
jjg@46 123 switch (tag) {
jjg@46 124 case CONSTANT_Class:
jjg@46 125 pool[i] = new CONSTANT_Class_info(this, cr);
jjg@46 126 break;
jjg@46 127
jjg@46 128 case CONSTANT_Double:
jjg@46 129 pool[i] = new CONSTANT_Double_info(cr);
jjg@46 130 i++;
jjg@46 131 break;
jjg@46 132
jjg@46 133 case CONSTANT_Fieldref:
jjg@46 134 pool[i] = new CONSTANT_Fieldref_info(this, cr);
jjg@46 135 break;
jjg@46 136
jjg@46 137 case CONSTANT_Float:
jjg@46 138 pool[i] = new CONSTANT_Float_info(cr);
jjg@46 139 break;
jjg@46 140
jjg@46 141 case CONSTANT_Integer:
jjg@46 142 pool[i] = new CONSTANT_Integer_info(cr);
jjg@46 143 break;
jjg@46 144
jjg@46 145 case CONSTANT_InterfaceMethodref:
jjg@46 146 pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
jjg@46 147 break;
jjg@46 148
jjg@46 149 case CONSTANT_Long:
jjg@46 150 pool[i] = new CONSTANT_Long_info(cr);
jjg@46 151 i++;
jjg@46 152 break;
jjg@46 153
jjg@46 154 case CONSTANT_Methodref:
jjg@46 155 pool[i] = new CONSTANT_Methodref_info(this, cr);
jjg@46 156 break;
jjg@46 157
jjg@46 158 case CONSTANT_NameAndType:
jjg@46 159 pool[i] = new CONSTANT_NameAndType_info(this, cr);
jjg@46 160 break;
jjg@46 161
jjg@46 162 case CONSTANT_String:
jjg@52 163 pool[i] = new CONSTANT_String_info(this, cr);
jjg@46 164 break;
jjg@46 165
jjg@46 166 case CONSTANT_Utf8:
jjg@46 167 pool[i] = new CONSTANT_Utf8_info(cr);
jjg@46 168 break;
jjg@46 169
jjg@46 170 default:
jjg@46 171 throw new InvalidEntry(i, tag);
jjg@46 172 }
jjg@46 173 }
jjg@46 174 }
jjg@46 175
jjg@46 176 public ConstantPool(CPInfo[] pool) {
jjg@46 177 this.pool = pool;
jjg@46 178 }
jjg@46 179
jjg@46 180 public int size() {
jjg@46 181 return pool.length;
jjg@46 182 }
jjg@46 183
jjg@345 184 public int byteLength() {
jjg@345 185 int length = 2;
jjg@345 186 for (int i = 1; i < size(); ) {
jjg@345 187 CPInfo cpInfo = pool[i];
jjg@345 188 length += cpInfo.byteLength();
jjg@345 189 i += cpInfo.size();
jjg@345 190 }
jjg@345 191 return length;
jjg@345 192 }
jjg@345 193
jjg@46 194 public CPInfo get(int index) throws InvalidIndex {
jjg@46 195 if (index <= 0 || index >= pool.length)
jjg@46 196 throw new InvalidIndex(index);
jjg@46 197 CPInfo info = pool[index];
jjg@46 198 if (info == null) {
jjg@46 199 // this occurs for indices referencing the "second half" of an
jjg@46 200 // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
jjg@46 201 throw new InvalidIndex(index);
jjg@46 202 }
jjg@46 203 return pool[index];
jjg@46 204 }
jjg@46 205
jjg@46 206 private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
jjg@46 207 CPInfo info = get(index);
jjg@46 208 if (info.getTag() != expected_type)
jjg@46 209 throw new UnexpectedEntry(index, expected_type, info.getTag());
jjg@46 210 return info;
jjg@46 211 }
jjg@46 212
jjg@46 213 public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 214 return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
jjg@46 215 }
jjg@46 216
jjg@46 217 public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 218 return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
jjg@46 219 }
jjg@46 220
jjg@46 221 public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 222 return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
jjg@46 223 }
jjg@46 224
jjg@46 225 public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 226 return getUTF8Info(index).value;
jjg@46 227 }
jjg@46 228
jjg@46 229 public int getUTF8Index(String value) throws EntryNotFound {
jjg@46 230 for (int i = 1; i < pool.length; i++) {
jjg@46 231 CPInfo info = pool[i];
jjg@46 232 if (info instanceof CONSTANT_Utf8_info &&
jjg@46 233 ((CONSTANT_Utf8_info) info).value.equals(value))
jjg@46 234 return i;
jjg@46 235 }
jjg@46 236 throw new EntryNotFound(value);
jjg@46 237 }
jjg@46 238
jjg@282 239 public Iterable<CPInfo> entries() {
jjg@282 240 return new Iterable<CPInfo>() {
jjg@282 241 public Iterator<CPInfo> iterator() {
jjg@282 242 return new Iterator<CPInfo>() {
jjg@282 243
jjg@282 244 public boolean hasNext() {
jjg@282 245 return next < pool.length;
jjg@282 246 }
jjg@282 247
jjg@282 248 public CPInfo next() {
jjg@282 249 current = pool[next];
jjg@282 250 switch (current.getTag()) {
jjg@282 251 case CONSTANT_Double:
jjg@282 252 case CONSTANT_Long:
jjg@282 253 next += 2;
jjg@282 254 break;
jjg@282 255 default:
jjg@282 256 next += 1;
jjg@282 257 }
jjg@282 258 return current;
jjg@282 259 }
jjg@282 260
jjg@282 261 public void remove() {
jjg@282 262 throw new UnsupportedOperationException();
jjg@282 263 }
jjg@282 264
jjg@282 265 private CPInfo current;
jjg@282 266 private int next = 1;
jjg@282 267
jjg@282 268 };
jjg@282 269 }
jjg@282 270 };
jjg@282 271 }
jjg@282 272
jjg@46 273 private CPInfo[] pool;
jjg@46 274
jjg@46 275 public interface Visitor<R,P> {
jjg@46 276 R visitClass(CONSTANT_Class_info info, P p);
jjg@46 277 R visitDouble(CONSTANT_Double_info info, P p);
jjg@46 278 R visitFieldref(CONSTANT_Fieldref_info info, P p);
jjg@46 279 R visitFloat(CONSTANT_Float_info info, P p);
jjg@46 280 R visitInteger(CONSTANT_Integer_info info, P p);
jjg@46 281 R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
jjg@46 282 R visitLong(CONSTANT_Long_info info, P p);
jjg@46 283 R visitNameAndType(CONSTANT_NameAndType_info info, P p);
jjg@46 284 R visitMethodref(CONSTANT_Methodref_info info, P p);
jjg@46 285 R visitString(CONSTANT_String_info info, P p);
jjg@46 286 R visitUtf8(CONSTANT_Utf8_info info, P p);
jjg@46 287 }
jjg@46 288
jjg@46 289 public static abstract class CPInfo {
jjg@46 290 CPInfo() {
jjg@46 291 this.cp = null;
jjg@46 292 }
jjg@46 293
jjg@46 294 CPInfo(ConstantPool cp) {
jjg@46 295 this.cp = cp;
jjg@46 296 }
jjg@46 297
jjg@46 298 public abstract int getTag();
jjg@46 299
jjg@282 300 /** The number of slots in the constant pool used by this entry.
jjg@282 301 * 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */
jjg@282 302 public int size() {
jjg@282 303 return 1;
jjg@282 304 }
jjg@282 305
jjg@345 306 public abstract int byteLength();
jjg@345 307
jjg@46 308 public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
jjg@46 309
jjg@46 310 protected final ConstantPool cp;
jjg@46 311 }
jjg@46 312
jjg@46 313 public static abstract class CPRefInfo extends CPInfo {
jjg@46 314 protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
jjg@46 315 super(cp);
jjg@46 316 this.tag = tag;
jjg@46 317 class_index = cr.readUnsignedShort();
jjg@46 318 name_and_type_index = cr.readUnsignedShort();
jjg@46 319 }
jjg@46 320
jjg@46 321 protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
jjg@46 322 super(cp);
jjg@46 323 this.tag = tag;
jjg@46 324 this.class_index = class_index;
jjg@46 325 this.name_and_type_index = name_and_type_index;
jjg@46 326 }
jjg@46 327
jjg@46 328 public int getTag() {
jjg@46 329 return tag;
jjg@46 330 }
jjg@46 331
jjg@345 332 public int byteLength() {
jjg@345 333 return 5;
jjg@345 334 }
jjg@345 335
jjg@46 336 public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
jjg@46 337 return cp.getClassInfo(class_index);
jjg@46 338 }
jjg@46 339
jjg@46 340 public String getClassName() throws ConstantPoolException {
jjg@46 341 return cp.getClassInfo(class_index).getName();
jjg@46 342 }
jjg@46 343
jjg@46 344 public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
jjg@46 345 return cp.getNameAndTypeInfo(name_and_type_index);
jjg@46 346 }
jjg@46 347
jjg@46 348 public final int tag;
jjg@46 349 public final int class_index;
jjg@46 350 public final int name_and_type_index;
jjg@46 351 }
jjg@46 352
jjg@46 353 public static class CONSTANT_Class_info extends CPInfo {
jjg@46 354 CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 355 super(cp);
jjg@46 356 name_index = cr.readUnsignedShort();
jjg@46 357 }
jjg@46 358
jjg@46 359 public CONSTANT_Class_info(ConstantPool cp, int name_index) {
jjg@46 360 super(cp);
jjg@46 361 this.name_index = name_index;
jjg@46 362 }
jjg@46 363
jjg@46 364 public int getTag() {
jjg@46 365 return CONSTANT_Class;
jjg@46 366 }
jjg@46 367
jjg@345 368 public int byteLength() {
jjg@345 369 return 3;
jjg@345 370 }
jjg@345 371
jjg@422 372 /**
jjg@422 373 * Get the raw value of the class referenced by this constant pool entry.
jjg@422 374 * This will either be the name of the class, in internal form, or a
jjg@422 375 * descriptor for an array class.
jjg@422 376 * @return the raw value of the class
jjg@422 377 */
jjg@46 378 public String getName() throws ConstantPoolException {
jjg@46 379 return cp.getUTF8Value(name_index);
jjg@46 380 }
jjg@46 381
jjg@422 382 /**
jjg@422 383 * If this constant pool entry identifies either a class or interface type,
jjg@422 384 * or a possibly multi-dimensional array of a class of interface type,
jjg@422 385 * return the name of the class or interface in internal form. Otherwise,
jjg@422 386 * (i.e. if this is a possibly multi-dimensional array of a primitive type),
jjg@422 387 * return null.
jjg@422 388 * @return the base class or interface name
jjg@422 389 */
jjg@281 390 public String getBaseName() throws ConstantPoolException {
jjg@281 391 String name = getName();
jjg@422 392 if (name.startsWith("[")) {
jjg@422 393 int index = name.indexOf("[L");
jjg@422 394 if (index == -1)
jjg@422 395 return null;
jjg@422 396 return name.substring(index + 2, name.length() - 1);
jjg@422 397 } else
jjg@422 398 return name;
jjg@281 399 }
jjg@281 400
jjg@281 401 public int getDimensionCount() throws ConstantPoolException {
jjg@281 402 String name = getName();
jjg@281 403 int count = 0;
jjg@281 404 while (name.charAt(count) == '[')
jjg@281 405 count++;
jjg@281 406 return count;
jjg@281 407 }
jjg@281 408
jjg@46 409 @Override
jjg@46 410 public String toString() {
jjg@46 411 return "CONSTANT_Class_info[name_index: " + name_index + "]";
jjg@46 412 }
jjg@46 413
jjg@46 414 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 415 return visitor.visitClass(this, data);
jjg@46 416 }
jjg@46 417
jjg@46 418 public final int name_index;
jjg@46 419 }
jjg@46 420
jjg@46 421 public static class CONSTANT_Double_info extends CPInfo {
jjg@46 422 CONSTANT_Double_info(ClassReader cr) throws IOException {
jjg@46 423 value = cr.readDouble();
jjg@46 424 }
jjg@46 425
jjg@46 426 public CONSTANT_Double_info(double value) {
jjg@46 427 this.value = value;
jjg@46 428 }
jjg@46 429
jjg@46 430 public int getTag() {
jjg@46 431 return CONSTANT_Double;
jjg@46 432 }
jjg@46 433
jjg@345 434 public int byteLength() {
jjg@345 435 return 9;
jjg@345 436 }
jjg@345 437
jjg@46 438 @Override
jjg@282 439 public int size() {
jjg@282 440 return 2;
jjg@282 441 }
jjg@282 442
jjg@282 443 @Override
jjg@46 444 public String toString() {
jjg@46 445 return "CONSTANT_Double_info[value: " + value + "]";
jjg@46 446 }
jjg@46 447
jjg@46 448 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 449 return visitor.visitDouble(this, data);
jjg@46 450 }
jjg@46 451
jjg@46 452 public final double value;
jjg@46 453 }
jjg@46 454
jjg@46 455 public static class CONSTANT_Fieldref_info extends CPRefInfo {
jjg@46 456 CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 457 super(cp, cr, CONSTANT_Fieldref);
jjg@46 458 }
jjg@46 459
jjg@46 460 public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
jjg@46 461 super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
jjg@46 462 }
jjg@46 463
jjg@46 464 @Override
jjg@46 465 public String toString() {
jjg@46 466 return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
jjg@46 467 }
jjg@46 468
jjg@46 469 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 470 return visitor.visitFieldref(this, data);
jjg@46 471 }
jjg@46 472 }
jjg@46 473
jjg@46 474 public static class CONSTANT_Float_info extends CPInfo {
jjg@46 475 CONSTANT_Float_info(ClassReader cr) throws IOException {
jjg@46 476 value = cr.readFloat();
jjg@46 477 }
jjg@46 478
jjg@46 479 public CONSTANT_Float_info(float value) {
jjg@46 480 this.value = value;
jjg@46 481 }
jjg@46 482
jjg@46 483 public int getTag() {
jjg@46 484 return CONSTANT_Float;
jjg@46 485 }
jjg@46 486
jjg@345 487 public int byteLength() {
jjg@345 488 return 5;
jjg@345 489 }
jjg@345 490
jjg@46 491 @Override
jjg@46 492 public String toString() {
jjg@46 493 return "CONSTANT_Float_info[value: " + value + "]";
jjg@46 494 }
jjg@46 495
jjg@46 496 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 497 return visitor.visitFloat(this, data);
jjg@46 498 }
jjg@46 499
jjg@46 500 public final float value;
jjg@46 501 }
jjg@46 502
jjg@46 503 public static class CONSTANT_Integer_info extends CPInfo {
jjg@46 504 CONSTANT_Integer_info(ClassReader cr) throws IOException {
jjg@46 505 value = cr.readInt();
jjg@46 506 }
jjg@46 507
jjg@46 508 public CONSTANT_Integer_info(int value) {
jjg@46 509 this.value = value;
jjg@46 510 }
jjg@46 511
jjg@46 512 public int getTag() {
jjg@46 513 return CONSTANT_Integer;
jjg@46 514 }
jjg@46 515
jjg@345 516 public int byteLength() {
jjg@345 517 return 5;
jjg@345 518 }
jjg@345 519
jjg@46 520 @Override
jjg@46 521 public String toString() {
jjg@46 522 return "CONSTANT_Integer_info[value: " + value + "]";
jjg@46 523 }
jjg@46 524
jjg@46 525 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 526 return visitor.visitInteger(this, data);
jjg@46 527 }
jjg@46 528
jjg@46 529 public final int value;
jjg@46 530 }
jjg@46 531
jjg@46 532 public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
jjg@46 533 CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 534 super(cp, cr, CONSTANT_InterfaceMethodref);
jjg@46 535 }
jjg@46 536
jjg@46 537 public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
jjg@46 538 super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
jjg@46 539 }
jjg@46 540
jjg@46 541 @Override
jjg@46 542 public String toString() {
jjg@46 543 return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
jjg@46 544 }
jjg@46 545
jjg@46 546 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 547 return visitor.visitInterfaceMethodref(this, data);
jjg@46 548 }
jjg@46 549 }
jjg@46 550
jjg@46 551 public static class CONSTANT_Long_info extends CPInfo {
jjg@46 552 CONSTANT_Long_info(ClassReader cr) throws IOException {
jjg@46 553 value = cr.readLong();
jjg@46 554 }
jjg@46 555
jjg@46 556 public CONSTANT_Long_info(long value) {
jjg@46 557 this.value = value;
jjg@46 558 }
jjg@46 559
jjg@46 560 public int getTag() {
jjg@46 561 return CONSTANT_Long;
jjg@46 562 }
jjg@46 563
jjg@46 564 @Override
jjg@282 565 public int size() {
jjg@282 566 return 2;
jjg@282 567 }
jjg@282 568
jjg@345 569 public int byteLength() {
jjg@345 570 return 9;
jjg@345 571 }
jjg@345 572
jjg@282 573 @Override
jjg@46 574 public String toString() {
jjg@46 575 return "CONSTANT_Long_info[value: " + value + "]";
jjg@46 576 }
jjg@46 577
jjg@46 578 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 579 return visitor.visitLong(this, data);
jjg@46 580 }
jjg@46 581
jjg@46 582 public final long value;
jjg@46 583 }
jjg@46 584
jjg@46 585 public static class CONSTANT_Methodref_info extends CPRefInfo {
jjg@46 586 CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 587 super(cp, cr, CONSTANT_Methodref);
jjg@46 588 }
jjg@46 589
jjg@46 590 public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
jjg@46 591 super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
jjg@46 592 }
jjg@46 593
jjg@46 594 @Override
jjg@46 595 public String toString() {
jjg@46 596 return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
jjg@46 597 }
jjg@46 598
jjg@46 599 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 600 return visitor.visitMethodref(this, data);
jjg@46 601 }
jjg@46 602 }
jjg@46 603
jjg@46 604 public static class CONSTANT_NameAndType_info extends CPInfo {
jjg@46 605 CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 606 super(cp);
jjg@46 607 name_index = cr.readUnsignedShort();
jjg@46 608 type_index = cr.readUnsignedShort();
jjg@46 609 }
jjg@46 610
jjg@46 611 public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
jjg@46 612 super(cp);
jjg@46 613 this.name_index = name_index;
jjg@46 614 this.type_index = type_index;
jjg@46 615 }
jjg@46 616
jjg@46 617 public int getTag() {
jjg@46 618 return CONSTANT_NameAndType;
jjg@46 619 }
jjg@46 620
jjg@345 621 public int byteLength() {
jjg@345 622 return 5;
jjg@345 623 }
jjg@345 624
jjg@46 625 public String getName() throws ConstantPoolException {
jjg@46 626 return cp.getUTF8Value(name_index);
jjg@46 627 }
jjg@46 628
jjg@46 629 public String getType() throws ConstantPoolException {
jjg@46 630 return cp.getUTF8Value(type_index);
jjg@46 631 }
jjg@46 632
jjg@46 633 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 634 return visitor.visitNameAndType(this, data);
jjg@46 635 }
jjg@46 636
jjg@300 637 @Override
jjg@300 638 public String toString() {
jjg@300 639 return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";
jjg@300 640 }
jjg@300 641
jjg@46 642 public final int name_index;
jjg@46 643 public final int type_index;
jjg@46 644 }
jjg@46 645
jjg@46 646 public static class CONSTANT_String_info extends CPInfo {
jjg@52 647 CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@52 648 super(cp);
jjg@46 649 string_index = cr.readUnsignedShort();
jjg@46 650 }
jjg@46 651
jjg@46 652 public CONSTANT_String_info(ConstantPool cp, int string_index) {
jjg@46 653 super(cp);
jjg@46 654 this.string_index = string_index;
jjg@46 655 }
jjg@46 656
jjg@46 657 public int getTag() {
jjg@46 658 return CONSTANT_String;
jjg@46 659 }
jjg@46 660
jjg@345 661 public int byteLength() {
jjg@345 662 return 3;
jjg@345 663 }
jjg@345 664
jjg@46 665 public String getString() throws ConstantPoolException {
jjg@46 666 return cp.getUTF8Value(string_index);
jjg@46 667 }
jjg@46 668
jjg@46 669 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 670 return visitor.visitString(this, data);
jjg@46 671 }
jjg@46 672
jjg@300 673 @Override
jjg@300 674 public String toString() {
jjg@300 675 return "CONSTANT_String_info[class_index: " + string_index + "]";
jjg@300 676 }
jjg@300 677
jjg@46 678 public final int string_index;
jjg@46 679 }
jjg@46 680
jjg@46 681 public static class CONSTANT_Utf8_info extends CPInfo {
jjg@46 682 CONSTANT_Utf8_info(ClassReader cr) throws IOException {
jjg@46 683 value = cr.readUTF();
jjg@46 684 }
jjg@46 685
jjg@46 686 public CONSTANT_Utf8_info(String value) {
jjg@46 687 this.value = value;
jjg@46 688 }
jjg@46 689
jjg@46 690 public int getTag() {
jjg@46 691 return CONSTANT_Utf8;
jjg@46 692 }
jjg@46 693
jjg@345 694 public int byteLength() {
jjg@345 695 class SizeOutputStream extends OutputStream {
jjg@345 696 @Override
jjg@513 697 public void write(int b) {
jjg@345 698 size++;
jjg@345 699 }
jjg@345 700 int size;
jjg@345 701 }
jjg@345 702 SizeOutputStream sizeOut = new SizeOutputStream();
jjg@345 703 DataOutputStream out = new DataOutputStream(sizeOut);
jjg@345 704 try { out.writeUTF(value); } catch (IOException ignore) { }
jjg@345 705 return 1 + sizeOut.size;
jjg@345 706 }
jjg@345 707
jjg@46 708 @Override
jjg@46 709 public String toString() {
jjg@300 710 if (value.length() < 32 && isPrintableAscii(value))
jjg@300 711 return "CONSTANT_Utf8_info[value: \"" + value + "\"]";
jjg@300 712 else
jjg@300 713 return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";
jjg@300 714 }
jjg@300 715
jjg@300 716 static boolean isPrintableAscii(String s) {
jjg@300 717 for (int i = 0; i < s.length(); i++) {
jjg@300 718 char c = s.charAt(i);
jjg@300 719 if (c < 32 || c >= 127)
jjg@300 720 return false;
jjg@300 721 }
jjg@300 722 return true;
jjg@46 723 }
jjg@46 724
jjg@46 725 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 726 return visitor.visitUtf8(this, data);
jjg@46 727 }
jjg@46 728
jjg@46 729 public final String value;
jjg@46 730 }
jjg@46 731
jjg@46 732
jjg@46 733 }

mercurial