1b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang/*
2b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *             of Java bytecode.
4b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
5b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
7b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This program is free software; you can redistribute it and/or modify it
8b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * under the terms of the GNU General Public License as published by the Free
9b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Software Foundation; either version 2 of the License, or (at your option)
10b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * any later version.
11b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
12b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This program is distributed in the hope that it will be useful, but WITHOUT
13b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * more details.
16b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
17b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * You should have received a copy of the GNU General Public License along
18b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * with this program; if not, write to the Free Software Foundation, Inc.,
19b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */
21b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangpackage proguard;
22b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
23b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.ClassPool;
24b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.attribute.visitor.AllAttributeVisitor;
25b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.constant.visitor.AllConstantVisitor;
26b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.instruction.visitor.AllInstructionVisitor;
27b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.util.*;
28b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.visitor.*;
29b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.optimize.*;
30b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.util.*;
31b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
32b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport java.io.*;
33b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport java.util.*;
34b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
35b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang/**
36b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This class prints out the seeds specified by keep options.
37b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
38b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * @author Eric Lafortune
39b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */
40b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangpublic class SeedPrinter
41b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang{
42b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    private final PrintStream ps;
43b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
44b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
45b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    /**
46b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     * Creates a new ConfigurationWriter for the given PrintStream.
47b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     */
48b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public SeedPrinter(PrintStream ps) throws IOException
49b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
50b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        this.ps = ps;
51b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
52b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
53b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
54b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    /**
55b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     * Prints out the seeds for the classes in the given program class pool.
56b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     * @param configuration the configuration containing the keep options.
57b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     * @throws IOException if an IO error occurs while writing the configuration.
58b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     */
59b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public void write(Configuration configuration,
60b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                      ClassPool     programClassPool,
61b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                      ClassPool     libraryClassPool) throws IOException
62b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
63b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Check if we have at least some keep commands.
64b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (configuration.keep == null)
65b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
66b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            throw new IOException("You have to specify '-keep' options for the shrinking step.");
67b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
68b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
69b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Clean up any old visitor info.
70b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        programClassPool.classesAccept(new ClassCleaner());
71b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        libraryClassPool.classesAccept(new ClassCleaner());
72b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
73b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Create a visitor for printing out the seeds. We're  printing out
74b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // the program elements that are preserved against shrinking,
75b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // optimization, or obfuscation.
76b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        KeepMarker keepMarker = new KeepMarker();
77b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        ClassPoolVisitor classPoolvisitor =
78b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
79b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                                    keepMarker,
80b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                                    keepMarker,
81b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                                    true,
82b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                                    true,
83b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                                    true);
84b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Mark the seeds.
85b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        programClassPool.accept(classPoolvisitor);
86b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        libraryClassPool.accept(classPoolvisitor);
87b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
88b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Print out the seeds.
89b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        SimpleClassPrinter printer = new SimpleClassPrinter(false, ps);
90b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        programClassPool.classesAcceptAlphabetically(new MultiClassVisitor(
91b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            new ClassVisitor[]
92b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
93b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                new KeptClassFilter(printer),
94b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                new AllMemberVisitor(new KeptMemberFilter(printer))
95b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }));
96b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
97b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang}