KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > shrink > UsageMarker


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.shrink;
22
23 import proguard.classfile.*;
24 import proguard.classfile.attribute.*;
25 import proguard.classfile.attribute.annotation.*;
26 import proguard.classfile.attribute.preverification.*;
27 import proguard.classfile.attribute.preverification.visitor.*;
28 import proguard.classfile.attribute.visitor.*;
29 import proguard.classfile.constant.*;
30 import proguard.classfile.constant.visitor.ConstantVisitor;
31 import proguard.classfile.instruction.*;
32 import proguard.classfile.instruction.visitor.InstructionVisitor;
33 import proguard.classfile.util.SimplifiedVisitor;
34 import proguard.classfile.visitor.*;
35
36
37 /**
38  * This ClassVisitor and MemberVisitor recursively marks all classes and class
39  * elements that are being used.
40  *
41  * @see ClassShrinker
42  *
43  * @author Eric Lafortune
44  */

45 class UsageMarker
46 extends SimplifiedVisitor
47 implements ClassVisitor,
48            MemberVisitor,
49            ConstantVisitor,
50            AttributeVisitor,
51            InnerClassesInfoVisitor,
52            ExceptionInfoVisitor,
53            StackMapFrameVisitor,
54            VerificationTypeVisitor,
55            LocalVariableInfoVisitor,
56            LocalVariableTypeInfoVisitor,
57 // AnnotationVisitor,
58
// ElementValueVisitor,
59
InstructionVisitor
60 {
61     // A visitor info flag to indicate the ProgramMember object is being used,
62
// if its Clazz can be determined as being used as well.
63
private static final Object JavaDoc POSSIBLY_USED = new Object JavaDoc();
64     // A visitor info flag to indicate the visitor accepter is being used.
65
private static final Object JavaDoc USED = new Object JavaDoc();
66
67
68     private MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
69     private MyPossiblyUsedMethodUsageMarker possiblyUsedMethodUsageMarker = new MyPossiblyUsedMethodUsageMarker();
70 // private ClassVisitor dynamicClassMarker =
71
// new MultiClassVisitor(
72
// new ClassVisitor[]
73
// {
74
// this,
75
// new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
76
// ClassConstants.INTERNAL_METHOD_TYPE_INIT,
77
// this)
78
// });
79

80
81     // Implementations for ClassVisitor.
82

83     public void visitProgramClass(ProgramClass programClass)
84     {
85         if (shouldBeMarkedAsUsed(programClass))
86         {
87             // Mark this class.
88
markAsUsed(programClass);
89
90             markProgramClassBody(programClass);
91         }
92     }
93
94
95     protected void markProgramClassBody(ProgramClass programClass)
96     {
97         // Mark this class's name.
98
markConstant(programClass, programClass.u2thisClass);
99
100         // Mark the superclass.
101
if (programClass.u2superClass != 0)
102         {
103             markConstant(programClass, programClass.u2superClass);
104         }
105
106         // Give the interfaces preliminary marks.
107
programClass.hierarchyAccept(false, false, true, false,
108                                      interfaceUsageMarker);
109
110         // Explicitly mark the <clinit> method.
111
programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
112                                   ClassConstants.INTERNAL_METHOD_TYPE_CLINIT,
113                                   this);
114
115         // Explicitly mark the parameterless <init> method.
116
programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_INIT,
117                                   ClassConstants.INTERNAL_METHOD_TYPE_INIT,
118                                   this);
119
120         // Process all methods that have already been marked as possibly used.
121
programClass.methodsAccept(possiblyUsedMethodUsageMarker);
122
123         // Mark the attributes.
124
programClass.attributesAccept(this);
125     }
126
127
128     public void visitLibraryClass(LibraryClass libraryClass)
129     {
130         if (shouldBeMarkedAsUsed(libraryClass))
131         {
132             markAsUsed(libraryClass);
133
134             // We're not going to analyze all library code. We're assuming that
135
// if this class is being used, all of its methods will be used as
136
// well. We'll mark them as such (here and in all subclasses).
137

138             // Mark the superclass.
139
Clazz superClass = libraryClass.superClass;
140             if (superClass != null)
141             {
142                 superClass.accept(this);
143             }
144
145             // Mark the interfaces.
146
Clazz[] interfaceClasses = libraryClass.interfaceClasses;
147             if (interfaceClasses != null)
148             {
149                 for (int index = 0; index < interfaceClasses.length; index++)
150                 {
151                     if (interfaceClasses[index] != null)
152                     {
153                         interfaceClasses[index].accept(this);
154                     }
155                 }
156             }
157
158             // Mark all methods.
159
libraryClass.methodsAccept(this);
160         }
161     }
162
163
164     /**
165      * This ClassVisitor marks ProgramClass objects as possibly used,
166      * and it visits LibraryClass objects with its outer UsageMarker.
167      */

