• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

raphw / byte-buddy / #803

27 Oct 2025 11:52AM UTC coverage: 84.961% (+0.3%) from 84.697%
#803

push

raphw
Add missing annotation.

29755 of 35022 relevant lines covered (84.96%)

0.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.25
/byte-buddy-dep/src/main/java/net/bytebuddy/utility/visitor/MetadataAwareClassVisitor.java
1
/*
2
 * Copyright 2014 - Present 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.utility.visitor;
17

18
import net.bytebuddy.utility.nullability.MaybeNull;
19
import org.objectweb.asm.AnnotationVisitor;
20
import org.objectweb.asm.Attribute;
21
import org.objectweb.asm.ClassVisitor;
22
import org.objectweb.asm.FieldVisitor;
23
import org.objectweb.asm.MethodVisitor;
24
import org.objectweb.asm.ModuleVisitor;
25
import org.objectweb.asm.RecordComponentVisitor;
26
import org.objectweb.asm.TypePath;
27

28
/**
29
 * A class visitor that traces invocations of visitation methods and notifies if a nest host or outer class was not visited.
30
 */
31
public abstract class MetadataAwareClassVisitor extends ClassVisitor {
32

33
    /**
34
     * {@code true} if the sources were not yet visited.
35
     */
36
    private boolean triggerSource;
37

38
    /**
39
     * {@code true} if the module information was not yet visited.
40
     */
41
    private boolean triggerModule;
42

43
    /**
44
     * {@code true} if the nest host was not yet visited.
45
     */
46
    private boolean triggerNestHost;
47

48
    /**
49
     * {@code true} if the outer class was not yet visited.
50
     */
51
    private boolean triggerOuterClass;
52

53
    /**
54
     * {@code true} if the attribute visitation is not yet completed.
55
     */
56
    private boolean triggerAttributes;
57

58
    /**
59
     * Creates a metadata aware class visitor.
60
     *
61
     * @param api          The API version.
62
     * @param classVisitor The class visitor to delegate to.
63
     */
64
    protected MetadataAwareClassVisitor(int api, ClassVisitor classVisitor) {
65
        super(api, classVisitor);
1✔
66
        triggerSource = true;
1✔
67
        triggerModule = true;
1✔
68
        triggerNestHost = true;
1✔
69
        triggerOuterClass = true;
1✔
70
        triggerAttributes = true;
1✔
71
    }
1✔
72

73
    /**
74
     * Invoked if the sources were not visited.
75
     */
76
    protected void onSource() {
77
        /* do nothing */
78
    }
1✔
79

80
    /**
81
     * Invoked if the module was not visited.
82
     */
83
    protected void onModule() {
84
        /* do nothing */
85
    }
1✔
86

87
    /**
88
     * Invoked if the nest host was not visited.
89
     */
90
    protected void onNestHost() {
91
        /* do nothing */
92
    }
1✔
93

94
    /**
95
     * Invoked if the outer class was not visited.
96
     */
97
    protected void onOuterType() {
98
        /* do nothing */
99
    }
1✔
100

101
    /**
102
     * Invoked if the attribute visitation is about to complete.
103
     */
104
    protected void onAfterAttributes() {
105
        /* do nothing */
106
    }
×
107

108
    /**
109
     * Considers triggering a source visitation.
110
     */
111
    private void considerTriggerSource() {
112
        if (triggerSource) {
1✔
113
            triggerSource = false;
1✔
114
            onSource();
1✔
115
        }
116
    }
1✔
117

118
    /**
119
     * Considers triggering a module visitation.
120
     */
121
    private void considerTriggerModule() {
122
        if (triggerModule) {
1✔
123
            triggerModule = false;
1✔
124
            onModule();
1✔
125
        }
126
    }
1✔
127

128
    /**
129
     * Considers triggering a nest host visitation.
130
     */
131
    private void considerTriggerNestHost() {
132
        if (triggerNestHost) {
1✔
133
            triggerNestHost = false;
1✔
134
            onNestHost();
1✔
135
        }
136
    }
1✔
137

138
    /**
139
     * Considers triggering an outer class visitation.
140
     */
141
    private void considerTriggerOuterClass() {
142
        if (triggerOuterClass) {
1✔
143
            triggerOuterClass = false;
1✔
144
            onOuterType();
1✔
145
        }
146
    }
1✔
147

148
    /**
149
     * Considers triggering the after attribute visitation.
150
     */
151
    private void considerTriggerAfterAttributes() {
152
        if (triggerAttributes) {
1✔
153
            triggerAttributes = false;
1✔
154
            onAfterAttributes();
1✔
155
        }
156
    }
1✔
157

158
    @Override
159
    public final void visitSource(@MaybeNull String source, @MaybeNull String debug) {
160
        triggerSource = false;
1✔
161
        onVisitSource(source, debug);
1✔
162
    }
1✔
163

164
    /**
165
     * An order-sensitive invocation og {@link ClassVisitor#visitSource(String, String)}.
166
     *
167
     * @param source The name of the source file or {@code null} if not available.
168
     * @param debug  Additional debug information or {@code null} if not available.
169
     */
170
    protected void onVisitSource(@MaybeNull String source, @MaybeNull String debug) {
171
        super.visitSource(source, debug);
1✔
172
    }
1✔
173

174
    @Override
175
    @MaybeNull
176
    public final ModuleVisitor visitModule(String name, int access, @MaybeNull String version) {
177
        considerTriggerSource();
1✔
178
        triggerModule = false;
1✔
179
        return onVisitModule(name, access, version);
1✔
180
    }
181

182
    /**
183
     * An order-sensitive invocation og {@link ClassVisitor#visitModule(String, int, String)}.
184
     *
185
     * @param name      The name of the module
186
     * @param modifiers The modifiers of the module.
187
     * @param version   The module version or {@code null} if not available.
188
     * @return A visitor for the module information or {@code null} if skipped.
189
     */
190
    @MaybeNull
191
    protected ModuleVisitor onVisitModule(String name, int modifiers, @MaybeNull String version) {
192
        return super.visitModule(name, modifiers, version);
1✔
193
    }
194

195
    @Override
196
    public final void visitNestHost(String nestHost) {
197
        considerTriggerSource();
1✔
198
        considerTriggerModule();
1✔
199
        triggerNestHost = false;
1✔
200
        onVisitNestHost(nestHost);
1✔
201
    }
1✔
202

203
    /**
204
     * An order-sensitive invocation of {@link ClassVisitor#visitNestHost(String)}.
205
     *
206
     * @param nestHost The internal name of the nest host.
207
     */
208
    protected void onVisitNestHost(String nestHost) {
209
        super.visitNestHost(nestHost);
1✔
210
    }
1✔
211

212
    @Override
213
    public final void visitOuterClass(String owner, @MaybeNull String name, @MaybeNull String descriptor) {
214
        considerTriggerSource();
1✔
215
        considerTriggerModule();
1✔
216
        considerTriggerNestHost();
1✔
217
        triggerOuterClass = false;
1✔
218
        onVisitOuterClass(owner, name, descriptor);
1✔
219
    }
1✔
220

221
    /**
222
     * An order-sensitive invocation of {@link ClassVisitor#visitOuterClass(String, String, String)}.
223
     *
224
     * @param owner      The outer class's internal name.
225
     * @param name       The outer method's name or {@code null} if it does not exist.
226
     * @param descriptor The outer method's descriptor or {@code null} if it does not exist.
227
     */
228
    protected void onVisitOuterClass(String owner, @MaybeNull String name, @MaybeNull String descriptor) {
229
        super.visitOuterClass(owner, name, descriptor);
1✔
230
    }
1✔
231

232
    @Override
233
    public final void visitPermittedSubclass(String permittedSubclass) {
234
        considerTriggerSource();
1✔
235
        considerTriggerModule();
1✔
236
        considerTriggerNestHost();
1✔
237
        considerTriggerOuterClass();
1✔
238
        considerTriggerAfterAttributes();
1✔
239
        onVisitPermittedSubclass(permittedSubclass);
1✔
240
    }
1✔
241

242
    /**
243
     * An order-sensitive invocation of {@code ClassVisitor#visitPermittedSubclass}.
244
     *
245
     * @param permittedSubclass The internal name of the permitted subclass.
246
     */
247
    protected void onVisitPermittedSubclass(String permittedSubclass) {
248
        super.visitPermittedSubclass(permittedSubclass);
1✔
249
    }
1✔
250

251
    @Override
252
    @MaybeNull
253
    public RecordComponentVisitor visitRecordComponent(String name, String descriptor, @MaybeNull String signature) {
254
        considerTriggerSource();
1✔
255
        considerTriggerModule();
1✔
256
        considerTriggerNestHost();
1✔
257
        considerTriggerOuterClass();
1✔
258
        considerTriggerAfterAttributes();
1✔
259
        return onVisitRecordComponent(name, descriptor, signature);
1✔
260
    }
261

262
    /**
263
     * An order-sensitive invocation of {@link ClassVisitor#visitRecordComponent(String, String, String)}.
264
     *
265
     * @param name       The record component's name.
266
     * @param descriptor The record component's descriptor.
267
     * @param signature  The record component's generic signature or {@code null} if the record component's type is non-generic.
268
     * @return The record component visitor or {@code null} if the component should not be visited.
269
     */
270
    @MaybeNull
271
    protected RecordComponentVisitor onVisitRecordComponent(String name, String descriptor, @MaybeNull String signature) {
272
        return super.visitRecordComponent(name, descriptor, signature);
1✔
273
    }
274

275
    @Override
276
    @MaybeNull
277
    public final AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
278
        considerTriggerSource();
1✔
279
        considerTriggerModule();
1✔
280
        considerTriggerNestHost();
1✔
281
        considerTriggerOuterClass();
1✔
282
        return onVisitAnnotation(descriptor, visible);
1✔
283
    }
