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

Fri, 26 Jun 2009 19:12:41 -0700

author
jjg
date
Fri, 26 Jun 2009 19:12:41 -0700
changeset 309
664edca41e34
parent 300
ed989c347b3c
child 345
23505e6ea22d
permissions
-rw-r--r--

6855544: add missing files
Reviewed-by: jjg, mcimadamore, darcy
Contributed-by: mernst@cs.washington.edu, mali@csail.mit.edu, mpapi@csail.mit.edu

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

mercurial