168     private class MyInterfaceUsageMarker
169     implements ClassVisitor
170     {
171         public void visitProgramClass(ProgramClass programClass)
172         {
173             if (shouldBeMarkedAsPossiblyUsed(programClass))
174             {
175                 // We can't process the interface yet, because it might not
176
// be required. Give it a preliminary mark.
177
markAsPossiblyUsed(programClass);
178             }
179         }
180
181         public void visitLibraryClass(LibraryClass libraryClass)
182         {
183             // Make sure all library interface methods are marked.
184
UsageMarker.this.visitLibraryClass(libraryClass);
185         }
186     }
187
188
189     private class MyPossiblyUsedMethodUsageMarker
190     extends SimplifiedVisitor
191     implements MemberVisitor
192     {
193         // Implementations for MemberVisitor.
194

195         public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
196         {
197             // Has the method already been referenced?
198
if (isPossiblyUsed(programMethod))
199             {
200                 markAsUsed(programMethod);
201
202                 // Mark the method body.
203
markProgramMethodBody(programClass, programMethod);
204
205                 // Note that, if the method has been marked as possibly used,
206
// the method hierarchy has already been marked (cfr. below).
207
}
208         }
209
210
211     }
212
213
214     // Implementations for MemberVisitor.
215

216     public void visitProgramField(ProgramClass programClass, ProgramField programField)
217     {
218         if (shouldBeMarkedAsUsed(programField))
219         {
220             markAsUsed(programField);
221
222             // Mark the name and descriptor.
223
markConstant(programClass, programField.u2nameIndex);
224             markConstant(programClass, programField.u2descriptorIndex);
225
226             // Mark the attributes.
227
programField.attributesAccept(programClass, this);
228
229             // Mark the classes referenced in the descriptor string.
230
programField.referencedClassesAccept(this);
231         }
232     }
233
234
235     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
236     {
237         if (shouldBeMarkedAsUsed(programMethod))
238         {
239             // Is the method's class used?
240
if (isUsed(programClass))
241             {
242                 markAsUsed(programMethod);
243
244                 // Mark the method body.
245
markProgramMethodBody(programClass, programMethod);
246
247                 // Mark the method hierarchy.
248
markMethodHierarchy(programClass, programMethod);
249             }
250
251             // Hasn't the method been marked as possibly being used yet?
252
else if (shouldBeMarkedAsPossiblyUsed(programMethod))
253             {
254                 // We can't process the method yet, because the class isn't
255
// marked as being used (yet). Give it a preliminary mark.
256
markAsPossiblyUsed(programMethod);
257
258                 // Mark the method hierarchy.
259
markMethodHierarchy(programClass, programMethod);
260             }
261         }
262     }
263
264
265     public void visitLibraryField(LibraryClass programClass, LibraryField programField) {}
266
267
268     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
269     {
270         if (shouldBeMarkedAsUsed(libraryMethod))
271         {
272             markAsUsed(libraryMethod);
273
274             // Mark the method hierarchy.
275
markMethodHierarchy(libraryClass, libraryMethod);
276         }
277     }
278
279
280     protected void markProgramMethodBody(ProgramClass programClass, ProgramMethod programMethod)
281     {
282         // Mark the name and descriptor.
283
markConstant(programClass, programMethod.u2nameIndex);
284         markConstant(programClass, programMethod.u2descriptorIndex);
285
286         // Mark the attributes.
287
programMethod.attributesAccept(programClass, this);
288
289         // Mark the classes referenced in the descriptor string.
290
programMethod.referencedClassesAccept(this);
291     }
292
293
294     /**
295      * Marks the hierarchy of implementing or overriding methods corresponding
296      * to the given method, if any.
297      */

