ConstantPoolRemapper.java revision b9cc48a43ed984587c939d02fba5316bf5c0df6e
1/* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21package proguard.classfile.editor; 22 23import proguard.classfile.*; 24import proguard.classfile.attribute.*; 25import proguard.classfile.attribute.annotation.*; 26import proguard.classfile.attribute.annotation.visitor.*; 27import proguard.classfile.attribute.preverification.*; 28import proguard.classfile.attribute.preverification.visitor.*; 29import proguard.classfile.attribute.visitor.*; 30import proguard.classfile.constant.*; 31import proguard.classfile.constant.visitor.ConstantVisitor; 32import proguard.classfile.instruction.*; 33import proguard.classfile.instruction.visitor.InstructionVisitor; 34import proguard.classfile.util.SimplifiedVisitor; 35import proguard.classfile.visitor.*; 36 37/** 38 * This ClassVisitor remaps all possible references to constant pool entries 39 * of the classes that it visits, based on a given index map. It is assumed that 40 * the constant pool entries themselves have already been remapped. 41 * 42 * @author Eric Lafortune 43 */ 44public class ConstantPoolRemapper 45extends SimplifiedVisitor 46implements ClassVisitor, 47 ConstantVisitor, 48 MemberVisitor, 49 AttributeVisitor, 50 BootstrapMethodInfoVisitor, 51 InnerClassesInfoVisitor, 52 ExceptionInfoVisitor, 53 InstructionVisitor, 54 StackMapFrameVisitor, 55 VerificationTypeVisitor, 56 LocalVariableInfoVisitor, 57 LocalVariableTypeInfoVisitor, 58 AnnotationVisitor, 59 ElementValueVisitor 60{ 61 private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false, true); 62 63 private int[] constantIndexMap; 64 65 66 /** 67 * Sets the given mapping of old constant pool entry indexes to their new 68 * indexes. 69 */ 70 public void setConstantIndexMap(int[] constantIndexMap) 71 { 72 this.constantIndexMap = constantIndexMap; 73 } 74 75 76 // Implementations for ClassVisitor. 77 78 public void visitProgramClass(ProgramClass programClass) 79 { 80 // Remap the local constant pool references. 81 programClass.u2thisClass = remapConstantIndex(programClass.u2thisClass); 82 programClass.u2superClass = remapConstantIndex(programClass.u2superClass); 83 84 remapConstantIndexArray(programClass.u2interfaces, 85 programClass.u2interfacesCount); 86 87 // Remap the references of the contant pool entries themselves. 88 programClass.constantPoolEntriesAccept(this); 89 90 // Remap the references in all fields, methods, and attributes. 91 programClass.fieldsAccept(this); 92 programClass.methodsAccept(this); 93 programClass.attributesAccept(this); 94 } 95 96 97 public void visitLibraryClass(LibraryClass libraryClass) 98 { 99 } 100 101 102 // Implementations for ConstantVisitor. 103 104 public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) 105 { 106 // Nothing to do. 107 } 108 109 110 public void visitLongConstant(Clazz clazz, LongConstant longConstant) 111 { 112 // Nothing to do. 113 } 114 115 116 public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) 117 { 118 // Nothing to do. 119 } 120 121 122 public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) 123 { 124 // Nothing to do. 125 } 126 127 128 public void visitStringConstant(Clazz clazz, StringConstant stringConstant) 129 { 130 stringConstant.u2stringIndex = 131 remapConstantIndex(stringConstant.u2stringIndex); 132 } 133 134 135 public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) 136 { 137 // Nothing to do. 138 } 139 140 141 public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) 142 { 143 invokeDynamicConstant.u2nameAndTypeIndex = 144 remapConstantIndex(invokeDynamicConstant.u2nameAndTypeIndex); 145 } 146 147 148 public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) 149 { 150 methodHandleConstant.u2referenceIndex = 151 remapConstantIndex(methodHandleConstant.u2referenceIndex); 152 } 153 154 155 public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) 156 { 157 fieldrefConstant.u2classIndex = 158 remapConstantIndex(fieldrefConstant.u2classIndex); 159 fieldrefConstant.u2nameAndTypeIndex = 160 remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex); 161 } 162 163 164 public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) 165 { 166 interfaceMethodrefConstant.u2classIndex = 167 remapConstantIndex(interfaceMethodrefConstant.u2classIndex); 168 interfaceMethodrefConstant.u2nameAndTypeIndex = 169 remapConstantIndex(interfaceMethodrefConstant.u2nameAndTypeIndex); 170 } 171 172 173 public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) 174 { 175 methodrefConstant.u2classIndex = 176 remapConstantIndex(methodrefConstant.u2classIndex); 177 methodrefConstant.u2nameAndTypeIndex = 178 remapConstantIndex(methodrefConstant.u2nameAndTypeIndex); 179 } 180 181 182 public void visitClassConstant(Clazz clazz, ClassConstant classConstant) 183 { 184 classConstant.u2nameIndex = 185 remapConstantIndex(classConstant.u2nameIndex); 186 } 187 188 189 public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) 190 { 191 methodTypeConstant.u2descriptorIndex = 192 remapConstantIndex(methodTypeConstant.u2descriptorIndex); 193 } 194 195 196 public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) 197 { 198 nameAndTypeConstant.u2nameIndex = 199 remapConstantIndex(nameAndTypeConstant.u2nameIndex); 200 nameAndTypeConstant.u2descriptorIndex = 201 remapConstantIndex(nameAndTypeConstant.u2descriptorIndex); 202 } 203 204 205 // Implementations for MemberVisitor. 206 207 public void visitProgramField(ProgramClass programClass, ProgramField programField) 208 { 209 visitMember(programClass, programField); 210 } 211 212 213 public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 214 { 215 visitMember(programClass, programMethod); 216 } 217 218 219 private void visitMember(ProgramClass programClass, ProgramMember programMember) 220 { 221 // Remap the local constant pool references. 222 programMember.u2nameIndex = 223 remapConstantIndex(programMember.u2nameIndex); 224 programMember.u2descriptorIndex = 225 remapConstantIndex(programMember.u2descriptorIndex); 226 227 // Remap the constant pool references of the remaining attributes. 228 programMember.attributesAccept(programClass, this); 229 } 230 231 232 public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) 233 { 234 // Library classes are left unchanged. 235 } 236 237 238 public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) 239 { 240 // Library classes are left unchanged. 241 } 242 243 244 // Implementations for AttributeVisitor. 245 246 public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) 247 { 248 unknownAttribute.u2attributeNameIndex = 249 remapConstantIndex(unknownAttribute.u2attributeNameIndex); 250 251 // There's not much else we can do with unknown attributes. 252 } 253 254 255 public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) 256 { 257 bootstrapMethodsAttribute.u2attributeNameIndex = 258 remapConstantIndex(bootstrapMethodsAttribute.u2attributeNameIndex); 259 260 // Remap the constant pool references of the bootstrap method entries. 261 bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); 262 } 263 264 265 public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) 266 { 267 sourceFileAttribute.u2attributeNameIndex = 268 remapConstantIndex(sourceFileAttribute.u2attributeNameIndex); 269 sourceFileAttribute.u2sourceFileIndex = 270 remapConstantIndex(sourceFileAttribute.u2sourceFileIndex); 271 } 272 273 274 public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) 275 { 276 sourceDirAttribute.u2attributeNameIndex = 277 remapConstantIndex(sourceDirAttribute.u2attributeNameIndex); 278 sourceDirAttribute.u2sourceDirIndex = 279 remapConstantIndex(sourceDirAttribute.u2sourceDirIndex); 280 } 281 282 283 public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) 284 { 285 innerClassesAttribute.u2attributeNameIndex = 286 remapConstantIndex(innerClassesAttribute.u2attributeNameIndex); 287 288 // Remap the constant pool references of the inner classes. 289 innerClassesAttribute.innerClassEntriesAccept(clazz, this); 290 } 291 292 293 public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) 294 { 295 enclosingMethodAttribute.u2attributeNameIndex = 296 remapConstantIndex(enclosingMethodAttribute.u2attributeNameIndex); 297 enclosingMethodAttribute.u2classIndex = 298 remapConstantIndex(enclosingMethodAttribute.u2classIndex); 299 enclosingMethodAttribute.u2nameAndTypeIndex = 300 remapConstantIndex(enclosingMethodAttribute.u2nameAndTypeIndex); 301 } 302 303 304 public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) 305 { 306 deprecatedAttribute.u2attributeNameIndex = 307 remapConstantIndex(deprecatedAttribute.u2attributeNameIndex); 308 } 309 310 311 public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) 312 { 313 syntheticAttribute.u2attributeNameIndex = 314 remapConstantIndex(syntheticAttribute.u2attributeNameIndex); 315 } 316 317 318 public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) 319 { 320 signatureAttribute.u2attributeNameIndex = 321 remapConstantIndex(signatureAttribute.u2attributeNameIndex); 322 signatureAttribute.u2signatureIndex = 323 remapConstantIndex(signatureAttribute.u2signatureIndex); 324 } 325 326 327 public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) 328 { 329 constantValueAttribute.u2attributeNameIndex = 330 remapConstantIndex(constantValueAttribute.u2attributeNameIndex); 331 constantValueAttribute.u2constantValueIndex = 332 remapConstantIndex(constantValueAttribute.u2constantValueIndex); 333 } 334 335 336 public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) 337 { 338 exceptionsAttribute.u2attributeNameIndex = 339 remapConstantIndex(exceptionsAttribute.u2attributeNameIndex); 340 341 // Remap the constant pool references of the exceptions. 342 remapConstantIndexArray(exceptionsAttribute.u2exceptionIndexTable, 343 exceptionsAttribute.u2exceptionIndexTableLength); 344 } 345 346 347 public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) 348 { 349 codeAttribute.u2attributeNameIndex = 350 remapConstantIndex(codeAttribute.u2attributeNameIndex); 351 352 // Initially, the code attribute editor doesn't contain any changes. 353 codeAttributeEditor.reset(codeAttribute.u4codeLength); 354 355 // Remap the constant pool references of the instructions. 356 codeAttribute.instructionsAccept(clazz, method, this); 357 358 // Apply the code atribute editor. It will only contain any changes if 359 // the code length is changing at any point. 360 codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); 361 362 // Remap the constant pool references of the exceptions and attributes. 363 codeAttribute.exceptionsAccept(clazz, method, this); 364 codeAttribute.attributesAccept(clazz, method, this); 365 } 366 367 368 public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) 369 { 370 stackMapAttribute.u2attributeNameIndex = 371 remapConstantIndex(stackMapAttribute.u2attributeNameIndex); 372 373 // Remap the constant pool references of the stack map frames. 374 stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); 375 } 376 377 378 public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) 379 { 380 stackMapTableAttribute.u2attributeNameIndex = 381 remapConstantIndex(stackMapTableAttribute.u2attributeNameIndex); 382 383 // Remap the constant pool references of the stack map frames. 384 stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); 385 } 386 387 388 public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) 389 { 390 lineNumberTableAttribute.u2attributeNameIndex = 391 remapConstantIndex(lineNumberTableAttribute.u2attributeNameIndex); 392 } 393 394 395 public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) 396 { 397 localVariableTableAttribute.u2attributeNameIndex = 398 remapConstantIndex(localVariableTableAttribute.u2attributeNameIndex); 399 400 // Remap the constant pool references of the local variables. 401 localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 402 } 403 404 405 public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) 406 { 407 localVariableTypeTableAttribute.u2attributeNameIndex = 408 remapConstantIndex(localVariableTypeTableAttribute.u2attributeNameIndex); 409 410 // Remap the constant pool references of the local variables. 411 localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 412 } 413 414 415 public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) 416 { 417 annotationsAttribute.u2attributeNameIndex = 418 remapConstantIndex(annotationsAttribute.u2attributeNameIndex); 419 420 // Remap the constant pool references of the annotations. 421 annotationsAttribute.annotationsAccept(clazz, this); 422 } 423 424 425 public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) 426 { 427 parameterAnnotationsAttribute.u2attributeNameIndex = 428 remapConstantIndex(parameterAnnotationsAttribute.u2attributeNameIndex); 429 430 // Remap the constant pool references of the annotations. 431 parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); 432 } 433 434 435 public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) 436 { 437 annotationDefaultAttribute.u2attributeNameIndex = 438 remapConstantIndex(annotationDefaultAttribute.u2attributeNameIndex); 439 440 // Remap the constant pool references of the annotations. 441 annotationDefaultAttribute.defaultValueAccept(clazz, this); 442 } 443 444 445 // Implementations for BootstrapMethodInfoVisitor. 446 447 public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) 448 { 449 bootstrapMethodInfo.u2methodHandleIndex = 450 remapConstantIndex(bootstrapMethodInfo.u2methodHandleIndex); 451 452 // Remap the constant pool references of the bootstrap methods.. 453 remapConstantIndexArray(bootstrapMethodInfo.u2methodArguments, 454 bootstrapMethodInfo.u2methodArgumentCount); 455 } 456 457 458 // Implementations for InnerClassesInfoVisitor. 459 460 public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) 461 { 462 if (innerClassesInfo.u2innerClassIndex != 0) 463 { 464 innerClassesInfo.u2innerClassIndex = 465 remapConstantIndex(innerClassesInfo.u2innerClassIndex); 466 } 467 468 if (innerClassesInfo.u2outerClassIndex != 0) 469 { 470 innerClassesInfo.u2outerClassIndex = 471 remapConstantIndex(innerClassesInfo.u2outerClassIndex); 472 } 473 474 if (innerClassesInfo.u2innerNameIndex != 0) 475 { 476 innerClassesInfo.u2innerNameIndex = 477 remapConstantIndex(innerClassesInfo.u2innerNameIndex); 478 } 479 } 480 481 482 // Implementations for ExceptionInfoVisitor. 483 484 public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) 485 { 486 if (exceptionInfo.u2catchType != 0) 487 { 488 exceptionInfo.u2catchType = 489 remapConstantIndex(exceptionInfo.u2catchType); 490 } 491 } 492 493 494 // Implementations for InstructionVisitor. 495 496 public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} 497 498 499 public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) 500 { 501 // Is the new constant pool index different from the original one? 502 int newConstantIndex = remapConstantIndex(constantInstruction.constantIndex); 503 if (newConstantIndex != constantInstruction.constantIndex) 504 { 505 // Replace the instruction. 506 Instruction replacementInstruction = 507 new ConstantInstruction(constantInstruction.opcode, 508 newConstantIndex, 509 constantInstruction.constant); 510 511 codeAttributeEditor.replaceInstruction(offset, replacementInstruction); 512 } 513 } 514 515 516 // Implementations for StackMapFrameVisitor. 517 518 public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {} 519 520 521 public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) 522 { 523 // Remap the constant pool references of the verification types. 524 sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this); 525 } 526 527 528 public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame) 529 { 530 // Remap the constant pool references of the verification types. 531 moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this); 532 } 533 534 535 public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame) 536 { 537 // Remap the constant pool references of the verification types. 538 fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); 539 fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); 540 } 541 542 543 // Implementations for VerificationTypeVisitor. 544 545 public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {} 546 547 548 public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType) 549 { 550 objectType.u2classIndex = 551 remapConstantIndex(objectType.u2classIndex); 552 } 553 554 555 // Implementations for LocalVariableInfoVisitor. 556 557 public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) 558 { 559 localVariableInfo.u2nameIndex = 560 remapConstantIndex(localVariableInfo.u2nameIndex); 561 localVariableInfo.u2descriptorIndex = 562 remapConstantIndex(localVariableInfo.u2descriptorIndex); 563 } 564 565 566 // Implementations for LocalVariableTypeInfoVisitor. 567 568 public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) 569 { 570 localVariableTypeInfo.u2nameIndex = 571 remapConstantIndex(localVariableTypeInfo.u2nameIndex); 572 localVariableTypeInfo.u2signatureIndex = 573 remapConstantIndex(localVariableTypeInfo.u2signatureIndex); 574 } 575 576 577 // Implementations for AnnotationVisitor. 578 579 public void visitAnnotation(Clazz clazz, Annotation annotation) 580 { 581 annotation.u2typeIndex = 582 remapConstantIndex(annotation.u2typeIndex); 583 584 // Remap the constant pool references of the element values. 585 annotation.elementValuesAccept(clazz, this); 586 } 587 588 589 // Implementations for ElementValueVisitor. 590 591 public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) 592 { 593 constantElementValue.u2elementNameIndex = 594 remapConstantIndex(constantElementValue.u2elementNameIndex); 595 constantElementValue.u2constantValueIndex = 596 remapConstantIndex(constantElementValue.u2constantValueIndex); 597 } 598 599 600 public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) 601 { 602 enumConstantElementValue.u2elementNameIndex = 603 remapConstantIndex(enumConstantElementValue.u2elementNameIndex); 604 enumConstantElementValue.u2typeNameIndex = 605 remapConstantIndex(enumConstantElementValue.u2typeNameIndex); 606 enumConstantElementValue.u2constantNameIndex = 607 remapConstantIndex(enumConstantElementValue.u2constantNameIndex); 608 } 609 610 611 public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) 612 { 613 classElementValue.u2elementNameIndex = 614 remapConstantIndex(classElementValue.u2elementNameIndex); 615 classElementValue.u2classInfoIndex = 616 remapConstantIndex(classElementValue.u2classInfoIndex); 617 } 618 619 620 public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) 621 { 622 annotationElementValue.u2elementNameIndex = 623 remapConstantIndex(annotationElementValue.u2elementNameIndex); 624 625 // Remap the constant pool references of the annotation. 626 annotationElementValue.annotationAccept(clazz, this); 627 } 628 629 630 public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) 631 { 632 arrayElementValue.u2elementNameIndex = 633 remapConstantIndex(arrayElementValue.u2elementNameIndex); 634 635 // Remap the constant pool references of the element values. 636 arrayElementValue.elementValuesAccept(clazz, annotation, this); 637 } 638 639 640 // Small utility methods. 641 642 /** 643 * Remaps all constant pool indices in the given array. 644 */ 645 private void remapConstantIndexArray(int[] array, int length) 646 { 647 for (int index = 0; index < length; index++) 648 { 649 array[index] = remapConstantIndex(array[index]); 650 } 651 } 652 653 654 /** 655 * Returns the new constant pool index of the entry at the 656 * given index. 657 */ 658 private int remapConstantIndex(int constantIndex) 659 { 660 return constantIndexMap[constantIndex]; 661 } 662} 663