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