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.matcher;
17
18 import net.bytebuddy.build.HashCodeAndEqualsPlugin;
19 import net.bytebuddy.description.ModifierReviewable;
20 import net.bytebuddy.jar.asm.Opcodes;
21
22 /**
23  * An element matcher that matches a byte code element by its modifiers.
24  *
25  * @param <T> The type of the matched entity.
26  */

27 @HashCodeAndEqualsPlugin.Enhance
28 public class ModifierMatcher<T extends ModifierReviewable> extends ElementMatcher.Junction.AbstractBase<T> {
29
30     /**
31      * The matching mode to apply by this modifier matcher.
32      */

33     private final Mode mode;
34
35     /**
36      * Creates a new element matcher that matches an element by its modifier.
37      *
38      * @param mode The match mode to apply to the matched element's modifier.
39      */

40     public ModifierMatcher(Mode mode) {
41         this.mode = mode;
42     }
43
44     /**
45      * {@inheritDoc}
46      */

47     public boolean matches(T target) {
48         return (mode.getModifiers() & target.getModifiers()) != 0;
49     }
50
51     @Override
52     public String toString() {
53         return mode.getDescription();
54     }
55
56     /**
57      * Determines the type of modifier to be matched by a {@link net.bytebuddy.matcher.ModifierMatcher}.
58      */

59     public enum Mode {
60
61         /**
62          * Matches an element that is considered {@code public}.
63          */

64         PUBLIC(Opcodes.ACC_PUBLIC, "isPublic()"),
65
66         /**
67          * Matches an element that is considered {@code protected}.
68          */

69         PROTECTED(Opcodes.ACC_PROTECTED, "isProtected()"),
70
71         /**
72          * Matches an element that is considered {@code private}.
73          */

74         PRIVATE(Opcodes.ACC_PRIVATE, "isPrivate()"),
75
76         /**
77          * Matches an element that is considered {@code final}.
78          */

79         FINAL(Opcodes.ACC_FINAL, "isFinal()"),
80
81         /**
82          * Matches an element that is considered {@code static}.
83          */

84         STATIC(Opcodes.ACC_STATIC, "isStatic()"),
85
86         /**
87          * Matches an element that is considered {@code synchronized}.
88          */

89         SYNCHRONIZED(Opcodes.ACC_SYNCHRONIZED, "isSynchronized()"),
90
91         /**
92          * Matches an element that is considered {@code native}.
93          */

94         NATIVE(Opcodes.ACC_NATIVE, "isNative()"),
95
96         /**
97          * Matches an element that is considered {@code strict}.
98          */

99         STRICT(Opcodes.ACC_STRICT, "isStrict()"),
100
101         /**
102          * Matches an element that is considered to be varargs.
103          */

104         VAR_ARGS(Opcodes.ACC_VARARGS, "isVarArgs()"),
105
106         /**
107          * Matches an element that is considered {@code synthetic}.
108          */

109         SYNTHETIC(Opcodes.ACC_SYNTHETIC, "isSynthetic()"),
110
111         /**
112          * Matches an element that is considered a bridge method.
113          */

114         BRIDGE(Opcodes.ACC_BRIDGE, "isBridge()"),
115
116         /**
117          * Matches an element that is considered {@code abstract}.
118          */

119         ABSTRACT(Opcodes.ACC_ABSTRACT, "isAbstract()"),
120
121         /**
122          * Matches a type that is considered an interface.
123          */

124         INTERFACE(Opcodes.ACC_INTERFACE, "isInterface()"),
125
126         /**
127          * Matches a type that is considered an annotation.
128          */

129         ANNOTATION(Opcodes.ACC_ANNOTATION, "isAnnotation()"),
130
131         /**
132          * Matches a volatile field.
133          */

134         VOLATILE(Opcodes.ACC_VOLATILE, "isVolatile()"),
135
136         /**
137          * Matches a transient field.
138          */

139         TRANSIENT(Opcodes.ACC_TRANSIENT, "isTransient()"),
140
141         /**
142          * Matches a mandated parameter.
143          */

144         MANDATED(Opcodes.ACC_MANDATED, "isMandated()"),
145
146         /**
147          * Matches a type or field for describing an enumeration.
148          */

149         ENUMERATION(Opcodes.ACC_ENUM, "isEnum()");
150
151         /**
152          * The mask of the modifier to match.
153          */

154         private final int modifiers;
155
156         /**
157          * The textual representation of this instance's matching mode.
158          */

159         private final String description;
160
161         /**
162          * Creates a new modifier matcher mode.
163          *
164          * @param modifiers   The mask of the modifier to match.
165          * @param description The textual representation of this instance's matching mode.
166          */

167         Mode(int modifiers, String description) {
168             this.modifiers = modifiers;
169             this.description = description;
170         }
171
172         /**
173          * Returns the textual description of this mode.
174          *
175          * @return The textual description of this mode.
176          */

177         protected String getDescription() {
178             return description;
179         }
180
181         /**
182          * Returns the modifiers to match by this mode.
183          *
184          * @return The modifiers to match by this mode.
185          */

186         protected int getModifiers() {
187             return modifiers;
188         }
189     }
190 }
191