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.optimize.info;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.constant.*;
25 import proguard.classfile.constant.visitor.ConstantVisitor;
26 import proguard.classfile.util.SimplifiedVisitor;
27 import proguard.classfile.visitor.*;
28 
29 /**
30  * This ConstantVisitor marks all classes that refer to package visible classes
31  * or class members.
32  *
33  * @author Eric Lafortune
34  */
35 public class PackageVisibleMemberInvokingClassMarker
36 extends      SimplifiedVisitor
37 implements   ConstantVisitor,
38              ClassVisitor,
39              MemberVisitor
40 {
41     private Clazz referencingClass;
42 
43 
44     // Implementations for ConstantVisitor.
45 
visitAnyConstant(Clazz clazz, Constant constant)46     public void visitAnyConstant(Clazz clazz, Constant constant) {}
47 
48 
visitStringConstant(Clazz clazz, StringConstant stringConstant)49     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
50     {
51         // Check the referenced class and class member, if any.
52         if (stringConstant.referencedClass != clazz)
53         {
54             referencingClass = clazz;
55 
56             stringConstant.referencedClassAccept(this);
57             stringConstant.referencedMemberAccept(this);
58         }
59     }
60 
61 
visitAnyRefConstant(Clazz clazz, RefConstant refConstant)62     public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
63     {
64         // Check the referenced class and class member.
65         if (refConstant.referencedClass != clazz)
66         {
67             referencingClass = clazz;
68 
69             refConstant.referencedClassAccept(this);
70             refConstant.referencedMemberAccept(this);
71         }
72     }
73 
74 
visitClassConstant(Clazz clazz, ClassConstant classConstant)75     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
76     {
77         // Check the referenced class.
78         if (classConstant.referencedClass != clazz)
79         {
80             referencingClass = clazz;
81 
82             classConstant.referencedClassAccept(this);
83         }
84     }
85 
86 
87     // Implementations for ClassVisitor.
88 
visitAnyClass(Clazz clazz)89     public void visitAnyClass(Clazz clazz)
90     {
91         if ((clazz.getAccessFlags() &
92              ClassConstants.ACC_PUBLIC) == 0)
93         {
94             setInvokesPackageVisibleMembers(referencingClass);
95         }
96     }
97 
98 
99     // Implementations for MemberVisitor.
100 
visitAnyMember(Clazz clazz, Member member)101     public void visitAnyMember(Clazz clazz, Member member)
102     {
103         if ((member.getAccessFlags() &
104              (ClassConstants.ACC_PUBLIC |
105               ClassConstants.ACC_PRIVATE)) == 0)
106         {
107             setInvokesPackageVisibleMembers(referencingClass);
108         }
109     }
110 
111 
112     // Small utility methods.
113 
setInvokesPackageVisibleMembers(Clazz clazz)114     private static void setInvokesPackageVisibleMembers(Clazz clazz)
115     {
116         ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
117         if (info != null)
118         {
119             info.setInvokesPackageVisibleMembers();
120         }
121     }
122 
123 
invokesPackageVisibleMembers(Clazz clazz)124     public static boolean invokesPackageVisibleMembers(Clazz clazz)
125     {
126         ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
127         return info == null || info.invokesPackageVisibleMembers();
128     }
129 }