KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > shrink > ShortestUsagePrinter


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.util.*;
25 import proguard.classfile.visitor.*;
26
27 import java.io.*;
28
29
30 /**
31  * This ClassVisitor and MemberVisitor prints out the reasons why
32  * classes and class members have been marked as being used.
33  *
34  * @see UsageMarker
35  *
36  * @author Eric Lafortune
37  */

38 public class ShortestUsagePrinter
39 implements ClassVisitor,
40              MemberVisitor
41 {
42     private ShortestUsageMarker shortestUsageMarker;
43     private boolean verbose;
44     private PrintStream ps;
45
46
47     /**
48      * Creates a new UsagePrinter that prints verbosely to <code>System.out</code>.
49      * @param shortestUsageMarker the usage marker that was used to mark the
50      * classes and class members.
51      */

52     public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker)
53     {
54         this(shortestUsageMarker, true);
55     }
56
57
58     /**
59      * Creates a new UsagePrinter that prints to the given stream.
60      * @param shortestUsageMarker the usage marker that was used to mark the
61      * classes and class members.
62      * @param verbose specifies whether the output should be verbose.
63      */

64     public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker,
65                                 boolean verbose)
66     {
67         this(shortestUsageMarker, verbose, System.out);
68     }
69
70     /**
71      * Creates a new UsagePrinter that prints to the given stream.
72      * @param shortestUsageMarker the usage marker that was used to mark the
73      * classes and class members.
74      * @param verbose specifies whether the output should be verbose.
75      * @param printStream the stream to which to print.
76      */

77     public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker,
78                                 boolean verbose,
79                                 PrintStream printStream)
80     {
81         this.shortestUsageMarker = shortestUsageMarker;
82         this.verbose = verbose;
83         this.ps = printStream;
84     }
85
86
87     // Implementations for ClassVisitor.
88

89     public void visitProgramClass(ProgramClass programClass)
90     {
91         // Print the name of this class.
92
ps.println(ClassUtil.externalClassName(programClass.getName()));
93
94         // Print the reason for keeping this class.
95
printReason(programClass);
96     }
97
98
99     public void visitLibraryClass(LibraryClass libraryClass)
100     {
101         // Print the name of this class.
102
ps.println(ClassUtil.externalClassName(libraryClass.getName()));
103
104         // Print the reason for keeping this class.
105
ps.println(" is a library class.\n");
106     }
107
108
109     // Implementations for MemberVisitor.
110

111     public void visitProgramField(ProgramClass programClass, ProgramField programField)
112     {
113         // Print the name of this field.
114
String JavaDoc name = programField.getName(programClass);
115         String JavaDoc type = programField.getDescriptor(programClass);
116
117         ps.println(ClassUtil.externalClassName(programClass.getName()) +
118                    (verbose ?
119                         ": " + ClassUtil.externalFullFieldDescription(0, name, type):
120                         "." + name) +
121                    lineNumberRange(programClass, programField));
122
123         // Print the reason for keeping this method.
124
printReason(programField);
125     }
126
127
128     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
129     {
130         // Print the name of this method.
131
String JavaDoc name = programMethod.getName(programClass);
132         String JavaDoc type = programMethod.getDescriptor(programClass);
133
134         ps.println(ClassUtil.externalClassName(programClass.getName()) +
135                    (verbose ?
136                         ": " + ClassUtil.externalFullMethodDescription(programClass.getName(), 0, name, type):
137                         "." + name) +
138                    lineNumberRange(programClass, programMethod));
139
140         // Print the reason for keeping this method.
141
printReason(programMethod);
142     }
143
144
145     public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
146     {
147         // Print the name of this field.
148
String JavaDoc name = libraryField.getName(libraryClass);
149         String JavaDoc type = libraryField.getDescriptor(libraryClass);
150
151         ps.println(ClassUtil.externalClassName(libraryClass.getName()) +
152                    (verbose ?
153                         ": " + ClassUtil.externalFullFieldDescription(0, name, type):
154                         "." + name));
155
156         // Print the reason for keeping this field.
157
ps.println(" is a library field.\n");
158     }
159
160
161     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
162     {
163         // Print the name of this method.
164
String JavaDoc name = libraryMethod.getName(libraryClass);
165         String JavaDoc type = libraryMethod.getDescriptor(libraryClass);
166
167         ps.println(ClassUtil.externalClassName(libraryClass.getName()) +
168                    (verbose ?
169                         ": " + ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, name, type):
170                         "." + name));
171
172         // Print the reason for keeping this method.
173
ps.println(" is a library method.\n");
174     }
175
176
177     // Small utility methods.
178

179     private void printReason(VisitorAccepter visitorAccepter)
180     {
181         if (shortestUsageMarker.isUsed(visitorAccepter))
182         {
183             ShortestUsageMark shortestUsageMark = shortestUsageMarker.getShortestUsageMark(visitorAccepter);
184
185             // Print the reason for keeping this class.
186
ps.print(" " + shortestUsageMark.getReason());
187
188             // Print the class or method that is responsible, with its reasons.
189
shortestUsageMark.acceptClassVisitor(this);
190             shortestUsageMark.acceptMethodVisitor(this);
191         }
192         else
193         {
194             ps.println(" is not being kept.\n");
195         }
196     }
197
198
199     /**
200      * Returns the line number range of the given class member, followed by a
201      * colon, or just an empty String if no range is available.
202      */

203     private static String JavaDoc lineNumberRange(ProgramClass programClass, ProgramMember programMember)
204     {
205         String JavaDoc range = programMember.getLineNumberRange(programClass);
206         return range != null ?
207             (" (" + range + ")") :
208             "";
209     }
210 }
211
Popular Tags