KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > classfile > editor > ConstantPoolRemapper


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 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 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      */

69     public void setConstantIndexMap(int[] constantIndexMap)
70     {
71         this.constantIndexMap = constantIndexMap;
72     }
73
74
75     // Implementations for ClassVisitor.
76

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
96     public void visitLibraryClass(LibraryClass libraryClass)
97     {
98     }
99
100
101     // Implementations for ConstantVisitor.
102

103     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
104     {
105         classConstant.u2nameIndex =
106             remapConstantIndex(classConstant.u2nameIndex);
107     }
108
109
110     public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
111     {
112         // Nothing to do.
113
}
114
115
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
125     public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
126     {
127         // Nothing to do.
128
}
129
130
131     public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
132     {
133         // Nothing to do.
134
}
135
136
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
146     public void visitLongConstant(Clazz clazz, LongConstant longConstant)
147     {
148         // Nothing to do.
149
}
150
151
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
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
170     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
171     {
172         stringConstant.u2stringIndex =
173             remapConstantIndex(stringConstant.u2stringIndex);
174     }
175
176
177     public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
178     {
179         // Nothing to do.
180
}
181
182
183     // Implementations for MemberVisitor.
184

185     public void visitProgramField(ProgramClass programClass, ProgramField programField)
186     {
187         visitMember(programClass, programField);
188     }
189
190
191     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
192     {
193         visitMember(programClass, programMethod);
194     }
195
196
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
210     public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
211     {
212         // Library classes are left unchanged.
213
}
214
215
216     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
217     {
218         // Library classes are left unchanged.
219
}
220
221
222     // Implementations for AttributeVisitor.
223

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
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
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
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
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
272     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
273     {
274         deprecatedAttribute.u2attributeNameIndex =
275             remapConstantIndex(deprecatedAttribute.u2attributeNameIndex);
276     }
277
278
279     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
280     {
281         syntheticAttribute.u2attributeNameIndex =
282             remapConstantIndex(syntheticAttribute.u2attributeNameIndex);
283     }
284
285
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
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
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
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
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
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
356     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
357     {
358         lineNumberTableAttribute.u2attributeNameIndex =
359             remapConstantIndex(lineNumberTableAttribute.u2attributeNameIndex);
360     }
361
362
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
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
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
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
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

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

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

451     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
452
453
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

473     public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {}
474
475
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
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
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

500     public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {}
501
502
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

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

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

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

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
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
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
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
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      */

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      */

613     private int remapConstantIndex(int constantIndex)
614     {
615         return constantIndexMap[constantIndex];
616     }
617 }
618
Popular Tags