1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
59f606f95f03a75961498803e24bee6799a7c0885Ying Wang * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it
8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free
9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option)
10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version.
11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT
13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details.
16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along
18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc.,
19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.shrink;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.*;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This ClassVisitor and MemberVisitor recursively marks all classes
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * and class elements that are being used. For each element, it finds the
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * shortest chain of dependencies.
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see ClassShrinker
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class ShortestUsageMarker extends UsageMarker
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private static final ShortestUsageMark INITIAL_MARK =
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new ShortestUsageMark("is kept by a directive in the configuration.\n\n");
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // A field acting as a parameter to the visitor methods.
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private ShortestUsageMark currentUsageMark = INITIAL_MARK;
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // A utility object to check for recursive causes.
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final MyRecursiveCauseChecker recursiveCauseChecker = new MyRecursiveCauseChecker();
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Overriding implementations for UsageMarker.
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void markProgramClassBody(ProgramClass programClass)
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ShortestUsageMark previousUsageMark = currentUsageMark;
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programClass),
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 "is extended by   ",
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 10000,
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 programClass);
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        super.markProgramClassBody(programClass);
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = previousUsageMark;
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void markProgramFieldBody(ProgramClass programClass, ProgramField programField)
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ShortestUsageMark previousUsageMark = currentUsageMark;
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programField),
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 "is referenced by ",
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 1,
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 programClass,
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 programField);
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        super.markProgramFieldBody(programClass, programField);
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = previousUsageMark;
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void markProgramMethodBody(ProgramClass programClass, ProgramMethod programMethod)
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ShortestUsageMark previousUsageMark = currentUsageMark;
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = new ShortestUsageMark(getShortestUsageMark(programMethod),
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 "is invoked by    ",
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 1,
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 programClass,
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 programMethod);
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        super.markProgramMethodBody(programClass, programMethod);
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = previousUsageMark;
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void markMethodHierarchy(Clazz clazz, Method method)
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ShortestUsageMark previousUsageMark = currentUsageMark;
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = new ShortestUsageMark(getShortestUsageMark(method),
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 "implements       ",
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 100,
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 clazz,
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                 method);
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        super.markMethodHierarchy(clazz, method);
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        currentUsageMark = previousUsageMark;
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Small utility methods.
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void markAsUsed(VisitorAccepter visitorAccepter)
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Object visitorInfo = visitorAccepter.getVisitorInfo();
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ShortestUsageMark shortestUsageMark =
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            visitorInfo != null                           &&
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            visitorInfo instanceof ShortestUsageMark      &&
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            !((ShortestUsageMark)visitorInfo).isCertain() &&
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            !currentUsageMark.isShorter((ShortestUsageMark)visitorInfo) ?
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new ShortestUsageMark((ShortestUsageMark)visitorInfo, true):
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                currentUsageMark;
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        visitorAccepter.setVisitorInfo(shortestUsageMark);
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected boolean shouldBeMarkedAsUsed(VisitorAccepter visitorAccepter)
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Object visitorInfo = visitorAccepter.getVisitorInfo();
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return //!(visitorAccepter instanceof Clazz &&
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               //  isCausedBy(currentUsageMark, (Clazz)visitorAccepter)) &&
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               (visitorInfo == null                           ||
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               !(visitorInfo instanceof ShortestUsageMark)   ||
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               !((ShortestUsageMark)visitorInfo).isCertain() ||
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               currentUsageMark.isShorter((ShortestUsageMark)visitorInfo));
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected boolean isUsed(VisitorAccepter visitorAccepter)
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Object visitorInfo = visitorAccepter.getVisitorInfo();
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return visitorInfo != null                      &&
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               visitorInfo instanceof ShortestUsageMark &&
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               ((ShortestUsageMark)visitorInfo).isCertain();
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void markAsPossiblyUsed(VisitorAccepter visitorAccepter)
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        visitorAccepter.setVisitorInfo(new ShortestUsageMark(currentUsageMark, false));
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected boolean shouldBeMarkedAsPossiblyUsed(VisitorAccepter visitorAccepter)
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Object visitorInfo = visitorAccepter.getVisitorInfo();
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return visitorInfo == null                         ||
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               !(visitorInfo instanceof ShortestUsageMark) ||
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               (!((ShortestUsageMark)visitorInfo).isCertain() &&
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                currentUsageMark.isShorter((ShortestUsageMark)visitorInfo));
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected boolean isPossiblyUsed(VisitorAccepter visitorAccepter)
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Object visitorInfo = visitorAccepter.getVisitorInfo();
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return visitorInfo != null                      &&
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               visitorInfo instanceof ShortestUsageMark &&
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato               !((ShortestUsageMark)visitorInfo).isCertain();
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected ShortestUsageMark getShortestUsageMark(VisitorAccepter visitorAccepter)
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Object visitorInfo = visitorAccepter.getVisitorInfo();
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return (ShortestUsageMark)visitorInfo;
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Small utility methods.
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private boolean isCausedBy(ShortestUsageMark shortestUsageMark,
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               Clazz             clazz)
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return recursiveCauseChecker.check(shortestUsageMark, clazz);
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private class MyRecursiveCauseChecker implements ClassVisitor, MemberVisitor
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private Clazz   checkClass;
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private boolean isRecursing;
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public boolean check(ShortestUsageMark shortestUsageMark,
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                             Clazz             clazz)
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            checkClass  = clazz;
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            isRecursing = false;
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            shortestUsageMark.acceptClassVisitor(this);
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            shortestUsageMark.acceptMemberVisitor(this);
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return isRecursing;
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Implementations for ClassVisitor.
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public void visitProgramClass(ProgramClass programClass)
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            checkCause(programClass);
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public void visitLibraryClass(LibraryClass libraryClass)
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            checkCause(libraryClass);
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Implementations for MemberVisitor.
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public void visitProgramField(ProgramClass programClass, ProgramField programField)
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            checkCause(programField);
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            checkCause(programMethod);
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato             checkCause(libraryField);
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato       }
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            checkCause(libraryMethod);
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Small utility methods.
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private void checkCause(VisitorAccepter visitorAccepter)
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (ShortestUsageMarker.this.isUsed(visitorAccepter))
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                ShortestUsageMark shortestUsageMark = ShortestUsageMarker.this.getShortestUsageMark(visitorAccepter);
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Check the class of this mark, if any
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                isRecursing = shortestUsageMark.isCausedBy(checkClass);
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Check the causing class or method, if still necessary.
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (!isRecursing)
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    shortestUsageMark.acceptClassVisitor(this);
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    shortestUsageMark.acceptMemberVisitor(this);
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
278