1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2014 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 
22 package proguard.shrink;
23 
24 import proguard.classfile.*;
25 import proguard.classfile.attribute.*;
26 import proguard.classfile.attribute.visitor.AttributeVisitor;
27 import proguard.classfile.constant.Constant;
28 import proguard.classfile.constant.visitor.ConstantVisitor;
29 import proguard.classfile.util.SimplifiedVisitor;
30 import proguard.classfile.visitor.ClassVisitor;
31 
32 /**
33  * This AttributeVisitor recursively marks all Signature attributes that it
34  * visits and that point to used classes.
35  *
36  * @see UsageMarker
37  *
38  * @author Eric Lafortune
39  */
40 public class SignatureUsageMarker
41 extends      SimplifiedVisitor
42 implements   AttributeVisitor,
43              ClassVisitor,
44              ConstantVisitor
45 {
46     private final UsageMarker usageMarker;
47 
48     // Fields acting as a return parameters for several methods.
49     private boolean attributeUsed;
50 
51 
52     /**
53      * Creates a new SignatureUsageMarker.
54      * @param usageMarker the usage marker that is used to mark the classes
55      *                    and class members.
56      */
SignatureUsageMarker(UsageMarker usageMarker)57     public SignatureUsageMarker(UsageMarker usageMarker)
58     {
59         this.usageMarker = usageMarker;
60     }
61 
62 
63     // Implementations for AttributeVisitor.
64 
visitAnyAttribute(Clazz clazz, Attribute attribute)65     public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
66 
67 
visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)68     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
69     {
70         // Only keep the signature if any of its classes are used.
71         attributeUsed = false;
72         signatureAttribute.referencedClassesAccept(this);
73 
74         if (attributeUsed)
75         {
76             // We got a positive used flag, so the signature is useful.
77             usageMarker.markAsUsed(signatureAttribute);
78 
79             markConstant(clazz, signatureAttribute.u2attributeNameIndex);
80             markConstant(clazz, signatureAttribute.u2signatureIndex);
81         }
82     }
83 
84 
85     // Implementations for ClassVisitor.
86 
visitLibraryClass(LibraryClass libraryClass)87     public void visitLibraryClass(LibraryClass libraryClass)
88     {
89         attributeUsed = true;
90     }
91 
92 
visitProgramClass(ProgramClass programClass)93     public void visitProgramClass(ProgramClass programClass)
94     {
95         // Don't keep the signature if one of its classes is not used.
96         if (usageMarker.isUsed(programClass))
97         {
98             attributeUsed = true;
99         }
100     }
101 
102 
103     // Implementations for ConstantVisitor.
104 
visitAnyConstant(Clazz clazz, Constant constant)105     public void visitAnyConstant(Clazz clazz, Constant constant)
106     {
107         usageMarker.markAsUsed(constant);
108     }
109 
110 
111     // Small utility methods.
112 
113     /**
114      * Marks the given constant pool entry of the given class.
115      */
markConstant(Clazz clazz, int index)116     private void markConstant(Clazz clazz, int index)
117     {
118          clazz.constantPoolEntryAccept(index, this);
119     }
120 }
121