• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package proguard.shrink;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.visitor.*;
25 
26 
27 /**
28  * This class can be used as a mark when keeping classes, class members, and
29  * other elements. It can be certain or preliminary. It also contains additional
30  * information about the reasons why an element is being kept.
31  *
32  * @see ClassShrinker
33  *
34  * @author Eric Lafortune
35  */
36 final class ShortestUsageMark
37 {
38     private final boolean certain;
39     private final String  reason;
40     private final int     depth;
41     private       Clazz   clazz;
42     private       Member  member;
43 
44 
45     /**
46      * Creates a new certain ShortestUsageMark.
47      * @param reason the reason for this mark.
48      */
ShortestUsageMark(String reason)49     public ShortestUsageMark(String reason)
50     {
51         this.certain = true;
52         this.reason  = reason;
53         this.depth   = 0;
54     }
55 
56 
57     /**
58      * Creates a new certain ShortestUsageMark.
59      * @param previousUsageMark the previous mark to which this one is linked.
60      * @param reason            the reason for this mark.
61      * @param clazz             the class causing this mark.
62      */
ShortestUsageMark(ShortestUsageMark previousUsageMark, String reason, int cost, Clazz clazz)63     public ShortestUsageMark(ShortestUsageMark previousUsageMark,
64                              String            reason,
65                              int               cost,
66                              Clazz             clazz)
67     {
68         this(previousUsageMark, reason, cost, clazz, null);
69     }
70 
71 
72     /**
73      * Creates a new certain ShortestUsageMark.
74      * @param previousUsageMark the previous mark to which this one is linked.
75      * @param reason            the reason for this mark.
76      * @param clazz             the class causing this mark.
77      * @param member            the member in the above class causing this mark.
78      * @param cost              the added cost of following this path.
79      */
ShortestUsageMark(ShortestUsageMark previousUsageMark, String reason, int cost, Clazz clazz, Member member)80     public ShortestUsageMark(ShortestUsageMark previousUsageMark,
81                              String            reason,
82                              int               cost,
83                              Clazz             clazz,
84                              Member            member)
85     {
86         this.certain = true;
87         this.reason  = reason;
88         this.depth   = previousUsageMark.depth + cost;
89         this.clazz   = clazz;
90         this.member  = member;
91     }
92 
93 
94     /**
95      * Creates a new ShortestUsageMark, based on another mark.
96      * @param otherUsageMark the other mark, whose properties will be copied.
97      * @param certain        specifies whether this is a certain mark.
98      */
ShortestUsageMark(ShortestUsageMark otherUsageMark, boolean certain)99     public ShortestUsageMark(ShortestUsageMark otherUsageMark,
100                              boolean           certain)
101     {
102         this.certain = certain;
103         this.reason  = otherUsageMark.reason;
104         this.depth   = otherUsageMark.depth;
105         this.clazz   = otherUsageMark.clazz;
106         this.member  = otherUsageMark.member;
107     }
108 
109 
110     /**
111      * Returns whether this is a certain mark.
112      */
isCertain()113     public boolean isCertain()
114     {
115         return certain;
116     }
117 
118 
119     /**
120      * Returns the reason for this mark.
121      */
getReason()122     public String getReason()
123     {
124         return reason;
125     }
126 
127 
128     /**
129      * Returns whether this mark has a shorter chain of reasons than the
130      * given mark.
131      */
isShorter(ShortestUsageMark otherUsageMark)132     public boolean isShorter(ShortestUsageMark otherUsageMark)
133     {
134         return this.depth < otherUsageMark.depth;
135     }
136 
137 
138     /**
139      * Returns whether this is mark is caused by the given class.
140      */
isCausedBy(Clazz clazz)141     public boolean isCausedBy(Clazz clazz)
142     {
143         return clazz.equals(this.clazz);
144     }
145 
146 
147     /**
148      * Applies the given class visitor to this mark's class, if any,
149      * and if this mark doesn't have a member.
150      */
acceptClassVisitor(ClassVisitor classVisitor)151     public void acceptClassVisitor(ClassVisitor classVisitor)
152     {
153         if (clazz  != null &&
154             member == null)
155         {
156             clazz.accept(classVisitor);
157         }
158     }
159 
160 
161     /**
162      * Applies the given class visitor to this mark's member, if any.
163      */
acceptMemberVisitor(MemberVisitor memberVisitor)164     public void acceptMemberVisitor(MemberVisitor memberVisitor)
165     {
166         if (clazz  != null &&
167             member != null)
168         {
169             member.accept(clazz, memberVisitor);
170         }
171     }
172 
173 
174     // Implementations for Object.
175 
toString()176     public String toString()
177     {
178         return "certain=" + certain + ", depth="+depth+": " +
179                reason +
180                (clazz      != null ? clazz.getName() : "(none)") + ": " +
181                (member     != null ? member.getName(clazz) : "(none)");
182     }
183 }
184