284

285
    /**
286
     * An order-sensitive invocation of {@link ClassVisitor#visitAnnotation(String, boolean)}.
287
     *
288
     * @param descriptor The annotation type's descriptor.
289
     * @param visible    {@code true} if the annotation is visible at runtime.
290
     * @return An annotation visitor or {@code null} if the annotation should be ignored.
291
     */
292
    @MaybeNull
293
    protected AnnotationVisitor onVisitAnnotation(String descriptor, boolean visible) {
294
        return super.visitAnnotation(descriptor, visible);
1✔
295
    }
296

297
    @Override
298
    @MaybeNull
299
    public final AnnotationVisitor visitTypeAnnotation(int typeReference, TypePath typePath, String descriptor, boolean visible) {
300
        considerTriggerSource();
1✔
301
        considerTriggerModule();
1✔
302
        considerTriggerNestHost();
1✔
303
        considerTriggerOuterClass();
1✔
304
        return onVisitTypeAnnotation(typeReference, typePath, descriptor, visible);
1✔
305
    }
306

307
    /**
308
     * An order-sensitive invocation of {@link ClassVisitor#visitTypeAnnotation(int, TypePath, String, boolean)}.
309
     *
310
     * @param typeReference The type reference of the type annotation.
311
     * @param typePath      The type path of the type annotation.
312
     * @param descriptor    The descriptor of the annotation type.
313
     * @param visible       {@code true} if the annotation is visible at runtime.
314
     * @return An annotation visitor or {@code null} if the annotation should be ignored.
315
     */