298     protected void markMethodHierarchy(Clazz clazz, Method method)
299     {
300         clazz.methodImplementationsAccept(method, false, this);
301     }
302
303
304     // Implementations for ConstantVisitor.
305

306     public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
307     {
308         if (shouldBeMarkedAsUsed(integerConstant))
309         {
310             markAsUsed(integerConstant);
311         }
312     }
313
314
315     public void visitLongConstant(Clazz clazz, LongConstant longConstant)
316     {
317         if (shouldBeMarkedAsUsed(longConstant))
318         {
319             markAsUsed(longConstant);
320         }
321     }
322
323
324     public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
325     {
326         if (shouldBeMarkedAsUsed(floatConstant))
327         {
328             markAsUsed(floatConstant);
329         }
330     }
331
332
333     public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
334     {
335         if (shouldBeMarkedAsUsed(doubleConstant))
336         {
337             markAsUsed(doubleConstant);
338         }
339     }
340
341
342     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
343     {
344         if (shouldBeMarkedAsUsed(stringConstant))
345         {
346             markAsUsed(stringConstant);
347
348             markConstant(clazz, stringConstant.u2stringIndex);
349
350             // Mark the referenced class and its parameterless constructor,
351
// if the string is being used in a Class.forName construct.
352
//stringConstant.referencedClassAccept(dynamicClassMarker);
353

354             // Mark the referenced class or class member, if any.
355
stringConstant.referencedClassAccept(this);
356             stringConstant.referencedMemberAccept(this);
357         }
358     }
359
360
361     public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
362     {
363         if (shouldBeMarkedAsUsed(utf8Constant))
364         {
365             markAsUsed(utf8Constant);
366         }
367     }
368
369
370     public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
371     {
372         visitRefConstant(clazz, fieldrefConstant);
373     }
374
375
376     public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
377     {
378         visitRefConstant(clazz, interfaceMethodrefConstant);
379     }
380
381
382     public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
383     {
384         visitRefConstant(clazz, methodrefConstant);
385     }
386
387
388     private void visitRefConstant(Clazz clazz, RefConstant methodrefConstant)
389     {
390         if (shouldBeMarkedAsUsed(methodrefConstant))
391         {
392             markAsUsed(methodrefConstant);
393
394             markConstant(clazz, methodrefConstant.u2classIndex);
395             markConstant(clazz, methodrefConstant.u2nameAndTypeIndex);
396
397             // When compiled with "-target 1.2" or higher, the class or
398
// interface actually containing the referenced method may be
399
// higher up the hierarchy. Make sure it's marked, in case it
400
// isn't used elsewhere.
401
methodrefConstant.referencedClassAccept(this);
402
403             // Mark the referenced method itself.
404
methodrefConstant.referencedMemberAccept(this);
405         }
406     }
407
408
409     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
410     {
411         if (shouldBeMarkedAsUsed(classConstant))
412         {
413             markAsUsed(classConstant);
414
415             markConstant(clazz, classConstant.u2nameIndex);
416
417             // Mark the referenced class itself.
418
classConstant.referencedClassAccept(this);
419         }
420     }
421
422
423     public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
424     {
425         if (shouldBeMarkedAsUsed(nameAndTypeConstant))
426         {
427             markAsUsed(nameAndTypeConstant);
428
429             markConstant(clazz, nameAndTypeConstant.u2nameIndex);
430             markConstant(clazz, nameAndTypeConstant.u2descriptorIndex);
431         }
432     }
433
434
435     // Implementations for AttributeVisitor.
436
// Note that attributes are typically only referenced once, so we don't
437
// test if they have been marked already.
438

