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.classfile.util;
22 
23 import proguard.classfile.ClassConstants;
24 
25 
26 /**
27  * Utility methods for working with access flags. For convenience, this class
28  * defines access levels, in ascending order: <code>PRIVATE</code>,
29  * <code>PACKAGE_VISIBLE</code>, <code>PROTECTED</code>, and <code>PUBLIC</code>.
30  *
31  * @author Eric Lafortune
32  */
33 public class AccessUtil
34 {
35     public static final int PRIVATE         = 0;
36     public static final int PACKAGE_VISIBLE = 1;
37     public static final int PROTECTED       = 2;
38     public static final int PUBLIC          = 3;
39 
40 
41     // The mask of access flags.
42     private static final int ACCESS_MASK =
43         ClassConstants.ACC_PUBLIC  |
44         ClassConstants.ACC_PRIVATE |
45         ClassConstants.ACC_PROTECTED;
46 
47 
48     /**
49      * Returns the corresponding access level of the given access flags.
50      * @param accessFlags the internal access flags.
51      * @return the corresponding access level: <code>PRIVATE</code>,
52      *         <code>PACKAGE_VISIBLE</code>, <code>PROTECTED</code>, or
53      *         <code>PUBLIC</code>.
54      */
accessLevel(int accessFlags)55     public static int accessLevel(int accessFlags)
56     {
57         switch (accessFlags & ACCESS_MASK)
58         {
59             case ClassConstants.ACC_PRIVATE:   return PRIVATE;
60             default:                           return PACKAGE_VISIBLE;
61             case ClassConstants.ACC_PROTECTED: return PROTECTED;
62             case ClassConstants.ACC_PUBLIC:    return PUBLIC;
63         }
64     }
65 
66 
67     /**
68      * Returns the corresponding access flags of the given access level.
69      * @param accessLevel the access level: <code>PRIVATE</code>,
70      *                    <code>PACKAGE_VISIBLE</code>, <code>PROTECTED</code>,
71      *                    or <code>PUBLIC</code>.
72      * @return the corresponding internal access flags,  the internal access
73      *         flags as a logical bit mask of <code>INTERNAL_ACC_PRIVATE</code>,
74      *         <code>INTERNAL_ACC_PROTECTED</code>, and
75      *         <code>INTERNAL_ACC_PUBLIC</code>.
76      */
accessFlags(int accessLevel)77     public static int accessFlags(int accessLevel)
78     {
79         switch (accessLevel)
80         {
81             case PRIVATE:   return ClassConstants.ACC_PRIVATE;
82             default:        return 0;
83             case PROTECTED: return ClassConstants.ACC_PROTECTED;
84             case PUBLIC:    return ClassConstants.ACC_PUBLIC;
85         }
86     }
87 
88 
89     /**
90      * Replaces the access part of the given access flags.
91      * @param accessFlags the internal access flags.
92      * @param accessFlags the new internal access flags.
93      */
replaceAccessFlags(int accessFlags, int newAccessFlags)94     public static int replaceAccessFlags(int accessFlags, int newAccessFlags)
95     {
96         // A private class member should not be explicitly final.
97         if (newAccessFlags == ClassConstants.ACC_PRIVATE)
98         {
99             accessFlags &= ~ClassConstants.ACC_FINAL;
100         }
101 
102         return (accessFlags    & ~ACCESS_MASK) |
103                (newAccessFlags &  ACCESS_MASK);
104     }
105 }
106