• 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.optimize.info;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.attribute.CodeAttribute;
25 import proguard.classfile.constant.*;
26 import proguard.classfile.constant.visitor.ConstantVisitor;
27 import proguard.classfile.instruction.*;
28 import proguard.classfile.instruction.visitor.InstructionVisitor;
29 import proguard.classfile.util.SimplifiedVisitor;
30 import proguard.classfile.visitor.*;
31 
32 /**
33  * This InstructionVisitor marks the types of class accesses and class member
34  * accesses of the methods whose instructions it visits.
35  *
36  * @author Eric Lafortune
37  */
38 public class AccessMethodMarker
39 extends      SimplifiedVisitor
40 implements   InstructionVisitor,
41              ConstantVisitor,
42              ClassVisitor,
43              MemberVisitor
44 {
45     private Method invokingMethod;
46 
47 
48     // Implementations for InstructionVisitor.
49 
visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)50     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
51 
52 
visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)53     public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
54     {
55         invokingMethod = method;
56 
57         clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
58     }
59 
60 
61     // Implementations for ConstantVisitor.
62 
visitAnyConstant(Clazz clazz, Constant constant)63     public void visitAnyConstant(Clazz clazz, Constant constant) {}
64 
65 
visitStringConstant(Clazz clazz, StringConstant stringConstant)66     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
67     {
68         // Check the referenced class or class member, if any.
69        stringConstant.referencedClassAccept(this);
70        stringConstant.referencedMemberAccept(this);
71     }
72 
73 
visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)74     public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
75     {
76         // Check the bootstrap method.
77         invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this);
78     }
79 
80 
visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)81     public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
82     {
83         // Check the method reference.
84         clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
85     }
86 
87 
visitAnyRefConstant(Clazz clazz, RefConstant refConstant)88     public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
89     {
90         // Check the referenced class.
91         clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
92 
93         // Check the referenced class member itself.
94         refConstant.referencedClassAccept(this);
95         refConstant.referencedMemberAccept(this);
96     }
97 
98 
visitClassConstant(Clazz clazz, ClassConstant classConstant)99     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
100     {
101         // Check the referenced class.
102        classConstant.referencedClassAccept(this);
103     }
104 
105 
106     // Implementations for ClassVisitor.
107 
visitAnyClass(Clazz clazz)108     public void visitAnyClass(Clazz clazz)
109     {
110         int accessFlags = clazz.getAccessFlags();
111 
112         if ((accessFlags & ClassConstants.ACC_PUBLIC) == 0)
113         {
114             setAccessesPackageCode(invokingMethod);
115         }
116     }
117 
118 
119     // Implementations for MemberVisitor.
120 
visitAnyMember(Clazz clazz, Member member)121     public void visitAnyMember(Clazz clazz, Member member)
122     {
123         int accessFlags = member.getAccessFlags();
124 
125         if      ((accessFlags & ClassConstants.ACC_PRIVATE)   != 0)
126         {
127             setAccessesPrivateCode(invokingMethod);
128         }
129         else if ((accessFlags & ClassConstants.ACC_PROTECTED) != 0)
130         {
131             setAccessesProtectedCode(invokingMethod);
132         }
133         else if ((accessFlags & ClassConstants.ACC_PUBLIC)    == 0)
134         {
135             setAccessesPackageCode(invokingMethod);
136         }
137     }
138 
139 
140     // Small utility methods.
141 
setAccessesPrivateCode(Method method)142     private static void setAccessesPrivateCode(Method method)
143     {
144         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
145         if (info != null)
146         {
147             info.setAccessesPrivateCode();
148         }
149     }
150 
151 
152     /**
153      * Returns whether the given method accesses private class members.
154      */
accessesPrivateCode(Method method)155     public static boolean accessesPrivateCode(Method method)
156     {
157         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
158         return info == null || info.accessesPrivateCode();
159     }
160 
161 
setAccessesPackageCode(Method method)162     private static void setAccessesPackageCode(Method method)
163     {
164         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
165         if (info != null)
166         {
167             info.setAccessesPackageCode();
168         }
169     }
170 
171 
172     /**
173      * Returns whether the given method accesses package visible classes or class
174      * members.
175      */
accessesPackageCode(Method method)176     public static boolean accessesPackageCode(Method method)
177     {
178         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
179         return info == null || info.accessesPackageCode();
180     }
181 
182 
setAccessesProtectedCode(Method method)183     private static void setAccessesProtectedCode(Method method)
184     {
185         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
186         if (info != null)
187         {
188             info.setAccessesProtectedCode();
189         }
190     }
191 
192 
193     /**
194      * Returns whether the given method accesses protected class members.
195      */
accessesProtectedCode(Method method)196     public static boolean accessesProtectedCode(Method method)
197     {
198         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
199         return info == null || info.accessesProtectedCode();
200     }
201 }
202