001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This library is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This library is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
015: * for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this library; if not, write to the Free Software Foundation,
019: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.optimize.info;
022:
023: import proguard.classfile.*;
024: import proguard.classfile.attribute.CodeAttribute;
025: import proguard.classfile.constant.*;
026: import proguard.classfile.constant.visitor.ConstantVisitor;
027: import proguard.classfile.instruction.*;
028: import proguard.classfile.instruction.visitor.InstructionVisitor;
029: import proguard.classfile.util.SimplifiedVisitor;
030: import proguard.classfile.visitor.*;
031:
032: /**
033: * This InstructionVisitor marks the types of class accesses and class member
034: * accesses of the methods whose instructions it visits.
035: *
036: * @author Eric Lafortune
037: */
038: public class AccessMethodMarker extends SimplifiedVisitor implements
039: InstructionVisitor, ConstantVisitor, ClassVisitor,
040: MemberVisitor {
041: private Method invokingMethod;
042:
043: // Implementations for InstructionVisitor.
044:
045: public void visitAnyInstruction(Clazz clazz, Method method,
046: CodeAttribute codeAttribute, int offset,
047: Instruction instruction) {
048: }
049:
050: public void visitConstantInstruction(Clazz clazz, Method method,
051: CodeAttribute codeAttribute, int offset,
052: ConstantInstruction constantInstruction) {
053: invokingMethod = method;
054:
055: clazz.constantPoolEntryAccept(
056: constantInstruction.constantIndex, this );
057: }
058:
059: // Implementations for ConstantVisitor.
060:
061: public void visitAnyConstant(Clazz clazz, Constant constant) {
062: }
063:
064: public void visitStringConstant(Clazz clazz,
065: StringConstant stringConstant) {
066: // Check the referenced class or class member, if any.
067: stringConstant.referencedClassAccept(this );
068: stringConstant.referencedMemberAccept(this );
069: }
070:
071: public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) {
072: // Check the referenced class.
073: clazz.constantPoolEntryAccept(refConstant.u2classIndex, this );
074:
075: // Check the referenced class member itself.
076: refConstant.referencedClassAccept(this );
077: refConstant.referencedMemberAccept(this );
078: }
079:
080: public void visitClassConstant(Clazz clazz,
081: ClassConstant classConstant) {
082: // Check the referenced class.
083: classConstant.referencedClassAccept(this );
084: }
085:
086: // Implementations for ClassVisitor.
087:
088: public void visitAnyClass(Clazz clazz) {
089: int accessFlags = clazz.getAccessFlags();
090:
091: if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) == 0) {
092: setAccessesPackageCode(invokingMethod);
093: }
094: }
095:
096: // Implementations for MemberVisitor.
097:
098: public void visitAnyMember(Clazz clazz, Member member) {
099: int accessFlags = member.getAccessFlags();
100:
101: if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0) {
102: setAccessesPrivateCode(invokingMethod);
103: } else if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0) {
104: setAccessesProtectedCode(invokingMethod);
105: } else if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) == 0) {
106: setAccessesPackageCode(invokingMethod);
107: }
108: }
109:
110: // Small utility methods.
111:
112: private static void setAccessesPrivateCode(Method method) {
113: MethodOptimizationInfo info = MethodOptimizationInfo
114: .getMethodOptimizationInfo(method);
115: if (info != null) {
116: info.setAccessesPrivateCode();
117: }
118: }
119:
120: /**
121: * Returns whether the given method accesses private class members.
122: */
123: public static boolean accessesPrivateCode(Method method) {
124: MethodOptimizationInfo info = MethodOptimizationInfo
125: .getMethodOptimizationInfo(method);
126: return info == null || info.accessesPrivateCode();
127: }
128:
129: private static void setAccessesPackageCode(Method method) {
130: MethodOptimizationInfo info = MethodOptimizationInfo
131: .getMethodOptimizationInfo(method);
132: if (info != null) {
133: info.setAccessesPackageCode();
134: }
135: }
136:
137: /**
138: * Returns whether the given method accesses package visible classes or class
139: * members.
140: */
141: public static boolean accessesPackageCode(Method method) {
142: MethodOptimizationInfo info = MethodOptimizationInfo
143: .getMethodOptimizationInfo(method);
144: return info == null || info.accessesPackageCode();
145: }
146:
147: private static void setAccessesProtectedCode(Method method) {
148: MethodOptimizationInfo info = MethodOptimizationInfo
149: .getMethodOptimizationInfo(method);
150: if (info != null) {
151: info.setAccessesProtectedCode();
152: }
153: }
154:
155: /**
156: * Returns whether the given method accesses protected class members.
157: */
158: public static boolean accessesProtectedCode(Method method) {
159: MethodOptimizationInfo info = MethodOptimizationInfo
160: .getMethodOptimizationInfo(method);
161: return info == null || info.accessesProtectedCode();
162: }
163: }
|