KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > shrink > InterfaceUsageMarker


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.constant.*;
25 import proguard.classfile.constant.visitor.ConstantVisitor;
26 import proguard.classfile.util.SimplifiedVisitor;
27 import proguard.classfile.visitor.ClassVisitor;
28
29
30 /**
31  * This ClassVisitor recursively marks all interface
32  * classes that are being used in the visited class.
33  *
34  * @see UsageMarker
35  *
36  * @author Eric Lafortune
37  */

38 public class InterfaceUsageMarker
39 extends SimplifiedVisitor
40 implements ClassVisitor,
41              ConstantVisitor
42 {
43     private UsageMarker usageMarker;
44
45     // A field acting as a return parameter for several methods.
46
private boolean used;
47
48
49     /**
50      * Creates a new InterfaceUsageMarker.
51      * @param usageMarker the usage marker that is used to mark the classes
52      * and class members.
53      */

54     public InterfaceUsageMarker(UsageMarker usageMarker)
55     {
56         this.usageMarker = usageMarker;
57     }
58
59
60     // Implementations for ClassVisitor.
61

62     public void visitProgramClass(ProgramClass programClass)
63     {
64         boolean classUsed = usageMarker.isUsed(programClass);
65         boolean classPossiblyUsed = usageMarker.isPossiblyUsed(programClass);
66
67         if (classUsed || classPossiblyUsed)
68         {
69             // Mark the references to interfaces that are being used.
70
for (int index = 0; index < programClass.u2interfacesCount; index++)
71             {
72                 // Check if the interface is used. Mark the constant pool entry
73
// if so.
74
markConstant(programClass, programClass.u2interfaces[index]);
75                 classUsed |= used;
76             }
77
78             // Is this an interface with a preliminary mark?
79
if (classPossiblyUsed)
80             {
81                 // Should it be included now?
82
if (classUsed)
83                 {
84                     // At least one if this interface's interfaces is being used.
85
// Mark this interface as well.
86
usageMarker.markAsUsed(programClass);
87
88                     // Mark this interface's name.
89
markConstant(programClass, programClass.u2thisClass);
90
91                     // Mark the superclass (java/lang/Object).
92
if (programClass.u2superClass != 0)
93                     {
94                         markConstant(programClass, programClass.u2superClass);
95                     }
96                 }
97                 else
98                 {
99                     // Unmark this interface, so we don't bother looking at it again.
100
usageMarker.markAsUnused(programClass);
101                 }
102             }
103         }
104
105         // The return value.
106
used = classUsed;
107     }
108
109
110     public void visitLibraryClass(LibraryClass libraryClass)
111     {
112         // The return value.
113
used = true;
114     }
115
116
117     // Implementations for ConstantVisitor.
118

119     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
120     {
121         boolean classUsed = usageMarker.isUsed(classConstant);
122
123         if (!classUsed)
124         {
125             // The ClassConstant isn't marked as being used yet. But maybe it should
126
// be included as an interface, so check the actual class.
127
classConstant.referencedClassAccept(this);
128             classUsed = used;
129
130             if (classUsed)
131             {
132                 // The class is being used. Mark the ClassConstant as being used
133
// as well.
134
usageMarker.markAsUsed(classConstant);
135
136                 markConstant(clazz, classConstant.u2nameIndex);
137             }
138         }
139
140         // The return value.
141
used = classUsed;
142     }
143
144
145     public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
146     {
147         if (!usageMarker.isUsed(utf8Constant))
148         {
149             usageMarker.markAsUsed(utf8Constant);
150         }
151     }
152
153
154     // Small utility methods.
155

156     /**
157      * Marks the given constant pool entry of the given class. This includes
158      * visiting any referenced objects.
159      */

160     private void markConstant(Clazz clazz, int index)
161     {
162          clazz.constantPoolEntryAccept(index, this);
163     }
164 }
165
Popular Tags