001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.shrink;
022:
023: import proguard.classfile.*;
024: import proguard.classfile.attribute.*;
025: import proguard.classfile.attribute.annotation.*;
026: import proguard.classfile.attribute.preverification.*;
027: import proguard.classfile.attribute.preverification.visitor.*;
028: import proguard.classfile.attribute.visitor.*;
029: import proguard.classfile.constant.*;
030: import proguard.classfile.constant.visitor.ConstantVisitor;
031: import proguard.classfile.instruction.*;
032: import proguard.classfile.instruction.visitor.InstructionVisitor;
033: import proguard.classfile.util.SimplifiedVisitor;
034: import proguard.classfile.visitor.*;
035:
036: /**
037: * This ClassVisitor and MemberVisitor recursively marks all classes and class
038: * elements that are being used.
039: *
040: * @see ClassShrinker
041: *
042: * @author Eric Lafortune
043: */
044: class UsageMarker extends SimplifiedVisitor implements ClassVisitor,
045: MemberVisitor, ConstantVisitor, AttributeVisitor,
046: InnerClassesInfoVisitor, ExceptionInfoVisitor,
047: StackMapFrameVisitor, VerificationTypeVisitor,
048: LocalVariableInfoVisitor, LocalVariableTypeInfoVisitor,
049: // AnnotationVisitor,
050: // ElementValueVisitor,
051: InstructionVisitor {
052: // A visitor info flag to indicate the ProgramMember object is being used,
053: // if its Clazz can be determined as being used as well.
054: private static final Object POSSIBLY_USED = new Object();
055: // A visitor info flag to indicate the visitor accepter is being used.
056: private static final Object USED = new Object();
057:
058: private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
059: private final MyPossiblyUsedMethodUsageMarker possiblyUsedMethodUsageMarker = new MyPossiblyUsedMethodUsageMarker();
060:
061: // private ClassVisitor dynamicClassMarker =
062: // new MultiClassVisitor(
063: // new ClassVisitor[]
064: // {
065: // this,
066: // new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
067: // ClassConstants.INTERNAL_METHOD_TYPE_INIT,
068: // this)
069: // });
070:
071: // Implementations for ClassVisitor.
072:
073: public void visitProgramClass(ProgramClass programClass) {
074: if (shouldBeMarkedAsUsed(programClass)) {
075: // Mark this class.
076: markAsUsed(programClass);
077:
078: markProgramClassBody(programClass);
079: }
080: }
081:
082: protected void markProgramClassBody(ProgramClass programClass) {
083: // Mark this class's name.
084: markConstant(programClass, programClass.u2this Class);
085:
086: // Mark the superclass.
087: if (programClass.u2super Class != 0) {
088: markConstant(programClass, programClass.u2super Class);
089: }
090:
091: // Give the interfaces preliminary marks.
092: programClass.hierarchyAccept(false, false, true, false,
093: interfaceUsageMarker);
094:
095: // Explicitly mark the <clinit> method.
096: programClass.methodAccept(
097: ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
098: ClassConstants.INTERNAL_METHOD_TYPE_CLINIT, this );
099:
100: // Explicitly mark the parameterless <init> method.
101: programClass.methodAccept(
102: ClassConstants.INTERNAL_METHOD_NAME_INIT,
103: ClassConstants.INTERNAL_METHOD_TYPE_INIT, this );
104:
105: // Process all methods that have already been marked as possibly used.
106: programClass.methodsAccept(possiblyUsedMethodUsageMarker);
107:
108: // Mark the attributes.
109: programClass.attributesAccept(this );
110: }
111:
112: public void visitLibraryClass(LibraryClass libraryClass) {
113: if (shouldBeMarkedAsUsed(libraryClass)) {
114: markAsUsed(libraryClass);
115:
116: // We're not going to analyze all library code. We're assuming that
117: // if this class is being used, all of its methods will be used as
118: // well. We'll mark them as such (here and in all subclasses).
119:
120: // Mark the superclass.
121: Clazz super Class = libraryClass.super Class;
122: if (super Class != null) {
123: super Class.accept(this );
124: }
125:
126: // Mark the interfaces.
127: Clazz[] interfaceClasses = libraryClass.interfaceClasses;
128: if (interfaceClasses != null) {
129: for (int index = 0; index < interfaceClasses.length; index++) {
130: if (interfaceClasses[index] != null) {
131: interfaceClasses[index].accept(this );
132: }
133: }
134: }
135:
136: // Mark all methods.
137: libraryClass.methodsAccept(this );
138: }
139: }
140:
141: /**
142: * This ClassVisitor marks ProgramClass objects as possibly used,
143: * and it visits LibraryClass objects with its outer UsageMarker.
144: */
145: private class MyInterfaceUsageMarker implements ClassVisitor {
146: public void visitProgramClass(ProgramClass programClass) {
147: if (shouldBeMarkedAsPossiblyUsed(programClass)) {
148: // We can't process the interface yet, because it might not
149: // be required. Give it a preliminary mark.
150: markAsPossiblyUsed(programClass);
151: }
152: }
153:
154: public void visitLibraryClass(LibraryClass libraryClass) {
155: // Make sure all library interface methods are marked.
156: UsageMarker.this .visitLibraryClass(libraryClass);
157: }
158: }
159:
160: private class MyPossiblyUsedMethodUsageMarker extends
161: SimplifiedVisitor implements MemberVisitor {
162: // Implementations for MemberVisitor.
163:
164: public void visitProgramMethod(ProgramClass programClass,
165: ProgramMethod programMethod) {
166: // Has the method already been referenced?
167: if (isPossiblyUsed(programMethod)) {
168: markAsUsed(programMethod);
169:
170: // Mark the method body.
171: markProgramMethodBody(programClass, programMethod);
172:
173: // Note that, if the method has been marked as possibly used,
174: // the method hierarchy has already been marked (cfr. below).
175: }
176: }
177:
178: }
179:
180: // Implementations for MemberVisitor.
181:
182: public void visitProgramField(ProgramClass programClass,
183: ProgramField programField) {
184: if (shouldBeMarkedAsUsed(programField)) {
185: markAsUsed(programField);
186:
187: // Mark the name and descriptor.
188: markConstant(programClass, programField.u2nameIndex);
189: markConstant(programClass, programField.u2descriptorIndex);
190:
191: // Mark the attributes.
192: programField.attributesAccept(programClass, this );
193:
194: // Mark the classes referenced in the descriptor string.
195: programField.referencedClassesAccept(this );
196: }
197: }
198:
199: public void visitProgramMethod(ProgramClass programClass,
200: ProgramMethod programMethod) {
201: if (shouldBeMarkedAsUsed(programMethod)) {
202: // Is the method's class used?
203: if (isUsed(programClass)) {
204: markAsUsed(programMethod);
205:
206: // Mark the method body.
207: markProgramMethodBody(programClass, programMethod);
208:
209: // Mark the method hierarchy.
210: markMethodHierarchy(programClass, programMethod);
211: }
212:
213: // Hasn't the method been marked as possibly being used yet?
214: else if (shouldBeMarkedAsPossiblyUsed(programMethod)) {
215: // We can't process the method yet, because the class isn't
216: // marked as being used (yet). Give it a preliminary mark.
217: markAsPossiblyUsed(programMethod);
218:
219: // Mark the method hierarchy.
220: markMethodHierarchy(programClass, programMethod);
221: }
222: }
223: }
224:
225: public void visitLibraryField(LibraryClass programClass,
226: LibraryField programField) {
227: }
228:
229: public void visitLibraryMethod(LibraryClass libraryClass,
230: LibraryMethod libraryMethod) {
231: if (shouldBeMarkedAsUsed(libraryMethod)) {
232: markAsUsed(libraryMethod);
233:
234: // Mark the method hierarchy.
235: markMethodHierarchy(libraryClass, libraryMethod);
236: }
237: }
238:
239: protected void markProgramMethodBody(ProgramClass programClass,
240: ProgramMethod programMethod) {
241: // Mark the name and descriptor.
242: markConstant(programClass, programMethod.u2nameIndex);
243: markConstant(programClass, programMethod.u2descriptorIndex);
244:
245: // Mark the attributes.
246: programMethod.attributesAccept(programClass, this );
247:
248: // Mark the classes referenced in the descriptor string.
249: programMethod.referencedClassesAccept(this );
250: }
251:
252: /**
253: * Marks the hierarchy of implementing or overriding methods corresponding
254: * to the given method, if any.
255: */
256: protected void markMethodHierarchy(Clazz clazz, Method method) {
257: clazz.methodImplementationsAccept(method, false, this );
258: }
259:
260: // Implementations for ConstantVisitor.
261:
262: public void visitIntegerConstant(Clazz clazz,
263: IntegerConstant integerConstant) {
264: if (shouldBeMarkedAsUsed(integerConstant)) {
265: markAsUsed(integerConstant);
266: }
267: }
268:
269: public void visitLongConstant(Clazz clazz, LongConstant longConstant) {
270: if (shouldBeMarkedAsUsed(longConstant)) {
271: markAsUsed(longConstant);
272: }
273: }
274:
275: public void visitFloatConstant(Clazz clazz,
276: FloatConstant floatConstant) {
277: if (shouldBeMarkedAsUsed(floatConstant)) {
278: markAsUsed(floatConstant);
279: }
280: }
281:
282: public void visitDoubleConstant(Clazz clazz,
283: DoubleConstant doubleConstant) {
284: if (shouldBeMarkedAsUsed(doubleConstant)) {
285: markAsUsed(doubleConstant);
286: }
287: }
288:
289: public void visitStringConstant(Clazz clazz,
290: StringConstant stringConstant) {
291: if (shouldBeMarkedAsUsed(stringConstant)) {
292: markAsUsed(stringConstant);
293:
294: markConstant(clazz, stringConstant.u2stringIndex);
295:
296: // Mark the referenced class and its parameterless constructor,
297: // if the string is being used in a Class.forName construct.
298: //stringConstant.referencedClassAccept(dynamicClassMarker);
299:
300: // Mark the referenced class or class member, if any.
301: stringConstant.referencedClassAccept(this );
302: stringConstant.referencedMemberAccept(this );
303: }
304: }
305:
306: public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) {
307: if (shouldBeMarkedAsUsed(utf8Constant)) {
308: markAsUsed(utf8Constant);
309: }
310: }
311:
312: public void visitFieldrefConstant(Clazz clazz,
313: FieldrefConstant fieldrefConstant) {
314: visitRefConstant(clazz, fieldrefConstant);
315: }
316:
317: public void visitInterfaceMethodrefConstant(Clazz clazz,
318: InterfaceMethodrefConstant interfaceMethodrefConstant) {
319: visitRefConstant(clazz, interfaceMethodrefConstant);
320: }
321:
322: public void visitMethodrefConstant(Clazz clazz,
323: MethodrefConstant methodrefConstant) {
324: visitRefConstant(clazz, methodrefConstant);
325: }
326:
327: private void visitRefConstant(Clazz clazz,
328: RefConstant methodrefConstant) {
329: if (shouldBeMarkedAsUsed(methodrefConstant)) {
330: markAsUsed(methodrefConstant);
331:
332: markConstant(clazz, methodrefConstant.u2classIndex);
333: markConstant(clazz, methodrefConstant.u2nameAndTypeIndex);
334:
335: // When compiled with "-target 1.2" or higher, the class or
336: // interface actually containing the referenced method may be
337: // higher up the hierarchy. Make sure it's marked, in case it
338: // isn't used elsewhere.
339: methodrefConstant.referencedClassAccept(this );
340:
341: // Mark the referenced method itself.
342: methodrefConstant.referencedMemberAccept(this );
343: }
344: }
345:
346: public void visitClassConstant(Clazz clazz,
347: ClassConstant classConstant) {
348: if (shouldBeMarkedAsUsed(classConstant)) {
349: markAsUsed(classConstant);
350:
351: markConstant(clazz, classConstant.u2nameIndex);
352:
353: // Mark the referenced class itself.
354: classConstant.referencedClassAccept(this );
355: }
356: }
357:
358: public void visitNameAndTypeConstant(Clazz clazz,
359: NameAndTypeConstant nameAndTypeConstant) {
360: if (shouldBeMarkedAsUsed(nameAndTypeConstant)) {
361: markAsUsed(nameAndTypeConstant);
362:
363: markConstant(clazz, nameAndTypeConstant.u2nameIndex);
364: markConstant(clazz, nameAndTypeConstant.u2descriptorIndex);
365: }
366: }
367:
368: // Implementations for AttributeVisitor.
369: // Note that attributes are typically only referenced once, so we don't
370: // test if they have been marked already.
371:
372: public void visitUnknownAttribute(Clazz clazz,
373: UnknownAttribute unknownAttribute) {
374: // This is the best we can do for unknown attributes.
375: markAsUsed(unknownAttribute);
376:
377: markConstant(clazz, unknownAttribute.u2attributeNameIndex);
378: }
379:
380: public void visitSourceFileAttribute(Clazz clazz,
381: SourceFileAttribute sourceFileAttribute) {
382: markAsUsed(sourceFileAttribute);
383:
384: markConstant(clazz, sourceFileAttribute.u2attributeNameIndex);
385: markConstant(clazz, sourceFileAttribute.u2sourceFileIndex);
386: }
387:
388: public void visitSourceDirAttribute(Clazz clazz,
389: SourceDirAttribute sourceDirAttribute) {
390: markAsUsed(sourceDirAttribute);
391:
392: markConstant(clazz, sourceDirAttribute.u2attributeNameIndex);
393: markConstant(clazz, sourceDirAttribute.u2sourceDirIndex);
394: }
395:
396: public void visitInnerClassesAttribute(Clazz clazz,
397: InnerClassesAttribute innerClassesAttribute) {
398: // Don't mark the attribute and its name yet. We may mark it later, in
399: // InnerUsageMarker.
400: //markAsUsed(innerClassesAttribute);
401:
402: //markConstant(clazz, innerClassesAttribute.u2attrNameIndex);
403:
404: // Do mark the outer class entries.
405: innerClassesAttribute.innerClassEntriesAccept(clazz, this );
406: }
407:
408: public void visitEnclosingMethodAttribute(Clazz clazz,
409: EnclosingMethodAttribute enclosingMethodAttribute) {
410: markAsUsed(enclosingMethodAttribute);
411:
412: markConstant(clazz,
413: enclosingMethodAttribute.u2attributeNameIndex);
414: markConstant(clazz, enclosingMethodAttribute.u2classIndex);
415:
416: if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) {
417: markConstant(clazz,
418: enclosingMethodAttribute.u2nameAndTypeIndex);
419: }
420: }
421:
422: public void visitDeprecatedAttribute(Clazz clazz,
423: DeprecatedAttribute deprecatedAttribute) {
424: markAsUsed(deprecatedAttribute);
425:
426: markConstant(clazz, deprecatedAttribute.u2attributeNameIndex);
427: }
428:
429: public void visitSyntheticAttribute(Clazz clazz,
430: SyntheticAttribute syntheticAttribute) {
431: markAsUsed(syntheticAttribute);
432:
433: markConstant(clazz, syntheticAttribute.u2attributeNameIndex);
434: }
435:
436: public void visitSignatureAttribute(Clazz clazz,
437: SignatureAttribute signatureAttribute) {
438: markAsUsed(signatureAttribute);
439:
440: markConstant(clazz, signatureAttribute.u2attributeNameIndex);
441: markConstant(clazz, signatureAttribute.u2signatureIndex);
442: }
443:
444: public void visitConstantValueAttribute(Clazz clazz, Field field,
445: ConstantValueAttribute constantValueAttribute) {
446: markAsUsed(constantValueAttribute);
447:
448: markConstant(clazz, constantValueAttribute.u2attributeNameIndex);
449: markConstant(clazz, constantValueAttribute.u2constantValueIndex);
450: }
451:
452: public void visitExceptionsAttribute(Clazz clazz, Method method,
453: ExceptionsAttribute exceptionsAttribute) {
454: markAsUsed(exceptionsAttribute);
455:
456: markConstant(clazz, exceptionsAttribute.u2attributeNameIndex);
457:
458: // Mark the constant pool entries referenced by the exceptions.
459: exceptionsAttribute.exceptionEntriesAccept(
460: (ProgramClass) clazz, this );
461: }
462:
463: public void visitCodeAttribute(Clazz clazz, Method method,
464: CodeAttribute codeAttribute) {
465: markAsUsed(codeAttribute);
466:
467: markConstant(clazz, codeAttribute.u2attributeNameIndex);
468:
469: // Mark the constant pool entries referenced by the instructions,
470: // by the exceptions, and by the attributes.
471: codeAttribute.instructionsAccept(clazz, method, this );
472: codeAttribute.exceptionsAccept(clazz, method, this );
473: codeAttribute.attributesAccept(clazz, method, this );
474: }
475:
476: public void visitStackMapAttribute(Clazz clazz, Method method,
477: CodeAttribute codeAttribute,
478: StackMapAttribute stackMapAttribute) {
479: markAsUsed(stackMapAttribute);
480:
481: markConstant(clazz, stackMapAttribute.u2attributeNameIndex);
482:
483: // Mark the constant pool entries referenced by the stack map frames.
484: stackMapAttribute.stackMapFramesAccept(clazz, method,
485: codeAttribute, this );
486: }
487:
488: public void visitStackMapTableAttribute(Clazz clazz, Method method,
489: CodeAttribute codeAttribute,
490: StackMapTableAttribute stackMapTableAttribute) {
491: markAsUsed(stackMapTableAttribute);
492:
493: markConstant(clazz, stackMapTableAttribute.u2attributeNameIndex);
494:
495: // Mark the constant pool entries referenced by the stack map frames.
496: stackMapTableAttribute.stackMapFramesAccept(clazz, method,
497: codeAttribute, this );
498: }
499:
500: public void visitLineNumberTableAttribute(Clazz clazz,
501: Method method, CodeAttribute codeAttribute,
502: LineNumberTableAttribute lineNumberTableAttribute) {
503: markAsUsed(lineNumberTableAttribute);
504:
505: markConstant(clazz,
506: lineNumberTableAttribute.u2attributeNameIndex);
507: }
508:
509: public void visitLocalVariableTableAttribute(Clazz clazz,
510: Method method, CodeAttribute codeAttribute,
511: LocalVariableTableAttribute localVariableTableAttribute) {
512: markAsUsed(localVariableTableAttribute);
513:
514: markConstant(clazz,
515: localVariableTableAttribute.u2attributeNameIndex);
516:
517: // Mark the constant pool entries referenced by the local variables.
518: localVariableTableAttribute.localVariablesAccept(clazz, method,
519: codeAttribute, this );
520: }
521:
522: public void visitLocalVariableTypeTableAttribute(
523: Clazz clazz,
524: Method method,
525: CodeAttribute codeAttribute,
526: LocalVariableTypeTableAttribute localVariableTypeTableAttribute) {
527: markAsUsed(localVariableTypeTableAttribute);
528:
529: markConstant(clazz,
530: localVariableTypeTableAttribute.u2attributeNameIndex);
531:
532: // Mark the constant pool entries referenced by the local variable types.
533: localVariableTypeTableAttribute.localVariablesAccept(clazz,
534: method, codeAttribute, this );
535: }
536:
537: public void visitAnyAnnotationsAttribute(Clazz clazz,
538: AnnotationsAttribute annotationsAttribute) {
539: // Don't mark the attribute and its contents yet. We may mark them later,
540: // in AnnotationUsageMarker.
541: // markAsUsed(annotationsAttribute);
542: //
543: // markConstant(clazz, annotationsAttribute.u2attributeNameIndex);
544: //
545: // // Mark the constant pool entries referenced by the annotations.
546: // annotationsAttribute.annotationsAccept(clazz, this);
547: }
548:
549: public void visitAnyParameterAnnotationsAttribute(Clazz clazz,
550: Method method,
551: ParameterAnnotationsAttribute parameterAnnotationsAttribute) {
552: // Don't mark the attribute and its contents yet. We may mark them later,
553: // in AnnotationUsageMarker.
554: // markAsUsed(parameterAnnotationsAttribute);
555: //
556: // markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex);
557: //
558: // // Mark the constant pool entries referenced by the annotations.
559: // parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
560: }
561:
562: public void visitAnnotationDefaultAttribute(Clazz clazz,
563: Method method,
564: AnnotationDefaultAttribute annotationDefaultAttribute) {
565: // Don't mark the attribute and its contents yet. We may mark them later,
566: // in AnnotationUsageMarker.
567: // markAsUsed(annotationDefaultAttribute);
568: //
569: // markConstant(clazz, annotationDefaultAttribute.u2attributeNameIndex);
570: //
571: // // Mark the constant pool entries referenced by the element value.
572: // annotationDefaultAttribute.defaultValueAccept(clazz, this);
573: }
574:
575: // Implementations for ExceptionInfoVisitor.
576:
577: public void visitExceptionInfo(Clazz clazz, Method method,
578: CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) {
579: markAsUsed(exceptionInfo);
580:
581: if (exceptionInfo.u2catchType != 0) {
582: markConstant(clazz, exceptionInfo.u2catchType);
583: }
584: }
585:
586: // Implementations for InnerClassesInfoVisitor.
587:
588: public void visitInnerClassesInfo(Clazz clazz,
589: InnerClassesInfo innerClassesInfo) {
590: // At this point, we only mark outer classes of this class.
591: // Inner class can be marked later, by InnerUsageMarker.
592: if (innerClassesInfo.u2innerClassIndex == 0
593: && clazz
594: .getName()
595: .equals(
596: clazz
597: .getClassName(innerClassesInfo.u2innerClassIndex))) {
598: markAsUsed(innerClassesInfo);
599:
600: if (innerClassesInfo.u2innerClassIndex != 0) {
601: markConstant(clazz, innerClassesInfo.u2innerClassIndex);
602: }
603:
604: if (innerClassesInfo.u2outerClassIndex != 0) {
605: markConstant(clazz, innerClassesInfo.u2outerClassIndex);
606: }
607:
608: if (innerClassesInfo.u2innerNameIndex != 0) {
609: markConstant(clazz, innerClassesInfo.u2innerNameIndex);
610: }
611: }
612: }
613:
614: // Implementations for StackMapFrameVisitor.
615:
616: public void visitAnyStackMapFrame(Clazz clazz, Method method,
617: CodeAttribute codeAttribute, int offset,
618: StackMapFrame stackMapFrame) {
619: }
620:
621: public void visitSameOneFrame(Clazz clazz, Method method,
622: CodeAttribute codeAttribute, int offset,
623: SameOneFrame sameOneFrame) {
624: // Mark the constant pool entries referenced by the verification types.
625: sameOneFrame.stackItemAccept(clazz, method, codeAttribute,
626: offset, this );
627: }
628:
629: public void visitMoreZeroFrame(Clazz clazz, Method method,
630: CodeAttribute codeAttribute, int offset,
631: MoreZeroFrame moreZeroFrame) {
632: // Mark the constant pool entries referenced by the verification types.
633: moreZeroFrame.additionalVariablesAccept(clazz, method,
634: codeAttribute, offset, this );
635: }
636:
637: public void visitFullFrame(Clazz clazz, Method method,
638: CodeAttribute codeAttribute, int offset, FullFrame fullFrame) {
639: // Mark the constant pool entries referenced by the verification types.
640: fullFrame.variablesAccept(clazz, method, codeAttribute, offset,
641: this );
642: fullFrame.stackAccept(clazz, method, codeAttribute, offset,
643: this );
644: }
645:
646: // Implementations for VerificationTypeVisitor.
647:
648: public void visitAnyVerificationType(Clazz clazz, Method method,
649: CodeAttribute codeAttribute, int offset,
650: VerificationType verificationType) {
651: }
652:
653: public void visitObjectType(Clazz clazz, Method method,
654: CodeAttribute codeAttribute, int offset,
655: ObjectType objectType) {
656: markConstant(clazz, objectType.u2classIndex);
657: }
658:
659: // Implementations for LocalVariableInfoVisitor.
660:
661: public void visitLocalVariableInfo(Clazz clazz, Method method,
662: CodeAttribute codeAttribute,
663: LocalVariableInfo localVariableInfo) {
664: markConstant(clazz, localVariableInfo.u2nameIndex);
665: markConstant(clazz, localVariableInfo.u2descriptorIndex);
666: }
667:
668: // Implementations for LocalVariableTypeInfoVisitor.
669:
670: public void visitLocalVariableTypeInfo(Clazz clazz, Method method,
671: CodeAttribute codeAttribute,
672: LocalVariableTypeInfo localVariableTypeInfo) {
673: markConstant(clazz, localVariableTypeInfo.u2nameIndex);
674: markConstant(clazz, localVariableTypeInfo.u2signatureIndex);
675: }
676:
677: // // Implementations for AnnotationVisitor.
678: //
679: // public void visitAnnotation(Clazz clazz, Annotation annotation)
680: // {
681: // markConstant(clazz, annotation.u2typeIndex);
682: //
683: // // Mark the constant pool entries referenced by the element values.
684: // annotation.elementValuesAccept(clazz, this);
685: // }
686: //
687: //
688: // // Implementations for ElementValueVisitor.
689: //
690: // public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
691: // {
692: // if (constantElementValue.u2elementNameIndex != 0)
693: // {
694: // markConstant(clazz, constantElementValue.u2elementNameIndex);
695: // }
696: //
697: // markConstant(clazz, constantElementValue.u2constantValueIndex);
698: // }
699: //
700: //
701: // public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
702: // {
703: // if (enumConstantElementValue.u2elementNameIndex != 0)
704: // {
705: // markConstant(clazz, enumConstantElementValue.u2elementNameIndex);
706: // }
707: //
708: // markConstant(clazz, enumConstantElementValue.u2typeNameIndex);
709: // markConstant(clazz, enumConstantElementValue.u2constantNameIndex);
710: // }
711: //
712: //
713: // public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
714: // {
715: // if (classElementValue.u2elementNameIndex != 0)
716: // {
717: // markConstant(clazz, classElementValue.u2elementNameIndex);
718: // }
719: //
720: // // Mark the referenced class constant pool entry.
721: // markConstant(clazz, classElementValue.u2classInfoIndex);
722: // }
723: //
724: //
725: // public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
726: // {
727: // if (annotationElementValue.u2elementNameIndex != 0)
728: // {
729: // markConstant(clazz, annotationElementValue.u2elementNameIndex);
730: // }
731: //
732: // // Mark the constant pool entries referenced by the annotation.
733: // annotationElementValue.annotationAccept(clazz, this);
734: // }
735: //
736: //
737: // public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
738: // {
739: // if (arrayElementValue.u2elementNameIndex != 0)
740: // {
741: // markConstant(clazz, arrayElementValue.u2elementNameIndex);
742: // }
743: //
744: // // Mark the constant pool entries referenced by the element values.
745: // arrayElementValue.elementValuesAccept(clazz, annotation, this);
746: // }
747:
748: // Implementations for InstructionVisitor.
749:
750: public void visitAnyInstruction(Clazz clazz, Method method,
751: CodeAttribute codeAttribute, int offset,
752: Instruction instruction) {
753: }
754:
755: public void visitConstantInstruction(Clazz clazz, Method method,
756: CodeAttribute codeAttribute, int offset,
757: ConstantInstruction constantInstruction) {
758: markConstant(clazz, constantInstruction.constantIndex);
759: }
760:
761: // Small utility methods.
762:
763: /**
764: * Marks the given visitor accepter as being used.
765: */
766: protected void markAsUsed(VisitorAccepter visitorAccepter) {
767: visitorAccepter.setVisitorInfo(USED);
768: }
769:
770: /**
771: * Returns whether the given visitor accepter should still be marked as
772: * being used.
773: */
774: protected boolean shouldBeMarkedAsUsed(
775: VisitorAccepter visitorAccepter) {
776: return visitorAccepter.getVisitorInfo() != USED;
777: }
778:
779: /**
780: * Returns whether the given visitor accepter has been marked as being used.
781: */
782: protected boolean isUsed(VisitorAccepter visitorAccepter) {
783: return visitorAccepter.getVisitorInfo() == USED;
784: }
785:
786: /**
787: * Marks the given visitor accepter as possibly being used.
788: */
789: protected void markAsPossiblyUsed(VisitorAccepter visitorAccepter) {
790: visitorAccepter.setVisitorInfo(POSSIBLY_USED);
791: }
792:
793: /**
794: * Returns whether the given visitor accepter should still be marked as
795: * possibly being used.
796: */
797: protected boolean shouldBeMarkedAsPossiblyUsed(
798: VisitorAccepter visitorAccepter) {
799: return visitorAccepter.getVisitorInfo() != USED
800: && visitorAccepter.getVisitorInfo() != POSSIBLY_USED;
801: }
802:
803: /**
804: * Returns whether the given visitor accepter has been marked as possibly
805: * being used.
806: */
807: protected boolean isPossiblyUsed(VisitorAccepter visitorAccepter) {
808: return visitorAccepter.getVisitorInfo() == POSSIBLY_USED;
809: }
810:
811: /**
812: * Clears any usage marks from the given visitor accepter.
813: */
814: protected void markAsUnused(VisitorAccepter visitorAccepter) {
815: visitorAccepter.setVisitorInfo(null);
816: }
817:
818: /**
819: * Marks the given constant pool entry of the given class. This includes
820: * visiting any referenced objects.
821: */
822: private void markConstant(Clazz clazz, int index) {
823: clazz.constantPoolEntryAccept(index, this);
824: }
825: }
|