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