KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > shrink > ShortestUsageMarker


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.instruction.*;
27 import proguard.classfile.visitor.*;
28
29
30 /**
31  * This ClassVisitor and MemberVisitor recursively marks all classes
32  * and class elements that are being used. For each element, it finds the
33  * shortest chain of dependencies.
34  *
35  * @see ClassShrinker
36  *
37  * @author Eric Lafortune
38  */

39 public class ShortestUsageMarker extends UsageMarker
40 {
41     private static final ShortestUsageMark INITIAL_MARK =
42         new ShortestUsageMark("is kept by a directive in the configuration.\n\n");
43
44
45     // A field acting as a parameter to the visitor methods.
46
private ShortestUsageMark currentUsageMark = INITIAL_MARK;
47
48     // A utility object to check for recursive causes.
49
private MyRecursiveCauseChecker recursiveCauseChecker = new MyRecursiveCauseChecker();
50
51
52     // Overriding implementations for UsageMarker.
53

54     protected void markProgramClassBody(ProgramClass programClass)
55     {
56         ShortestUsageMark previousUsageMark = currentUsageMark;
57
58         currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programClass),
59                                                  "is extended by ",
60                                                  10000,
61                                                  programClass);
62
63         super.markProgramClassBody(programClass);
64
65         currentUsageMark = previousUsageMark;
66     }
67
68
69     protected void markProgramMethodBody(ProgramClass programClass, ProgramMethod programMethod)
70     {
71         ShortestUsageMark previousUsageMark = currentUsageMark;
72
73         currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programMethod),
74                                                  "is invoked by ",
75                                                  1,
76                                                  programClass,
77                                                  programMethod);
78
79         super.markProgramMethodBody(programClass, programMethod);
80
81         currentUsageMark = previousUsageMark;
82     }
83
84
85     protected void markMethodHierarchy(Clazz clazz, Method method)
86     {
87         ShortestUsageMark previousUsageMark = currentUsageMark;
88
89         currentUsageMark = new ShortestUsageMark(getShortestUsageMark(method),
90                                                  "implements ",
91                                                  100,
92                                                  clazz,
93                                                  method);
94
95         super.markMethodHierarchy(clazz, method);
96
97         currentUsageMark = previousUsageMark;
98     }
99
100
101     // Small utility methods.
102

103     protected void markAsUsed(VisitorAccepter visitorAccepter)
104     {
105         Object JavaDoc visitorInfo = visitorAccepter.getVisitorInfo();
106
107         ShortestUsageMark shortestUsageMark =
108             visitorInfo != null &&
109             visitorInfo instanceof ShortestUsageMark &&
110             !((ShortestUsageMark)visitorInfo).isCertain() &&
111             !currentUsageMark.isShorter((ShortestUsageMark)visitorInfo) ?
112                 new ShortestUsageMark((ShortestUsageMark)visitorInfo, true):
113                 currentUsageMark;
114
115         visitorAccepter.setVisitorInfo(shortestUsageMark);
116     }
117
118
119     protected boolean shouldBeMarkedAsUsed(VisitorAccepter visitorAccepter)
120     {
121         Object JavaDoc visitorInfo = visitorAccepter.getVisitorInfo();
122
123         return //!(visitorAccepter instanceof Clazz &&
124
// isCausedBy(currentUsageMark, (Clazz)visitorAccepter)) &&
125
(visitorInfo == null ||
126                !(visitorInfo instanceof ShortestUsageMark) ||
127                !((ShortestUsageMark)visitorInfo).isCertain() ||
128                currentUsageMark.isShorter((ShortestUsageMark)visitorInfo));
129     }
130
131
132     protected boolean isUsed(VisitorAccepter visitorAccepter)
133     {
134         Object JavaDoc visitorInfo = visitorAccepter.getVisitorInfo();
135
136         return visitorInfo != null &&
137                visitorInfo instanceof ShortestUsageMark &&
138                ((ShortestUsageMark)visitorInfo).isCertain();
139     }
140
141
142     protected void markAsPossiblyUsed(VisitorAccepter visitorAccepter)
143     {
144         visitorAccepter.setVisitorInfo(new ShortestUsageMark(currentUsageMark, false));
145     }
146
147
148     protected boolean shouldBeMarkedAsPossiblyUsed(VisitorAccepter visitorAccepter)
149     {
150         Object JavaDoc visitorInfo = visitorAccepter.getVisitorInfo();
151
152         return visitorInfo == null ||
153                !(visitorInfo instanceof ShortestUsageMark) ||
154                (!((ShortestUsageMark)visitorInfo).isCertain() &&
155                 currentUsageMark.isShorter((ShortestUsageMark)visitorInfo));
156     }
157
158
159     protected boolean isPossiblyUsed(VisitorAccepter visitorAccepter)
160     {
161         Object JavaDoc visitorInfo = visitorAccepter.getVisitorInfo();
162
163         return visitorInfo != null &&
164                visitorInfo instanceof ShortestUsageMark &&
165                !((ShortestUsageMark)visitorInfo).isCertain();
166     }
167
168
169     protected ShortestUsageMark getShortestUsageMark(VisitorAccepter visitorAccepter)
170     {
171         Object JavaDoc visitorInfo = visitorAccepter.getVisitorInfo();
172
173         return (ShortestUsageMark)visitorInfo;
174     }
175
176
177     // Small utility methods.
178

179     private boolean isCausedBy(ShortestUsageMark shortestUsageMark,
180                                Clazz clazz)
181     {
182         return recursiveCauseChecker.check(shortestUsageMark, clazz);
183     }
184
185
186     private class MyRecursiveCauseChecker implements ClassVisitor, MemberVisitor
187     {
188         private Clazz checkClass;
189         private boolean isRecursing;
190
191
192         public boolean check(ShortestUsageMark shortestUsageMark,
193                              Clazz clazz)
194         {
195             checkClass = clazz;
196             isRecursing = false;
197
198             shortestUsageMark.acceptClassVisitor(this);
199             shortestUsageMark.acceptMethodVisitor(this);
200
201             return isRecursing;
202         }
203
204         // Implementations for ClassVisitor.
205

206         public void visitProgramClass(ProgramClass programClass)
207         {
208             checkCause(programClass);
209         }
210
211
212         public void visitLibraryClass(LibraryClass libraryClass)
213         {
214             checkCause(libraryClass);
215         }
216
217
218         // Implementations for MemberVisitor.
219

220         public void visitProgramField(ProgramClass programClass, ProgramField programField)
221         {
222             checkCause(programField);
223         }
224
225
226         public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
227         {
228             checkCause(programMethod);
229         }
230
231
232         public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
233         {
234              checkCause(libraryField);
235        }
236
237
238         public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
239         {
240             checkCause(libraryMethod);
241         }
242
243
244         // Small utility methods.
245

246         private void checkCause(VisitorAccepter visitorAccepter)
247         {
248             if (ShortestUsageMarker.this.isUsed(visitorAccepter))
249             {
250                 ShortestUsageMark shortestUsageMark = ShortestUsageMarker.this.getShortestUsageMark(visitorAccepter);
251
252                 // Check the class of this mark, if any
253
isRecursing = shortestUsageMark.isCausedBy(checkClass);
254
255                 // Check the causing class or method, if still necessary.
256
if (!isRecursing)
257                 {
258                     shortestUsageMark.acceptClassVisitor(this);
259                     shortestUsageMark.acceptMethodVisitor(this);
260                 }
261             }
262         }
263     }
264 }
265
Popular Tags