316
    @MaybeNull
317
    protected AnnotationVisitor onVisitTypeAnnotation(int typeReference, TypePath typePath, String descriptor, boolean visible) {
318
        return super.visitTypeAnnotation(typeReference, typePath, descriptor, visible);
1✔
319
    }
320

321
    @Override
322
    public final void visitAttribute(Attribute attribute) {
323
        considerTriggerSource();
1✔
324
        considerTriggerModule();
1✔
325
        considerTriggerNestHost();
1✔
326
        considerTriggerOuterClass();
1✔
327
        onVisitAttribute(attribute);
1✔
328
    }
1✔
329

330
    /**
331
     * An order-sensitive invocation of {@link ClassVisitor#visitAttribute(Attribute)}.
332
     *
333
     * @param attribute The attribute to visit.
334
     */
335
    protected void onVisitAttribute(Attribute attribute) {
336
        super.visitAttribute(attribute);
1✔
337
    }
1✔
338

339
    @Override
340
    public final void visitNestMember(String nestMember) {
341
        considerTriggerSource();
1✔
342
        considerTriggerModule();
1✔
343
        considerTriggerNestHost();
1✔
344
        considerTriggerOuterClass();
1✔
345
        considerTriggerAfterAttributes();
1✔
346
        onVisitNestMember(nestMember);
1✔
347
    }
1✔
348

349
    /**
350
     * An order-sensitive invocation of {@link ClassVisitor#visitNestMember(String)}.
351
     *
352
     * @param nestMember The internal name of the nest member.
353
     */
354
    protected void onVisitNestMember(String nestMember) {
355
        super.visitNestMember(nestMember);
1✔
356
    }
1✔
357

358
    @Override
