~ubuntu-branches/ubuntu/wily/proguard/wily-proposed

1.1.4 by Sam Clegg
Import upstream version 4.1
1
/*
2
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3
 *             of Java bytecode.
1.2.1 by Sam Clegg
Import upstream version 4.2
4
 *
1.2.7 by komal Sukhani
Import upstream version 5.2.1
5
 * Copyright (c) 2002-2015 Eric Lafortune @ GuardSquare
1.1.1 by Sam Clegg
Import upstream version 3.4
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.*;
1.2.5 by Emmanuel Bourg
Import upstream version 4.11
24
import proguard.classfile.attribute.*;
25
import proguard.classfile.attribute.visitor.AttributeVisitor;
26
import proguard.classfile.util.*;
1.1.1 by Sam Clegg
Import upstream version 3.4
27
import proguard.classfile.visitor.*;
28
1.1.4 by Sam Clegg
Import upstream version 4.1
29
import java.io.PrintStream;
1.1.1 by Sam Clegg
Import upstream version 3.4
30
31
32
/**
1.1.4 by Sam Clegg
Import upstream version 4.1
33
 * This ClassVisitor     and MemberVisitor prints out the reasons why
34
 * classes and class members have been marked as being used.
1.1.1 by Sam Clegg
Import upstream version 3.4
35
 *
36
 * @see UsageMarker
37
 *
38
 * @author Eric Lafortune
39
 */
40
public class ShortestUsagePrinter
1.2.5 by Emmanuel Bourg
Import upstream version 4.11
41
extends      SimplifiedVisitor
1.1.4 by Sam Clegg
Import upstream version 4.1
42
implements   ClassVisitor,
1.2.5 by Emmanuel Bourg
Import upstream version 4.11
43
             MemberVisitor,
44
             AttributeVisitor
1.1.1 by Sam Clegg
Import upstream version 3.4
45
{
1.1.4 by Sam Clegg
Import upstream version 4.1
46
    private final ShortestUsageMarker shortestUsageMarker;
47
    private final boolean             verbose;
48
    private final PrintStream         ps;
1.1.1 by Sam Clegg
Import upstream version 3.4
49
50
51
    /**
52
     * Creates a new UsagePrinter that prints verbosely to <code>System.out</code>.
53
     * @param shortestUsageMarker the usage marker that was used to mark the
54
     *                            classes and class members.
55
     */
56
    public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker)
57
    {
58
        this(shortestUsageMarker, true);
59
    }
60
61
62
    /**
63
     * Creates a new UsagePrinter that prints to the given stream.
64
     * @param shortestUsageMarker the usage marker that was used to mark the
65
     *                            classes and class members.
66
     * @param verbose             specifies whether the output should be verbose.
67
     */
68
    public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker,
69
                                boolean             verbose)
70
    {
71
        this(shortestUsageMarker, verbose, System.out);
72
    }
73
74
    /**
75
     * Creates a new UsagePrinter that prints to the given stream.
76
     * @param shortestUsageMarker the usage marker that was used to mark the
77
     *                            classes and class members.
78
     * @param verbose             specifies whether the output should be verbose.
79
     * @param printStream         the stream to which to print.
80
     */
81
    public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker,
82
                                boolean             verbose,
83
                                PrintStream         printStream)
84
    {
85
        this.shortestUsageMarker = shortestUsageMarker;
86
        this.verbose             = verbose;
87
        this.ps                  = printStream;
88
    }
89
90
1.1.4 by Sam Clegg
Import upstream version 4.1
91
    // Implementations for ClassVisitor.
1.1.1 by Sam Clegg
Import upstream version 3.4
92
1.1.4 by Sam Clegg
Import upstream version 4.1
93
    public void visitProgramClass(ProgramClass programClass)
1.1.1 by Sam Clegg
Import upstream version 3.4
94
    {
1.1.4 by Sam Clegg
Import upstream version 4.1
95
        // Print the name of this class.
96
        ps.println(ClassUtil.externalClassName(programClass.getName()));
1.1.1 by Sam Clegg
Import upstream version 3.4
97
1.1.4 by Sam Clegg
Import upstream version 4.1
98
        // Print the reason for keeping this class.
99
        printReason(programClass);
1.1.1 by Sam Clegg
Import upstream version 3.4
100
    }
101
102
1.1.4 by Sam Clegg
Import upstream version 4.1
103
    public void visitLibraryClass(LibraryClass libraryClass)
1.1.1 by Sam Clegg
Import upstream version 3.4
104
    {
1.1.4 by Sam Clegg
Import upstream version 4.1
105
        // Print the name of this class.
106
        ps.println(ClassUtil.externalClassName(libraryClass.getName()));
1.1.1 by Sam Clegg
Import upstream version 3.4
107
1.1.4 by Sam Clegg
Import upstream version 4.1
108
        // Print the reason for keeping this class.
1.1.1 by Sam Clegg
Import upstream version 3.4
109
        ps.println("  is a library class.\n");
110
    }
111
112
1.1.4 by Sam Clegg
Import upstream version 4.1
113
    // Implementations for MemberVisitor.
1.1.1 by Sam Clegg
Import upstream version 3.4
114
1.1.4 by Sam Clegg
Import upstream version 4.1
115
    public void visitProgramField(ProgramClass programClass, ProgramField programField)