439     public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
440     {
441         // This is the best we can do for unknown attributes.
442
markAsUsed(unknownAttribute);
443
444         markConstant(clazz, unknownAttribute.u2attributeNameIndex);
445     }
446
447
448     public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
449     {
450         markAsUsed(sourceFileAttribute);
451
452         markConstant(clazz, sourceFileAttribute.u2attributeNameIndex);
453         markConstant(clazz, sourceFileAttribute.u2sourceFileIndex);
454     }
455
456
457     public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
458     {
459         markAsUsed(sourceDirAttribute);
460
461         markConstant(clazz, sourceDirAttribute.u2attributeNameIndex);
462         markConstant(clazz, sourceDirAttribute.u2sourceDirIndex);
463     }
464
465
466     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
467     {
468         // Don't mark the attribute and its name yet. We may mark it later, in
469
// InnerUsageMarker.
470
//markAsUsed(innerClassesAttribute);
471

472         //markConstant(clazz, innerClassesAttribute.u2attrNameIndex);
473

474         // Do mark the outer class entries.
475
innerClassesAttribute.innerClassEntriesAccept(clazz, this);
476     }
477
478
479     public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
480     {
481         markAsUsed(enclosingMethodAttribute);
482
483         markConstant(clazz, enclosingMethodAttribute.u2attributeNameIndex);
484         markConstant(clazz, enclosingMethodAttribute.u2classIndex);
485
486         if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
487         {
488             markConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex);
489         }
490     }
491
492
493     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
494     {
495         markAsUsed(deprecatedAttribute);
496
497         markConstant(clazz, deprecatedAttribute.u2attributeNameIndex);
498     }
499
500
501     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
502     {
503         markAsUsed(syntheticAttribute);
504
505         markConstant(clazz, syntheticAttribute.u2attributeNameIndex);
506     }
507
508
509     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
510     {
511         markAsUsed(signatureAttribute);
512
513         markConstant(clazz, signatureAttribute.u2attributeNameIndex);
514         markConstant(clazz, signatureAttribute.u2signatureIndex);
515     }
516
517
518     public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
519     {
520         markAsUsed(constantValueAttribute);
521
522         markConstant(clazz, constantValueAttribute.u2attributeNameIndex);
523         markConstant(clazz, constantValueAttribute.u2constantValueIndex);
524     }
525
526
527     public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
528     {
529         markAsUsed(exceptionsAttribute);
530
531         markConstant(clazz, exceptionsAttribute.u2attributeNameIndex);
532
533         // Mark the constant pool entries referenced by the exceptions.
534
exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this);
535     }
536
537
538     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
539     {
540         markAsUsed(codeAttribute);
541
542         markConstant(clazz, codeAttribute.u2attributeNameIndex);
543
544         // Mark the constant pool entries referenced by the instructions,
545
// by the exceptions, and by the attributes.
546
codeAttribute.instructionsAccept(clazz, method, this);
547         codeAttribute.exceptionsAccept(clazz, method, this);
548         codeAttribute.attributesAccept(clazz, method, this);
549     }
550
551
552     public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
553     {
554         markAsUsed(stackMapAttribute);
555
556         markConstant(clazz, stackMapAttribute.u2attributeNameIndex);
557
558         // Mark the constant pool entries referenced by the stack map frames.
559
stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
560     }
561
562
563     public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
564     {
565         markAsUsed(stackMapTableAttribute);
566
567         markConstant(clazz, stackMapTableAttribute.u2attributeNameIndex);
568
569         // Mark the constant pool entries referenced by the stack map frames.
570
stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
571     }
572
573
574     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
575     {
576         markAsUsed(lineNumberTableAttribute);
577
578         markConstant(clazz, lineNumberTableAttribute.u2attributeNameIndex);
579     }
580
581
582     public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
583     {
584         markAsUsed(localVariableTableAttribute);
585
586         markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex);
587
588         // Mark the constant pool entries referenced by the local variables.
589
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
590     }
591
592
593     public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
594     {
595         markAsUsed(localVariableTypeTableAttribute);
596
597         markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex);
598
599         // Mark the constant pool entries referenced by the local variable types.
600
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
601     }
602
603
604     public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
605     {
606         // Don't mark the attribute and its contents yet. We may mark them later,
607
// in AnnotationUsageMarker.
608
// markAsUsed(annotationsAttribute);
609
//
610
// markConstant(clazz, annotationsAttribute.u2attributeNameIndex);
611
//
612
// // Mark the constant pool entries referenced by the annotations.
613
// annotationsAttribute.annotationsAccept(clazz, this);
614
}
615
616
617     public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
618     {
619         // Don't mark the attribute and its contents yet. We may mark them later,
620
// in AnnotationUsageMarker.
621
// markAsUsed(parameterAnnotationsAttribute);
622
//
623
// markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex);
624
//
625
// // Mark the constant pool entries referenced by the annotations.
626
// parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
627
}
628
629
630     public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
631     {
632         // Don't mark the attribute and its contents yet. We may mark them later,
633
// in AnnotationUsageMarker.
634
// markAsUsed(annotationDefaultAttribute);
635
//
636
// markConstant(clazz, annotationDefaultAttribute.u2attributeNameIndex);
637
//
638
// // Mark the constant pool entries referenced by the element value.
639
// annotationDefaultAttribute.defaultValueAccept(clazz, this);
640
}
641
642
643     // Implementations for ExceptionInfoVisitor.
644

