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