1.1.1 by Sam Clegg
Import upstream version 3.4
116
    {
117
        // Print the name of this field.
1.1.4 by Sam Clegg
Import upstream version 4.1
118
        String name = programField.getName(programClass);
119
        String type = programField.getDescriptor(programClass);
1.1.1 by Sam Clegg
Import upstream version 3.4
120
1.1.4 by Sam Clegg
Import upstream version 4.1
121
        ps.println(ClassUtil.externalClassName(programClass.getName()) +
1.1.1 by Sam Clegg
Import upstream version 3.4
122
                   (verbose ?
123
                        ": " + ClassUtil.externalFullFieldDescription(0, name, type):
1.2.5 by Emmanuel Bourg
Import upstream version 4.11
124
                        "."  + name));
1.1.1 by Sam Clegg
Import upstream version 3.4
125
126
        // Print the reason for keeping this method.
1.1.4 by Sam Clegg
Import upstream version 4.1
127
        printReason(programField);
1.1.1 by Sam Clegg
Import upstream version 3.4
128
    }
129
130
1.1.4 by Sam Clegg
Import upstream version 4.1
131
    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
1.1.1 by Sam Clegg
Import upstream version 3.4
132
    {
133
        // Print the name of this method.
1.1.4 by Sam Clegg
Import upstream version 4.1
134
        String name = programMethod.getName(programClass);
135
        String type = programMethod.getDescriptor(programClass);
1.1.1 by Sam Clegg
Import upstream version 3.4
136
1.2.5 by Emmanuel Bourg
Import upstream version 4.11
137
        ps.print(ClassUtil.externalClassName(programClass.getName()) +
138
                 (verbose ?
139
                      ": " + ClassUtil.externalFullMethodDescription(programClass.getName(), 0, name, type):
140
                      "."  + name));
141
        programMethod.attributesAccept(programClass, this);
142
        ps.println();
1.1.1 by Sam Clegg
Import upstream version 3.4
143
144
        // Print the reason for keeping this method.
1.1.4 by Sam Clegg
Import upstream version 4.1
145
        printReason(programMethod);
1.1.1 by Sam Clegg
Import upstream version 3.4
146
    }
147
148
1.1.4 by Sam Clegg
Import upstream version 4.1
149
    public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
1.1.1 by Sam Clegg
Import upstream version 3.4
150
    {
151
        // Print the name of this field.
1.1.4 by Sam Clegg
Import upstream version 4.1
152
        String name = libraryField.getName(libraryClass);
153
        String type = libraryField.getDescriptor(libraryClass);
1.1.1 by Sam Clegg
Import upstream version 3.4
154
1.1.4 by Sam Clegg
Import upstream version 4.1
155
        ps.println(ClassUtil.externalClassName(libraryClass.getName()) +
1.1.1 by Sam Clegg
Import upstream version 3.4
156
                   (verbose ?
157
                        ": " + ClassUtil.externalFullFieldDescription(0, name, type):
158
                        "."  + name));
159
160
        // Print the reason for keeping this field.
161
        ps.println("  is a library field.\n");
162
    }
163
164
1.1.4 by Sam Clegg
Import upstream version 4.1
165
    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
1.1.1 by Sam Clegg
Import upstream version 3.4
166
    {
167
        // Print the name of this method.
1.1.4 by Sam Clegg
Import upstream version 4.1
168
        String name = libraryMethod.getName(libraryClass);
169
        String type = libraryMethod.getDescriptor(libraryClass);
1.1.1 by Sam Clegg
Import upstream version 3.4
170
1.1.4 by Sam Clegg
Import upstream version 4.1
171
        ps.println(ClassUtil.externalClassName(libraryClass.getName()) +
1.1.1 by Sam Clegg
Import upstream version 3.4
172
                   (verbose ?
1.1.4 by Sam Clegg
Import upstream version 4.1
173
                        ": " + ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, name, type):
1.1.1 by Sam Clegg
Import upstream version 3.4
174
                        "."  + name));
175
176
        // Print the reason for keeping this method.
177
        ps.println("  is a library method.\n");
178
    }
179
180
1.2.5 by Emmanuel Bourg
Import upstream version 4.11
181
    // Implementations for AttributeVisitor.
182
183
    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
184
185
186
    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
187
    {
188
        codeAttribute.attributesAccept(clazz, method, this);
189
    }
190
191
192
    public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
193
    {
194
        ps.print(" (" +
195
                 lineNumberTableAttribute.getLowestLineNumber() + ":" +
196
                 lineNumberTableAttribute.getHighestLineNumber() + ")");
197
    }
198
199
1.1.1 by Sam Clegg
Import upstream version 3.4
200
    // Small utility methods.
201
202
    private void printReason(VisitorAccepter visitorAccepter)
203
    {
204
        if (shortestUsageMarker.isUsed(visitorAccepter))
205
        {
206
            ShortestUsageMark shortestUsageMark = shortestUsageMarker.getShortestUsageMark(visitorAccepter);
207
1.1.4 by Sam Clegg
Import upstream version 4.1
208
            // Print the reason for keeping this class.
1.1.1 by Sam Clegg
Import upstream version 3.4
209
            ps.print("  " + shortestUsageMark.getReason());
210
211
            // Print the class or method that is responsible, with its reasons.
1.1.4 by Sam Clegg
Import upstream version 4.1
212
            shortestUsageMark.acceptClassVisitor(this);
1.2.2 by Sam Clegg
Import upstream version 4.3
213
            shortestUsageMark.acceptMemberVisitor(this);
1.1.1 by Sam Clegg
Import upstream version 3.4
214
        }
215
        else
216
        {
217
            ps.println("  is not being kept.\n");
218
        }
219
    }
220
}