1 /*
2  * Copyright 2014 - 2020 Rafael Winterhalter
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.bytebuddy.description.modifier;
17
18 import net.bytebuddy.jar.asm.Opcodes;
19
20 /**
21  * Describes a type's, field's or a method's visibility.
22  */

23 public enum Visibility implements ModifierContributor.ForType, ModifierContributor.ForMethod, ModifierContributor.ForField {
24
25     /**
26      * A modifier contributor for {@code public} visibility.
27      */

28     PUBLIC(Opcodes.ACC_PUBLIC),
29
30     /**
31      * Modifier for a package-private visibility. (This is the default modifier.)
32      */

33     PACKAGE_PRIVATE(EMPTY_MASK),
34
35     /**
36      * A modifier contributor for {@code protected} visibility.
37      */

38     PROTECTED(Opcodes.ACC_PROTECTED),
39
40     /**
41      * A modifier contributor for {@code private} visibility.
42      */

43     PRIVATE(Opcodes.ACC_PRIVATE);
44
45     /**
46      * The mask the modifier contributor.
47      */

48     private final int mask;
49
50     /**
51      * Creates a new visibility representation.
52      *
53      * @param mask The modifier mask of this instance.
54      */

55     Visibility(int mask) {
56         this.mask = mask;
57     }
58
59     /**
60      * {@inheritDoc}
61      */

62     public int getMask() {
63         return mask;
64     }
65
66     /**
67      * {@inheritDoc}
68      */

69     public int getRange() {
70         return Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE;
71     }
72
73     /**
74      * {@inheritDoc}
75      */

76     public boolean isDefault() {
77         return this == PACKAGE_PRIVATE;
78     }
79
80     /**
81      * Returns {@code trueif this instance describes {@code public} visibility.
82      *
83      * @return {@code trueif this instance describes {@code public} visibility.
84      */

85     public boolean isPublic() {
86         return (mask & Opcodes.ACC_PUBLIC) != 0;
87     }
88
89     /**
90      * Returns {@code trueif this instance describes {@code protected} visibility.
91      *
92      * @return {@code trueif this instance describes {@code protected} visibility.
93      */

94     public boolean isProtected() {
95         return (mask & Opcodes.ACC_PROTECTED) != 0;
96     }
97
98     /**
99      * Returns {@code trueif this instance describes package-private visibility.
100      *
101      * @return {@code trueif this instance describes package-private visibility.
102      */

103     public boolean isPackagePrivate() {
104         return !(isPublic() || isPrivate() || isProtected());
105     }
106
107     /**
108      * Returns {@code trueif this instance describes {@code private} visibility.
109      *
110      * @return {@code trueif this instance describes {@code private} visibility.
111      */

112     public boolean isPrivate() {
113         return (mask & Opcodes.ACC_PRIVATE) != 0;
114     }
115
116     /**
117      * Expands the visibility to be at least as high as this visibility and the provided visibility.
118      *
119      * @param visibility A visibility to compare against.
120      * @return A visibility that is as least as high as this and the supplied visibility.
121      */

122     public Visibility expandTo(Visibility visibility) {
123         switch (visibility) {
124             case PUBLIC:
125                 return PUBLIC;
126             case PROTECTED:
127                 return this == PUBLIC
128                         ? PUBLIC
129                         : visibility;
130             case PACKAGE_PRIVATE:
131                 return this == PRIVATE
132                         ? PACKAGE_PRIVATE
133                         : this;
134             case PRIVATE:
135                 return this;
136             default:
137                 throw new IllegalStateException("Unexpected visibility: " + visibility);
138         }
139     }
140 }
141