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