359
    public final void visitInnerClass(String name, @MaybeNull String outerName, @MaybeNull String innerName, int modifiers) {
360
        considerTriggerSource();
1✔
361
        considerTriggerModule();
1✔
362
        considerTriggerNestHost();
1✔
363
        considerTriggerOuterClass();
1✔
364
        considerTriggerAfterAttributes();
1✔
365
        onVisitInnerClass(name, outerName, innerName, modifiers);
1✔
366
    }
1✔
367

368
    /**
369
     * An order-sensitive invocation of {@link ClassVisitor#visitInnerClass(String, String, String, int)}.
370
     *
371
     * @param internalName The internal name of the inner class.
372
     * @param outerName    The internal name of the outer class or {@code null} for a member class.
373
     * @param innerName    The inner class's simple name or {@code null} for an anonymous class.
374
     * @param modifiers    The inner class's source code modifiers.
375
     */
376
    protected void onVisitInnerClass(String internalName, @MaybeNull String outerName, @MaybeNull String innerName, int modifiers) {
377
        super.visitInnerClass(internalName, outerName, innerName, modifiers);
1✔
378
    }
1✔
379

380
    @Override
381
    @MaybeNull
382
    public final FieldVisitor visitField(int modifiers, String internalName, String descriptor, @MaybeNull String signature, @MaybeNull Object value) {
383
        considerTriggerSource();
1✔
384
        considerTriggerModule();
1✔
385
        considerTriggerNestHost();
1✔
386
        considerTriggerOuterClass();
1✔
387
        considerTriggerAfterAttributes();
1✔
388
        return onVisitField(modifiers, internalName, descriptor, signature, value);
1✔
389
    }
390

391
    /**
392
     * An order-sensitive invocation of {@link ClassVisitor#visitField(int, String, String, String, Object)}.
393
     *
394
     * @param modifiers    The field's modifiers.
395
     * @param internalName The field's internal name.
396
     * @param descriptor   The field type's descriptor.
397
     * @param signature    The field's generic signature or {@code null} if the field is not generic.
398
     * @param value        The field's default value or {@code null} if no such value exists.
399
     * @return A field visitor to visit the field or {@code null} to ignore it.
400
     */
401
    @MaybeNull
402
    protected FieldVisitor onVisitField(int modifiers, String internalName, String descriptor, @MaybeNull String signature, @MaybeNull Object value) {
403
        return super.visitField(modifiers, internalName, descriptor, signature, value);
1✔
404
    }
405

406
    @Override
407
    @MaybeNull
408
    public final MethodVisitor visitMethod(int modifiers, String internalName, String descriptor, @MaybeNull String signature, @MaybeNull String[] exception) {
409
        considerTriggerSource();
1✔
410
        considerTriggerModule();
1✔
411
        considerTriggerNestHost();
1✔
412
        considerTriggerOuterClass();
1✔
413
        considerTriggerAfterAttributes();
1✔
414
        return onVisitMethod(modifiers, internalName, descriptor, signature, exception);
1✔
415
    }
416

417
    /**
418
     * An order-sensitive invocation of {@link ClassVisitor#visitMethod(int, String, String, String, String[])}.
419
     *
420
     * @param modifiers    The method's modifiers.
421
     * @param internalName The method's internal name.
422
     * @param descriptor   The field type's descriptor.
423
     * @param signature    The method's generic signature or {@code null} if the method is not generic.
424
     * @param exception    The method's declared exceptions or {@code null} if no exceptions are declared.
425
     * @return A method visitor to visit the method or {@code null} to ignore it.
426
     */
427
    @MaybeNull
428
    protected MethodVisitor onVisitMethod(int modifiers, String internalName, String descriptor, @MaybeNull String signature, @MaybeNull String[] exception) {
429
        return super.visitMethod(modifiers, internalName, descriptor, signature, exception);
1✔
430
    }
431

432
    @Override
433
    public final void visitEnd() {
434
        considerTriggerSource();
1✔
435
        considerTriggerModule();
1✔
436
        considerTriggerNestHost();
1✔
437
        considerTriggerOuterClass();
1✔
438
        considerTriggerAfterAttributes();
1✔
439
        onVisitEnd();
1✔
440
    }
1✔
441

442
    /**
443
     * An order-sensitive invocation of {@link ClassVisitor#visitEnd()}.
444
     */
445
    protected void onVisitEnd() {
446
        super.visitEnd();
1✔
447
    }
1✔
448
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc