KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > shrink > InnerUsageMarker


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.visitor.*;
26 import proguard.classfile.constant.*;
27 import proguard.classfile.constant.visitor.ConstantVisitor;
28 import proguard.classfile.util.SimplifiedVisitor;
29 import proguard.classfile.visitor.ClassVisitor;
30
31 /**
32  * This AttributeVisitor recursively marks all necessary inner class information
33  * in the attributes that it visits.
34  *
35  * @see UsageMarker
36  *
37  * @author Eric Lafortune
38  */

39 public class InnerUsageMarker
40 extends SimplifiedVisitor
41 implements AttributeVisitor,
42              InnerClassesInfoVisitor,
43              ConstantVisitor,
44              ClassVisitor
45 {
46     private UsageMarker usageMarker;
47
48     // Fields acting as a return parameters for several methods.
49
private boolean attributeUsed;
50     private boolean classUsed;
51
52
53     /**
54      * Creates a new InnerUsageMarker.
55      * @param usageMarker the usage marker that is used to mark the classes
56      * and class members.
57      */

58     public InnerUsageMarker(UsageMarker usageMarker)
59     {
60         this.usageMarker = usageMarker;
61     }
62
63
64     // Implementations for AttributeVisitor.
65

66     public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
67
68
69     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
70     {
71         // Mark the necessary inner classes information.
72
attributeUsed = false;
73         innerClassesAttribute.innerClassEntriesAccept(clazz, this);
74
75         if (attributeUsed)
76         {
77             // We got a positive used flag, so some inner class is being used.
78
// Mark this attribute as being used as well.
79
usageMarker.markAsUsed(innerClassesAttribute);
80
81             markConstant(clazz, innerClassesAttribute.u2attributeNameIndex);
82         }
83     }
84
85
86     // Implementations for InnerClassesInfoVisitor.
87

88     public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
89     {
90         boolean innerClassesInfoUsed = usageMarker.isUsed(innerClassesInfo);
91
92         if (!innerClassesInfoUsed)
93         {
94             int u2innerClassIndex = innerClassesInfo.u2innerClassIndex;
95             int u2outerClassIndex = innerClassesInfo.u2outerClassIndex;
96             int u2innerNameIndex = innerClassesInfo.u2innerNameIndex;
97
98             innerClassesInfoUsed = true;
99
100             if (u2innerClassIndex != 0)
101             {
102                 // Check if the inner class is marked as being used.
103
markConstant(clazz, u2innerClassIndex);
104                 innerClassesInfoUsed &= classUsed;
105             }
106
107             if (u2outerClassIndex != 0)
108             {
109                 // Check if the outer class is marked as being used.
110
markConstant(clazz, u2outerClassIndex);
111                 innerClassesInfoUsed &= classUsed;
112             }
113
114             // If both the inner class and the outer class are marked as being
115
// used, then mark this InnerClassesInfo as well.
116
if (innerClassesInfoUsed)
117             {
118                 usageMarker.markAsUsed(innerClassesInfo);
119
120                 if (u2innerNameIndex != 0)
121                 {
122                     markConstant(clazz, u2innerNameIndex);
123                 }
124             }
125         }
126
127         // The return value.
128
attributeUsed |= innerClassesInfoUsed;
129     }
130
131
132     // Implementations for ConstantVisitor.
133

134     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
135     {
136         classUsed = usageMarker.isUsed(classConstant);
137
138         // Is the class constant marked as being used?
139
if (!classUsed)
140         {
141             // Check the referenced class.
142
classUsed = true;
143             classConstant.referencedClassAccept(this);
144
145             // Is the referenced class marked as being used?
146
if (classUsed)
147             {
148                 // Mark the class constant and its Utf8 constant.
149
usageMarker.markAsUsed(classConstant);
150
151                 markConstant(clazz, classConstant.u2nameIndex);
152             }
153         }
154     }
155
156
157     public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
158     {
159         usageMarker.markAsUsed(utf8Constant);
160     }
161
162
163     // Implementations for ClassVisitor.
164

165     public void visitProgramClass(ProgramClass programClass)
166     {
167         classUsed = usageMarker.isUsed(programClass);
168     }
169
170
171     public void visitLibraryClass(LibraryClass libraryClass)
172     {
173         classUsed = true;
174     }
175
176
177     // Small utility methods.
178

179     /**
180      * Marks the given constant pool entry of the given class. This includes
181      * visiting any other referenced constant pool entries.
182      */

183     private void markConstant(Clazz clazz, int index)
184     {
185          clazz.constantPoolEntryAccept(index, this);
186     }
187 }
188
Popular Tags