645     public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
646     {
647         markAsUsed(exceptionInfo);
648
649         if (exceptionInfo.u2catchType != 0)
650         {
651             markConstant(clazz, exceptionInfo.u2catchType);
652         }
653     }
654
655
656     // Implementations for InnerClassesInfoVisitor.
657

658     public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
659     {
660         // At this point, we only mark outer classes of this class.
661
// Inner class can be marked later, by InnerUsageMarker.
662
if (innerClassesInfo.u2innerClassIndex == 0 &&
663             clazz.getName().equals(clazz.getClassName(innerClassesInfo.u2innerClassIndex)))
664         {
665             markAsUsed(innerClassesInfo);
666
667             if (innerClassesInfo.u2innerClassIndex != 0)
668             {
669                 markConstant(clazz, innerClassesInfo.u2innerClassIndex);
670             }
671
672             if (innerClassesInfo.u2outerClassIndex != 0)
673             {
674                 markConstant(clazz, innerClassesInfo.u2outerClassIndex);
675             }
676
677             if (innerClassesInfo.u2innerNameIndex != 0)
678             {
679                 markConstant(clazz, innerClassesInfo.u2innerNameIndex);
680             }
681         }
682     }
683
684
685     // Implementations for StackMapFrameVisitor.
686

687     public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {}
688
689
690     public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
691     {
692         // Mark the constant pool entries referenced by the verification types.
693
sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
694     }
695
696
697     public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
698     {
699         // Mark the constant pool entries referenced by the verification types.
700
moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
701     }
702
703
704     public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
705     {
706         // Mark the constant pool entries referenced by the verification types.
707
fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
708         fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
709     }
710
711
712     // Implementations for VerificationTypeVisitor.
713

714     public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {}
715
716
717     public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
718     {
719         markConstant(clazz, objectType.u2classIndex);
720     }
721
722
723     // Implementations for LocalVariableInfoVisitor.
724

725     public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
726     {
727         markConstant(clazz, localVariableInfo.u2nameIndex);
728         markConstant(clazz, localVariableInfo.u2descriptorIndex);
729     }
730
731
732     // Implementations for LocalVariableTypeInfoVisitor.
733

734     public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
735     {
736         markConstant(clazz, localVariableTypeInfo.u2nameIndex);
737         markConstant(clazz, localVariableTypeInfo.u2signatureIndex);
738     }
739
740
741 // // Implementations for AnnotationVisitor.
742
//
743
// public void visitAnnotation(Clazz clazz, Annotation annotation)
744
// {
745
// markConstant(clazz, annotation.u2typeIndex);
746
//
747
// // Mark the constant pool entries referenced by the element values.
748
// annotation.elementValuesAccept(clazz, this);
749
// }
750
//
751
//
752
// // Implementations for ElementValueVisitor.
753
//
754
// public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
755
// {
756
// if (constantElementValue.u2elementNameIndex != 0)
757
// {
758
// markConstant(clazz, constantElementValue.u2elementNameIndex);
759
// }
760
//
761
// markConstant(clazz, constantElementValue.u2constantValueIndex);
762
// }
763
//
764
//
765
// public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
766
// {
767
// if (enumConstantElementValue.u2elementNameIndex != 0)
768
// {
769
// markConstant(clazz, enumConstantElementValue.u2elementNameIndex);
770
// }
771
//
772
// markConstant(clazz, enumConstantElementValue.u2typeNameIndex);
773
// markConstant(clazz, enumConstantElementValue.u2constantNameIndex);
774
// }
775
//
776
//
777
// public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
778
// {
779
// if (classElementValue.u2elementNameIndex != 0)
780
// {
781
// markConstant(clazz, classElementValue.u2elementNameIndex);
782
// }
783
//
784
// // Mark the referenced class constant pool entry.
785
// markConstant(clazz, classElementValue.u2classInfoIndex);
786
// }
787
//
788
//
789
// public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
790
// {
791
// if (annotationElementValue.u2elementNameIndex != 0)
792
// {
793
// markConstant(clazz, annotationElementValue.u2elementNameIndex);
794
// }
795
//
796
// // Mark the constant pool entries referenced by the annotation.
797
// annotationElementValue.annotationAccept(clazz, this);
798
// }
799
//
800
//
801
// public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
802
// {
803
// if (arrayElementValue.u2elementNameIndex != 0)
804
// {
805
// markConstant(clazz, arrayElementValue.u2elementNameIndex);
806
// }
807
//
808
// // Mark the constant pool entries referenced by the element values.
809
// arrayElementValue.elementValuesAccept(clazz, annotation, this);
810
// }
811

812
813     // Implementations for InstructionVisitor.
814

815     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
816
817
818     public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
819     {
820         markConstant(clazz, constantInstruction.constantIndex);
821     }
822
823
824     // Small utility methods.
825

826     /**
827      * Marks the given visitor accepter as being used.
828      */

829     protected void markAsUsed(VisitorAccepter visitorAccepter)
830     {
831         visitorAccepter.setVisitorInfo(USED);
832     }
833
834
835     /**
836      * Returns whether the given visitor accepter should still be marked as
837      * being used.
838      */

839     protected boolean shouldBeMarkedAsUsed(VisitorAccepter visitorAccepter)
840     {
841         return visitorAccepter.getVisitorInfo() != USED;
842     }
843
844
845     /**
846      * Returns whether the given visitor accepter has been marked as being used.
847      */

848     protected boolean isUsed(VisitorAccepter visitorAccepter)
849     {
850         return visitorAccepter.getVisitorInfo() == USED;
851     }
852
853
854     /**
855      * Marks the given visitor accepter as possibly being used.
856      */

857     protected void markAsPossiblyUsed(VisitorAccepter visitorAccepter)
858     {
859         visitorAccepter.setVisitorInfo(POSSIBLY_USED);
860     }
861
862
863     /**
864      * Returns whether the given visitor accepter should still be marked as
865      * possibly being used.
866      */

867     protected boolean shouldBeMarkedAsPossiblyUsed(VisitorAccepter visitorAccepter)
868     {
869         return visitorAccepter.getVisitorInfo() != USED &&
870                visitorAccepter.getVisitorInfo() != POSSIBLY_USED;
871     }
872
873
874     /**
875      * Returns whether the given visitor accepter has been marked as possibly
876      * being used.
877      */

878     protected boolean isPossiblyUsed(VisitorAccepter visitorAccepter)
879     {
880         return visitorAccepter.getVisitorInfo() == POSSIBLY_USED;
881     }
882
883
884     /**
885      * Clears any usage marks from the given visitor accepter.
886      */

887     protected void markAsUnused(VisitorAccepter visitorAccepter)
888     {
889         visitorAccepter.setVisitorInfo(null);
890     }
891
892
893     /**
894      * Marks the given constant pool entry of the given class. This includes
895      * visiting any referenced objects.
896      */

897     private void markConstant(Clazz clazz, int index)
898     {
899          clazz.constantPoolEntryAccept(index, this);
900     }
901 }
902
Popular Tags