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

raphw / byte-buddy / #801

27 Oct 2025 09:37AM UTC coverage: 84.715% (-0.4%) from 85.118%
#801

push

raphw
Fix imports.

29586 of 34924 relevant lines covered (84.72%)

0.85 hits per line

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

79.57
/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/DynamicType.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.dynamic;
17

18
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19
import net.bytebuddy.ClassFileVersion;
20
import net.bytebuddy.asm.AsmVisitorWrapper;
21
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
22
import net.bytebuddy.description.annotation.AnnotationDescription;
23
import net.bytebuddy.description.annotation.AnnotationList;
24
import net.bytebuddy.description.annotation.AnnotationValue;
25
import net.bytebuddy.description.field.FieldDescription;
26
import net.bytebuddy.description.method.MethodDescription;
27
import net.bytebuddy.description.method.ParameterDescription;
28
import net.bytebuddy.description.method.ParameterList;
29
import net.bytebuddy.description.modifier.FieldManifestation;
30
import net.bytebuddy.description.modifier.MethodManifestation;
31
import net.bytebuddy.description.modifier.ModifierContributor;
32
import net.bytebuddy.description.modifier.Ownership;
33
import net.bytebuddy.description.modifier.Visibility;
34
import net.bytebuddy.description.type.RecordComponentDescription;
35
import net.bytebuddy.description.type.TypeDefinition;
36
import net.bytebuddy.description.type.TypeDescription;
37
import net.bytebuddy.description.type.TypeList;
38
import net.bytebuddy.description.type.TypeVariableToken;
39
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
40
import net.bytebuddy.dynamic.loading.InjectionClassLoader;
41
import net.bytebuddy.dynamic.scaffold.FieldRegistry;
42
import net.bytebuddy.dynamic.scaffold.InstrumentedType;
43
import net.bytebuddy.dynamic.scaffold.MethodGraph;
44
import net.bytebuddy.dynamic.scaffold.MethodRegistry;
45
import net.bytebuddy.dynamic.scaffold.RecordComponentRegistry;
46
import net.bytebuddy.dynamic.scaffold.TypeValidation;
47
import net.bytebuddy.dynamic.scaffold.TypeWriter;
48
import net.bytebuddy.implementation.EqualsMethod;
49
import net.bytebuddy.implementation.FieldAccessor;
50
import net.bytebuddy.implementation.HashCodeMethod;
51
import net.bytebuddy.implementation.Implementation;
52
import net.bytebuddy.implementation.LoadedTypeInitializer;
53
import net.bytebuddy.implementation.ToStringMethod;
54
import net.bytebuddy.implementation.attribute.AnnotationRetention;
55
import net.bytebuddy.implementation.attribute.AnnotationValueFilter;
56
import net.bytebuddy.implementation.attribute.FieldAttributeAppender;
57
import net.bytebuddy.implementation.attribute.MethodAttributeAppender;
58
import net.bytebuddy.implementation.attribute.RecordComponentAttributeAppender;
59
import net.bytebuddy.implementation.attribute.TypeAttributeAppender;
60
import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
61
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
62
import net.bytebuddy.matcher.ElementMatcher;
63
import net.bytebuddy.matcher.LatentMatcher;
64
import net.bytebuddy.pool.TypePool;
65
import net.bytebuddy.utility.AsmClassReader;
66
import net.bytebuddy.utility.AsmClassWriter;
67
import net.bytebuddy.utility.CompoundList;
68
import net.bytebuddy.utility.FileSystem;
69
import net.bytebuddy.utility.nullability.MaybeNull;
70
import net.bytebuddy.utility.visitor.ContextClassVisitor;
71
import org.objectweb.asm.ClassVisitor;
72
import org.objectweb.asm.Opcodes;
73

74
import java.io.File;
75
import java.io.FileInputStream;
76
import java.io.FileOutputStream;
77
import java.io.IOException;
78
import java.io.InputStream;
79
import java.io.OutputStream;
80
import java.lang.annotation.Annotation;
81
import java.lang.reflect.AnnotatedElement;
82
import java.lang.reflect.Constructor;
83
import java.lang.reflect.Field;
84
import java.lang.reflect.Method;
85
import java.lang.reflect.Type;
86
import java.util.ArrayList;
87
import java.util.Arrays;
88
import java.util.Collection;
89
import java.util.Collections;
90
import java.util.HashMap;
91
import java.util.LinkedHashMap;
92
import java.util.LinkedHashSet;
93
import java.util.List;
94
import java.util.Map;
95
import java.util.Set;
96
import java.util.jar.Attributes;
97
import java.util.jar.JarEntry;
98
import java.util.jar.JarInputStream;
99
import java.util.jar.JarOutputStream;
100
import java.util.jar.Manifest;
101

102
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
103
import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy;
104
import static net.bytebuddy.matcher.ElementMatchers.isEquals;
105
import static net.bytebuddy.matcher.ElementMatchers.isHashCode;
106
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
107
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
108
import static net.bytebuddy.matcher.ElementMatchers.isSuperTypeOf;
109
import static net.bytebuddy.matcher.ElementMatchers.isSynthetic;
110
import static net.bytebuddy.matcher.ElementMatchers.isToString;
111
import static net.bytebuddy.matcher.ElementMatchers.none;
112

113
/**
114
 * A dynamic type that is created at runtime, usually as the result of applying a
115
 * {@link net.bytebuddy.dynamic.DynamicType.Builder} or as the result of an
116
 * {@link net.bytebuddy.implementation.auxiliary.AuxiliaryType}.
117
 * <p>&nbsp;</p>
118
 * Note that the {@link TypeDescription}s will represent their
119
 * unloaded forms and therefore differ from the loaded types, especially with regards to annotations.
120
 */
121
public interface DynamicType extends ClassFileLocator {
122

123
    /**
124
     * <p>
125
     * Returns a description of this dynamic type.
126
     * </p>
127
     * <p>
128
     * <b>Note</b>: This description will most likely differ from the binary representation of this type. Normally,
129
     * annotations and intercepted methods are not added to this type description.
130
     * </p>
131
     *
132
     * @return A description of this dynamic type.
133
     */
134
    TypeDescription getTypeDescription();
135

136
    /**
137
     * Returns a byte array representing this dynamic type. This byte array might be reused by this dynamic type and
138
     * must therefore not be altered.
139
     *
140
     * @return A byte array of the type's binary representation.
141
     */
142
    byte[] getBytes();
143

144
    /**
145
     * Returns the loaded type initializer of this dynamic type.
146
     *
147
     * @return The loaded type initializer of this dynamic type.
148
     */
149
    LoadedTypeInitializer getLoadedTypeInitializer();
150

151
    /**
152
     * Returns all auxiliary types of this dynamic type.
153
     *
154
     * @return A list of all auxiliary types of this dynamic type.
155
     */
156
    List<? extends DynamicType> getAuxiliaries();
157

158
    /**
159
     * Returns a set of all auxiliary types that are represented by this dynamic type.
160
     *
161
     * @return A set of all auxiliary types.
162
     */
163
    Set<TypeDescription> getAuxiliaryTypeDescriptions();
164

165
    /**
166
     * Returns a set of all types that are represented by this dynamic type.
167
     *
168
     * @return A set of all represented types.
169
     */
170
    Set<TypeDescription> getAllTypeDescriptions();
171

172
    /**
173
     * <p>
174
     * Returns a map of all auxiliary types that are required for making use of the main type.
175
     * </p>
176
     * <p>
177
     * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
178
     * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
179
     * </p>
180
     *
181
     * @return A map of all auxiliary types by their descriptions to their binary representation.
182
     */
183
    Map<TypeDescription, byte[]> getAuxiliaryTypes();
184

185
    /**
186
     * Returns all types that are implied by this dynamic type.
187
     *
188
     * @return A mapping from all type descriptions, the actual type and its auxiliary types to their binary
189
     * representation
190
     */
191
    Map<TypeDescription, byte[]> getAllTypes();
192

193
    /**
194
     * <p>
195
     * Returns a map of all loaded type initializers for the main type and all auxiliary types, if any.
196
     * </p>
197
     * <p>
198
     * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
199
     * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
200
     * </p>
201
     *
202
     * @return A mapping of all types' descriptions to their loaded type initializers.
203
     */
204
    Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers();
205

206
    /**
207
     * Checks if a dynamic type requires some form of explicit type initialization, either for itself or for one
208
     * of its auxiliary types, if any. This is the case when this dynamic type was defined to delegate method calls
209
     * to a specific instance which is stored in a field of the created type. If this class serialized, it could not
210
     * be used without its loaded type initializers since the field value represents a specific runtime context.
211
     *
212
     * @return {@code true} if this type requires explicit type initialization.
213
     */
214
    boolean hasAliveLoadedTypeInitializers();
215

216
    /**
217
     * <p>
218
     * Saves a dynamic type in a given folder using the Java class file format while respecting the naming conventions
219
     * for saving compiled Java classes. All auxiliary types, if any, are saved in the same directory. The resulting
220
     * folder structure will resemble the structure that is required for Java run times, i.e. each folder representing
221
     * a segment of the package name. If the specified {@code folder} does not yet exist, it is created during the
222
     * call of this method.
223
     * </p>
224
     * <p>
225
     * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
226
     * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
227
     * </p>
228
     *
229
     * @param folder The base target folder for storing this dynamic type and its auxiliary types, if any.
230
     * @return A map of type descriptions pointing to files with their stored binary representations within {@code folder}.
231
     * @throws IOException Thrown if the underlying file operations cause an {@code IOException}.
232
     */
233
    Map<TypeDescription, File> saveIn(File folder) throws IOException;
234

235
    /**
236
     * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
237
     * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
238
     * patched version with a new central directory. No directory entries are added to the generated jar.
239
     *
240
     * @param sourceJar The original jar file.
241
     * @param targetJar The {@code source} jar file with the injected contents.
242
     * @return The {@code target} jar file.
243
     * @throws IOException If an I/O exception occurs while injecting from the source into the target.
244
     */
245
    File inject(File sourceJar, File targetJar) throws IOException;
246

247
    /**
248
     * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
249
     * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
250
     * patched version with a new central directory. No directory entries are added to the generated jar.
251
     *
252
     * @param jar The jar file to replace with an injected version.
253
     * @return The {@code jar} file.
254
     * @throws IOException If an I/O exception occurs while injecting into the jar.
255
     */
256
    File inject(File jar) throws IOException;
257

258
    /**
259
     * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
260
     * exist prior to calling this method. The jar file is created with a simple manifest that only contains a version
261
     * number. No directory entries are added to the generated jar.
262
     *
263
     * @param file The target file to which the <i>jar</i> is written to.
264
     * @return The given {@code file}.
265
     * @throws IOException If an I/O exception occurs while writing the file.
266
     */
267
    File toJar(File file) throws IOException;
268

269
    /**
270
     * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
271
     * exist prior to calling this method. No directory entries are added to the generated jar.
272
     *
273
     * @param file     The target file to which the <i>jar</i> is written to.
274
     * @param manifest The manifest of the created <i>jar</i>.
275
     * @return The given {@code file}.
276
     * @throws IOException If an I/O exception occurs while writing the file.
277
     */
278
    File toJar(File file, Manifest manifest) throws IOException;
279

280
    /**
281
     * {@inheritDoc}
282
     */
283
    void close();
284

285
    /**
286
     * A builder for creating a dynamic type.
287
     *
288
     * @param <T> A loaded type that the built type is guaranteed to be a subclass of.
289
     */
290
    interface Builder<T> {
291

292
        /**
293
         * Applies the supplied {@link AsmVisitorWrapper} onto the {@link org.objectweb.asm.ClassVisitor} during building a dynamic type.
294
         * Using an ASM visitor, it is possible to manipulate byte code directly. Byte Buddy does not validate directly created byte code
295
         * and it remains the responsibility of the visitor's implementor to generate legal byte code. If several ASM visitor wrappers
296
         * are registered, they are applied on top of another in their registration order.
297
         *
298
         * @param asmVisitorWrapper The ASM visitor wrapper to apply during
299
         * @return A new builder that is equal to this builder and applies the ASM visitor wrapper.
300
         */
301
        Builder<T> visit(AsmVisitorWrapper asmVisitorWrapper);
302

303
        /**
304
         * Names the dynamic type by the supplied name. The name needs to be fully qualified and in the binary format (packages separated
305
         * by dots: {@code foo.Bar}). A type's package determines what other types are visible to the instrumented type and what methods
306
         * can be overridden or be represented in method signatures or as field types.
307
         *
308
         * @param name The fully qualified name of the generated class in a binary format.
309
         * @return A new builder that is equal to this builder but with the instrumented type named by the supplied name.
310
         */
311
        Builder<T> name(String name);
312

313
        /**
314
         * Adds a suffix to the current type name without changing the type's package.
315
         *
316
         * @param suffix The suffix to append to the current type name.
317
         * @return A new builder that is equal to this builder but with the instrumented type named suffixed by the supplied suffix.
318
         */
319
        Builder<T> suffix(String suffix);
320

321
        /**
322
         * Defines the supplied modifiers as the modifiers of the instrumented type.
323
         *
324
         * @param modifierContributor The modifiers of the instrumented type.
325
         * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
326
         */
327
        Builder<T> modifiers(ModifierContributor.ForType... modifierContributor);
328

329
        /**
330
         * Defines the supplied modifiers as the modifiers of the instrumented type.
331
         *
332
         * @param modifierContributors The modifiers of the instrumented type.
333
         * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
334
         */
335
        Builder<T> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors);
336

337
        /**
338
         * Defines the supplied modifiers as the modifiers of the instrumented type.
339
         *
340
         * @param modifiers The modifiers of the instrumented type.
341
         * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
342
         */
343
        Builder<T> modifiers(int modifiers);
344

345
        /**
346
         * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
347
         * type's new modifiers.
348
         *
349
         * @param modifierContributor The modifiers of the instrumented type.
350
         * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
351
         */
352
        Builder<T> merge(ModifierContributor.ForType... modifierContributor);
353

354
        /**
355
         * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
356
         * type's new modifiers.
357
         *
358
         * @param modifierContributors The modifiers of the instrumented type.
359
         * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
360
         */
361
        Builder<T> merge(Collection<? extends ModifierContributor.ForType> modifierContributors);
362

363
        /**
364
         * <p>
365
         * Defines this type as a top-level type that is not declared by another type or enclosed by another member.
366
         * </p>
367
         * <p>
368
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
369
         * </p>
370
         * <p>
371
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
372
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
373
         * consistent among the definitions of connected types.
374
         * </p>
375
         *
376
         * @return A new builder that is equal to this builder but without any declaration of a declared or enclosed type.
377
         */
378
        Builder<T> topLevelType();
379

380
        /**
381
         * <p>
382
         * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is defined
383
         * as a local type.
384
         * </p>
385
         * <p>
386
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
387
         * </p>
388
         * <p>
389
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
390
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
391
         * consistent among the definitions of connected types.
392
         * </p>
393
         *
394
         * @param type The type to declare as the built type's outer type.
395
         * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
396
         */
397
        InnerTypeDefinition.ForType<T> innerTypeOf(Class<?> type);
398

399
        /**
400
         * <p>
401
         * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is
402
         * defined as a local type.
403
         * </p>
404
         * <p>
405
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
406
         * </p>
407
         * <p>
408
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
409
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
410
         * consistent among the definitions of connected types.
411
         * </p>
412
         *
413
         * @param type The type to declare as the built type's outer type.
414
         * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
415
         */
416
        InnerTypeDefinition.ForType<T> innerTypeOf(TypeDescription type);
417

418
        /**
419
         * <p>
420
         * Defines this type as an inner type that was declared within the supplied method.  Without any additional configuration, the type
421
         * declaration is defined as a local type.
422
         * </p>
423
         * <p>
424
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
425
         * </p>
426
         * <p>
427
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
428
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
429
         * consistent among the definitions of connected types.
430
         * </p>
431
         *
432
         * @param method The method to declare as the built type's declaring method.
433
         * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method.
434
         */
435
        InnerTypeDefinition<T> innerTypeOf(Method method);
436

437
        /**
438
         * <p>
439
         * Defines this type as an inner type that was declared within the supplied constructor. Without any additional configuration, the type
440
         * declaration is defined as a local type.
441
         * </p>
442
         * <p>
443
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
444
         * </p>
445
         * <p>
446
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
447
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
448
         * consistent among the definitions of connected types.
449
         * </p>
450
         *
451
         * @param constructor The constructor to declare as the built type's declaring method.
452
         * @return A new builder that is equal to this builder with the supplied method as the built type's declaring constructor.
453
         */
454
        InnerTypeDefinition<T> innerTypeOf(Constructor<?> constructor);
455

456
        /**
457
         * <p>
458
         * Defines this type as an inner type that was declared within the supplied method or constructor. Without any additional configuration,
459
         * the type declaration is defined as a local type.
460
         * </p>
461
         * <p>
462
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
463
         * </p>
464
         * <p>
465
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
466
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
467
         * consistent among the definitions of connected types.
468
         * </p>
469
         *
470
         * @param methodDescription The method or constructor to declare as the built type's declaring method.
471
         * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method or constructor.
472
         */
473
        InnerTypeDefinition<T> innerTypeOf(MethodDescription.InDefinedShape methodDescription);
474

475
        /**
476
         * <p>
477
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
478
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
479
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
480
         * </p>
481
         * <p>
482
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
483
         * </p>
484
         * <p>
485
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
486
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
487
         * consistent among the definitions of connected types.
488
         * </p>
489
         *
490
         * @param type The types being declared.
491
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
492
         */
493
        Builder<T> declaredTypes(Class<?>... type);
494

495
        /**
496
         * <p>
497
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
498
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
499
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
500
         * </p>
501
         * <p>
502
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
503
         * </p>
504
         * <p>
505
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
506
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
507
         * consistent among the definitions of connected types.
508
         * </p>
509
         *
510
         * @param type The types being declared.
511
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
512
         */
513
        Builder<T> declaredTypes(TypeDescription... type);
514

515
        /**
516
         * <p>
517
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
518
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
519
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
520
         * </p>
521
         * <p>
522
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
523
         * </p>
524
         * <p>
525
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
526
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
527
         * consistent among the definitions of connected types.
528
         * </p>
529
         *
530
         * @param types The types being declared.
531
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
532
         */
533
        Builder<T> declaredTypes(List<? extends Class<?>> types);
534

535
        /**
536
         * <p>
537
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
538
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
539
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
540
         * </p>
541
         * <p>
542
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
543
         * </p>
544
         * <p>
545
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
546
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
547
         * consistent among the definitions of connected types.
548
         * </p>
549
         *
550
         * @param types The types being declared.
551
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
552
         */
553
        Builder<T> declaredTypes(Collection<? extends TypeDescription> types);
554

555
        /**
556
         * <p>
557
         * Defines this type as self-hosted, i.e. as only being a nest mate of itself.
558
         * </p>
559
         * <p>
560
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
561
         * </p>
562
         * <p>
563
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
564
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
565
         * consistent among the definitions of connected types.
566
         * </p>
567
         *
568
         * @return A new builder that is equal to this builder but where the built type is a self-hosted nest mate.
569
         */
570
        Builder<T> noNestMate();
571

572
        /**
573
         * <p>
574
         * Defines this type as a nest member of the supplied type as a nest host.
575
         * </p>
576
         * <p>
577
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
578
         * </p>
579
         * <p>
580
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
581
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
582
         * consistent among the definitions of connected types.
583
         * </p>
584
         *
585
         * @param type The nest host.
586
         * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
587
         */
588
        Builder<T> nestHost(Class<?> type);
589

590
        /**
591
         * <p>
592
         * Defines this type as a nest member of the supplied type as a nest host.
593
         * </p>
594
         * <p>
595
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
596
         * </p>
597
         * <p>
598
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
599
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
600
         * consistent among the definitions of connected types.
601
         * </p>
602
         *
603
         * @param type The nest host.
604
         * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
605
         */
606
        Builder<T> nestHost(TypeDescription type);
607

608
        /**
609
         * <p>
610
         * Defines this type as a nest host for the supplied types.
611
         * </p>
612
         * <p>
613
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
614
         * </p>
615
         * <p>
616
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
617
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
618
         * consistent among the definitions of connected types.
619
         * </p>
620
         *
621
         * @param type The nest members.
622
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
623
         */
624
        Builder<T> nestMembers(Class<?>... type);
625

626
        /**
627
         * <p>
628
         * Defines this type as a nest host for the supplied types.
629
         * </p>
630
         * <p>
631
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
632
         * </p>
633
         * <p>
634
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
635
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
636
         * consistent among the definitions of connected types.
637
         * </p>
638
         *
639
         * @param type The nest members.
640
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
641
         */
642
        Builder<T> nestMembers(TypeDescription... type);
643

644
        /**
645
         * <p>
646
         * Defines this type as a nest host for the supplied types.
647
         * </p>
648
         * <p>
649
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
650
         * </p>
651
         * <p>
652
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
653
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
654
         * consistent among the definitions of connected types.
655
         * </p>
656
         *
657
         * @param types The nest members.
658
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
659
         */
660
        Builder<T> nestMembers(List<? extends Class<?>> types);
661

662
        /**
663
         * <p>
664
         * Defines this type as a nest host for the supplied types.
665
         * </p>
666
         * <p>
667
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
668
         * </p>
669
         * <p>
670
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
671
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
672
         * consistent among the definitions of connected types.
673
         * </p>
674
         *
675
         * @param types The nest members.
676
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
677
         */
678
        Builder<T> nestMembers(Collection<? extends TypeDescription> types);
679

680
        /**
681
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
682
         * this type was not previously sealed, only the supplied subclasses are permitted.
683
         *
684
         * @param type The permitted subclasses.
685
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
686
         */
687
        Builder<T> permittedSubclass(Class<?>... type);
688

689
        /**
690
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
691
         * this type was not previously sealed, only the supplied subclasses are permitted.
692
         *
693
         * @param type The permitted subclasses.
694
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
695
         */
696
        Builder<T> permittedSubclass(TypeDescription... type);
697

698
        /**
699
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
700
         * this type was not previously sealed, only the supplied subclasses are permitted.
701
         *
702
         * @param types The permitted subclasses.
703
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
704
         */
705
        Builder<T> permittedSubclass(List<? extends Class<?>> types);
706

707
        /**
708
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
709
         * this type was not previously sealed, only the supplied subclasses are permitted.
710
         *
711
         * @param types The permitted subclasses.
712
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
713
         */
714
        Builder<T> permittedSubclass(Collection<? extends TypeDescription> types);
715

716
        /**
717
         * Unseales this type.
718
         *
719
         * @return A new builder that is equal to this builder but where the built type does not restrain its permitted subclasses.
720
         */
721
        Builder<T> unsealed();
722

723
        /**
724
         * Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
725
         * any type of meta data to a type, not only Java {@link Annotation}s.
726
         *
727
         * @param typeAttributeAppender The type attribute appender to apply.
728
         * @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
729
         */
730
        Builder<T> attribute(TypeAttributeAppender typeAttributeAppender);
731

732
        /**
733
         * Annotates the instrumented type with the supplied annotations.
734
         *
735
         * @param annotation The annotations to add to the instrumented type.
736
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
737
         */
738
        Builder<T> annotateType(Annotation... annotation);
739

740
        /**
741
         * Annotates the instrumented type with the supplied annotations.
742
         *
743
         * @param annotations The annotations to add to the instrumented type.
744
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
745
         */
746
        Builder<T> annotateType(List<? extends Annotation> annotations);
747

748
        /**
749
         * Annotates the instrumented type with the supplied annotations.
750
         *
751
         * @param annotation The annotations to add to the instrumented type.
752
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
753
         */
754
        Builder<T> annotateType(AnnotationDescription... annotation);
755

756
        /**
757
         * Annotates the instrumented type with the supplied annotations.
758
         *
759
         * @param annotations The annotations to add to the instrumented type.
760
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
761
         */
762
        Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
763

764
        /**
765
         * <p>
766
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
767
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
768
         * are explicitly ignored.
769
         * </p>
770
         * <p>
771
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
772
         * as raw types if they declare type variables or an owner type.
773
         * </p>
774
         *
775
         * @param interfaceType The interface types to implement.
776
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
777
         */
778
        MethodDefinition.ImplementationDefinition.Optional<T> implement(Type... interfaceType);
779

780
        /**
781
         * <p>
782
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
783
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
784
         * are explicitly ignored.
785
         * </p>
786
         * <p>
787
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
788
         * as raw types if they declare type variables or an owner type.
789
         * </p>
790
         *
791
         * @param interfaceTypes The interface types to implement.
792
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
793
         */
794
        MethodDefinition.ImplementationDefinition.Optional<T> implement(List<? extends Type> interfaceTypes);
795

796
        /**
797
         * <p>
798
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
799
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
800
         * are explicitly ignored.
801
         * </p>
802
         * <p>
803
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
804
         * implemented as raw types if they declare type variables or an owner type.
805
         * </p>
806
         *
807
         * @param interfaceType The interface types to implement.
808
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
809
         */
810
        MethodDefinition.ImplementationDefinition.Optional<T> implement(TypeDefinition... interfaceType);
811

812
        /**
813
         * <p>
814
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
815
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
816
         * are explicitly ignored.
817
         * </p>
818
         * <p>
819
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
820
         * implemented as raw types if they declare type variables or an owner type.
821
         * </p>
822
         *
823
         * @param interfaceTypes The interface types to implement.
824
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
825
         */
826
        MethodDefinition.ImplementationDefinition.Optional<T> implement(Collection<? extends TypeDefinition> interfaceTypes);
827

828
        /**
829
         * <p>
830
         * Executes the supplied byte code appender within the beginning of the instrumented type's type initializer. The
831
         * supplied byte code appender <b>must not return</b> from the method. If several byte code appenders are supplied,
832
         * they are executed within their application order.
833
         * </p>
834
         * <p>
835
         * This method should only be used for preparing an instrumented type with a specific configuration. Normally,
836
         * a byte code appender is applied via Byte Buddy's standard API by invoking {@link Builder#invokable(ElementMatcher)}
837
         * using the {@link net.bytebuddy.matcher.ElementMatchers#isTypeInitializer()} matcher.
838
         * </p>
839
         *
840
         * @param byteCodeAppender The byte code appender to execute within the instrumented type's type initializer.
841
         * @return A new builder that is equal to this builder but with the supplied byte code appender being executed within
842
         * the instrumented type's type initializer.
843
         */
844
        Builder<T> initializer(ByteCodeAppender byteCodeAppender);
845

846
        /**
847
         * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
848
         * type initializers are supplied, each loaded type initializer is executed in its registration order.
849
         *
850
         * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
851
         * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
852
         * loading the instrumented type.
853
         */
854
        Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
855

856
        /**
857
         * Explicitly requires another dynamic type for the creation of this type.
858
         *
859
         * @param type                 The type to require.
860
         * @param binaryRepresentation The type's binary representation.
861
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
862
         */
863
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation);
864

865
        /**
866
         * Explicitly requires another dynamic type for the creation of this type.
867
         *
868
         * @param type                 The type to require.
869
         * @param binaryRepresentation The type's binary representation.
870
         * @param typeInitializer      The type's loaded type initializer.
871
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
872
         */
873
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
874

875
        /**
876
         * Explicitly requires other dynamic types for the creation of this type.
877
         *
878
         * @param auxiliaryType The required dynamic types.
879
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
880
         */
881
        Builder<T> require(DynamicType... auxiliaryType);
882

883
        /**
884
         * Explicitly requires other dynamic types for the creation of this type.
885
         *
886
         * @param auxiliaryTypes The required dynamic types.
887
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
888
         */
889
        Builder<T> require(Collection<DynamicType> auxiliaryTypes);
890

891
        /**
892
         * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
893
         *
894
         * @param symbol The type variable's symbol.
895
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
896
         */
897
        TypeVariableDefinition<T> typeVariable(String symbol);
898

899
        /**
900
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
901
         *
902
         * @param symbol The type variable's symbol.
903
         * @param bound  The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
904
         *               should be equal to the currently instrumented type.
905
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
906
         */
907
        TypeVariableDefinition<T> typeVariable(String symbol, Type... bound);
908

909
        /**
910
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
911
         *
912
         * @param symbol The type variable's symbol.
913
         * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
914
         *               should be equal to the currently instrumented type.
915
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
916
         */
917
        TypeVariableDefinition<T> typeVariable(String symbol, List<? extends Type> bounds);
918

919
        /**
920
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
921
         *
922
         * @param symbol The type variable's symbol.
923
         * @param bound  The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
924
         *               should be equal to the currently instrumented type.
925
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
926
         */
927
        TypeVariableDefinition<T> typeVariable(String symbol, TypeDefinition... bound);
928

929
        /**
930
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
931
         *
932
         * @param symbol The type variable's symbol.
933
         * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
934
         *               should be equal to the currently instrumented type.
935
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
936
         */
937
        TypeVariableDefinition<T> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
938

939
        /**
940
         * Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
941
         *
942
         * @param matcher     The matcher to decide what type variables to transform.
943
         * @param transformer The transformer to apply to the matched type variables.
944
         * @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
945
         */
946
        Builder<T> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer);
947

948
        /**
949
         * Defines the specified field as a field of the built dynamic type.
950
         *
951
         * @param name                The name of the field.
952
         * @param type                The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
953
         *                            should be equal to the currently instrumented type.
954
         * @param modifierContributor The modifiers of the field.
955
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
956
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
957
         */
958
        FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor);
959

960
        /**
961
         * Defines the specified field as a field of the built dynamic type.
962
         *
963
         * @param name                 The name of the field.
964
         * @param type                 The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
965
         *                             should be equal to the currently instrumented type.
966
         * @param modifierContributors The modifiers of the field.
967
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
968
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
969
         */
970
        FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors);
971

972
        /**
973
         * Defines the specified field as a field of the built dynamic type.
974
         *
975
         * @param name      The name of the field.
976
         * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
977
         *                  should be equal to the currently instrumented type.
978
         * @param modifiers The modifiers of the field.
979
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
980
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
981
         */
982
        FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, int modifiers);
983

984
        /**
985
         * Defines the specified field as a field of the built dynamic type.
986
         *
987
         * @param name                The name of the field.
988
         * @param type                The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
989
         *                            should be equal to the currently instrumented type.
990
         * @param modifierContributor The modifiers of the field.
991
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
992
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
993
         */
994
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor);
995

996
        /**
997
         * Defines the specified field as a field of the built dynamic type.
998
         *
999
         * @param name                 The name of the field.
1000
         * @param type                 The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
1001
         *                             should be equal to the currently instrumented type.
1002
         * @param modifierContributors The modifiers of the field.
1003
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1004
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1005
         */
1006
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors);
1007

1008
        /**
1009
         * Defines the specified field as a field of the built dynamic type.
1010
         *
1011
         * @param name      The name of the field.
1012
         * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
1013
         *                  should be equal to the currently instrumented type.
1014
         * @param modifiers The modifiers of the field.
1015
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1016
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1017
         */
1018
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, int modifiers);
1019

1020
        /**
1021
         * Defines a field that is similar to the supplied field but without copying any annotations on the field.
1022
         *
1023
         * @param field The field to imitate as a field of the instrumented type.
1024
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1025
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1026
         */
1027
        FieldDefinition.Optional.Valuable<T> define(Field field);
1028

1029
        /**
1030
         * Defines a field that is similar to the supplied field but without copying any annotations on the field.
1031
         *
1032
         * @param field The field to imitate as a field of the instrumented type.
1033
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1034
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1035
         */
1036
        FieldDefinition.Optional.Valuable<T> define(FieldDescription field);
1037

1038
        /**
1039
         * Defines a private, static, final field for a serial version UID of the given value.
1040
         *
1041
         * @param serialVersionUid The serial version UID to define as a value.
1042
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
1043
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1044
         */
1045
        FieldDefinition.Optional<T> serialVersionUid(long serialVersionUid);
1046

1047
        /**
1048
         * <p>
1049
         * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
1050
         * default value, annotations or custom attributes.
1051
         * </p>
1052
         * <p>
1053
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1054
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1055
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1056
         * altered, annotation retention must be disabled.
1057
         * </p>
1058
         * <p>
1059
         * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
1060
         * over the previous definition, i.e. the previous field definition is no longer applied.
1061
         * </p>
1062
         *
1063
         * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
1064
         * @return A builder that allows for changing a field's definition.
1065
         */
1066
        @SuppressWarnings("overloads")
1067
        FieldDefinition.Valuable<T> field(ElementMatcher<? super FieldDescription> matcher);
1068

1069
        /**
1070
         * <p>
1071
         * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
1072
         * default value, annotations or custom attributes. Using a latent matcher gives opportunity to resolve an
1073
         * {@link ElementMatcher} based on the instrumented type before applying the matcher.
1074
         * </p>
1075
         * <p>
1076
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1077
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1078
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1079
         * altered, annotation retention must be disabled.
1080
         * </p>
1081
         * <p>
1082
         * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
1083
         * over the previous definition, i.e. the previous field definition is no longer applied.
1084
         * </p>
1085
         *
1086
         * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
1087
         * @return A builder that allows for changing a field's definition.
1088
         */
1089
        @SuppressWarnings("overloads")
1090
        FieldDefinition.Valuable<T> field(LatentMatcher<? super FieldDescription> matcher);
1091

1092
        /**
1093
         * <p>
1094
         * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1095
         * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1096
         * </p>
1097
         * <p>
1098
         * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1099
         * is to be ignored, this matcher is no longer executed.
1100
         * </p>
1101
         *
1102
         * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1103
         * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1104
         * instrumentation.
1105
         */
1106
        @SuppressWarnings("overloads")
1107
        Builder<T> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods);
1108

1109
        /**
1110
         * <p>
1111
         * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1112
         * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1113
         * Using a latent matcher gives opportunity to resolve an {@link ElementMatcher} based on the instrumented type before applying the
1114
         * matcher.
1115
         * </p>
1116
         * <p>
1117
         * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1118
         * is to be ignored, this matcher is no longer executed.
1119
         * </p>
1120
         *
1121
         * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1122
         * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1123
         * instrumentation.
1124
         */
1125
        @SuppressWarnings("overloads")
1126
        Builder<T> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods);
1127

1128
        /**
1129
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1130
         * type variables can be defined in subsequent steps.
1131
         *
1132
         * @param name                The name of the method.
1133
         * @param returnType          The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1134
         *                            should be equal to the currently instrumented type.
1135
         * @param modifierContributor The method's modifiers.
1136
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1137
         */
1138
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor);
1139

1140
        /**
1141
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1142
         * type variables can be defined in subsequent steps.
1143
         *
1144
         * @param name                 The name of the method.
1145
         * @param returnType           The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1146
         *                             should be equal to the currently instrumented type.
1147
         * @param modifierContributors The method's modifiers.
1148
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1149
         */
1150
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1151

1152
        /**
1153
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1154
         * type variables can be defined in subsequent steps.
1155
         *
1156
         * @param name       The name of the method.
1157
         * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1158
         *                   should be equal to the currently instrumented type.
1159
         * @param modifiers  The method's modifiers.
1160
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1161
         */
1162
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, int modifiers);
1163

1164
        /**
1165
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1166
         * type variables can be defined in subsequent steps.
1167
         *
1168
         * @param name                The name of the method.
1169
         * @param returnType          The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1170
         *                            should be equal to the currently instrumented type.
1171
         * @param modifierContributor The method's modifiers.
1172
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1173
         */
1174
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor);
1175

1176
        /**
1177
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1178
         * type variables can be defined in subsequent steps.
1179
         *
1180
         * @param name                 The name of the method.
1181
         * @param returnType           The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1182
         *                             should be equal to the currently instrumented type.
1183
         * @param modifierContributors The method's modifiers.
1184
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1185
         */
1186
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1187

1188
        /**
1189
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1190
         * type variables can be defined in subsequent steps.
1191
         *
1192
         * @param name       The name of the method.
1193
         * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1194
         *                   should be equal to the currently instrumented type.
1195
         * @param modifiers  The method's modifiers.
1196
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1197
         */
1198
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, int modifiers);
1199

1200
        /**
1201
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1202
         * type variables can be defined in subsequent steps.
1203
         *
1204
         * @param modifierContributor The constructor's modifiers.
1205
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1206
         */
1207
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(ModifierContributor.ForMethod... modifierContributor);
1208

1209
        /**
1210
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1211
         * type variables can be defined in subsequent steps.
1212
         *
1213
         * @param modifierContributors The constructor's modifiers.
1214
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1215
         */
1216
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1217

1218
        /**
1219
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1220
         * type variables can be defined in subsequent steps.
1221
         *
1222
         * @param modifiers The constructor's modifiers.
1223
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1224
         */
1225
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(int modifiers);
1226

1227
        /**
1228
         * Defines a method that is similar to the supplied method but without copying any annotations of the method or method parameters.
1229
         *
1230
         * @param method The method to imitate as a method of the instrumented type.
1231
         * @return A builder that allows for defining an implementation for the method.
1232
         */
1233
        MethodDefinition.ImplementationDefinition<T> define(Method method);
1234

1235
        /**
1236
         * Defines a constructor that is similar to the supplied constructor but without copying any annotations of the constructor or
1237
         * constructor parameters.
1238
         *
1239
         * @param constructor The constructor to imitate as a method of the instrumented type.
1240
         * @return A builder that allows for defining an implementation for the constructor.
1241
         */
1242
        MethodDefinition.ImplementationDefinition<T> define(Constructor<?> constructor);
1243

1244
        /**
1245
         * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
1246
         * the method/constructor or method/constructor parameters.
1247
         *
1248
         * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
1249
         * @return A builder that allows for defining an implementation for the method or constructor.
1250
         */
1251
        MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
1252

1253
        /**
1254
         * Defines a Java bean property with the specified name.
1255
         *
1256
         * @param name The name of the property.
1257
         * @param type The property type.
1258
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1259
         */
1260
        FieldDefinition.Optional<T> defineProperty(String name, Type type);
1261

1262
        /**
1263
         * Defines a Java bean property with the specified name.
1264
         *
1265
         * @param name     The name of the property.
1266
         * @param type     The property type.
1267
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1268
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1269
         */
1270
        FieldDefinition.Optional<T> defineProperty(String name, Type type, boolean readOnly);
1271

1272
        /**
1273
         * Defines a Java bean property with the specified name.
1274
         *
1275
         * @param name The name of the property.
1276
         * @param type The property type.
1277
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1278
         */
1279
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type);
1280

1281
        /**
1282
         * Defines a Java bean property with the specified name.
1283
         *
1284
         * @param name     The name of the property.
1285
         * @param type     The property type.
1286
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1287
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1288
         */
1289
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type, boolean readOnly);
1290

1291
        /**
1292
         * <p>
1293
         * Matches a method that is already declared or inherited by the instrumented type. This gives opportunity to change or to
1294
         * override that method's implementation, default value, annotations or custom attributes. It is also possible to make
1295
         * a method abstract.
1296
         * </p>
1297
         * <p>
1298
         * When a type is redefined or rebased, any annotations that the method declared previously is preserved
1299
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1300
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1301
         * altered, annotation retention must be disabled.
1302
         * </p>
1303
         * <p>
1304
         * If a method is already matched by a previously specified matcher, the new method definition gets precedence
1305
         * over the previous definition, i.e. the previous method definition is no longer applied.
1306
         * </p>
1307
         * <p>
1308
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1309
         * </p>
1310
         *
1311
         * @param matcher The matcher that determines what methods are affected by the subsequent specification.
1312
         * @return A builder that allows for changing a method's or constructor's definition.
1313
         */
1314
        MethodDefinition.ImplementationDefinition<T> method(ElementMatcher<? super MethodDescription> matcher);
1315

1316
        /**
1317
         * <p>
1318
         * Matches a constructor that is already declared by the instrumented type. This gives opportunity to change that constructor's
1319
         * implementation, default value, annotations or custom attributes.
1320
         * </p>
1321
         * <p>
1322
         * When a type is redefined or rebased, any annotations that the constructor declared previously is preserved
1323
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1324
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1325
         * altered, annotation retention must be disabled.
1326
         * </p>
1327
         * <p>
1328
         * If a constructor is already matched by a previously specified matcher, the new constructor definition gets precedence
1329
         * over the previous definition, i.e. the previous constructor definition is no longer applied.
1330
         * </p>
1331
         * <p>
1332
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1333
         * </p>
1334
         *
1335
         * @param matcher The matcher that determines what constructors are affected by the subsequent specification.
1336
         * @return A builder that allows for changing a method's or constructor's definition.
1337
         */
1338
        MethodDefinition.ImplementationDefinition<T> constructor(ElementMatcher<? super MethodDescription> matcher);
1339

1340
        /**
1341
         * <p>
1342
         * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1343
         * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1344
         * or custom attributes. It is also possible to make a method abstract.
1345
         * </p>
1346
         * <p>
1347
         * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1348
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1349
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1350
         * altered, annotation retention must be disabled.
1351
         * </p>
1352
         * <p>
1353
         * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1354
         * over the previous definition, i.e. the previous definition is no longer applied.
1355
         * </p>
1356
         * <p>
1357
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1358
         * </p>
1359
         * <p>
1360
         * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1361
         * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1362
         * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1363
         * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1364
         * </p>
1365
         *
1366
         * @param matcher The matcher that determines what methods or constructors are affected by the subsequent specification.
1367
         * @return A builder that allows for changing a method's or constructor's definition.
1368
         */
1369
        @SuppressWarnings("overloads")
1370
        MethodDefinition.ImplementationDefinition<T> invokable(ElementMatcher<? super MethodDescription> matcher);
1371

1372
        /**
1373
         * <p>
1374
         * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1375
         * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1376
         * or custom attributes. It is also possible to make a method abstract. Using a latent matcher gives opportunity
1377
         * to resolve an {@link ElementMatcher} based on the instrumented type before applying the matcher.
1378
         * </p>
1379
         * <p>
1380
         * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1381
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1382
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1383
         * altered, annotation retention must be disabled.
1384
         * </p>
1385
         * <p>
1386
         * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1387
         * over the previous definition, i.e. the previous definition is no longer applied.
1388
         * </p>
1389
         * <p>
1390
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1391
         * </p>
1392
         * <p>
1393
         * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1394
         * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1395
         * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1396
         * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1397
         * </p>
1398
         *
1399
         * @param matcher The matcher that determines what declared methods or constructors are affected by the subsequent specification.
1400
         * @return A builder that allows for changing a method's or constructor's definition.
1401
         */
1402
        @SuppressWarnings("overloads")
1403
        MethodDefinition.ImplementationDefinition<T> invokable(LatentMatcher<? super MethodDescription> matcher);
1404

1405
        /**
1406
         * Implements {@link Object#hashCode()} and {@link Object#equals(Object)} methods for the instrumented type if those
1407
         * methods are not declared as {@code final} by a super class. The implementations do not consider any implementations
1408
         * of a super class and compare a class field by field without considering synthetic fields.
1409
         *
1410
         * @return A new type builder that defines {@link Object#hashCode()} and {@link Object#equals(Object)} methods accordingly.
1411
         */
1412
        Builder<T> withHashCodeEquals();
1413

1414
        /**
1415
         * Implements a {@link Object#toString()} method for the instrumented type if such a method is not declared as {@code final}
1416
         * by a super class. The implementation prefixes the string with the simple class name and prints each non-synthetic field's
1417
         * value after the field's name.
1418
         *
1419
         * @return A new type builder that defines {@link Object#toString()} method accordingly.
1420
         */
1421
        Builder<T> withToString();
1422

1423
        /**
1424
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1425
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1426
         *
1427
         * @param name The record component's name.
1428
         * @param type The record component's type.
1429
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1430
         */
1431
        RecordComponentDefinition.Optional<T> defineRecordComponent(String name, Type type);
1432

1433
        /**
1434
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1435
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1436
         *
1437
         * @param name The record component's name.
1438
         * @param type The record component's type.
1439
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1440
         */
1441
        RecordComponentDefinition.Optional<T> defineRecordComponent(String name, TypeDefinition type);
1442

1443
        /**
1444
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1445
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1446
         *
1447
         * @param recordComponentDescription A description of the record component to immitate.
1448
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1449
         */
1450
        RecordComponentDefinition.Optional<T> define(RecordComponentDescription recordComponentDescription);
1451

1452
        /**
1453
         * <p>
1454
         * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1455
         * record component's annotations or custom attributes.
1456
         * </p>
1457
         * <p>
1458
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1459
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1460
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1461
         * altered, annotation retention must be disabled.
1462
         * </p>
1463
         * <p>
1464
         * If a record component is already matched by a previously specified record component matcher, the new record component
1465
         * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1466
         * </p>
1467
         *
1468
         * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1469
         * @return A builder that allows for changing a record component's definition.
1470
         */
1471
        @SuppressWarnings("overloads")
1472
        RecordComponentDefinition<T> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher);
1473

1474
        /**
1475
         * <p>
1476
         * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1477
         * record component's annotations or custom attributes.
1478
         * </p>
1479
         * <p>
1480
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1481
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1482
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1483
         * altered, annotation retention must be disabled.
1484
         * </p>
1485
         * <p>
1486
         * If a record component is already matched by a previously specified record component matcher, the new record component
1487
         * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1488
         * </p>
1489
         *
1490
         * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1491
         * @return A builder that allows for changing a record component's definition.
1492
         */
1493
        @SuppressWarnings("overloads")
1494
        RecordComponentDefinition<T> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher);
1495

1496
        /**
1497
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder, using a
1498
         * default {@link TypePool}. A wrapper might not apply all features that are normally applied by Byte
1499
         * Buddy, if those features require control of the class loading life cycle. Neither does a wrapper define
1500
         * auxiliary types. It is therefore recommended to use {@link Implementation.Context.Disabled}.
1501
         *
1502
         * @param classVisitor The class visitor to wrap.
1503
         * @return A new class visitor that wraps a representation of this dynamic type.
1504
         */
1505
        ContextClassVisitor wrap(ClassVisitor classVisitor);
1506

1507
        /**
1508
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder, using a
1509
         * default {@link TypePool}. A wrapper might not apply all features that are normally applied by Byte
1510
         * Buddy, if those features require control of the class loading life cycle. Neither does a wrapper define
1511
         * auxiliary types. It is therefore recommended to use {@link Implementation.Context.Disabled}.
1512
         *
1513
         * @param classVisitor The class visitor to wrap.
1514
         * @param writerFlags  The ASM writer flags to apply.
1515
         * @param readerFlags  The ASM reader flags to apply.
1516
         * @return A new class visitor that wraps a representation of this dynamic type.
1517
         */
1518
        ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags);
1519

1520
        /**
1521
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder. A wrapper
1522
         * might not apply all features that are normally applied by Byte Buddy, if those features require control of
1523
         * the class loading life cycle. Neither does a wrapper define auxiliary types.  It is therefore recommended
1524
         * to use {@link Implementation.Context.Disabled}.
1525
         *
1526
         * @param classVisitor The class visitor to wrap.
1527
         * @param typePool     A type pool that is used for computing stack map frames by the underlying class writer, if required.
1528
         * @return A new class visitor that wraps a representation of this dynamic type.
1529
         */
1530
        ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool);
1531

1532
        /**
1533
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder. A wrapper
1534
         * might not apply all features that are normally applied by Byte Buddy, if those features require control
1535
         * of the class loading life cycle. Neither does a wrapper define auxiliary types.  It is therefore
1536
         * recommended to use {@link Implementation.Context.Disabled}.
1537
         *
1538
         * @param classVisitor The class visitor to wrap.
1539
         * @param typePool     A type pool that is used for computing stack map frames by the underlying class writer, if required.
1540
         * @param writerFlags  The ASM writer flags to apply.
1541
         * @param readerFlags  The ASM reader flags to apply.
1542
         * @return A new class visitor that wraps a representation of this dynamic type.
1543
         */
1544
        ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags);
1545

1546
        /**
1547
         * <p>
1548
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1549
         * </p>
1550
         * <p>
1551
         * Other than {@link DynamicType.Builder#make(TypePool)}, this method supplies a context-dependant type pool to the underlying class writer.
1552
         * Supplying a type pool only makes sense if custom byte code is created by adding a custom {@link AsmVisitorWrapper} where ASM might be
1553
         * required to compute stack map frames by processing information over any mentioned type's class hierarchy.
1554
         * </p>
1555
         * <p>
1556
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1557
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1558
         * executing the initializer must rely on such an initializer.
1559
         * </p>
1560
         *
1561
         * @return An unloaded dynamic type representing the type specified by this builder.
1562
         */
1563
        DynamicType.Unloaded<T> make();
1564

1565
        /**
1566
         * <p>
1567
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1568
         * </p>
1569
         * <p>
1570
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1571
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1572
         * executing the initializer must rely on such an initializer.
1573
         * </p>
1574
         *
1575
         * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1576
         * @return An unloaded dynamic type representing the type specified by this builder.
1577
         */
1578
        DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy);
1579

1580
        /**
1581
         * <p>
1582
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1583
         * </p>
1584
         * <p>
1585
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1586
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1587
         * executing the initializer must rely on such an initializer.
1588
         * </p>
1589
         *
1590
         * @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
1591
         * @return An unloaded dynamic type representing the type specified by this builder.
1592
         */
1593
        DynamicType.Unloaded<T> make(TypePool typePool);
1594

1595
        /**
1596
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1597
         *
1598
         * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1599
         * @param typePool               A type pool that is used for computing stack map frames by the underlying class writer, if required.
1600
         * @return An unloaded dynamic type representing the type specified by this builder.
1601
         */
1602
        DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool);
1603

1604
        /**
1605
         * Returns a {@link TypeDescription} for the currently built type.
1606
         *
1607
         * @return A {@link TypeDescription} for the currently built type.
1608
         */
1609
        TypeDescription toTypeDescription();
1610

1611
        /**
1612
         * An inner type definition for defining a type that is contained within another type, method or constructor.
1613
         *
1614
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1615
         */
1616
        interface InnerTypeDefinition<S> extends Builder<S> {
1617

1618
            /**
1619
             * Defines this inner type declaration as an anonymous type.
1620
             *
1621
             * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
1622
             */
1623
            Builder<S> asAnonymousType();
1624

1625
            /**
1626
             * An inner type definition for defining a type that is contained within another type.
1627
             *
1628
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1629
             */
1630
            interface ForType<U> extends InnerTypeDefinition<U> {
1631

1632
                /**
1633
                 * Defines this inner type declaration as a member type.
1634
                 *
1635
                 * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
1636
                 */
1637
                Builder<U> asMemberType();
1638
            }
1639
        }
1640

1641
        /**
1642
         * A builder for a type variable definition.
1643
         *
1644
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1645
         */
1646
        interface TypeVariableDefinition<S> extends Builder<S> {
1647

1648
            /**
1649
             * Annotates the previously defined type variable with the supplied annotations.
1650
             *
1651
             * @param annotation The annotations to declare on the previously defined type variable.
1652
             * @return A new builder that is equal to this builder but with the given annotations declared
1653
             * on the previously defined type variable.
1654
             */
1655
            TypeVariableDefinition<S> annotateTypeVariable(Annotation... annotation);
1656

1657
            /**
1658
             * Annotates the previously defined type variable with the supplied annotations.
1659
             *
1660
             * @param annotations The annotations to declare on the previously defined type variable.
1661
             * @return A new builder that is equal to this builder but with the given annotations declared
1662
             * on the previously defined type variable.
1663
             */
1664
            TypeVariableDefinition<S> annotateTypeVariable(List<? extends Annotation> annotations);
1665

1666
            /**
1667
             * Annotates the previously defined type variable with the supplied annotations.
1668
             *
1669
             * @param annotation The annotations to declare on the previously defined type variable.
1670
             * @return A new builder that is equal to this builder but with the given annotations declared
1671
             * on the previously defined type variable.
1672
             */
1673
            TypeVariableDefinition<S> annotateTypeVariable(AnnotationDescription... annotation);
1674

1675
            /**
1676
             * Annotates the previously defined type variable with the supplied annotations.
1677
             *
1678
             * @param annotations The annotations to declare on the previously defined type variable.
1679
             * @return A new builder that is equal to this builder but with the given annotations declared
1680
             * on the previously defined type variable.
1681
             */
1682
            TypeVariableDefinition<S> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
1683

1684
            /**
1685
             * An abstract base implementation of a type variable definition.
1686
             *
1687
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1688
             */
1689
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
1✔
1690

1691
                /**
1692
                 * {@inheritDoc}
1693
                 */
1694
                public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
1695
                    return annotateTypeVariable(Arrays.asList(annotation));
×
1696
                }
1697

1698
                /**
1699
                 * {@inheritDoc}
1700
                 */
1701
                public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
1702
                    return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
1703
                }
1704

1705
                /**
1706
                 * {@inheritDoc}
1707
                 */
1708
                public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
1709
                    return annotateTypeVariable(Arrays.asList(annotation));
1✔
1710
                }
1711
            }
1712
        }
1713

1714
        /**
1715
         * A builder for a field definition.
1716
         *
1717
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1718
         */
1719
        interface FieldDefinition<S> {
1720

1721
            /**
1722
             * Annotates the previously defined or matched field with the supplied annotations.
1723
             *
1724
             * @param annotation The annotations to declare on the previously defined or matched field.
1725
             * @return A new builder that is equal to this builder but with the given annotations declared
1726
             * on the previously defined or matched field.
1727
             */
1728
            FieldDefinition.Optional<S> annotateField(Annotation... annotation);
1729

1730
            /**
1731
             * Annotates the previously defined or matched field with the supplied annotations.
1732
             *
1733
             * @param annotations The annotations to declare on the previously defined or matched field.
1734
             * @return A new builder that is equal to this builder but with the given annotations declared
1735
             * on the previously defined or matched field.
1736
             */
1737
            FieldDefinition.Optional<S> annotateField(List<? extends Annotation> annotations);
1738

1739
            /**
1740
             * Annotates the previously defined or matched field with the supplied annotations.
1741
             *
1742
             * @param annotation The annotations to declare on the previously defined or matched field.
1743
             * @return A new builder that is equal to this builder but with the given annotations declared
1744
             * on the previously defined or matched field.
1745
             */
1746
            FieldDefinition.Optional<S> annotateField(AnnotationDescription... annotation);
1747

1748
            /**
1749
             * Annotates the previously defined or matched field with the supplied annotations.
1750
             *
1751
             * @param annotations The annotations to declare on the previously defined or matched field.
1752
             * @return A new builder that is equal to this builder but with the given annotations declared
1753
             * on the previously defined or matched field.
1754
             */
1755
            FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
1756

1757
            /**
1758
             * Applies the supplied attribute appender factory onto the previously defined or matched field.
1759
             *
1760
             * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
1761
             *                                      previously defined or matched field.
1762
             * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
1763
             * applied to the previously defined or matched field.
1764
             */
1765
            FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
1766

1767
            /**
1768
             * Applies the supplied transformer onto the previously defined or matched field. The transformed
1769
             * field is written <i>as it is</i> and is not subject to any validations.
1770
             *
1771
             * @param transformer The transformer to apply to the previously defined or matched field.
1772
             * @return A new builder that is equal to this builder but with the supplied field transformer
1773
             * applied to the previously defined or matched field.
1774
             */
1775
            FieldDefinition.Optional<S> transform(Transformer<FieldDescription> transformer);
1776

1777
            /**
1778
             * A builder for a field definition that allows for defining a value.
1779
             *
1780
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1781
             */
1782
            interface Valuable<U> extends FieldDefinition<U> {
1783

1784
                /**
1785
                 * <p>
1786
                 * Defines the supplied {@code boolean} value as a default value of the previously defined or matched field. The value can only
1787
                 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int}. For non-boolean
1788
                 * fields, the field's value is set to {@code 0} for {@code false} or {@code 1} for {@code true}.
1789
                 * </p>
1790
                 * <p>
1791
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1792
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1793
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1794
                 * </p>
1795
                 *
1796
                 * @param value The value to define as a default value of the defined field.
1797
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1798
                 * previously defined or matched field.
1799
                 */
1800
                FieldDefinition.Optional<U> value(boolean value);
1801

1802
                /**
1803
                 * <p>
1804
                 * Defines the supplied {@code int} value as a default value of the previously defined or matched field. The value can only
1805
                 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int} where the
1806
                 * value must be within the numeric type's range. The {@code boolean} type is regarded as a numeric type with the possible
1807
                 * values of {@code 0} and {@code 1} representing {@code false} and {@code true}.
1808
                 * </p>
1809
                 * <p>
1810
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1811
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1812
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1813
                 * </p>
1814
                 *
1815
                 * @param value The value to define as a default value of the defined field.
1816
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1817
                 * previously defined or matched field.
1818
                 */
1819
                FieldDefinition.Optional<U> value(int value);
1820

1821
                /**
1822
                 * <p>
1823
                 * Defines the supplied {@code long} value as a default value of the previously defined or matched field.
1824
                 * </p>
1825
                 * <p>
1826
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1827
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1828
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1829
                 * </p>
1830
                 *
1831
                 * @param value The value to define as a default value of the defined field.
1832
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1833
                 * previously defined or matched field.
1834
                 */
1835
                FieldDefinition.Optional<U> value(long value);
1836

1837
                /**
1838
                 * <p>
1839
                 * Defines the supplied {@code float} value as a default value of the previously defined or matched field.
1840
                 * </p>
1841
                 * <p>
1842
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1843
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1844
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1845
                 * </p>
1846
                 *
1847
                 * @param value The value to define as a default value of the defined field.
1848
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1849
                 * previously defined or matched field.
1850
                 */
1851
                FieldDefinition.Optional<U> value(float value);
1852

1853
                /**
1854
                 * <p>
1855
                 * Defines the supplied {@code double} value as a default value of the previously defined or matched field.
1856
                 * </p>
1857
                 * <p>
1858
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1859
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1860
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1861
                 * </p>
1862
                 *
1863
                 * @param value The value to define as a default value of the defined field.
1864
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1865
                 * previously defined or matched field.
1866
                 */
1867
                FieldDefinition.Optional<U> value(double value);
1868

1869
                /**
1870
                 * <p>
1871
                 * Defines the supplied {@link String} value as a default value of the previously defined or matched field.
1872
                 * </p>
1873
                 * <p>
1874
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1875
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1876
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1877
                 * </p>
1878
                 *
1879
                 * @param value The value to define as a default value of the defined field.
1880
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1881
                 * previously defined or matched field.
1882
                 */
1883
                FieldDefinition.Optional<U> value(String value);
1884
            }
1885

1886
            /**
1887
             * A builder for an optional field definition.
1888
             *
1889
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1890
             */
1891
            interface Optional<U> extends FieldDefinition<U>, Builder<U> {
1892

1893
                /**
1894
                 * A builder for an optional field definition that allows for defining a value.
1895
                 *
1896
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1897
                 */
1898
                interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
1899

1900
                    /**
1901
                     * An abstract base implementation of an optional field definition that allows for defining a value.
1902
                     *
1903
                     * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1904
                     */
1905
                    abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1✔
1906

1907
                        /**
1908
                         * {@inheritDoc}
1909
                         */
1910
                        public FieldDefinition.Optional<U> value(boolean value) {
1911
                            return defaultValue(value ? 1 : 0);
1✔
1912
                        }
1913

1914
                        /**
1915
                         * {@inheritDoc}
1916
                         */
1917
                        public FieldDefinition.Optional<U> value(int value) {
1918
                            return defaultValue(value);
1✔
1919
                        }
1920

1921
                        /**
1922
                         * {@inheritDoc}
1923
                         */
1924
                        public FieldDefinition.Optional<U> value(long value) {
1925
                            return defaultValue(value);
1✔
1926
                        }
1927

1928
                        /**
1929
                         * {@inheritDoc}
1930
                         */
1931
                        public FieldDefinition.Optional<U> value(float value) {
1932
                            return defaultValue(value);
1✔
1933
                        }
1934

1935
                        /**
1936
                         * {@inheritDoc}
1937
                         */
1938
                        public FieldDefinition.Optional<U> value(double value) {
1939
                            return defaultValue(value);
1✔
1940
                        }
1941

1942
                        /**
1943
                         * {@inheritDoc}
1944
                         */
1945
                        public FieldDefinition.Optional<U> value(String value) {
1946
                            if (value == null) {
1✔
1947
                                throw new IllegalArgumentException("Cannot define 'null' as constant value");
1✔
1948
                            }
1949
                            return defaultValue(value);
1✔
1950
                        }
1951

1952
                        /**
1953
                         * Defines the supplied value as a default value of the previously defined or matched field.
1954
                         *
1955
                         * @param defaultValue The value to define as a default value of the defined field.
1956
                         * @return A new builder that is equal to this builder but with the given default value declared for the
1957
                         * previously defined or matched field.
1958
                         */
1959
                        protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
1960

1961
                        /**
1962
                         * An adapter for an optional field definition that allows for defining a value.
1963
                         *
1964
                         * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1965
                         */
1966
                        @HashCodeAndEqualsPlugin.Enhance
1967
                        private abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
1968

1969
                            /**
1970
                             * The field attribute appender factory to apply.
1971
                             */
1972
                            protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
1973

1974
                            /**
1975
                             * The field transformer to apply.
1976
                             */
1977
                            protected final Transformer<FieldDescription> transformer;
1978

1979
                            /**
1980
                             * The field's default value or {@code null} if no value is to be defined.
1981
                             */
1982
                            @MaybeNull
1983
                            @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
1984
                            protected final Object defaultValue;
1985

1986
                            /**
1987
                             * Creates a new field adapter.
1988
                             *
1989
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1990
                             * @param transformer                   The field transformer to apply.
1991
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
1992
                             */
1993
                            protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
1994
                                              Transformer<FieldDescription> transformer,
1995
                                              @MaybeNull Object defaultValue) {
1✔
1996
                                this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
1✔
1997
                                this.transformer = transformer;
1✔
1998
                                this.defaultValue = defaultValue;
1✔
1999
                            }
1✔
2000

2001
                            /**
2002
                             * {@inheritDoc}
2003
                             */
2004
                            public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
2005
                                return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
1✔
2006
                            }
2007

2008
                            /**
2009
                             * {@inheritDoc}
2010
                             */
2011
                            @SuppressWarnings("unchecked") // In absence of @SafeVarargs
2012
                            public FieldDefinition.Optional<V> transform(Transformer<FieldDescription> transformer) {
2013
                                return materialize(fieldAttributeAppenderFactory, new Transformer.Compound<FieldDescription>(this.transformer, transformer), defaultValue);
1✔
2014
                            }
2015

2016
                            @Override
2017
                            protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
2018
                                return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
2019
                            }
2020

2021
                            /**
2022
                             * Creates a new optional field definition for which all of the supplied values are represented.
2023
                             *
2024
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
2025
                             * @param transformer                   The field transformer to apply.
2026
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
2027
                             * @return A new field definition that represents the supplied values.
2028
                             */
2029
                            protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
2030
                                                                                       Transformer<FieldDescription> transformer,
2031
                                                                                       @MaybeNull Object defaultValue);
2032
                        }
2033
                    }
2034
                }
2035

2036
                /**
2037
                 * An abstract base implementation for an optional field definition.
2038
                 *
2039
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2040
                 */
2041
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1✔
2042

2043
                    /**
2044
                     * {@inheritDoc}
2045
                     */
2046
                    public FieldDefinition.Optional<U> annotateField(Annotation... annotation) {
2047
                        return annotateField(Arrays.asList(annotation));
1✔
2048
                    }
2049

2050
                    /**
2051
                     * {@inheritDoc}
2052
                     */
2053
                    public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
2054
                        return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
2055
                    }
2056

2057
                    /**
2058
                     * {@inheritDoc}
2059
                     */
2060
                    public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
2061
                        return annotateField(Arrays.asList(annotation));
1✔
2062
                    }
2063
                }
2064
            }
2065
        }
2066

2067
        /**
2068
         * A builder for a method definition.
2069
         *
2070
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2071
         */
2072
        interface MethodDefinition<S> extends Builder<S> {
2073

2074
            /**
2075
             * Annotates the previously defined or matched method with the supplied annotations.
2076
             *
2077
             * @param annotation The annotations to declare on the previously defined or matched method.
2078
             * @return A new builder that is equal to this builder but with the given annotations declared
2079
             * on the previously defined or matched method.
2080
             */
2081
            MethodDefinition<S> annotateMethod(Annotation... annotation);
2082

2083
            /**
2084
             * Annotates the previously defined or matched method with the supplied annotations.
2085
             *
2086
             * @param annotations The annotations to declare on the previously defined or matched method.
2087
             * @return A new builder that is equal to this builder but with the given annotations declared
2088
             * on the previously defined or matched method.
2089
             */
2090
            MethodDefinition<S> annotateMethod(List<? extends Annotation> annotations);
2091

2092
            /**
2093
             * Annotates the previously defined or matched method with the supplied annotations.
2094
             *
2095
             * @param annotation The annotations to declare on the previously defined or matched method.
2096
             * @return A new builder that is equal to this builder but with the given annotations declared
2097
             * on the previously defined or matched method.
2098
             */
2099
            MethodDefinition<S> annotateMethod(AnnotationDescription... annotation);
2100

2101
            /**
2102
             * Annotates the previously defined or matched method with the supplied annotations.
2103
             *
2104
             * @param annotations The annotations to declare on the previously defined or matched method.
2105
             * @return A new builder that is equal to this builder but with the given annotations declared
2106
             * on the previously defined or matched method.
2107
             */
2108
            MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
2109

2110
            /**
2111
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2112
             *
2113
             * @param index      The parameter's index.
2114
             * @param annotation The annotations to declare on the previously defined or matched method.
2115
             * @return A new builder that is equal to this builder but with the given annotations declared
2116
             * on the previously defined or matched method's parameter of the given index.
2117
             */
2118
            MethodDefinition<S> annotateParameter(int index, Annotation... annotation);
2119

2120
            /**
2121
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2122
             *
2123
             * @param index       The parameter's index.
2124
             * @param annotations The annotations to declare on the previously defined or matched method.
2125
             * @return A new builder that is equal to this builder but with the given annotations declared
2126
             * on the previously defined or matched method's parameter of the given index.
2127
             */
2128
            MethodDefinition<S> annotateParameter(int index, List<? extends Annotation> annotations);
2129

2130
            /**
2131
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2132
             *
2133
             * @param index      The parameter's index.
2134
             * @param annotation The annotations to declare on the previously defined or matched method.
2135
             * @return A new builder that is equal to this builder but with the given annotations declared
2136
             * on the previously defined or matched method's parameter of the given index.
2137
             */
2138
            MethodDefinition<S> annotateParameter(int index, AnnotationDescription... annotation);
2139

2140
            /**
2141
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2142
             *
2143
             * @param index       The parameter's index.
2144
             * @param annotations The annotations to declare on the previously defined or matched method.
2145
             * @return A new builder that is equal to this builder but with the given annotations declared
2146
             * on the previously defined or matched method's parameter of the given index.
2147
             */
2148
            MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
2149

2150
            /**
2151
             * Applies the supplied method attribute appender factory onto the previously defined or matched method.
2152
             *
2153
             * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
2154
             *                                       previously defined or matched method.
2155
             * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
2156
             * applied to the previously defined or matched method.
2157
             */
2158
            MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
2159

2160
            /**
2161
             * Applies the supplied transformer onto the previously defined or matched method. The transformed
2162
             * method is written <i>as it is</i> and it not subject to any validations.
2163
             *
2164
             * @param transformer The transformer to apply to the previously defined or matched method.
2165
             * @return A new builder that is equal to this builder but with the supplied transformer
2166
             * applied to the previously defined or matched method.
2167
             */
2168
            MethodDefinition<S> transform(Transformer<MethodDescription> transformer);
2169

2170
            /**
2171
             * A builder for a method definition with a receiver type.
2172
             *
2173
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2174
             */
2175
            interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
2176

2177
                /**
2178
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2179
                 *
2180
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2181
                 * @return A new builder that is equal to this builder but with the given type defined as the
2182
                 * receiver on the previously defined or matched method.
2183
                 */
2184
                MethodDefinition<U> receiverType(AnnotatedElement receiverType);
2185

2186
                /**
2187
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2188
                 *
2189
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2190
                 * @return A new builder that is equal to this builder but with the given type defined as the
2191
                 * receiver on the previously defined or matched method.
2192
                 */
2193
                MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
2194

2195
                /**
2196
                 * An abstract base implementation of a method definition that can accept a receiver type.
2197
                 *
2198
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2199
                 */
2200
                abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
1✔
2201

2202
                    /**
2203
                     * {@inheritDoc}
2204
                     */
2205
                    public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
2206
                        return receiverType(TypeDefinition.Sort.describeAnnotated(receiverType));
×
2207
                    }
2208
                }
2209
            }
2210

2211
            /**
2212
             * A builder for defining an implementation of a method.
2213
             *
2214
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2215
             */
2216
            interface ImplementationDefinition<U> {
2217

2218
                /**
2219
                 * Implements the previously defined or matched method by the supplied implementation. A method interception
2220
                 * is typically implemented in one of the following ways:
2221
                 * <ol>
2222
                 * <li>If a method is declared by the instrumented type and the type builder creates a subclass or redefinition,
2223
                 * any preexisting method is replaced by the given implementation. Any previously defined implementation is lost.</li>
2224
                 * <li>If a method is declared by the instrumented type and the type builder creates a rebased version of the
2225
                 * instrumented type, the original method is preserved within a private, synthetic method within the instrumented
2226
                 * type. The original method therefore remains invokeable and is treated as the direct super method of the new
2227
                 * method. When rebasing a type, it therefore becomes possible to invoke a non-virtual method's super method
2228
                 * when a preexisting method body is replaced.</li>
2229
                 * <li>If a virtual method is inherited from a super type, it is overridden. The overridden method is available
2230
                 * for super method invocation.</li>
2231
                 * </ol>
2232
                 *
2233
                 * @param implementation The implementation for implementing the previously defined or matched method.
2234
                 * @return A new builder where the previously defined or matched method is implemented by the
2235
                 * supplied implementation.
2236
                 */
2237
                MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation);
2238

2239
                /**
2240
                 * Defines the previously defined or matched method not to declare a method body. This implies the
2241
                 * method to be {@code abstract} unless it was already declared to be {@code native}.
2242
                 *
2243
                 * @return A new builder where the previously defined or matched method is implemented to be abstract.
2244
                 */
2245
                MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
2246

2247
                /**
2248
                 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2249
                 * value must be supplied in its unloaded state, i.e. enumerations as {@link net.bytebuddy.description.enumeration.EnumerationDescription},
2250
                 * types as {@link TypeDescription} and annotations as {@link AnnotationDescription}. For supplying loaded types, use
2251
                 * {@link ImplementationDefinition#defaultValue(Object, Class)} must be used.
2252
                 *
2253
                 * @param annotationValue The value to be defined as a default value.
2254
                 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2255
                 */
2256
                MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue);
2257

2258
                /**
2259
                 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2260
                 * value must be supplied in its loaded state paired with the property type of the value.
2261
                 *
2262
                 * @param value The value to be defined as a default value.
2263
                 * @param type  The type of the annotation property.
2264
                 * @param <W>   The type of the annotation property.
2265
                 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2266
                 */
2267
                <W> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(W value, Class<? extends W> type);
2268

2269
                /**
2270
                 * A builder for optionally defining an implementation of a method.
2271
                 *
2272
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2273
                 */
2274
                interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
2275
                    /* union type */
2276
                }
2277

2278
                /**
2279
                 * An abstract base implementation for a builder optionally defining an implementation of a method.
2280
                 *
2281
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2282
                 */
2283
                abstract class AbstractBase<V> implements ImplementationDefinition<V> {
1✔
2284

2285
                    /**
2286
                     * {@inheritDoc}
2287
                     */
2288
                    public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) {
2289
                        return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
1✔
2290
                    }
2291
                }
2292
            }
2293

2294
            /**
2295
             * A builder for defining an implementation of a method and optionally defining a type variable.
2296
             *
2297
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2298
             */
2299
            interface TypeVariableDefinition<U> extends ImplementationDefinition<U> {
2300

2301
                /**
2302
                 * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
2303
                 *
2304
                 * @param symbol The symbol of the type variable.
2305
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2306
                 */
2307
                Annotatable<U> typeVariable(String symbol);
2308

2309
                /**
2310
                 * Defines a method variable to be declared by the currently defined method.
2311
                 *
2312
                 * @param symbol The symbol of the type variable.
2313
                 * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2314
                 *               if a bound type should be equal to the currently instrumented type.
2315
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2316
                 */
2317
                Annotatable<U> typeVariable(String symbol, Type... bound);
2318

2319
                /**
2320
                 * Defines a method variable to be declared by the currently defined method.
2321
                 *
2322
                 * @param symbol The symbol of the type variable.
2323
                 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2324
                 *               if a bound type should be equal to the currently instrumented type.
2325
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2326
                 */
2327
                Annotatable<U> typeVariable(String symbol, List<? extends Type> bounds);
2328

2329
                /**
2330
                 * Defines a method variable to be declared by the currently defined method.
2331
                 *
2332
                 * @param symbol The symbol of the type variable.
2333
                 * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2334
                 *               if a bound type should be equal to the currently instrumented type.
2335
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2336
                 */
2337
                Annotatable<U> typeVariable(String symbol, TypeDefinition... bound);
2338

2339
                /**
2340
                 * Defines a method variable to be declared by the currently defined method.
2341
                 *
2342
                 * @param symbol The symbol of the type variable.
2343
                 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2344
                 *               if a bound type should be equal to the currently instrumented type.
2345
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2346
                 */
2347
                Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
2348

2349
                /**
2350
                 * A builder for optionally defining an annotation for a type variable.
2351
                 *
2352
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2353
                 */
2354
                interface Annotatable<V> extends TypeVariableDefinition<V> {
2355

2356
                    /**
2357
                     * Annotates the previously defined type variable with the supplied annotations.
2358
                     *
2359
                     * @param annotation The annotations to declare on the previously defined type variable.
2360
                     * @return A new builder that is equal to this builder but with the given annotations declared
2361
                     * on the previously defined type variable.
2362
                     */
2363
                    Annotatable<V> annotateTypeVariable(Annotation... annotation);
2364

2365
                    /**
2366
                     * Annotates the previously defined type variable with the supplied annotations.
2367
                     *
2368
                     * @param annotations The annotations to declare on the previously defined type variable.
2369
                     * @return A new builder that is equal to this builder but with the given annotations declared
2370
                     * on the previously defined type variable.
2371
                     */
2372
                    Annotatable<V> annotateTypeVariable(List<? extends Annotation> annotations);
2373

2374
                    /**
2375
                     * Annotates the previously defined type variable with the supplied annotations.
2376
                     *
2377
                     * @param annotation The annotations to declare on the previously defined type variable.
2378
                     * @return A new builder that is equal to this builder but with the given annotations declared
2379
                     * on the previously defined type variable.
2380
                     */
2381
                    Annotatable<V> annotateTypeVariable(AnnotationDescription... annotation);
2382

2383
                    /**
2384
                     * Annotates the previously defined type variable with the supplied annotations.
2385
                     *
2386
                     * @param annotations The annotations to declare on the previously defined type variable.
2387
                     * @return A new builder that is equal to this builder but with the given annotations declared
2388
                     * on the previously defined type variable.
2389
                     */
2390
                    Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
2391

2392
                    /**
2393
                     * An abstract base implementation for defining an annotation on a parameter.
2394
                     *
2395
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2396
                     */
2397
                    abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
2398

2399
                        /**
2400
                         * {@inheritDoc}
2401
                         */
2402
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
2403
                            return annotateTypeVariable(Arrays.asList(annotation));
×
2404
                        }
2405

2406
                        /**
2407
                         * {@inheritDoc}
2408
                         */
2409
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
2410
                            return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
2411
                        }
2412

2413
                        /**
2414
                         * {@inheritDoc}
2415
                         */
2416
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
2417
                            return annotateTypeVariable(Arrays.asList(annotation));
1✔
2418
                        }
2419

2420
                        /**
2421
                         * An adapter implementation for an annotatable type variable definition.
2422
                         *
2423
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2424
                         */
2425
                        protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
1✔
2426

2427
                            /**
2428
                             * {@inheritDoc}
2429
                             */
2430
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2431
                                return materialize().typeVariable(symbol, bounds);
1✔
2432
                            }
2433

2434
                            /**
2435
                             * {@inheritDoc}
2436
                             */
2437
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2438
                                return materialize().intercept(implementation);
1✔
2439
                            }
2440

2441
                            /**
2442
                             * {@inheritDoc}
2443
                             */
2444
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2445
                                return materialize().withoutCode();
1✔
2446
                            }
2447

2448
                            /**
2449
                             * {@inheritDoc}
2450
                             */
2451
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2452
                                return materialize().defaultValue(annotationValue);
×
2453
                            }
2454

2455
                            /**
2456
                             * {@inheritDoc}
2457
                             */
2458
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2459
                                return materialize().defaultValue(value, type);
×
2460
                            }
2461

2462
                            /**
2463
                             * Materializes this instance as a parameter definition with the currently defined properties.
2464
                             *
2465
                             * @return A parameter definition with the currently defined properties.
2466
                             */
2467
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2468
                        }
2469
                    }
2470
                }
2471

2472
                /**
2473
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
2474
                 *
2475
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2476
                 */
2477
                abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
1✔
2478

2479
                    /**
2480
                     * {@inheritDoc}
2481
                     */
2482
                    public Annotatable<V> typeVariable(String symbol) {
2483
                        return typeVariable(symbol, Collections.singletonList(Object.class));
1✔
2484
                    }
2485

2486
                    /**
2487
                     * {@inheritDoc}
2488
                     */
2489
                    public Annotatable<V> typeVariable(String symbol, Type... bound) {
2490
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
2491
                    }
2492

2493
                    /**
2494
                     * {@inheritDoc}
2495
                     */
2496
                    public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
2497
                        return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
2498
                    }
2499

2500
                    /**
2501
                     * {@inheritDoc}
2502
                     */
2503
                    public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
2504
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
2505
                    }
2506
                }
2507
            }
2508

2509
            /**
2510
             * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
2511
             *
2512
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2513
             */
2514
            interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
2515

2516
                /**
2517
                 * Defines a method variable to be declared by the currently defined method.
2518
                 *
2519
                 * @param type The type of the exception being declared by the currently defined method.
2520
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2521
                 */
2522
                ExceptionDefinition<U> throwing(Type... type);
2523

2524
                /**
2525
                 * Defines a method variable to be declared by the currently defined method.
2526
                 *
2527
                 * @param types The type of the exception being declared by the currently defined method.
2528
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2529
                 */
2530
                ExceptionDefinition<U> throwing(List<? extends Type> types);
2531

2532
                /**
2533
                 * Defines a method variable to be declared by the currently defined method.
2534
                 *
2535
                 * @param type The type of the exception being declared by the currently defined method.
2536
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2537
                 */
2538
                ExceptionDefinition<U> throwing(TypeDefinition... type);
2539

2540
                /**
2541
                 * Defines a method variable to be declared by the currently defined method.
2542
                 *
2543
                 * @param types The type of the exception being declared by the currently defined method.
2544
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2545
                 */
2546
                ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
2547

2548
                /**
2549
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
2550
                 *
2551
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2552
                 */
2553
                abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
1✔
2554

2555
                    /**
2556
                     * {@inheritDoc}
2557
                     */
2558
                    public ExceptionDefinition<V> throwing(Type... type) {
2559
                        return throwing(Arrays.asList(type));
1✔
2560
                    }
2561

2562
                    /**
2563
                     * {@inheritDoc}
2564
                     */
2565
                    public ExceptionDefinition<V> throwing(List<? extends Type> types) {
2566
                        return throwing(new TypeList.Generic.ForLoadedTypes(types));
1✔
2567
                    }
2568

2569
                    /**
2570
                     * {@inheritDoc}
2571
                     */
2572
                    public ExceptionDefinition<V> throwing(TypeDefinition... type) {
2573
                        return throwing(Arrays.asList(type));
1✔
2574
                    }
2575
                }
2576
            }
2577

2578
            /**
2579
             * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2580
             *
2581
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2582
             */
2583
            interface ParameterDefinition<U> extends ExceptionDefinition<U> {
2584

2585
                /**
2586
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2587
                 *
2588
                 * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2589
                 *                            should be equal to the currently instrumented type.
2590
                 * @param name                The parameter's name.
2591
                 * @param modifierContributor The parameter's modifiers.
2592
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2593
                 */
2594
                Annotatable<U> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor);
2595

2596
                /**
2597
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2598
                 *
2599
                 * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2600
                 *                             should be equal to the currently instrumented type.
2601
                 * @param name                 The parameter's name.
2602
                 * @param modifierContributors The parameter's modifiers.
2603
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2604
                 */
2605
                Annotatable<U> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2606

2607
                /**
2608
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2609
                 *
2610
                 * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2611
                 *                  should be equal to the currently instrumented type.
2612
                 * @param name      The parameter's name.
2613
                 * @param modifiers The parameter's modifiers.
2614
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2615
                 */
2616
                Annotatable<U> withParameter(Type type, String name, int modifiers);
2617

2618
                /**
2619
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2620
                 *
2621
                 * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2622
                 *                            should be equal to the currently instrumented type.
2623
                 * @param name                The parameter's name.
2624
                 * @param modifierContributor The parameter's modifiers.
2625
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2626
                 */
2627
                Annotatable<U> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor);
2628

2629
                /**
2630
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2631
                 *
2632
                 * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2633
                 *                             should be equal to the currently instrumented type.
2634
                 * @param name                 The parameter's name.
2635
                 * @param modifierContributors The parameter's modifiers.
2636
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2637
                 */
2638
                Annotatable<U> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2639

2640
                /**
2641
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2642
                 *
2643
                 * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2644
                 *                  should be equal to the currently instrumented type.
2645
                 * @param name      The parameter's name.
2646
                 * @param modifiers The parameter's modifiers.
2647
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2648
                 */
2649
                Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers);
2650

2651
                /**
2652
                 * A builder for optionally defining an annotation on a parameter.
2653
                 *
2654
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2655
                 */
2656
                interface Annotatable<V> extends ParameterDefinition<V> {
2657

2658
                    /**
2659
                     * Annotates the previously defined parameter with the specified annotations.
2660
                     *
2661
                     * @param annotation The annotations to declare on the previously defined parameter.
2662
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2663
                     * the specified annotations.
2664
                     */
2665
                    Annotatable<V> annotateParameter(Annotation... annotation);
2666

2667
                    /**
2668
                     * Annotates the previously defined parameter with the specified annotations.
2669
                     *
2670
                     * @param annotations The annotations to declare on the previously defined parameter.
2671
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2672
                     * the specified annotations.
2673
                     */
2674
                    Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2675

2676
                    /**
2677
                     * Annotates the previously defined parameter with the specified annotations.
2678
                     *
2679
                     * @param annotation The annotations to declare on the previously defined parameter.
2680
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2681
                     * the specified annotations.
2682
                     */
2683
                    Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2684

2685
                    /**
2686
                     * Annotates the previously defined parameter with the specified annotations.
2687
                     *
2688
                     * @param annotations The annotations to declare on the previously defined parameter.
2689
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2690
                     * the specified annotations.
2691
                     */
2692
                    Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2693

2694
                    /**
2695
                     * An abstract base implementation for defining an annotation on a parameter.
2696
                     *
2697
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2698
                     */
2699
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
2700

2701
                        /**
2702
                         * {@inheritDoc}
2703
                         */
2704
                        public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
2705
                            return annotateParameter(Arrays.asList(annotation));
×
2706
                        }
2707

2708
                        /**
2709
                         * {@inheritDoc}
2710
                         */
2711
                        public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2712
                            return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
2713
                        }
2714

2715
                        /**
2716
                         * {@inheritDoc}
2717
                         */
2718
                        public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2719
                            return annotateParameter(Arrays.asList(annotation));
×
2720
                        }
2721

2722
                        /**
2723
                         * An adapter implementation for defining an annotation on a parameter.
2724
                         *
2725
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2726
                         */
2727
                        protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
1✔
2728

2729
                            /**
2730
                             * {@inheritDoc}
2731
                             */
2732
                            public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
2733
                                return materialize().withParameter(type, name, modifiers);
×
2734
                            }
2735

2736
                            /**
2737
                             * {@inheritDoc}
2738
                             */
2739
                            public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2740
                                return materialize().throwing(types);
1✔
2741
                            }
2742

2743
                            /**
2744
                             * {@inheritDoc}
2745
                             */
2746
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2747
                                return materialize().typeVariable(symbol, bounds);
×
2748
                            }
2749

2750
                            /**
2751
                             * {@inheritDoc}
2752
                             */
2753
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2754
                                return materialize().intercept(implementation);
×
2755
                            }
2756

2757
                            /**
2758
                             * {@inheritDoc}
2759
                             */
2760
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2761
                                return materialize().withoutCode();
×
2762
                            }
2763

2764
                            /**
2765
                             * {@inheritDoc}
2766
                             */
2767
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2768
                                return materialize().defaultValue(annotationValue);
×
2769
                            }
2770

2771
                            /**
2772
                             * {@inheritDoc}
2773
                             */
2774
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2775
                                return materialize().defaultValue(value, type);
×
2776
                            }
2777

2778
                            /**
2779
                             * Materializes this instance as a parameter definition with the currently defined properties.
2780
                             *
2781
                             * @return A parameter definition with the currently defined properties.
2782
                             */
2783
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2784
                        }
2785
                    }
2786
                }
2787

2788
                /**
2789
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
2790
                 *
2791
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2792
                 */
2793
                interface Simple<V> extends ExceptionDefinition<V> {
2794

2795
                    /**
2796
                     * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2797
                     *
2798
                     * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2799
                     *             should be equal to the currently instrumented type.
2800
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2801
                     */
2802
                    Annotatable<V> withParameter(Type type);
2803

2804
                    /**
2805
                     * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2806
                     *
2807
                     * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2808
                     *             should be equal to the currently instrumented type.
2809
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2810
                     */
2811
                    Annotatable<V> withParameter(TypeDefinition type);
2812

2813
                    /**
2814
                     * A builder for optionally defining an annotation on a parameter.
2815
                     *
2816
                     * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2817
                     */
2818
                    interface Annotatable<V> extends Simple<V> {
2819

2820
                        /**
2821
                         * Annotates the previously defined parameter with the specified annotations.
2822
                         *
2823
                         * @param annotation The annotations to declare on the previously defined parameter.
2824
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2825
                         * the specified annotations.
2826
                         */
2827
                        Annotatable<V> annotateParameter(Annotation... annotation);
2828

2829
                        /**
2830
                         * Annotates the previously defined parameter with the specified annotations.
2831
                         *
2832
                         * @param annotations The annotations to declare on the previously defined parameter.
2833
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2834
                         * the specified annotations.
2835
                         */
2836
                        Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2837

2838
                        /**
2839
                         * Annotates the previously defined parameter with the specified annotations.
2840
                         *
2841
                         * @param annotation The annotations to declare on the previously defined parameter.
2842
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2843
                         * the specified annotations.
2844
                         */
2845
                        Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2846

2847
                        /**
2848
                         * Annotates the previously defined parameter with the specified annotations.
2849
                         *
2850
                         * @param annotations The annotations to declare on the previously defined parameter.
2851
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2852
                         * the specified annotations.
2853
                         */
2854
                        Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2855

2856
                        /**
2857
                         * An abstract base implementation of a simple parameter definition.
2858
                         *
2859
                         * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2860
                         */
2861
                        abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
1✔
2862

2863
                            /**
2864
                             * {@inheritDoc}
2865
                             */
2866
                            public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
2867
                                return annotateParameter(Arrays.asList(annotation));
×
2868
                            }
2869

2870
                            /**
2871
                             * {@inheritDoc}
2872
                             */
2873
                            public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2874
                                return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
2875
                            }
2876

2877
                            /**
2878
                             * {@inheritDoc}
2879
                             */
2880
                            public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2881
                                return annotateParameter(Arrays.asList(annotation));
1✔
2882
                            }
2883

2884
                            /**
2885
                             * An adapter implementation of a simple parameter definition.
2886
                             *
2887
                             * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2888
                             */
2889
                            protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
1✔
2890

2891
                                /**
2892
                                 * {@inheritDoc}
2893
                                 */
2894
                                public Simple.Annotatable<X> withParameter(TypeDefinition type) {
2895
                                    return materialize().withParameter(type);
1✔
2896
                                }
2897

2898
                                /**
2899
                                 * {@inheritDoc}
2900
                                 */
2901
                                public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2902
                                    return materialize().throwing(types);
1✔
2903
                                }
2904

2905
                                /**
2906
                                 * {@inheritDoc}
2907
                                 */
2908
                                public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2909
                                    return materialize().typeVariable(symbol, bounds);
×
2910
                                }
2911

2912
                                /**
2913
                                 * {@inheritDoc}
2914
                                 */
2915
                                public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2916
                                    return materialize().intercept(implementation);
1✔
2917
                                }
2918

2919
                                /**
2920
                                 * {@inheritDoc}
2921
                                 */
2922
                                public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2923
                                    return materialize().withoutCode();
1✔
2924
                                }
2925

2926
                                /**
2927
                                 * {@inheritDoc}
2928
                                 */
2929
                                public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2930
                                    return materialize().defaultValue(annotationValue);
×
2931
                                }
2932

2933
                                /**
2934
                                 * {@inheritDoc}
2935
                                 */
2936
                                public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2937
                                    return materialize().defaultValue(value, type);
×
2938
                                }
2939

2940
                                /**
2941
                                 * Materializes this instance as a simple parameter definition with the currently defined properties.
2942
                                 *
2943
                                 * @return A simple parameter definition with the currently defined properties.
2944
                                 */
2945
                                protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
2946
                            }
2947
                        }
2948
                    }
2949

2950
                    /**
2951
                     * An abstract base implementation of an exception definition.
2952
                     *
2953
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2954
                     */
2955
                    abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
1✔
2956

2957
                        /**
2958
                         * {@inheritDoc}
2959
                         */
2960
                        public Simple.Annotatable<W> withParameter(Type type) {
2961
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
2962
                        }
2963
                    }
2964
                }
2965

2966
                /**
2967
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2968
                 * Implementations allow for the <i>one-by-one</i> definition of parameters what gives opportunity to annotate parameters in a fluent
2969
                 * style. Doing so, it is optionally possible to define parameter names and modifiers. This can be done for either all or no parameters.
2970
                 * Alternatively, parameters without annotations, names or modifiers can be defined by a single step.
2971
                 *
2972
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2973
                 */
2974
                interface Initial<V> extends ParameterDefinition<V>, Simple<V> {
2975

2976
                    /**
2977
                     * Defines the specified parameters for the currently defined method.
2978
                     *
2979
                     * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2980
                     *             should be equal to the currently instrumented type.
2981
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2982
                     */
2983
                    ExceptionDefinition<V> withParameters(Type... type);
2984

2985
                    /**
2986
                     * Defines the specified parameters for the currently defined method.
2987
                     *
2988
                     * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2989
                     *              should be equal to the currently instrumented type.
2990
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2991
                     */
2992
                    ExceptionDefinition<V> withParameters(List<? extends Type> types);
2993

2994
                    /**
2995
                     * Defines the specified parameters for the currently defined method.
2996
                     *
2997
                     * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2998
                     *             should be equal to the currently instrumented type.
2999
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
3000
                     */
3001
                    ExceptionDefinition<V> withParameters(TypeDefinition... type);
3002

3003
                    /**
3004
                     * Defines the specified parameters for the currently defined method.
3005
                     *
3006
                     * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3007
                     *              should be equal to the currently instrumented type.
3008
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
3009
                     */
3010
                    ExceptionDefinition<V> withParameters(Collection<? extends TypeDefinition> types);
3011

3012
                    /**
3013
                     * An abstract base implementation for an initial parameter definition.
3014
                     *
3015
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3016
                     */
3017
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
1✔
3018

3019
                        /**
3020
                         * {@inheritDoc}
3021
                         */
3022
                        public Simple.Annotatable<W> withParameter(Type type) {
3023
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
3024
                        }
3025

3026
                        /**
3027
                         * {@inheritDoc}
3028
                         */
3029
                        public ExceptionDefinition<W> withParameters(Type... type) {
3030
                            return withParameters(Arrays.asList(type));
1✔
3031
                        }
3032

3033
                        /**
3034
                         * {@inheritDoc}
3035
                         */
3036
                        public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
3037
                            return withParameters(new TypeList.Generic.ForLoadedTypes(types));
1✔
3038
                        }
3039

3040
                        /**
3041
                         * {@inheritDoc}
3042
                         */
3043
                        public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
3044
                            return withParameters(Arrays.asList(type));
1✔
3045
                        }
3046

3047
                        /**
3048
                         * {@inheritDoc}
3049
                         */
3050
                        public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
3051
                            ParameterDefinition.Simple<W> parameterDefinition = this;
1✔
3052
                            for (TypeDefinition type : types) {
1✔
3053
                                parameterDefinition = parameterDefinition.withParameter(type);
1✔
3054
                            }
1✔
3055
                            return parameterDefinition;
1✔
3056
                        }
3057
                    }
3058
                }
3059

3060
                /**
3061
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable, thrown exception or parameter type.
3062
                 *
3063
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3064
                 */
3065
                abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
1✔
3066

3067
                    /**
3068
                     * {@inheritDoc}
3069
                     */
3070
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
3071
                        return withParameter(type, name, Arrays.asList(modifierContributor));
1✔
3072
                    }
3073

3074
                    /**
3075
                     * {@inheritDoc}
3076
                     */
3077
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
3078
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3079
                    }
3080

3081
                    /**
3082
                     * {@inheritDoc}
3083
                     */
3084
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
3085
                        return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
1✔
3086
                    }
3087

3088
                    /**
3089
                     * {@inheritDoc}
3090
                     */
3091
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
3092
                        return withParameter(type, name, Arrays.asList(modifierContributor));
×
3093
                    }
3094

3095
                    /**
3096
                     * {@inheritDoc}
3097
                     */
3098
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
3099
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
3100
                    }
3101
                }
3102
            }
3103

3104
            /**
3105
             * An abstract base implementation of a method definition.
3106
             *
3107
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3108
             */
3109
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
1✔
3110

3111
                /**
3112
                 * {@inheritDoc}
3113
                 */
3114
                public MethodDefinition<U> annotateMethod(Annotation... annotation) {
3115
                    return annotateMethod(Arrays.asList(annotation));
1✔
3116
                }
3117

3118
                /**
3119
                 * {@inheritDoc}
3120
                 */
3121
                public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
3122
                    return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
3123
                }
3124

3125
                /**
3126
                 * {@inheritDoc}
3127
                 */
3128
                public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
3129
                    return annotateMethod(Arrays.asList(annotation));
1✔
3130
                }
3131

3132
                /**
3133
                 * {@inheritDoc}
3134
                 */
3135
                public MethodDefinition<U> annotateParameter(int index, Annotation... annotation) {
3136
                    return annotateParameter(index, Arrays.asList(annotation));
×
3137
                }
3138

3139
                /**
3140
                 * {@inheritDoc}
3141
                 */
3142
                public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
3143
                    return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
×
3144
                }
3145

3146
                /**
3147
                 * {@inheritDoc}
3148
                 */
3149
                public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
3150
                    return annotateParameter(index, Arrays.asList(annotation));
×
3151
                }
3152

3153
                /**
3154
                 * An adapter implementation of a method definition.
3155
                 *
3156
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3157
                 */
3158
                @HashCodeAndEqualsPlugin.Enhance
3159
                protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
3160

3161
                    /**
3162
                     * The handler that determines how a method is implemented.
3163
                     */
3164
                    protected final MethodRegistry.Handler handler;
3165

3166
                    /**
3167
                     * The method attribute appender factory to apply onto the method that is currently being implemented.
3168
                     */
3169
                    protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
3170

3171
                    /**
3172
                     * The transformer to apply onto the method that is currently being implemented.
3173
                     */
3174
                    protected final Transformer<MethodDescription> transformer;
3175

3176
                    /**
3177
                     * Creates a new adapter for a method definition.
3178
                     *
3179
                     * @param handler                        The handler that determines how a method is implemented.
3180
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3181
                     * @param transformer                    The transformer to apply onto the method that is currently being implemented.
3182
                     */
3183
                    protected Adapter(MethodRegistry.Handler handler,
3184
                                      MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3185
                                      Transformer<MethodDescription> transformer) {
1✔
3186
                        this.handler = handler;
1✔
3187
                        this.methodAttributeAppenderFactory = methodAttributeAppenderFactory;
1✔
3188
                        this.transformer = transformer;
1✔
3189
                    }
1✔
3190

3191
                    /**
3192
                     * {@inheritDoc}
3193
                     */
3194
                    public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
3195
                        return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), transformer);
1✔
3196
                    }
3197

3198
                    /**
3199
                     * {@inheritDoc}
3200
                     */
3201
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
3202
                    public MethodDefinition<V> transform(Transformer<MethodDescription> transformer) {
3203
                        return materialize(handler, methodAttributeAppenderFactory, new Transformer.Compound<MethodDescription>(this.transformer, transformer));
1✔
3204
                    }
3205

3206
                    /**
3207
                     * Materializes the current builder as a method definition.
3208
                     *
3209
                     * @param handler                        The handler that determines how a method is implemented.
3210
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3211
                     * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
3212
                     * @return Returns a method definition for the supplied properties.
3213
                     */
3214
                    protected abstract MethodDefinition<V> materialize(MethodRegistry.Handler handler,
3215
                                                                       MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3216
                                                                       Transformer<MethodDescription> transformer);
3217
                }
3218
            }
3219
        }
3220

3221
        /**
3222
         * A builder for a record component definition.
3223
         *
3224
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3225
         */
3226
        interface RecordComponentDefinition<S> {
3227

3228
            /**
3229
             * Annotates the record component with the supplied annotations.
3230
             *
3231
             * @param annotation The annotations to declare.
3232
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3233
             */
3234
            Optional<S> annotateRecordComponent(Annotation... annotation);
3235

3236
            /**
3237
             * Annotates the record component with the supplied annotations.
3238
             *
3239
             * @param annotations The annotations to declare.
3240
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3241
             */
3242
            Optional<S> annotateRecordComponent(List<? extends Annotation> annotations);
3243

3244
            /**
3245
             * Annotates the record component with the supplied annotations.
3246
             *
3247
             * @param annotation The annotations to declare.
3248
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3249
             */
3250
            Optional<S> annotateRecordComponent(AnnotationDescription... annotation);
3251

3252
            /**
3253
             * Annotates the record component with the supplied annotations.
3254
             *
3255
             * @param annotations The annotations to declare.
3256
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3257
             */
3258
            Optional<S> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations);
3259

3260
            /**
3261
             * Applies the supplied record component attribute appender factory onto the previously defined record component.
3262
             *
3263
             * @param recordComponentAttributeAppenderFactory The record component attribute appender factory that should be applied on the
3264
             *                                                previously defined or matched method.
3265
             * @return A new builder that is equal to this builder but with the supplied record component attribute appender factory
3266
             * applied to the previously defined record component.
3267
             */
3268
            Optional<S> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory);
3269

3270
            /**
3271
             * Transforms a record component description before writing.
3272
             *
3273
             * @param transformer The transformer to apply.
3274
             * @return new builder that is equal to this builder but with the supplied transformer being applied.
3275
             */
3276
            Optional<S> transform(Transformer<RecordComponentDescription> transformer);
3277

3278
            /**
3279
             * A {@link RecordComponentDefinition} as an optional build step.
3280
             *
3281
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3282
             */
3283
            interface Optional<U> extends RecordComponentDefinition<U>, Builder<U> {
3284

3285
                /**
3286
                 * An abstract base implementation of a record definition.
3287
                 *
3288
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3289
                 */
3290
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements RecordComponentDefinition.Optional<U> {
×
3291

3292
                    /**
3293
                     * {@inheritDoc}
3294
                     */
3295
                    public Optional<U> annotateRecordComponent(Annotation... annotation) {
3296
                        return annotateRecordComponent(Arrays.asList(annotation));
×
3297
                    }
3298

3299
                    /**
3300
                     * {@inheritDoc}
3301
                     */
3302
                    public Optional<U> annotateRecordComponent(List<? extends Annotation> annotations) {
3303
                        return annotateRecordComponent(new AnnotationList.ForLoadedAnnotations(annotations));
×
3304
                    }
3305

3306
                    /**
3307
                     * {@inheritDoc}
3308
                     */
3309
                    public Optional<U> annotateRecordComponent(AnnotationDescription... annotation) {
3310
                        return annotateRecordComponent(Arrays.asList(annotation));
×
3311
                    }
3312
                }
3313
            }
3314
        }
3315

3316
        /**
3317
         * An abstract base implementation of a dynamic type builder.
3318
         *
3319
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3320
         */
3321
        abstract class AbstractBase<S> implements Builder<S> {
1✔
3322

3323
            /**
3324
             * {@inheritDoc}
3325
             */
3326
            public InnerTypeDefinition.ForType<S> innerTypeOf(Class<?> type) {
3327
                return innerTypeOf(TypeDescription.ForLoadedType.of(type));
1✔
3328
            }
3329

3330
            /**
3331
             * {@inheritDoc}
3332
             */
3333
            public InnerTypeDefinition<S> innerTypeOf(Method method) {
3334
                return innerTypeOf(new MethodDescription.ForLoadedMethod(method));
1✔
3335
            }
3336

3337
            /**
3338
             * {@inheritDoc}
3339
             */
3340
            public InnerTypeDefinition<S> innerTypeOf(Constructor<?> constructor) {
3341
                return innerTypeOf(new MethodDescription.ForLoadedConstructor(constructor));
1✔
3342
            }
3343

3344
            /**
3345
             * {@inheritDoc}
3346
             */
3347
            public Builder<S> declaredTypes(Class<?>... type) {
3348
                return declaredTypes(Arrays.asList(type));
×
3349
            }
3350

3351
            /**
3352
             * {@inheritDoc}
3353
             */
3354
            public Builder<S> declaredTypes(TypeDescription... type) {
3355
                return declaredTypes(Arrays.asList(type));
1✔
3356
            }
3357

3358
            /**
3359
             * {@inheritDoc}
3360
             */
3361
            public Builder<S> declaredTypes(List<? extends Class<?>> type) {
3362
                return declaredTypes(new TypeList.ForLoadedTypes(type));
×
3363
            }
3364

3365
            /**
3366
             * {@inheritDoc}
3367
             */
3368
            public Builder<S> noNestMate() {
3369
                return nestHost(TargetType.DESCRIPTION);
×
3370
            }
3371

3372
            /**
3373
             * {@inheritDoc}
3374
             */
3375
            public Builder<S> nestHost(Class<?> type) {
3376
                return nestHost(TypeDescription.ForLoadedType.of(type));
×
3377
            }
3378

3379
            /**
3380
             * {@inheritDoc}
3381
             */
3382
            public Builder<S> nestMembers(Class<?>... type) {
3383
                return nestMembers(Arrays.asList(type));
1✔
3384
            }
3385

3386
            /**
3387
             * {@inheritDoc}
3388
             */
3389
            public Builder<S> nestMembers(TypeDescription... type) {
3390
                return nestMembers(Arrays.asList(type));
×
3391
            }
3392

3393
            /**
3394
             * {@inheritDoc}
3395
             */
3396
            public Builder<S> nestMembers(List<? extends Class<?>> types) {
3397
                return nestMembers(new TypeList.ForLoadedTypes(types));
1✔
3398
            }
3399

3400
            /**
3401
             * {@inheritDoc}
3402
             */
3403
            public Builder<S> permittedSubclass(Class<?>... type) {
3404
                return permittedSubclass(Arrays.asList(type));
×
3405
            }
3406

3407
            /**
3408
             * {@inheritDoc}
3409
             */
3410
            public Builder<S> permittedSubclass(TypeDescription... type) {
3411
                return permittedSubclass(Arrays.asList(type));
×
3412
            }
3413

3414
            /**
3415
             * {@inheritDoc}
3416
             */
3417
            public Builder<S> permittedSubclass(List<? extends Class<?>> types) {
3418
                return permittedSubclass(new TypeList.ForLoadedTypes(types));
×
3419
            }
3420

3421
            /**
3422
             * {@inheritDoc}
3423
             */
3424
            public Builder<S> annotateType(Annotation... annotation) {
3425
                return annotateType(Arrays.asList(annotation));
1✔
3426
            }
3427

3428
            /**
3429
             * {@inheritDoc}
3430
             */
3431
            public Builder<S> annotateType(List<? extends Annotation> annotations) {
3432
                return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
3433
            }
3434

3435
            /**
3436
             * {@inheritDoc}
3437
             */
3438
            public Builder<S> annotateType(AnnotationDescription... annotation) {
3439
                return annotateType(Arrays.asList(annotation));
1✔
3440
            }
3441

3442
            /**
3443
             * {@inheritDoc}
3444
             */
3445
            public Builder<S> modifiers(ModifierContributor.ForType... modifierContributor) {
3446
                return modifiers(Arrays.asList(modifierContributor));
1✔
3447
            }
3448

3449
            /**
3450
             * {@inheritDoc}
3451
             */
3452
            public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3453
                return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3454
            }
3455

3456
            /**
3457
             * {@inheritDoc}
3458
             */
3459
            public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
3460
                return merge(Arrays.asList(modifierContributor));
1✔
3461
            }
3462

3463
            /**
3464
             * {@inheritDoc}
3465
             */
3466
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(Type... interfaceType) {
3467
                return implement(Arrays.asList(interfaceType));
1✔
3468
            }
3469

3470
            /**
3471
             * {@inheritDoc}
3472
             */
3473
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
3474
                return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
1✔
3475
            }
3476

3477
            /**
3478
             * {@inheritDoc}
3479
             */
3480
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
3481
                return implement(Arrays.asList(interfaceType));
1✔
3482
            }
3483

3484
            /**
3485
             * {@inheritDoc}
3486
             */
3487
            public TypeVariableDefinition<S> typeVariable(String symbol) {
3488
                return typeVariable(symbol, TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class));
1✔
3489
            }
3490

3491
            /**
3492
             * {@inheritDoc}
3493
             */
3494
            public TypeVariableDefinition<S> typeVariable(String symbol, Type... bound) {
3495
                return typeVariable(symbol, Arrays.asList(bound));
1✔
3496
            }
3497

3498
            /**
3499
             * {@inheritDoc}
3500
             */
3501
            public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
3502
                return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
3503
            }
3504

3505
            /**
3506
             * {@inheritDoc}
3507
             */
3508
            public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
3509
                return typeVariable(symbol, Arrays.asList(bound));
1✔
3510
            }
3511

3512
            /**
3513
             * {@inheritDoc}
3514
             */
3515
            public RecordComponentDefinition.Optional<S> defineRecordComponent(String name, Type type) {
3516
                return defineRecordComponent(name, TypeDefinition.Sort.describe(type));
×
3517
            }
3518

3519
            /**
3520
             * {@inheritDoc}
3521
             */
3522
            public RecordComponentDefinition.Optional<S> define(RecordComponentDescription recordComponentDescription) {
3523
                return defineRecordComponent(recordComponentDescription.getActualName(), recordComponentDescription.getType());
×
3524
            }
3525

3526
            /**
3527
             * {@inheritDoc}
3528
             */
3529
            public RecordComponentDefinition<S> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
3530
                return recordComponent(new LatentMatcher.Resolved<RecordComponentDescription>(matcher));
×
3531
            }
3532

3533
            /**
3534
             * {@inheritDoc}
3535
             */
3536
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor) {
3537
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
3538
            }
3539

3540
            /**
3541
             * {@inheritDoc}
3542
             */
3543
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3544
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3545
            }
3546

3547
            /**
3548
             * {@inheritDoc}
3549
             */
3550
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
3551
                return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
1✔
3552
            }
3553

3554
            /**
3555
             * {@inheritDoc}
3556
             */
3557
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
3558
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
3559
            }
3560

3561
            /**
3562
             * {@inheritDoc}
3563
             */
3564
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3565
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3566
            }
3567

3568
            /**
3569
             * {@inheritDoc}
3570
             */
3571
            public FieldDefinition.Optional.Valuable<S> define(Field field) {
3572
                return define(new FieldDescription.ForLoadedField(field));
×
3573
            }
3574

3575
            /**
3576
             * {@inheritDoc}
3577
             */
3578
            public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
3579
                return defineField(field.getName(), field.getType(), field.getModifiers());
×
3580
            }
3581

3582
            /**
3583
             * {@inheritDoc}
3584
             */
3585
            public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
3586
                return defineField("serialVersionUID", long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
1✔
3587
            }
3588

3589
            /**
3590
             * {@inheritDoc}
3591
             */
3592
            public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
3593
                return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
1✔
3594
            }
3595

3596
            /**
3597
             * {@inheritDoc}
3598
             */
3599
            public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3600
                return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
1✔
3601
            }
3602

3603
            /**
3604
             * {@inheritDoc}
3605
             */
3606
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor) {
3607
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
3608
            }
3609

3610
            /**
3611
             * {@inheritDoc}
3612
             */
3613
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3614
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3615
            }
3616

3617
            /**
3618
             * {@inheritDoc}
3619
             */
3620
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
3621
                return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
1✔
3622
            }
3623

3624
            /**
3625
             * {@inheritDoc}
3626
             */
3627
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
3628
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
3629
            }
3630

3631
            /**
3632
             * {@inheritDoc}
3633
             */
3634
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3635
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3636
            }
3637

3638
            /**
3639
             * {@inheritDoc}
3640
             */
3641
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
3642
                return defineConstructor(Arrays.asList(modifierContributor));
1✔
3643
            }
3644

3645
            /**
3646
             * {@inheritDoc}
3647
             */
3648
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3649
                return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3650
            }
3651

3652
            /**
3653
             * {@inheritDoc}
3654
             */
3655
            public MethodDefinition.ImplementationDefinition<S> define(Method method) {
3656
                return define(new MethodDescription.ForLoadedMethod(method));
×
3657
            }
3658

3659
            /**
3660
             * {@inheritDoc}
3661
             */
3662
            public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
3663
                return define(new MethodDescription.ForLoadedConstructor(constructor));
×
3664
            }
3665

3666
            /**
3667
             * {@inheritDoc}
3668
             */
3669
            public MethodDefinition.ImplementationDefinition<S> define(MethodDescription methodDescription) {
3670
                MethodDefinition.ParameterDefinition.Initial<S> initialParameterDefinition = methodDescription.isConstructor()
×
3671
                        ? defineConstructor(methodDescription.getModifiers())
×
3672
                        : defineMethod(methodDescription.getInternalName(), methodDescription.getReturnType(), methodDescription.getModifiers());
×
3673
                ParameterList<?> parameterList = methodDescription.getParameters();
×
3674
                MethodDefinition.ExceptionDefinition<S> exceptionDefinition;
3675
                if (parameterList.hasExplicitMetaData()) {
×
3676
                    MethodDefinition.ParameterDefinition<S> parameterDefinition = initialParameterDefinition;
×
3677
                    for (ParameterDescription parameter : parameterList) {
×
3678
                        parameterDefinition = parameterDefinition.withParameter(parameter.getType(), parameter.getName(), parameter.getModifiers());
×
3679
                    }
×
3680
                    exceptionDefinition = parameterDefinition;
×
3681
                } else {
×
3682
                    exceptionDefinition = initialParameterDefinition.withParameters(parameterList.asTypeList());
×
3683
                }
3684
                MethodDefinition.TypeVariableDefinition<S> typeVariableDefinition = exceptionDefinition.throwing(methodDescription.getExceptionTypes());
×
3685
                for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
×
3686
                    typeVariableDefinition = typeVariableDefinition.typeVariable(typeVariable.getSymbol(), typeVariable.getUpperBounds());
×
3687
                }
×
3688
                return typeVariableDefinition;
×
3689
            }
3690

3691
            /**
3692
             * {@inheritDoc}
3693
             */
3694
            public FieldDefinition.Optional<S> defineProperty(String name, Type type) {
3695
                return defineProperty(name, TypeDefinition.Sort.describe(type));
1✔
3696
            }
3697

3698
            /**
3699
             * {@inheritDoc}
3700
             */
3701
            public FieldDefinition.Optional<S> defineProperty(String name, Type type, boolean readOnly) {
3702
                return defineProperty(name, TypeDefinition.Sort.describe(type), readOnly);
1✔
3703
            }
3704

3705
            /**
3706
             * {@inheritDoc}
3707
             */
3708
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type) {
3709
                return defineProperty(name, type, false);
1✔
3710
            }
3711

3712
            /**
3713
             * {@inheritDoc}
3714
             */
3715
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type, boolean readOnly) {
3716
                if (name.length() == 0) {
1✔
3717
                    throw new IllegalArgumentException("A bean property cannot have an empty name");
1✔
3718
                } else if (type.represents(void.class)) {
1✔
3719
                    throw new IllegalArgumentException("A bean property cannot have a void type");
1✔
3720
                }
3721
                DynamicType.Builder<S> builder = this;
1✔
3722
                FieldManifestation fieldManifestation;
3723
                if (!readOnly) {
1✔
3724
                    builder = builder
1✔
3725
                            .defineMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), void.class, Visibility.PUBLIC)
1✔
3726
                            .withParameters(type)
1✔
3727
                            .intercept(FieldAccessor.ofField(name));
1✔
3728
                    fieldManifestation = FieldManifestation.PLAIN;
1✔
3729
                } else {
3730
                    fieldManifestation = FieldManifestation.FINAL;
1✔
3731
                }
3732
                return builder
1✔
3733
                        .defineMethod((type.represents(boolean.class)
1✔
3734
                                ? "is"
3735
                                : "get") + Character.toUpperCase(name.charAt(0)) + name.substring(1), type, Visibility.PUBLIC)
1✔
3736
                        .intercept(FieldAccessor.ofField(name))
1✔
3737
                        .defineField(name, type, Visibility.PRIVATE, fieldManifestation);
1✔
3738
            }
3739

3740
            /**
3741
             * {@inheritDoc}
3742
             */
3743
            public MethodDefinition.ImplementationDefinition<S> method(ElementMatcher<? super MethodDescription> matcher) {
3744
                return invokable(isMethod().and(matcher));
1✔
3745
            }
3746

3747
            /**
3748
             * {@inheritDoc}
3749
             */
3750
            public MethodDefinition.ImplementationDefinition<S> constructor(ElementMatcher<? super MethodDescription> matcher) {
3751
                return invokable(isConstructor().and(matcher));
1✔
3752
            }
3753

3754
            /**
3755
             * {@inheritDoc}
3756
             */
3757
            public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
3758
                return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
1✔
3759
            }
3760

3761
            /**
3762
             * {@inheritDoc}
3763
             */
3764
            public Builder<S> withHashCodeEquals() {
3765
                return method(isHashCode())
1✔
3766
                        .intercept(HashCodeMethod.usingDefaultOffset().withIgnoredFields(isSynthetic()))
1✔
3767
                        .method(isEquals())
1✔
3768
                        .intercept(EqualsMethod.isolated().withIgnoredFields(isSynthetic()));
1✔
3769
            }
3770

3771
            /**
3772
             * {@inheritDoc}
3773
             */
3774
            public Builder<S> withToString() {
3775
                return method(isToString()).intercept(ToStringMethod.prefixedBySimpleClassName());
1✔
3776
            }
3777

3778
            /**
3779
             * {@inheritDoc}
3780
             */
3781
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation) {
3782
                return require(type, binaryRepresentation, LoadedTypeInitializer.NoOp.INSTANCE);
1✔
3783
            }
3784

3785
            /**
3786
             * {@inheritDoc}
3787
             */
3788
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer) {
3789
                return require(new Default(type, binaryRepresentation, typeInitializer, Collections.<DynamicType>emptyList()));
1✔
3790
            }
3791

3792
            /**
3793
             * {@inheritDoc}
3794
             */
3795
            public Builder<S> require(DynamicType... auxiliaryType) {
3796
                return require(Arrays.asList(auxiliaryType));
1✔
3797
            }
3798

3799
            /**
3800
             * {@inheritDoc}
3801
             */
3802
            public ContextClassVisitor wrap(ClassVisitor classVisitor) {
3803
                return wrap(classVisitor, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
1✔
3804
            }
3805

3806
            /**
3807
             * {@inheritDoc}
3808
             */
3809
            public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool) {
3810
                return wrap(classVisitor, typePool, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
×
3811
            }
3812

3813
            /**
3814
             * {@inheritDoc}
3815
             */
3816
            public Unloaded<S> make(TypePool typePool) {
3817
                return make(TypeResolutionStrategy.Passive.INSTANCE, typePool);
1✔
3818
            }
3819

3820
            /**
3821
             * {@inheritDoc}
3822
             */
3823
            public Unloaded<S> make() {
3824
                return make(TypeResolutionStrategy.Passive.INSTANCE);
1✔
3825
            }
3826

3827
            /**
3828
             * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
3829
             *
3830
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3831
             */
3832
            public abstract static class Delegator<U> extends AbstractBase<U> {
1✔
3833

3834
                /**
3835
                 * {@inheritDoc}
3836
                 */
3837
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
3838
                    return materialize().visit(asmVisitorWrapper);
1✔
3839
                }
3840

3841
                /**
3842
                 * {@inheritDoc}
3843
                 */
3844
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
3845
                    return materialize().initializer(loadedTypeInitializer);
1✔
3846
                }
3847

3848
                /**
3849
                 * {@inheritDoc}
3850
                 */
3851
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
3852
                    return materialize().annotateType(annotations);
×
3853
                }
3854

3855
                /**
3856
                 * {@inheritDoc}
3857
                 */
3858
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
3859
                    return materialize().attribute(typeAttributeAppender);
×
3860
                }
3861

3862
                /**
3863
                 * {@inheritDoc}
3864
                 */
3865
                public Builder<U> modifiers(int modifiers) {
3866
                    return materialize().modifiers(modifiers);
1✔
3867
                }
3868

3869
                /**
3870
                 * {@inheritDoc}
3871
                 */
3872
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3873
                    return materialize().merge(modifierContributors);
×
3874
                }
3875

3876
                /**
3877
                 * {@inheritDoc}
3878
                 */
3879
                public Builder<U> suffix(String suffix) {
3880
                    return materialize().suffix(suffix);
×
3881
                }
3882

3883
                /**
3884
                 * {@inheritDoc}
3885
                 */
3886
                public Builder<U> name(String name) {
3887
                    return materialize().name(name);
1✔
3888
                }
3889

3890
                /**
3891
                 * {@inheritDoc}
3892
                 */
3893
                public Builder<U> topLevelType() {
3894
                    return materialize().topLevelType();
×
3895
                }
3896

3897
                /**
3898
                 * {@inheritDoc}
3899
                 */
3900
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
3901
                    return materialize().innerTypeOf(type);
×
3902
                }
3903

3904
                /**
3905
                 * {@inheritDoc}
3906
                 */
3907
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
3908
                    return materialize().innerTypeOf(methodDescription);
×
3909
                }
3910

3911
                /**
3912
                 * {@inheritDoc}
3913
                 */
3914
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
3915
                    return materialize().declaredTypes(types);
1✔
3916
                }
3917

3918
                /**
3919
                 * {@inheritDoc}
3920
                 */
3921
                public Builder<U> nestHost(TypeDescription type) {
3922
                    return materialize().nestHost(type);
×
3923
                }
3924

3925
                /**
3926
                 * {@inheritDoc}
3927
                 */
3928
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
3929
                    return materialize().nestMembers(types);
×
3930
                }
3931

3932
                /**
3933
                 * {@inheritDoc}
3934
                 */
3935
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
3936
                    return materialize().permittedSubclass(types);
×
3937
                }
3938

3939
                /**
3940
                 * {@inheritDoc}
3941
                 */
3942
                public Builder<U> unsealed() {
3943
                    return materialize().unsealed();
×
3944
                }
3945

3946
                /**
3947
                 * {@inheritDoc}
3948
                 */
3949
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
3950
                    return materialize().implement(interfaceTypes);
1✔
3951
                }
3952

3953
                /**
3954
                 * {@inheritDoc}
3955
                 */
3956
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
3957
                    return materialize().initializer(byteCodeAppender);
1✔
3958
                }
3959

3960
                /**
3961
                 * {@inheritDoc}
3962
                 */
3963
                public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3964
                    return materialize().ignoreAlso(ignoredMethods);
1✔
3965
                }
3966

3967
                /**
3968
                 * {@inheritDoc}
3969
                 */
3970
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
3971
                    return materialize().ignoreAlso(ignoredMethods);
×
3972
                }
3973

3974
                /**
3975
                 * {@inheritDoc}
3976
                 */
3977
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3978
                    return materialize().typeVariable(symbol, bounds);
1✔
3979
                }
3980

3981
                /**
3982
                 * {@inheritDoc}
3983
                 */
3984
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
3985
                    return materialize().transform(matcher, transformer);
1✔
3986
                }
3987

3988
                /**
3989
                 * {@inheritDoc}
3990
                 */
3991
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
3992
                    return materialize().defineField(name, type, modifiers);
1✔
3993
                }
3994

3995
                /**
3996
                 * {@inheritDoc}
3997
                 */
3998
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
3999
                    return materialize().field(matcher);
1✔
4000
                }
4001

4002
                /**
4003
                 * {@inheritDoc}
4004
                 */
4005
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4006
                    return materialize().defineMethod(name, returnType, modifiers);
1✔
4007
                }
4008

4009
                /**
4010
                 * {@inheritDoc}
4011
                 */
4012
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4013
                    return materialize().defineConstructor(modifiers);
1✔
4014
                }
4015

4016
                /**
4017
                 * {@inheritDoc}
4018
                 */
4019
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4020
                    return materialize().invokable(matcher);
1✔
4021
                }
4022

4023
                /**
4024
                 * {@inheritDoc}
4025
                 */
4026
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
4027
                    return materialize().require(auxiliaryTypes);
×
4028
                }
4029

4030
                /**
4031
                 * {@inheritDoc}
4032
                 */
4033
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
4034
                    return materialize().defineRecordComponent(name, type);
×
4035
                }
4036

4037
                /**
4038
                 * {@inheritDoc}
4039
                 */
4040
                public RecordComponentDefinition.Optional<U> define(RecordComponentDescription recordComponentDescription) {
4041
                    return materialize().define(recordComponentDescription);
×
4042
                }
4043

4044
                /**
4045
                 * {@inheritDoc}
4046
                 */
4047
                public RecordComponentDefinition<U> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
4048
                    return materialize().recordComponent(matcher);
×
4049
                }
4050

4051
                /**
4052
                 * {@inheritDoc}
4053
                 */
4054
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
4055
                    return materialize().recordComponent(matcher);
×
4056
                }
4057

4058
                /**
4059
                 * {@inheritDoc}
4060
                 */
4061
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4062
                    return materialize().wrap(classVisitor, writerFlags, readerFlags);
1✔
4063
                }
4064

4065
                /**
4066
                 * {@inheritDoc}
4067
                 */
4068
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
4069
                    return materialize().wrap(classVisitor, typePool, writerFlags, readerFlags);
×
4070
                }
4071

4072
                /**
4073
                 * {@inheritDoc}
4074
                 */
4075
                public DynamicType.Unloaded<U> make() {
4076
                    return materialize().make();
1✔
4077
                }
4078

4079
                /**
4080
                 * {@inheritDoc}
4081
                 */
4082
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4083
                    return materialize().make(typeResolutionStrategy);
1✔
4084
                }
4085

4086
                /**
4087
                 * {@inheritDoc}
4088
                 */
4089
                public Unloaded<U> make(TypePool typePool) {
4090
                    return materialize().make(typePool);
×
4091
                }
4092

4093
                /**
4094
                 * {@inheritDoc}
4095
                 */
4096
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4097
                    return materialize().make(typeResolutionStrategy, typePool);
1✔
4098
                }
4099

4100
                /**
4101
                 * {@inheritDoc}
4102
                 */
4103
                public TypeDescription toTypeDescription() {
4104
                    return materialize().toTypeDescription();
1✔
4105
                }
4106

4107
                /**
4108
                 * Creates a new builder that realizes the current state of the builder.
4109
                 *
4110
                 * @return A new builder that realizes the current state of the builder.
4111
                 */
4112
                protected abstract Builder<U> materialize();
4113
            }
4114

4115
            /**
4116
             * A dynamic type writer that uses a {@link TypeWriter} to create a dynamic type.
4117
             *
4118
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4119
             */
4120
            public abstract static class UsingTypeWriter<U> extends AbstractBase<U> {
1✔
4121

4122
                /**
4123
                 * {@inheritDoc}
4124
                 */
4125
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4126
                    return toTypeWriter().wrap(classVisitor, writerFlags, readerFlags);
1✔
4127
                }
4128

4129
                /**
4130
                 * {@inheritDoc}
4131
                 */
4132
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
4133
                    return toTypeWriter(typePool).wrap(classVisitor, writerFlags, readerFlags);
×
4134
                }
4135

4136
                /**
4137
                 * {@inheritDoc}
4138
                 */
4139
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4140
                    return toTypeWriter().make(typeResolutionStrategy.resolve());
1✔
4141
                }
4142

4143
                /**
4144
                 * {@inheritDoc}
4145
                 */
4146
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4147
                    return toTypeWriter(typePool).make(typeResolutionStrategy.resolve());
1✔
4148
                }
4149

4150
                /**
4151
                 * Creates a {@link TypeWriter} without an explicitly specified {@link TypePool}.
4152
                 *
4153
                 * @return An appropriate {@link TypeWriter}.
4154
                 */
4155
                protected abstract TypeWriter<U> toTypeWriter();
4156

4157
                /**
4158
                 * Creates a {@link TypeWriter} given the specified {@link TypePool}.
4159
                 *
4160
                 * @param typePool The {@link TypePool} to use.
4161
                 * @return An appropriate {@link TypeWriter}.
4162
                 */
4163
                protected abstract TypeWriter<U> toTypeWriter(TypePool typePool);
4164
            }
4165

4166
            /**
4167
             * An adapter implementation of a dynamic type builder.
4168
             *
4169
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4170
             */
4171
            @HashCodeAndEqualsPlugin.Enhance
4172
            public abstract static class Adapter<U> extends UsingTypeWriter<U> {
4173

4174
                /**
4175
                 * The instrumented type to be created.
4176
                 */
4177
                protected final InstrumentedType.WithFlexibleName instrumentedType;
4178

4179
                /**
4180
                 * The current field registry.
4181
                 */
4182
                protected final FieldRegistry fieldRegistry;
4183

4184
                /**
4185
                 * The current method registry.
4186
                 */
4187
                protected final MethodRegistry methodRegistry;
4188

4189
                /**
4190
                 * The current record component registry.
4191
                 */
4192
                protected final RecordComponentRegistry recordComponentRegistry;
4193

4194
                /**
4195
                 * The type attribute appender to apply onto the instrumented type.
4196
                 */
4197
                protected final TypeAttributeAppender typeAttributeAppender;
4198

4199
                /**
4200
                 * The ASM visitor wrapper to apply onto the class writer.
4201
                 */
4202
                protected final AsmVisitorWrapper asmVisitorWrapper;
4203

4204
                /**
4205
                 * The class file version to define auxiliary types in.
4206
                 */
4207
                protected final ClassFileVersion classFileVersion;
4208

4209
                /**
4210
                 * The naming strategy for auxiliary types to apply.
4211
                 */
4212
                protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
4213

4214
                /**
4215
                 * The annotation value filter factory to apply.
4216
                 */
4217
                protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
4218

4219
                /**
4220
                 * The annotation retention to apply.
4221
                 */
4222
                protected final AnnotationRetention annotationRetention;
4223

4224
                /**
4225
                 * The implementation context factory to apply.
4226
                 */
4227
                protected final Implementation.Context.Factory implementationContextFactory;
4228

4229
                /**
4230
                 * The method graph compiler to use.
4231
                 */
4232
                protected final MethodGraph.Compiler methodGraphCompiler;
4233

4234
                /**
4235
                 * Determines if a type should be explicitly validated.
4236
                 */
4237
                protected final TypeValidation typeValidation;
4238

4239
                /**
4240
                 * The visibility bridge strategy to apply.
4241
                 */
4242
                protected final VisibilityBridgeStrategy visibilityBridgeStrategy;
4243

4244
                /**
4245
                 * The class reader factory to use.
4246
                 */
4247
                protected final AsmClassReader.Factory classReaderFactory;
4248

4249
                /**
4250
                 * The class writer factory to use.
4251
                 */
4252
                protected final AsmClassWriter.Factory classWriterFactory;
4253

4254
                /**
4255
                 * A matcher for identifying methods that should be excluded from instrumentation.
4256
                 */
4257
                protected final LatentMatcher<? super MethodDescription> ignoredMethods;
4258

4259
                /**
4260
                 * A list of explicitly defined auxiliary types.
4261
                 */
4262
                protected final List<? extends DynamicType> auxiliaryTypes;
4263

4264
                /**
4265
                 * Creates a new default type writer for creating a new type that is not based on an existing class file.
4266
                 *
4267
                 * @param instrumentedType             The instrumented type to be created.
4268
                 * @param fieldRegistry                The current field registry.
4269
                 * @param methodRegistry               The current method registry.
4270
                 * @param recordComponentRegistry      The record component pool to use.
4271
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
4272
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
4273
                 * @param classFileVersion             The class file version to define auxiliary types in.
4274
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
4275
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
4276
                 * @param annotationRetention          The annotation retention to apply.
4277
                 * @param implementationContextFactory The implementation context factory to apply.
4278
                 * @param methodGraphCompiler          The method graph compiler to use.
4279
                 * @param typeValidation               Determines if a type should be explicitly validated.
4280
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
4281
                 * @param classReaderFactory           The class reader factory to use.
4282
                 * @param classWriterFactory           The class writer factory to use.
4283
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
4284
                 * @param auxiliaryTypes               A list of explicitly defined auxiliary types.
4285
                 */
4286
                protected Adapter(InstrumentedType.WithFlexibleName instrumentedType,
4287
                                  FieldRegistry fieldRegistry,
4288
                                  MethodRegistry methodRegistry,
4289
                                  RecordComponentRegistry recordComponentRegistry,
4290
                                  TypeAttributeAppender typeAttributeAppender,
4291
                                  AsmVisitorWrapper asmVisitorWrapper,
4292
                                  ClassFileVersion classFileVersion,
4293
                                  AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4294
                                  AnnotationValueFilter.Factory annotationValueFilterFactory,
4295
                                  AnnotationRetention annotationRetention,
4296
                                  Implementation.Context.Factory implementationContextFactory,
4297
                                  MethodGraph.Compiler methodGraphCompiler,
4298
                                  TypeValidation typeValidation,
4299
                                  VisibilityBridgeStrategy visibilityBridgeStrategy,
4300
                                  AsmClassReader.Factory classReaderFactory,
4301
                                  AsmClassWriter.Factory classWriterFactory,
4302
                                  LatentMatcher<? super MethodDescription> ignoredMethods,
4303
                                  List<? extends DynamicType> auxiliaryTypes) {
1✔
4304
                    this.instrumentedType = instrumentedType;
1✔
4305
                    this.fieldRegistry = fieldRegistry;
1✔
4306
                    this.methodRegistry = methodRegistry;
1✔
4307
                    this.recordComponentRegistry = recordComponentRegistry;
1✔
4308
                    this.typeAttributeAppender = typeAttributeAppender;
1✔
4309
                    this.asmVisitorWrapper = asmVisitorWrapper;
1✔
4310
                    this.classFileVersion = classFileVersion;
1✔
4311
                    this.auxiliaryTypeNamingStrategy = auxiliaryTypeNamingStrategy;
1✔
4312
                    this.annotationValueFilterFactory = annotationValueFilterFactory;
1✔
4313
                    this.annotationRetention = annotationRetention;
1✔
4314
                    this.implementationContextFactory = implementationContextFactory;
1✔
4315
                    this.methodGraphCompiler = methodGraphCompiler;
1✔
4316
                    this.typeValidation = typeValidation;
1✔
4317
                    this.visibilityBridgeStrategy = visibilityBridgeStrategy;
1✔
4318
                    this.classReaderFactory = classReaderFactory;
1✔
4319
                    this.classWriterFactory = classWriterFactory;
1✔
4320
                    this.ignoredMethods = ignoredMethods;
1✔
4321
                    this.auxiliaryTypes = auxiliaryTypes;
1✔
4322
                }
1✔
4323

4324
                /**
4325
                 * {@inheritDoc}
4326
                 */
4327
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
4328
                    return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
1✔
4329
                }
4330

4331
                /**
4332
                 * {@inheritDoc}
4333
                 */
4334
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
4335
                    return new FieldMatchAdapter(matcher);
1✔
4336
                }
4337

4338
                /**
4339
                 * {@inheritDoc}
4340
                 */
4341
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4342
                    return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
1✔
4343
                }
4344

4345
                /**
4346
                 * {@inheritDoc}
4347
                 */
4348
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4349
                    return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
1✔
4350
                }
4351

4352
                /**
4353
                 * {@inheritDoc}
4354
                 */
4355
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4356
                    return new MethodMatchAdapter(matcher);
1✔
4357
                }
4358

4359
                /**
4360
                 * {@inheritDoc}
4361
                 */
4362
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
4363
                    return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
1✔
4364
                }
4365

4366
                /**
4367
                 * {@inheritDoc}
4368
                 */
4369
                @SuppressWarnings("unchecked") // In absence of @SafeVarargs
4370
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
4371
                    return materialize(instrumentedType,
1✔
4372
                            fieldRegistry,
4373
                            methodRegistry,
4374
                            recordComponentRegistry,
4375
                            typeAttributeAppender,
4376
                            asmVisitorWrapper,
4377
                            classFileVersion,
4378
                            auxiliaryTypeNamingStrategy,
4379
                            annotationValueFilterFactory,
4380
                            annotationRetention,
4381
                            implementationContextFactory,
4382
                            methodGraphCompiler,
4383
                            typeValidation,
4384
                            visibilityBridgeStrategy,
4385
                            classReaderFactory,
4386
                            classWriterFactory,
4387
                            new LatentMatcher.Disjunction<MethodDescription>(this.ignoredMethods, ignoredMethods),
4388
                            auxiliaryTypes);
4389
                }
4390

4391
                /**
4392
                 * {@inheritDoc}
4393
                 */
4394
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
4395
                    return new RecordComponentDefinitionAdapter(new RecordComponentDescription.Token(name, type.asGenericType()));
×
4396
                }
4397

4398
                /**
4399
                 * {@inheritDoc}
4400
                 */
4401
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
4402
                    return new RecordComponentMatchAdapter(matcher);
×
4403
                }
4404

4405
                /**
4406
                 * {@inheritDoc}
4407
                 */
4408
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
4409
                    return materialize(instrumentedType.withInitializer(byteCodeAppender),
1✔
4410
                            fieldRegistry,
4411
                            methodRegistry,
4412
                            recordComponentRegistry,
4413
                            typeAttributeAppender,
4414
                            asmVisitorWrapper,
4415
                            classFileVersion,
4416
                            auxiliaryTypeNamingStrategy,
4417
                            annotationValueFilterFactory,
4418
                            annotationRetention,
4419
                            implementationContextFactory,
4420
                            methodGraphCompiler,
4421
                            typeValidation,
4422
                            visibilityBridgeStrategy,
4423
                            classReaderFactory,
4424
                            classWriterFactory,
4425
                            ignoredMethods,
4426
                            auxiliaryTypes);
4427
                }
4428

4429
                /**
4430
                 * {@inheritDoc}
4431
                 */
4432
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
4433
                    return materialize(instrumentedType.withInitializer(loadedTypeInitializer),
1✔
4434
                            fieldRegistry,
4435
                            methodRegistry,
4436
                            recordComponentRegistry,
4437
                            typeAttributeAppender,
4438
                            asmVisitorWrapper,
4439
                            classFileVersion,
4440
                            auxiliaryTypeNamingStrategy,
4441
                            annotationValueFilterFactory,
4442
                            annotationRetention,
4443
                            implementationContextFactory,
4444
                            methodGraphCompiler,
4445
                            typeValidation,
4446
                            visibilityBridgeStrategy,
4447
                            classReaderFactory,
4448
                            classWriterFactory,
4449
                            ignoredMethods,
4450
                            auxiliaryTypes);
4451
                }
4452

4453
                /**
4454
                 * {@inheritDoc}
4455
                 */
4456
                public Builder<U> name(String name) {
4457
                    return materialize(instrumentedType.withName(name),
1✔
4458
                            fieldRegistry,
4459
                            methodRegistry,
4460
                            recordComponentRegistry,
4461
                            typeAttributeAppender,
4462
                            asmVisitorWrapper,
4463
                            classFileVersion,
4464
                            auxiliaryTypeNamingStrategy,
4465
                            annotationValueFilterFactory,
4466
                            annotationRetention,
4467
                            implementationContextFactory,
4468
                            methodGraphCompiler,
4469
                            typeValidation,
4470
                            visibilityBridgeStrategy,
4471
                            classReaderFactory,
4472
                            classWriterFactory,
4473
                            ignoredMethods,
4474
                            auxiliaryTypes);
4475
                }
4476

4477
                /**
4478
                 * {@inheritDoc}
4479
                 */
4480
                public Builder<U> suffix(String suffix) {
4481
                    return name(instrumentedType.getName() + "$" + suffix);
×
4482
                }
4483

4484
                /**
4485
                 * {@inheritDoc}
4486
                 */
4487
                public Builder<U> modifiers(int modifiers) {
4488
                    return materialize(instrumentedType.withModifiers(modifiers),
1✔
4489
                            fieldRegistry,
4490
                            methodRegistry,
4491
                            recordComponentRegistry,
4492
                            typeAttributeAppender,
4493
                            asmVisitorWrapper,
4494
                            classFileVersion,
4495
                            auxiliaryTypeNamingStrategy,
4496
                            annotationValueFilterFactory,
4497
                            annotationRetention,
4498
                            implementationContextFactory,
4499
                            methodGraphCompiler,
4500
                            typeValidation,
4501
                            visibilityBridgeStrategy,
4502
                            classReaderFactory,
4503
                            classWriterFactory,
4504
                            ignoredMethods,
4505
                            auxiliaryTypes);
4506
                }
4507

4508
                /**
4509
                 * {@inheritDoc}
4510
                 */
4511
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4512
                    return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
1✔
4513
                            fieldRegistry,
4514
                            methodRegistry,
4515
                            recordComponentRegistry,
4516
                            typeAttributeAppender,
4517
                            asmVisitorWrapper,
4518
                            classFileVersion,
4519
                            auxiliaryTypeNamingStrategy,
4520
                            annotationValueFilterFactory,
4521
                            annotationRetention,
4522
                            implementationContextFactory,
4523
                            methodGraphCompiler,
4524
                            typeValidation,
4525
                            visibilityBridgeStrategy,
4526
                            classReaderFactory,
4527
                            classWriterFactory,
4528
                            ignoredMethods,
4529
                            auxiliaryTypes);
4530
                }
4531

4532
                /**
4533
                 * {@inheritDoc}
4534
                 */
4535
                public Builder<U> topLevelType() {
4536
                    return Adapter.this.materialize(instrumentedType
1✔
4537
                                    .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4538
                                    .withEnclosingType(TypeDescription.UNDEFINED)
1✔
4539
                                    .withLocalClass(false),
1✔
4540
                            fieldRegistry,
4541
                            methodRegistry,
4542
                            recordComponentRegistry,
4543
                            typeAttributeAppender,
4544
                            asmVisitorWrapper,
4545
                            classFileVersion,
4546
                            auxiliaryTypeNamingStrategy,
4547
                            annotationValueFilterFactory,
4548
                            annotationRetention,
4549
                            implementationContextFactory,
4550
                            methodGraphCompiler,
4551
                            typeValidation,
4552
                            visibilityBridgeStrategy,
4553
                            classReaderFactory,
4554
                            classWriterFactory,
4555
                            ignoredMethods,
4556
                            auxiliaryTypes);
4557
                }
4558

4559
                /**
4560
                 * {@inheritDoc}
4561
                 */
4562
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
4563
                    return new InnerTypeDefinitionForTypeAdapter(type);
1✔
4564
                }
4565

4566
                /**
4567
                 * {@inheritDoc}
4568
                 */
4569
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
4570
                    return methodDescription.isTypeInitializer()
1✔
4571
                            ? new InnerTypeDefinitionForTypeAdapter(methodDescription.getDeclaringType())
1✔
4572
                            : new InnerTypeDefinitionForMethodAdapter(methodDescription);
4573
                }
4574

4575
                /**
4576
                 * {@inheritDoc}
4577
                 */
4578
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
4579
                    return materialize(instrumentedType.withDeclaredTypes(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
4580
                            fieldRegistry,
4581
                            methodRegistry,
4582
                            recordComponentRegistry,
4583
                            typeAttributeAppender,
4584
                            asmVisitorWrapper,
4585
                            classFileVersion,
4586
                            auxiliaryTypeNamingStrategy,
4587
                            annotationValueFilterFactory,
4588
                            annotationRetention,
4589
                            implementationContextFactory,
4590
                            methodGraphCompiler,
4591
                            typeValidation,
4592
                            visibilityBridgeStrategy,
4593
                            classReaderFactory,
4594
                            classWriterFactory,
4595
                            ignoredMethods,
4596
                            auxiliaryTypes);
4597
                }
4598

4599
                /**
4600
                 * {@inheritDoc}
4601
                 */
4602
                public Builder<U> nestHost(TypeDescription type) {
4603
                    return materialize(instrumentedType.withNestHost(type),
×
4604
                            fieldRegistry,
4605
                            methodRegistry,
4606
                            recordComponentRegistry,
4607
                            typeAttributeAppender,
4608
                            asmVisitorWrapper,
4609
                            classFileVersion,
4610
                            auxiliaryTypeNamingStrategy,
4611
                            annotationValueFilterFactory,
4612
                            annotationRetention,
4613
                            implementationContextFactory,
4614
                            methodGraphCompiler,
4615
                            typeValidation,
4616
                            visibilityBridgeStrategy,
4617
                            classReaderFactory,
4618
                            classWriterFactory,
4619
                            ignoredMethods,
4620
                            auxiliaryTypes);
4621
                }
4622

4623
                /**
4624
                 * {@inheritDoc}
4625
                 */
4626
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
4627
                    return materialize(instrumentedType.withNestMembers(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
4628
                            fieldRegistry,
4629
                            methodRegistry,
4630
                            recordComponentRegistry,
4631
                            typeAttributeAppender,
4632
                            asmVisitorWrapper,
4633
                            classFileVersion,
4634
                            auxiliaryTypeNamingStrategy,
4635
                            annotationValueFilterFactory,
4636
                            annotationRetention,
4637
                            implementationContextFactory,
4638
                            methodGraphCompiler,
4639
                            typeValidation,
4640
                            visibilityBridgeStrategy,
4641
                            classReaderFactory,
4642
                            classWriterFactory,
4643
                            ignoredMethods,
4644
                            auxiliaryTypes);
4645
                }
4646

4647
                /**
4648
                 * {@inheritDoc}
4649
                 */
4650
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
4651
                    return materialize(instrumentedType.withPermittedSubclasses(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
×
4652
                            fieldRegistry,
4653
                            methodRegistry,
4654
                            recordComponentRegistry,
4655
                            typeAttributeAppender,
4656
                            asmVisitorWrapper,
4657
                            classFileVersion,
4658
                            auxiliaryTypeNamingStrategy,
4659
                            annotationValueFilterFactory,
4660
                            annotationRetention,
4661
                            implementationContextFactory,
4662
                            methodGraphCompiler,
4663
                            typeValidation,
4664
                            visibilityBridgeStrategy,
4665
                            classReaderFactory,
4666
                            classWriterFactory,
4667
                            ignoredMethods,
4668
                            auxiliaryTypes);
4669
                }
4670

4671
                /**
4672
                 * {@inheritDoc}
4673
                 */
4674
                public Builder<U> unsealed() {
4675
                    return materialize(instrumentedType.withPermittedSubclasses(TypeList.UNDEFINED),
×
4676
                            fieldRegistry,
4677
                            methodRegistry,
4678
                            recordComponentRegistry,
4679
                            typeAttributeAppender,
4680
                            asmVisitorWrapper,
4681
                            classFileVersion,
4682
                            auxiliaryTypeNamingStrategy,
4683
                            annotationValueFilterFactory,
4684
                            annotationRetention,
4685
                            implementationContextFactory,
4686
                            methodGraphCompiler,
4687
                            typeValidation,
4688
                            visibilityBridgeStrategy,
4689
                            classReaderFactory,
4690
                            classWriterFactory,
4691
                            ignoredMethods,
4692
                            auxiliaryTypes);
4693
                }
4694

4695
                /**
4696
                 * {@inheritDoc}
4697
                 */
4698
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
4699
                    return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
4700
                }
4701

4702
                /**
4703
                 * {@inheritDoc}
4704
                 */
4705
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
4706
                    return materialize(instrumentedType.withTypeVariables(matcher, transformer),
1✔
4707
                            fieldRegistry,
4708
                            methodRegistry,
4709
                            recordComponentRegistry,
4710
                            typeAttributeAppender,
4711
                            asmVisitorWrapper,
4712
                            classFileVersion,
4713
                            auxiliaryTypeNamingStrategy,
4714
                            annotationValueFilterFactory,
4715
                            annotationRetention,
4716
                            implementationContextFactory,
4717
                            methodGraphCompiler,
4718
                            typeValidation,
4719
                            visibilityBridgeStrategy,
4720
                            classReaderFactory,
4721
                            classWriterFactory,
4722
                            ignoredMethods,
4723
                            auxiliaryTypes);
4724
                }
4725

4726
                /**
4727
                 * {@inheritDoc}
4728
                 */
4729
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
4730
                    return materialize(instrumentedType,
1✔
4731
                            fieldRegistry,
4732
                            methodRegistry,
4733
                            recordComponentRegistry,
4734
                            new TypeAttributeAppender.Compound(this.typeAttributeAppender, typeAttributeAppender),
4735
                            asmVisitorWrapper,
4736
                            classFileVersion,
4737
                            auxiliaryTypeNamingStrategy,
4738
                            annotationValueFilterFactory,
4739
                            annotationRetention,
4740
                            implementationContextFactory,
4741
                            methodGraphCompiler,
4742
                            typeValidation,
4743
                            visibilityBridgeStrategy,
4744
                            classReaderFactory,
4745
                            classWriterFactory,
4746
                            ignoredMethods,
4747
                            auxiliaryTypes);
4748
                }
4749

4750
                /**
4751
                 * {@inheritDoc}
4752
                 */
4753
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
4754
                    return materialize(instrumentedType.withAnnotations(new ArrayList<AnnotationDescription>(annotations)),
1✔
4755
                            fieldRegistry,
4756
                            methodRegistry,
4757
                            recordComponentRegistry,
4758
                            typeAttributeAppender,
4759
                            asmVisitorWrapper,
4760
                            classFileVersion,
4761
                            auxiliaryTypeNamingStrategy,
4762
                            annotationValueFilterFactory,
4763
                            annotationRetention,
4764
                            implementationContextFactory,
4765
                            methodGraphCompiler,
4766
                            typeValidation,
4767
                            visibilityBridgeStrategy,
4768
                            classReaderFactory,
4769
                            classWriterFactory,
4770
                            ignoredMethods,
4771
                            auxiliaryTypes);
4772
                }
4773

4774
                /**
4775
                 * {@inheritDoc}
4776
                 */
4777
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
4778
                    return materialize(instrumentedType,
1✔
4779
                            fieldRegistry,
4780
                            methodRegistry,
4781
                            recordComponentRegistry,
4782
                            typeAttributeAppender,
4783
                            new AsmVisitorWrapper.Compound(this.asmVisitorWrapper, asmVisitorWrapper),
4784
                            classFileVersion,
4785
                            auxiliaryTypeNamingStrategy,
4786
                            annotationValueFilterFactory,
4787
                            annotationRetention,
4788
                            implementationContextFactory,
4789
                            methodGraphCompiler,
4790
                            typeValidation,
4791
                            visibilityBridgeStrategy,
4792
                            classReaderFactory,
4793
                            classWriterFactory,
4794
                            ignoredMethods,
4795
                            auxiliaryTypes);
4796
                }
4797

4798
                /**
4799
                 * {@inheritDoc}
4800
                 */
4801
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
4802
                    return materialize(instrumentedType,
1✔
4803
                            fieldRegistry,
4804
                            methodRegistry,
4805
                            recordComponentRegistry,
4806
                            typeAttributeAppender,
4807
                            asmVisitorWrapper,
4808
                            classFileVersion,
4809
                            auxiliaryTypeNamingStrategy,
4810
                            annotationValueFilterFactory,
4811
                            annotationRetention,
4812
                            implementationContextFactory,
4813
                            methodGraphCompiler,
4814
                            typeValidation,
4815
                            visibilityBridgeStrategy,
4816
                            classReaderFactory,
4817
                            classWriterFactory,
4818
                            ignoredMethods,
4819
                            CompoundList.of(this.auxiliaryTypes, new ArrayList<DynamicType>(auxiliaryTypes)));
1✔
4820
                }
4821

4822
                /**
4823
                 * {@inheritDoc}
4824
                 */
4825
                public TypeDescription toTypeDescription() {
4826
                    return instrumentedType;
1✔
4827
                }
4828

4829
                /**
4830
                 * Materializes the supplied state of a dynamic type builder.
4831
                 *
4832
                 * @param instrumentedType             The instrumented type.
4833
                 * @param fieldRegistry                The current field registry.
4834
                 * @param methodRegistry               The current method registry.
4835
                 * @param recordComponentRegistry      The record component pool to use.
4836
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
4837
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
4838
                 * @param classFileVersion             The class file version to define auxiliary types in.
4839
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
4840
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
4841
                 * @param annotationRetention          The annotation retention to apply.
4842
                 * @param implementationContextFactory The implementation context factory to apply.
4843
                 * @param methodGraphCompiler          The method graph compiler to use.
4844
                 * @param typeValidation               The type validation state.
4845
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
4846
                 * @param classReaderFactory           The class reader factory to use.
4847
                 * @param classWriterFactory           The class writer factory to use.
4848
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
4849
                 * @param auxiliaryTypes               A list of explicitly required auxiliary types.
4850
                 * @return A type builder that represents the supplied arguments.
4851
                 */
4852
                protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
4853
                                                          FieldRegistry fieldRegistry,
4854
                                                          MethodRegistry methodRegistry,
4855
                                                          RecordComponentRegistry recordComponentRegistry,
4856
                                                          TypeAttributeAppender typeAttributeAppender,
4857
                                                          AsmVisitorWrapper asmVisitorWrapper,
4858
                                                          ClassFileVersion classFileVersion,
4859
                                                          AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4860
                                                          AnnotationValueFilter.Factory annotationValueFilterFactory,
4861
                                                          AnnotationRetention annotationRetention,
4862
                                                          Implementation.Context.Factory implementationContextFactory,
4863
                                                          MethodGraph.Compiler methodGraphCompiler,
4864
                                                          TypeValidation typeValidation,
4865
                                                          VisibilityBridgeStrategy visibilityBridgeStrategy,
4866
                                                          AsmClassReader.Factory classReaderFactory,
4867
                                                          AsmClassWriter.Factory classWriterFactory,
4868
                                                          LatentMatcher<? super MethodDescription> ignoredMethods,
4869
                                                          List<? extends DynamicType> auxiliaryTypes);
4870

4871
                /**
4872
                 * An adapter for applying an inner type definition for an outer type.
4873
                 */
4874
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4875
                protected class InnerTypeDefinitionForTypeAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition.ForType<U> {
4876

4877
                    /**
4878
                     * A description of the type that is the defined outer type.
4879
                     */
4880
                    private final TypeDescription typeDescription;
4881

4882
                    /**
4883
                     * Creates a new adapter for an inner type definition for an outer type.
4884
                     *
4885
                     * @param typeDescription A description of the type that is the defined outer type.
4886
                     */
4887
                    protected InnerTypeDefinitionForTypeAdapter(TypeDescription typeDescription) {
1✔
4888
                        this.typeDescription = typeDescription;
1✔
4889
                    }
1✔
4890

4891
                    /**
4892
                     * {@inheritDoc}
4893
                     */
4894
                    public Builder<U> asAnonymousType() {
4895
                        return Adapter.this.materialize(instrumentedType
1✔
4896
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4897
                                        .withEnclosingType(typeDescription)
1✔
4898
                                        .withAnonymousClass(true),
1✔
4899
                                fieldRegistry,
4900
                                methodRegistry,
4901
                                recordComponentRegistry,
4902
                                typeAttributeAppender,
4903
                                asmVisitorWrapper,
4904
                                classFileVersion,
4905
                                auxiliaryTypeNamingStrategy,
4906
                                annotationValueFilterFactory,
4907
                                annotationRetention,
4908
                                implementationContextFactory,
4909
                                methodGraphCompiler,
4910
                                typeValidation,
4911
                                visibilityBridgeStrategy,
4912
                                classReaderFactory,
4913
                                classWriterFactory,
4914
                                ignoredMethods,
4915
                                auxiliaryTypes);
4916
                    }
4917

4918
                    /**
4919
                     * {@inheritDoc}
4920
                     */
4921
                    public Builder<U> asMemberType() {
4922
                        return Adapter.this.materialize(instrumentedType
1✔
4923
                                        .withDeclaringType(typeDescription)
1✔
4924
                                        .withEnclosingType(typeDescription)
1✔
4925
                                        .withAnonymousClass(false)
1✔
4926
                                        .withLocalClass(false),
1✔
4927
                                fieldRegistry,
4928
                                methodRegistry,
4929
                                recordComponentRegistry,
4930
                                typeAttributeAppender,
4931
                                asmVisitorWrapper,
4932
                                classFileVersion,
4933
                                auxiliaryTypeNamingStrategy,
4934
                                annotationValueFilterFactory,
4935
                                annotationRetention,
4936
                                implementationContextFactory,
4937
                                methodGraphCompiler,
4938
                                typeValidation,
4939
                                visibilityBridgeStrategy,
4940
                                classReaderFactory,
4941
                                classWriterFactory,
4942
                                ignoredMethods,
4943
                                auxiliaryTypes);
4944
                    }
4945

4946
                    @Override
4947
                    protected Builder<U> materialize() {
4948
                        return Adapter.this.materialize(instrumentedType
1✔
4949
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4950
                                        .withEnclosingType(typeDescription)
1✔
4951
                                        .withLocalClass(true),
1✔
4952
                                fieldRegistry,
4953
                                methodRegistry,
4954
                                recordComponentRegistry,
4955
                                typeAttributeAppender,
4956
                                asmVisitorWrapper,
4957
                                classFileVersion,
4958
                                auxiliaryTypeNamingStrategy,
4959
                                annotationValueFilterFactory,
4960
                                annotationRetention,
4961
                                implementationContextFactory,
4962
                                methodGraphCompiler,
4963
                                typeValidation,
4964
                                visibilityBridgeStrategy,
4965
                                classReaderFactory,
4966
                                classWriterFactory,
4967
                                ignoredMethods,
4968
                                auxiliaryTypes);
4969
                    }
4970
                }
4971

4972
                /**
4973
                 * An adapter for applying an inner type definition for an outer method or constructor.
4974
                 */
4975
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4976
                protected class InnerTypeDefinitionForMethodAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition<U> {
4977

4978
                    /**
4979
                     * A description of the declaring method or constructor.
4980
                     */
4981
                    private final MethodDescription.InDefinedShape methodDescription;
4982

4983
                    /**
4984
                     * Creates a new adapter for defining a type that is declared within a method or constructor.
4985
                     *
4986
                     * @param methodDescription A description of the declaring method or constructor.
4987
                     */
4988
                    protected InnerTypeDefinitionForMethodAdapter(MethodDescription.InDefinedShape methodDescription) {
1✔
4989
                        this.methodDescription = methodDescription;
1✔
4990
                    }
1✔
4991

4992
                    /**
4993
                     * {@inheritDoc}
4994
                     */
4995
                    public Builder<U> asAnonymousType() {
4996
                        return Adapter.this.materialize(instrumentedType
1✔
4997
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4998
                                        .withEnclosingMethod(methodDescription)
1✔
4999
                                        .withAnonymousClass(true),
1✔
5000
                                fieldRegistry,
5001
                                methodRegistry,
5002
                                recordComponentRegistry,
5003
                                typeAttributeAppender,
5004
                                asmVisitorWrapper,
5005
                                classFileVersion,
5006
                                auxiliaryTypeNamingStrategy,
5007
                                annotationValueFilterFactory,
5008
                                annotationRetention,
5009
                                implementationContextFactory,
5010
                                methodGraphCompiler,
5011
                                typeValidation,
5012
                                visibilityBridgeStrategy,
5013
                                classReaderFactory,
5014
                                classWriterFactory,
5015
                                ignoredMethods,
5016
                                auxiliaryTypes);
5017
                    }
5018

5019
                    @Override
5020
                    protected Builder<U> materialize() {
5021
                        return Adapter.this.materialize(instrumentedType
1✔
5022
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
5023
                                        .withEnclosingMethod(methodDescription)
1✔
5024
                                        .withLocalClass(true),
1✔
5025
                                fieldRegistry,
5026
                                methodRegistry,
5027
                                recordComponentRegistry,
5028
                                typeAttributeAppender,
5029
                                asmVisitorWrapper,
5030
                                classFileVersion,
5031
                                auxiliaryTypeNamingStrategy,
5032
                                annotationValueFilterFactory,
5033
                                annotationRetention,
5034
                                implementationContextFactory,
5035
                                methodGraphCompiler,
5036
                                typeValidation,
5037
                                visibilityBridgeStrategy,
5038
                                classReaderFactory,
5039
                                classWriterFactory,
5040
                                ignoredMethods,
5041
                                auxiliaryTypes);
5042
                    }
5043
                }
5044

5045
                /**
5046
                 * An adapter for defining a new type variable for the instrumented type.
5047
                 */
5048
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5049
                protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
5050

5051
                    /**
5052
                     * The current definition of the type variable.
5053
                     */
5054
                    private final TypeVariableToken token;
5055

5056
                    /**
5057
                     * Creates a new type variable definition adapter.
5058
                     *
5059
                     * @param token The current definition of the type variable.
5060
                     */
5061
                    protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
1✔
5062
                        this.token = token;
1✔
5063
                    }
1✔
5064

5065
                    /**
5066
                     * {@inheritDoc}
5067
                     */
5068
                    public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
5069
                        return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
1✔
5070
                                token.getBounds(),
1✔
5071
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
5072
                    }
5073

5074
                    @Override
5075
                    protected Builder<U> materialize() {
5076
                        return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
1✔
5077
                                fieldRegistry,
5078
                                methodRegistry,
5079
                                recordComponentRegistry,
5080
                                typeAttributeAppender,
5081
                                asmVisitorWrapper,
5082
                                classFileVersion,
5083
                                auxiliaryTypeNamingStrategy,
5084
                                annotationValueFilterFactory,
5085
                                annotationRetention,
5086
                                implementationContextFactory,
5087
                                methodGraphCompiler,
5088
                                typeValidation,
5089
                                visibilityBridgeStrategy,
5090
                                classReaderFactory,
5091
                                classWriterFactory,
5092
                                ignoredMethods,
5093
                                auxiliaryTypes);
5094
                    }
5095
                }
5096

5097
                /**
5098
                 * An adapter for defining a new field.
5099
                 */
5100
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5101
                protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
5102

5103
                    /**
5104
                     * The token representing the current field definition.
5105
                     */
5106
                    private final FieldDescription.Token token;
5107

5108
                    /**
5109
                     * Creates a new field definition adapter.
5110
                     *
5111
                     * @param token The token representing the current field definition.
5112
                     */
5113
                    protected FieldDefinitionAdapter(FieldDescription.Token token) {
5114
                        this(FieldAttributeAppender.ForInstrumentedField.INSTANCE,
1✔
5115
                                Transformer.NoOp.<FieldDescription>make(),
1✔
5116
                                FieldDescription.NO_DEFAULT_VALUE,
5117
                                token);
5118
                    }
1✔
5119

5120
                    /**
5121
                     * Creates a new field definition adapter.
5122
                     *
5123
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
5124
                     * @param transformer                   The field transformer to apply.
5125
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
5126
                     * @param token                         The token representing the current field definition.
5127
                     */
5128
                    protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5129
                                                     Transformer<FieldDescription> transformer,
5130
                                                     @MaybeNull Object defaultValue,
5131
                                                     FieldDescription.Token token) {
1✔
5132
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
5133
                        this.token = token;
1✔
5134
                    }
1✔
5135

5136
                    /**
5137
                     * {@inheritDoc}
5138
                     */
5139
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
5140
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, new FieldDescription.Token(token.getName(),
1✔
5141
                                token.getModifiers(),
1✔
5142
                                token.getType(),
1✔
5143
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
5144
                    }
5145

5146
                    @Override
5147
                    protected Builder<U> materialize() {
5148
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
1✔
5149
                                fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
5150
                                methodRegistry,
5151
                                recordComponentRegistry,
5152
                                typeAttributeAppender,
5153
                                asmVisitorWrapper,
5154
                                classFileVersion,
5155
                                auxiliaryTypeNamingStrategy,
5156
                                annotationValueFilterFactory,
5157
                                annotationRetention,
5158
                                implementationContextFactory,
5159
                                methodGraphCompiler,
5160
                                typeValidation,
5161
                                visibilityBridgeStrategy,
5162
                                classReaderFactory,
5163
                                classWriterFactory,
5164
                                ignoredMethods,
5165
                                auxiliaryTypes);
5166
                    }
5167

5168
                    @Override
5169
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5170
                                                      Transformer<FieldDescription> transformer,
5171
                                                      @MaybeNull Object defaultValue) {
5172
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
1✔
5173
                    }
5174
                }
5175

5176
                /**
5177
                 * An adapter for matching an existing field.
5178
                 */
5179
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5180
                protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
5181

5182
                    /**
5183
                     * The matcher for any fields to apply this matcher to.
5184
                     */
5185
                    private final LatentMatcher<? super FieldDescription> matcher;
5186

5187
                    /**
5188
                     * Creates a new field match adapter.
5189
                     *
5190
                     * @param matcher The matcher for any fields to apply this matcher to.
5191
                     */
5192
                    protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
5193
                        this(FieldAttributeAppender.NoOp.INSTANCE,
1✔
5194
                                Transformer.NoOp.<FieldDescription>make(),
1✔
5195
                                FieldDescription.NO_DEFAULT_VALUE,
5196
                                matcher);
5197
                    }
1✔
5198

5199
                    /**
5200
                     * Creates a new field match adapter.
5201
                     *
5202
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
5203
                     * @param transformer                   The field transformer to apply.
5204
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
5205
                     * @param matcher                       The matcher for any fields to apply this matcher to.
5206
                     */
5207
                    protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5208
                                                Transformer<FieldDescription> transformer,
5209
                                                @MaybeNull Object defaultValue,
5210
                                                LatentMatcher<? super FieldDescription> matcher) {
1✔
5211
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
5212
                        this.matcher = matcher;
1✔
5213
                    }
1✔
5214

5215
                    /**
5216
                     * {@inheritDoc}
5217
                     */
5218
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
5219
                        return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
1✔
5220
                    }
5221

5222
                    @Override
5223
                    protected Builder<U> materialize() {
5224
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
5225
                                fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
5226
                                methodRegistry,
5227
                                recordComponentRegistry,
5228
                                typeAttributeAppender,
5229
                                asmVisitorWrapper,
5230
                                classFileVersion,
5231
                                auxiliaryTypeNamingStrategy,
5232
                                annotationValueFilterFactory,
5233
                                annotationRetention,
5234
                                implementationContextFactory,
5235
                                methodGraphCompiler,
5236
                                typeValidation,
5237
                                visibilityBridgeStrategy,
5238
                                classReaderFactory,
5239
                                classWriterFactory,
5240
                                ignoredMethods,
5241
                                auxiliaryTypes);
5242
                    }
5243

5244
                    @Override
5245
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5246
                                                      Transformer<FieldDescription> transformer,
5247
                                                      @MaybeNull Object defaultValue) {
5248
                        return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
1✔
5249
                    }
5250
                }
5251

5252
                /**
5253
                 * An adapter for defining a new method.
5254
                 */
5255
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5256
                protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
5257

5258
                    /**
5259
                     * A token representing the currently defined method.
5260
                     */
5261
                    private final MethodDescription.Token token;
5262

5263
                    /**
5264
                     * Creates a new method definition adapter.
5265
                     *
5266
                     * @param token A token representing the currently defined method.
5267
                     */
5268
                    protected MethodDefinitionAdapter(MethodDescription.Token token) {
1✔
5269
                        this.token = token;
1✔
5270
                    }
1✔
5271

5272
                    /**
5273
                     * {@inheritDoc}
5274
                     */
5275
                    public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
5276
                        return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
1✔
5277
                    }
5278

5279
                    /**
5280
                     * {@inheritDoc}
5281
                     */
5282
                    public Simple.Annotatable<U> withParameter(TypeDefinition type) {
5283
                        return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
1✔
5284
                    }
5285

5286
                    /**
5287
                     * {@inheritDoc}
5288
                     */
5289
                    public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
5290
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5291
                                token.getModifiers(),
1✔
5292
                                token.getTypeVariableTokens(),
1✔
5293
                                token.getReturnType(),
1✔
5294
                                token.getParameterTokens(),
1✔
5295
                                CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
1✔
5296
                                token.getAnnotations(),
1✔
5297
                                token.getDefaultValue(),
1✔
5298
                                token.getReceiverType()));
1✔
5299
                    }
5300

5301
                    /**
5302
                     * {@inheritDoc}
5303
                     */
5304
                    public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
5305
                        return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
5306
                    }
5307

5308
                    /**
5309
                     * {@inheritDoc}
5310
                     */
5311
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5312
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
5313
                    }
5314

5315
                    /**
5316
                     * {@inheritDoc}
5317
                     */
5318
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5319
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5320
                                (token.getModifiers() & Opcodes.ACC_NATIVE) == 0
1✔
5321
                                        ? ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers())
1✔
5322
                                        : token.getModifiers(),
1✔
5323
                                token.getTypeVariableTokens(),
1✔
5324
                                token.getReturnType(),
1✔
5325
                                token.getParameterTokens(),
1✔
5326
                                token.getExceptionTypes(),
1✔
5327
                                token.getAnnotations(),
1✔
5328
                                token.getDefaultValue(),
1✔
5329
                                token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
5330
                    }
5331

5332
                    /**
5333
                     * {@inheritDoc}
5334
                     */
5335
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5336
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5337
                                ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
1✔
5338
                                token.getTypeVariableTokens(),
1✔
5339
                                token.getReturnType(),
1✔
5340
                                token.getParameterTokens(),
1✔
5341
                                token.getExceptionTypes(),
1✔
5342
                                token.getAnnotations(),
1✔
5343
                                annotationValue,
5344
                                token.getReceiverType())).materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
5345
                    }
5346

5347
                    /**
5348
                     * Materializes the given handler as the implementation.
5349
                     *
5350
                     * @param handler The handler for implementing the method.
5351
                     * @return A method definition for the given handler.
5352
                     */
5353
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5354
                        return new AnnotationAdapter(handler);
1✔
5355
                    }
5356

5357
                    /**
5358
                     * An adapter for defining a new type variable for the currently defined method.
5359
                     */
5360
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5361
                    protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
5362

5363
                        /**
5364
                         * The currently defined type variable.
5365
                         */
5366
                        private final TypeVariableToken token;
5367

5368
                        /**
5369
                         * Creates a new type variable annotation adapter.
5370
                         *
5371
                         * @param token The currently defined type variable.
5372
                         */
5373
                        protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
1✔
5374
                            this.token = token;
1✔
5375
                        }
1✔
5376

5377
                        @Override
5378
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
5379
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
5380
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
5381
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getTypeVariableTokens(), token),
1✔
5382
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
5383
                                    MethodDefinitionAdapter.this.token.getParameterTokens(),
1✔
5384
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
5385
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
5386
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
5387
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
5388
                        }
5389

5390
                        /**
5391
                         * {@inheritDoc}
5392
                         */
5393
                        public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
5394
                            return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
1✔
5395
                                    token.getBounds(),
1✔
5396
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
5397
                        }
5398
                    }
5399

5400
                    /**
5401
                     * An annotation adapter for a parameter definition.
5402
                     */
5403
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5404
                    protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
5405

5406
                        /**
5407
                         * The token of the currently defined parameter.
5408
                         */
5409
                        private final ParameterDescription.Token token;
5410

5411
                        /**
5412
                         * Creates a new parameter annotation adapter.
5413
                         *
5414
                         * @param token The token of the currently defined parameter.
5415
                         */
5416
                        protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
5417
                            this.token = token;
1✔
5418
                        }
1✔
5419

5420
                        /**
5421
                         * {@inheritDoc}
5422
                         */
5423
                        public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5424
                            return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
×
5425
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
5426
                                    token.getName(),
×
5427
                                    token.getModifiers()));
×
5428
                        }
5429

5430
                        @Override
5431
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
5432
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
5433
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
5434
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
5435
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
5436
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
5437
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
5438
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
5439
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
5440
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
5441
                        }
5442
                    }
5443

5444
                    /**
5445
                     * An annotation adapter for a simple parameter definition.
5446
                     */
5447
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5448
                    protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
5449

5450
                        /**
5451
                         * The token of the currently defined parameter.
5452
                         */
5453
                        private final ParameterDescription.Token token;
5454

5455
                        /**
5456
                         * Creates a new simple parameter annotation adapter.
5457
                         *
5458
                         * @param token The token of the currently defined parameter.
5459
                         */
5460
                        protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
5461
                            this.token = token;
1✔
5462
                        }
1✔
5463

5464
                        /**
5465
                         * {@inheritDoc}
5466
                         */
5467
                        public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5468
                            return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
1✔
5469
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
5470
                                    token.getName(),
1✔
5471
                                    token.getModifiers()));
1✔
5472
                        }
5473

5474
                        @Override
5475
                        protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
5476
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
5477
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
5478
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
5479
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
5480
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
5481
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
5482
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
5483
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
5484
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
5485
                        }
5486
                    }
5487

5488
                    /**
5489
                     * An annotation adapter for a method definition.
5490
                     */
5491
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5492
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5493

5494
                        /**
5495
                         * Creates a new annotation adapter.
5496
                         *
5497
                         * @param handler The handler that determines how a method is implemented.
5498
                         */
5499
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
5500
                            this(handler,
1✔
5501
                                    MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER,
5502
                                    Transformer.NoOp.<MethodDescription>make());
1✔
5503
                        }
1✔
5504

5505
                        /**
5506
                         * Creates a new annotation adapter.
5507
                         *
5508
                         * @param handler                        The handler that determines how a method is implemented.
5509
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5510
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
5511
                         */
5512
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
5513
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5514
                                                    Transformer<MethodDescription> transformer) {
1✔
5515
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
5516
                        }
1✔
5517

5518
                        /**
5519
                         * {@inheritDoc}
5520
                         */
5521
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5522
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5523
                                    token.getModifiers(),
1✔
5524
                                    token.getTypeVariableTokens(),
1✔
5525
                                    token.getReturnType(),
1✔
5526
                                    token.getParameterTokens(),
1✔
5527
                                    token.getExceptionTypes(),
1✔
5528
                                    token.getAnnotations(),
1✔
5529
                                    token.getDefaultValue(),
1✔
5530
                                    receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5531
                        }
5532

5533
                        /**
5534
                         * {@inheritDoc}
5535
                         */
5536
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5537
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5538
                                    token.getModifiers(),
1✔
5539
                                    token.getTypeVariableTokens(),
1✔
5540
                                    token.getReturnType(),
1✔
5541
                                    token.getParameterTokens(),
1✔
5542
                                    token.getExceptionTypes(),
1✔
5543
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
5544
                                    token.getDefaultValue(),
1✔
5545
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
5546
                        }
5547

5548
                        /**
5549
                         * {@inheritDoc}
5550
                         */
5551
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5552
                            List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
×
5553
                            parameterTokens.set(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
×
5554
                                    CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
5555
                                    token.getParameterTokens().get(index).getName(),
×
5556
                                    token.getParameterTokens().get(index).getModifiers()));
×
5557
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
×
5558
                                    token.getModifiers(),
×
5559
                                    token.getTypeVariableTokens(),
×
5560
                                    token.getReturnType(),
×
5561
                                    parameterTokens,
5562
                                    token.getExceptionTypes(),
×
5563
                                    token.getAnnotations(),
×
5564
                                    token.getDefaultValue(),
×
5565
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
5566
                        }
5567

5568
                        @Override
5569
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5570
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5571
                                                                  Transformer<MethodDescription> transformer) {
5572
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
5573
                        }
5574

5575
                        @Override
5576
                        protected Builder<U> materialize() {
5577
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
1✔
5578
                                    fieldRegistry,
5579
                                    methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
1✔
5580
                                            handler,
5581
                                            methodAttributeAppenderFactory,
5582
                                            transformer),
5583
                                    recordComponentRegistry,
5584
                                    typeAttributeAppender,
5585
                                    asmVisitorWrapper,
5586
                                    classFileVersion,
5587
                                    auxiliaryTypeNamingStrategy,
5588
                                    annotationValueFilterFactory,
5589
                                    annotationRetention,
5590
                                    implementationContextFactory,
5591
                                    methodGraphCompiler,
5592
                                    typeValidation,
5593
                                    visibilityBridgeStrategy,
5594
                                    classReaderFactory,
5595
                                    classWriterFactory,
5596
                                    ignoredMethods,
5597
                                    auxiliaryTypes);
5598
                        }
5599
                    }
5600
                }
5601

5602
                /**
5603
                 * An adapter for matching an existing method.
5604
                 */
5605
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5606
                protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
5607

5608
                    /**
5609
                     * The method matcher of this adapter.
5610
                     */
5611
                    private final LatentMatcher<? super MethodDescription> matcher;
5612

5613
                    /**
5614
                     * Creates a new method match adapter.
5615
                     *
5616
                     * @param matcher The method matcher of this adapter.
5617
                     */
5618
                    protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
1✔
5619
                        this.matcher = matcher;
1✔
5620
                    }
1✔
5621

5622
                    /**
5623
                     * {@inheritDoc}
5624
                     */
5625
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5626
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
5627
                    }
5628

5629
                    /**
5630
                     * {@inheritDoc}
5631
                     */
5632
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5633
                        return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
5634
                    }
5635

5636
                    /**
5637
                     * {@inheritDoc}
5638
                     */
5639
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5640
                        return materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
5641
                    }
5642

5643
                    /**
5644
                     * Materializes the method definition with the supplied handler.
5645
                     *
5646
                     * @param handler The handler that implements any method matched by this instances matcher.
5647
                     * @return A method definition where any matched method is implemented by the supplied handler.
5648
                     */
5649
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5650
                        return new AnnotationAdapter(handler);
1✔
5651
                    }
5652

5653
                    /**
5654
                     * An annotation adapter for implementing annotations during a method definition.
5655
                     */
5656
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5657
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5658

5659
                        /**
5660
                         * Creates a new annotation adapter.
5661
                         *
5662
                         * @param handler The handler that determines how a method is implemented.
5663
                         */
5664
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
5665
                            this(handler, MethodAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<MethodDescription>make());
1✔
5666
                        }
1✔
5667

5668
                        /**
5669
                         * Creates a new annotation adapter.
5670
                         *
5671
                         * @param handler                        The handler that determines how a method is implemented.
5672
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5673
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
5674
                         */
5675
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
5676
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5677
                                                    Transformer<MethodDescription> transformer) {
1✔
5678
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
5679
                        }
1✔
5680

5681
                        /**
5682
                         * {@inheritDoc}
5683
                         */
5684
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5685
                            return new AnnotationAdapter(handler,
1✔
5686
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
5687
                                    transformer);
5688
                        }
5689

5690
                        /**
5691
                         * {@inheritDoc}
5692
                         */
5693
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5694
                            return new AnnotationAdapter(handler,
1✔
5695
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
5696
                                    transformer);
5697
                        }
5698

5699
                        /**
5700
                         * {@inheritDoc}
5701
                         */
5702
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5703
                            return new AnnotationAdapter(handler,
×
5704
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
5705
                                    transformer);
5706
                        }
5707

5708
                        @Override
5709
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5710
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5711
                                                                  Transformer<MethodDescription> transformer) {
5712
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
5713
                        }
5714

5715
                        @Override
5716
                        protected Builder<U> materialize() {
5717
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
5718
                                    fieldRegistry,
5719
                                    methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, transformer),
1✔
5720
                                    recordComponentRegistry,
5721
                                    typeAttributeAppender,
5722
                                    asmVisitorWrapper,
5723
                                    classFileVersion,
5724
                                    auxiliaryTypeNamingStrategy,
5725
                                    annotationValueFilterFactory,
5726
                                    annotationRetention,
5727
                                    implementationContextFactory,
5728
                                    methodGraphCompiler,
5729
                                    typeValidation,
5730
                                    visibilityBridgeStrategy,
5731
                                    classReaderFactory,
5732
                                    classWriterFactory,
5733
                                    ignoredMethods,
5734
                                    auxiliaryTypes);
5735
                        }
5736
                    }
5737
                }
5738

5739
                /**
5740
                 * An adapter for optionally matching methods defined by declared interfaces.
5741
                 */
5742
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5743
                protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
5744

5745
                    /**
5746
                     * The interfaces whose methods are optionally matched.
5747
                     */
5748
                    private final TypeList.Generic interfaces;
5749

5750
                    /**
5751
                     * Creates a new optional method match adapter.
5752
                     *
5753
                     * @param interfaces The interfaces whose methods are optionally matched.
5754
                     */
5755
                    protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
1✔
5756
                        this.interfaces = interfaces;
1✔
5757
                    }
1✔
5758

5759
                    @Override
5760
                    protected Builder<U> materialize() {
5761
                        return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
1✔
5762
                                fieldRegistry,
5763
                                methodRegistry,
5764
                                recordComponentRegistry,
5765
                                typeAttributeAppender,
5766
                                asmVisitorWrapper,
5767
                                classFileVersion,
5768
                                auxiliaryTypeNamingStrategy,
5769
                                annotationValueFilterFactory,
5770
                                annotationRetention,
5771
                                implementationContextFactory,
5772
                                methodGraphCompiler,
5773
                                typeValidation,
5774
                                visibilityBridgeStrategy,
5775
                                classReaderFactory,
5776
                                classWriterFactory,
5777
                                ignoredMethods,
5778
                                auxiliaryTypes);
5779
                    }
5780

5781
                    /**
5782
                     * {@inheritDoc}
5783
                     */
5784
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5785
                        return interfaceType().intercept(implementation);
1✔
5786
                    }
5787

5788
                    /**
5789
                     * {@inheritDoc}
5790
                     */
5791
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5792
                        return interfaceType().withoutCode();
×
5793
                    }
5794

5795
                    /**
5796
                     * {@inheritDoc}
5797
                     */
5798
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5799
                        return interfaceType().defaultValue(annotationValue);
×
5800
                    }
5801

5802
                    /**
5803
                     * {@inheritDoc}
5804
                     */
5805
                    public <V> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(V value, Class<? extends V> type) {
5806
                        return interfaceType().defaultValue(value, type);
×
5807
                    }
5808

5809
                    /**
5810
                     * Returns a matcher for the interfaces' methods.
5811
                     *
5812
                     * @return A matcher for the interfaces' methods.
5813
                     */
5814
                    private MethodDefinition.ImplementationDefinition<U> interfaceType() {
5815
                        ElementMatcher.Junction<TypeDescription> elementMatcher = none();
1✔
5816
                        for (TypeDescription typeDescription : interfaces.asErasures()) {
1✔
5817
                            elementMatcher = elementMatcher.or(isSuperTypeOf(typeDescription));
1✔
5818
                        }
1✔
5819
                        return materialize().invokable(isDeclaredBy(isInterface().and(elementMatcher)));
1✔
5820
                    }
5821
                }
5822

5823
                /**
5824
                 * An adapter for defining a record component.
5825
                 */
5826
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5827
                protected class RecordComponentDefinitionAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5828

5829
                    /**
5830
                     * The record component attribute appender factory to apply.
5831
                     */
5832
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5833

5834
                    /**
5835
                     * A token representing the defined record component.
5836
                     */
5837
                    private final RecordComponentDescription.Token token;
5838

5839
                    /**
5840
                     * A transformer to apply on matched record component descriptions.
5841
                     */
5842
                    private final Transformer<RecordComponentDescription> transformer;
5843

5844
                    /**
5845
                     * Creates a new record component definition adapter.
5846
                     *
5847
                     * @param token A token representing the defined record component.
5848
                     */
5849
                    protected RecordComponentDefinitionAdapter(RecordComponentDescription.Token token) {
5850
                        this(RecordComponentAttributeAppender.ForInstrumentedRecordComponent.INSTANCE,
×
5851
                                Transformer.NoOp.<RecordComponentDescription>make(),
×
5852
                                token);
5853
                    }
×
5854

5855
                    /**
5856
                     * Creates a new record component definition adapter.
5857
                     *
5858
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5859
                     * @param transformer                             A transformer to apply on matched record component descriptions.
5860
                     * @param token                                   A token representing the defined record component.
5861
                     */
5862
                    protected RecordComponentDefinitionAdapter(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5863
                                                               Transformer<RecordComponentDescription> transformer,
5864
                                                               RecordComponentDescription.Token token) {
×
5865
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
5866
                        this.transformer = transformer;
×
5867
                        this.token = token;
×
5868
                    }
×
5869

5870
                    /**
5871
                     * {@inheritDoc}
5872
                     */
5873
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5874
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory, transformer, new RecordComponentDescription.Token(token.getName(),
×
5875
                                token.getType(),
×
5876
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
×
5877
                    }
5878

5879
                    /**
5880
                     * {@inheritDoc}
5881
                     */
5882
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5883
                        return new RecordComponentDefinitionAdapter(new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
5884
                                recordComponentAttributeAppenderFactory), transformer, token);
5885
                    }
5886

5887
                    /**
5888
                     * {@inheritDoc}
5889
                     */
5890
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
5891
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5892
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory,
×
5893
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer),
5894
                                token);
5895
                    }
5896

5897
                    @Override
5898
                    protected Builder<U> materialize() {
5899
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withRecordComponent(token),
×
5900
                                fieldRegistry,
5901
                                methodRegistry,
5902
                                recordComponentRegistry.prepend(new LatentMatcher.ForRecordComponentToken(token),
×
5903
                                        recordComponentAttributeAppenderFactory,
5904
                                        transformer),
5905
                                typeAttributeAppender,
5906
                                asmVisitorWrapper,
5907
                                classFileVersion,
5908
                                auxiliaryTypeNamingStrategy,
5909
                                annotationValueFilterFactory,
5910
                                annotationRetention,
5911
                                implementationContextFactory,
5912
                                methodGraphCompiler,
5913
                                typeValidation,
5914
                                visibilityBridgeStrategy,
5915
                                classReaderFactory,
5916
                                classWriterFactory,
5917
                                ignoredMethods,
5918
                                auxiliaryTypes);
5919
                    }
5920
                }
5921

5922
                /**
5923
                 * An adapter for matching record components.
5924
                 */
5925
                protected class RecordComponentMatchAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5926

5927
                    /**
5928
                     * The matcher for identifying record components to match.
5929
                     */
5930
                    private final LatentMatcher<? super RecordComponentDescription> matcher;
5931

5932
                    /**
5933
                     * The record component attribute appender factory to apply.
5934
                     */
5935
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5936

5937
                    /**
5938
                     * A transformer to apply on matched record component descriptions.
5939
                     */
5940
                    private final Transformer<RecordComponentDescription> transformer;
5941

5942
                    /**
5943
                     * Creates a new record component match adapter.
5944
                     *
5945
                     * @param matcher The matcher for identifying record components to match.
5946
                     */
5947
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher) {
5948
                        this(matcher, RecordComponentAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<RecordComponentDescription>make());
×
5949
                    }
×
5950

5951
                    /**
5952
                     * Creates a new record component match adapter.
5953
                     *
5954
                     * @param matcher                                 The matcher for identifying record components to match.
5955
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5956
                     * @param transformer                             A transformer to apply on matched record component descriptions.
5957
                     */
5958
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher,
5959
                                                          RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5960
                                                          Transformer<RecordComponentDescription> transformer) {
×
5961
                        this.matcher = matcher;
×
5962
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
5963
                        this.transformer = transformer;
×
5964
                    }
×
5965

5966
                    /**
5967
                     * {@inheritDoc}
5968
                     */
5969
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5970
                        return attribute(new RecordComponentAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
×
5971
                    }
5972

5973
                    /**
5974
                     * {@inheritDoc}
5975
                     */
5976
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5977
                        return new RecordComponentMatchAdapter(matcher, new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
5978
                                recordComponentAttributeAppenderFactory), transformer);
5979
                    }
5980

5981
                    /**
5982
                     * {@inheritDoc}
5983
                     */
5984
                    @SuppressWarnings("unchecked")  // In absence of @SafeVarargs
5985
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5986
                        return new RecordComponentMatchAdapter(matcher,
×
5987
                                recordComponentAttributeAppenderFactory,
5988
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer));
5989
                    }
5990

5991
                    @Override
5992
                    protected Builder<U> materialize() {
5993
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
×
5994
                                fieldRegistry,
5995
                                methodRegistry,
5996
                                recordComponentRegistry.prepend(matcher, recordComponentAttributeAppenderFactory, transformer),
×
5997
                                typeAttributeAppender,
5998
                                asmVisitorWrapper,
5999
                                classFileVersion,
6000
                                auxiliaryTypeNamingStrategy,
6001
                                annotationValueFilterFactory,
6002
                                annotationRetention,
6003
                                implementationContextFactory,
6004
                                methodGraphCompiler,
6005
                                typeValidation,
6006
                                visibilityBridgeStrategy,
6007
                                classReaderFactory,
6008
                                classWriterFactory,
6009
                                ignoredMethods,
6010
                                auxiliaryTypes);
6011
                    }
6012
                }
6013
            }
6014
        }
6015
    }
6016

6017
    /**
6018
     * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
6019
     *
6020
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6021
     *            type itself, an interface or the direct super class.
6022
     */
6023
    interface Unloaded<T> extends DynamicType {
6024

6025
        /**
6026
         * <p>
6027
         * Attempts to load this dynamic type including all of its auxiliary types, if any. If the class loader is an
6028
         * unsealed instance of {@link InjectionClassLoader}, the classes are injected directy into the class loader, otherwise,
6029
         * a new class loader is created where the supplied class loader is set as parent.
6030
         * </p>
6031
         * <p>
6032
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
6033
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
6034
         * </p>
6035
         *
6036
         * @param classLoader The class loader to use for this class loading or {@code null} for using the boot loader.
6037
         * @return This dynamic type in its loaded state.
6038
         */
6039
        Loaded<T> load(@MaybeNull ClassLoader classLoader);
6040

6041
        /**
6042
         * <p>
6043
         * Attempts to load this dynamic type including all of its auxiliary types, if any.
6044
         * </p>
6045
         * <p>
6046
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
6047
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
6048
         * </p>
6049
         *
6050
         * @param classLoader          The class loader to use for this class loading.
6051
         * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
6052
         * @param <S>                  The least specific type of class loader this strategy can apply to.
6053
         * @return This dynamic type in its loaded state.
6054
         * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
6055
         */
6056
        <S extends ClassLoader> Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
6057

6058
        /**
6059
         * Includes the provided dynamic types as auxiliary types of this instance.
6060
         *
6061
         * @param dynamicType The dynamic types to include.
6062
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
6063
         */
6064
        Unloaded<T> include(DynamicType... dynamicType);
6065

6066
        /**
6067
         * Includes the provided dynamic types as auxiliary types of this instance.
6068
         *
6069
         * @param dynamicTypes The dynamic types to include.
6070
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
6071
         */
6072
        Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
6073
    }
6074

6075
    /**
6076
     * A dynamic type that has been loaded into the running instance of the Java virtual machine.
6077
     *
6078
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6079
     *            type itself, an interface or the direct super class.
6080
     */
6081
    interface Loaded<T> extends DynamicType {
6082

6083
        /**
6084
         * Returns the loaded main class.
6085
         *
6086
         * @return A loaded class representation of this dynamic type.
6087
         */
6088
        Class<? extends T> getLoaded();
6089

6090
        /**
6091
         * <p>
6092
         * Returns a map of all loaded auxiliary types to this dynamic type.
6093
         * </p>
6094
         * <p>
6095
         * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
6096
         * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
6097
         * </p>
6098
         *
6099
         * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
6100
         */
6101
        Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
6102

6103
        /**
6104
         * Returns all loaded types that are implied by this dynamic type.
6105
         *
6106
         * @return All loaded types that are implied by this dynamic type.
6107
         */
6108
        Map<TypeDescription, Class<?>> getAllLoaded();
6109
    }
6110

6111
    @HashCodeAndEqualsPlugin.Enhance
6112
    abstract class AbstractBase implements DynamicType {
1✔
6113

6114
        /**
6115
         * The file name extension for Java class files.
6116
         */
6117
        private static final String CLASS_FILE_EXTENSION = ".class";
6118

6119
        /**
6120
         * The default version of a jar file manifest.
6121
         */
6122
        private static final String MANIFEST_VERSION = "1.0";
6123

6124
        /**
6125
         * A suffix for temporary files.
6126
         */
6127
        private static final String TEMP_SUFFIX = "tmp";
6128

6129
        /**
6130
         * {@inheritDoc}
6131
         */
6132
        public Resolution locate(String name) throws IOException {
6133
            if (getTypeDescription().getName().equals(name)) {
1✔
6134
                return new Resolution.Explicit(getBytes());
1✔
6135
            }
6136
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6137
                Resolution resolution = auxiliaryType.locate(name);
1✔
6138
                if (resolution.isResolved()) {
1✔
6139
                    return resolution;
1✔
6140
                }
6141
            }
1✔
6142
            return new Resolution.Illegal(name);
1✔
6143
        }
6144

6145
        /**
6146
         * {@inheritDoc}
6147
         */
6148
        public void close() {
6149
            /* do nothing */
6150
        }
×
6151

6152
        /**
6153
         * {@inheritDoc}
6154
         */
6155
        public Set<TypeDescription> getAuxiliaryTypeDescriptions() {
6156
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
6157
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6158
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
6159
            }
1✔
6160
            return types;
1✔
6161
        }
6162

6163
        /**
6164
         * {@inheritDoc}
6165
         */
6166
        public Set<TypeDescription> getAllTypeDescriptions() {
6167
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
6168
            types.add(getTypeDescription());
1✔
6169
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6170
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
6171
            }
1✔
6172
            return types;
1✔
6173
        }
6174

6175
        /**
6176
         * {@inheritDoc}
6177
         */
6178
        public Map<TypeDescription, byte[]> getAllTypes() {
6179
            Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
1✔
6180
            allTypes.put(getTypeDescription(), getBytes());
1✔
6181
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6182
                allTypes.putAll(auxiliaryType.getAllTypes());
1✔
6183
            }
1✔
6184
            return allTypes;
1✔
6185
        }
6186

6187
        /**
6188
         * {@inheritDoc}
6189
         */
6190
        public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
6191
            Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
1✔
6192
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6193
                classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
1✔
6194
            }
1✔
6195
            classLoadingCallbacks.put(getTypeDescription(), getLoadedTypeInitializer());
1✔
6196
            return classLoadingCallbacks;
1✔
6197
        }
6198

6199
        /**
6200
         * {@inheritDoc}
6201
         */
6202
        public boolean hasAliveLoadedTypeInitializers() {
6203
            if (getLoadedTypeInitializer().isAlive()) {
1✔
6204
                return true;
1✔
6205
            }
6206
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6207
                if (auxiliaryType.hasAliveLoadedTypeInitializers()) {
1✔
6208
                    return true;
1✔
6209
                }
6210
            }
1✔
6211
            return false;
1✔
6212
        }
6213

6214
        /**
6215
         * {@inheritDoc}
6216
         */
6217
        public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
6218
            Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
1✔
6219
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6220
                auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
1✔
6221
                auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
1✔
6222
            }
1✔
6223
            return auxiliaryTypes;
1✔
6224
        }
6225

6226
        /**
6227
         * {@inheritDoc}
6228
         */
6229
        public Map<TypeDescription, File> saveIn(File folder) throws IOException {
6230
            Map<TypeDescription, File> files = new HashMap<TypeDescription, File>();
1✔
6231
            File target = new File(folder, getTypeDescription().getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
1✔
6232
            if (target.getParentFile() != null && !target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
1✔
6233
                throw new IllegalArgumentException("Could not create directory: " + target.getParentFile());
×
6234
            }
6235
            OutputStream outputStream = new FileOutputStream(target);
1✔
6236
            try {
6237
                outputStream.write(getBytes());
1✔
6238
            } finally {
6239
                outputStream.close();
1✔
6240
            }
6241
            files.put(getTypeDescription(), target);
1✔
6242
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
6243
                files.putAll(auxiliaryType.saveIn(folder));
1✔
6244
            }
1✔
6245
            return files;
1✔
6246
        }
6247

6248
        /**
6249
         * {@inheritDoc}
6250
         */
6251
        public File inject(File sourceJar, File targetJar) throws IOException {
6252
            return sourceJar.equals(targetJar)
1✔
6253
                    ? inject(sourceJar)
1✔
6254
                    : doInject(sourceJar, targetJar);
1✔
6255
        }
6256

6257
        /**
6258
         * {@inheritDoc}
6259
         */
6260
        public File inject(File jar) throws IOException {
6261
            FileSystem.getInstance().move(doInject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX)), jar);
1✔
6262
            return jar;
1✔
6263
        }
6264

6265
        /**
6266
         * Injects this dynamic type into a source jar and writes the result to the target jar.
6267
         *
6268
         * @param sourceJar The source jar.
6269
         * @param targetJar The target jar.
6270
         * @return The jar file that was written to.
6271
         * @throws IOException If an I/O error occurs.
6272
         */
6273
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
6274
        private File doInject(File sourceJar, File targetJar) throws IOException {
6275
            InputStream inputStream = new FileInputStream(sourceJar);
1✔
6276
            try {
6277
                JarInputStream jarInputStream = new JarInputStream(inputStream);
1✔
6278
                if (!targetJar.isFile() && !targetJar.createNewFile()) {
1✔
6279
                    throw new IllegalArgumentException("Could not create file: " + targetJar);
×
6280
                }
6281
                Manifest manifest = jarInputStream.getManifest();
1✔
6282
                OutputStream outputStream = new FileOutputStream(targetJar);
1✔
6283
                try {
6284
                    JarOutputStream jarOutputStream = manifest == null
1✔
6285
                            ? new JarOutputStream(outputStream)
6286
                            : new JarOutputStream(outputStream, manifest);
6287
                    Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
1✔
6288
                    Map<String, byte[]> files = new HashMap<String, byte[]>();
1✔
6289
                    for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
1✔
6290
                        files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
1✔
6291
                    }
1✔
6292
                    files.put(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION, getBytes());
1✔
6293
                    JarEntry jarEntry;
6294
                    while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
1✔
6295
                        byte[] replacement = files.remove(jarEntry.getName());
1✔
6296
                        if (replacement == null) {
1✔
6297
                            jarOutputStream.putNextEntry(jarEntry);
1✔
6298
                            byte[] buffer = new byte[1024];
1✔
6299
                            int index;
6300
                            while ((index = jarInputStream.read(buffer)) != -1) {
1✔
6301
                                jarOutputStream.write(buffer, 0, index);
1✔
6302
                            }
6303
                        } else {
1✔
6304
                            jarOutputStream.putNextEntry(new JarEntry(jarEntry.getName()));
1✔
6305
                            jarOutputStream.write(replacement);
1✔
6306
                        }
6307
                        jarInputStream.closeEntry();
1✔
6308
                        jarOutputStream.closeEntry();
1✔
6309
                    }
1✔
6310
                    for (Map.Entry<String, byte[]> entry : files.entrySet()) {
1✔
6311
                        jarOutputStream.putNextEntry(new JarEntry(entry.getKey()));
1✔
6312
                        jarOutputStream.write(entry.getValue());
1✔
6313
                        jarOutputStream.closeEntry();
1✔
6314
                    }
1✔
6315
                    jarOutputStream.close();
1✔
6316
                } finally {
6317
                    outputStream.close();
1✔
6318
                }
6319
                jarInputStream.close();
1✔
6320
            } finally {
6321
                inputStream.close();
1✔
6322
            }
6323
            return targetJar;
1✔
6324
        }
6325

6326
        /**
6327
         * {@inheritDoc}
6328
         */
6329
        public File toJar(File file) throws IOException {
6330
            Manifest manifest = new Manifest();
1✔
6331
            manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
1✔
6332
            return toJar(file, manifest);
1✔
6333
        }
6334

6335
        /**
6336
         * {@inheritDoc}
6337
         */
6338
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
6339
        public File toJar(File file, Manifest manifest) throws IOException {
6340
            if (!file.isFile() && !file.createNewFile()) {
1✔
6341
                throw new IllegalArgumentException("Could not create file: " + file);
×
6342
            }
6343
            OutputStream outputStream = new FileOutputStream(file);
1✔
6344
            try {
6345
                JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest);
1✔
6346
                for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
1✔
6347
                    jarOutputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
1✔
6348
                    jarOutputStream.write(entry.getValue());
1✔
6349
                    jarOutputStream.closeEntry();
1✔
6350
                }
1✔
6351
                jarOutputStream.putNextEntry(new JarEntry(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION));
1✔
6352
                jarOutputStream.write(getBytes());
1✔
6353
                jarOutputStream.closeEntry();
1✔
6354
                jarOutputStream.close();
1✔
6355
            } finally {
6356
                outputStream.close();
1✔
6357
            }
6358
            return file;
1✔
6359
        }
6360
    }
6361

6362
    /**
6363
     * A default implementation of a dynamic type.
6364
     */
6365
    @HashCodeAndEqualsPlugin.Enhance
6366
    class Default extends AbstractBase {
6367

6368
        /**
6369
         * A type description of this dynamic type.
6370
         */
6371
        protected final TypeDescription typeDescription;
6372

6373
        /**
6374
         * The byte array representing this dynamic type.
6375
         */
6376
        protected final byte[] binaryRepresentation;
6377

6378
        /**
6379
         * The loaded type initializer for this dynamic type.
6380
         */
6381
        protected final LoadedTypeInitializer loadedTypeInitializer;
6382

6383
        /**
6384
         * A list of auxiliary types for this dynamic type.
6385
         */
6386
        protected final List<? extends DynamicType> auxiliaryTypes;
6387

6388
        /**
6389
         * Creates a new dynamic type.
6390
         *
6391
         * @param typeDescription       A description of this dynamic type.
6392
         * @param binaryRepresentation  A byte array containing the binary representation of this dynamic type. The array must not be modified.
6393
         * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
6394
         * @param auxiliaryTypes        The auxiliary type required for this dynamic type.
6395
         */
6396
        @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not modified by class contract.")
6397
        public Default(TypeDescription typeDescription,
6398
                       byte[] binaryRepresentation,
6399
                       LoadedTypeInitializer loadedTypeInitializer,
6400
                       List<? extends DynamicType> auxiliaryTypes) {
1✔
6401
            this.typeDescription = typeDescription;
1✔
6402
            this.binaryRepresentation = binaryRepresentation;
1✔
6403
            this.loadedTypeInitializer = loadedTypeInitializer;
1✔
6404
            this.auxiliaryTypes = auxiliaryTypes;
1✔
6405
        }
1✔
6406

6407
        /**
6408
         * {@inheritDoc}
6409
         */
6410
        public TypeDescription getTypeDescription() {
6411
            return typeDescription;
1✔
6412
        }
6413

6414
        /**
6415
         * {@inheritDoc}
6416
         */
6417
        @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not modified by class contract.")
6418
        public byte[] getBytes() {
6419
            return binaryRepresentation;
1✔
6420
        }
6421

6422
        /**
6423
         * {@inheritDoc}
6424
         */
6425
        public LoadedTypeInitializer getLoadedTypeInitializer() {
6426
            return loadedTypeInitializer;
1✔
6427
        }
6428

6429
        /**
6430
         * {@inheritDoc}
6431
         */
6432
        public List<? extends DynamicType> getAuxiliaries() {
6433
            return auxiliaryTypes;
1✔
6434
        }
6435

6436
        /**
6437
         * A default implementation of an unloaded dynamic type.
6438
         *
6439
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6440
         *            type itself, an interface or the direct super class.
6441
         */
6442
        @HashCodeAndEqualsPlugin.Enhance
6443
        public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
6444

6445
            /**
6446
             * The type resolution strategy to use for initializing the dynamic type.
6447
             */
6448
            private final TypeResolutionStrategy.Resolved typeResolutionStrategy;
6449

6450
            /**
6451
             * Creates a new unloaded representation of a dynamic type.
6452
             *
6453
             * @param typeDescription        A description of this dynamic type.
6454
             * @param binaryRepresentation   An array of byte of the binary representation of this dynamic type.
6455
             * @param loadedTypeInitializer  The type initializer of this dynamic type.
6456
             * @param auxiliaryTypes         The auxiliary types that are required for this dynamic type.
6457
             * @param typeResolutionStrategy The type resolution strategy to use for initializing the dynamic type.
6458
             */
6459
            public Unloaded(TypeDescription typeDescription,
6460
                            byte[] binaryRepresentation,
6461
                            LoadedTypeInitializer loadedTypeInitializer,
6462
                            List<? extends DynamicType> auxiliaryTypes,
6463
                            TypeResolutionStrategy.Resolved typeResolutionStrategy) {
6464
                super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
1✔
6465
                this.typeResolutionStrategy = typeResolutionStrategy;
1✔
6466
            }
1✔
6467

6468
            /**
6469
             * {@inheritDoc}
6470
             */
6471
            public DynamicType.Loaded<T> load(@MaybeNull ClassLoader classLoader) {
6472
                if (classLoader instanceof InjectionClassLoader && !((InjectionClassLoader) classLoader).isSealed()) {
1✔
6473
                    return load((InjectionClassLoader) classLoader, InjectionClassLoader.Strategy.INSTANCE);
1✔
6474
                } else {
6475
                    return load(classLoader, ClassLoadingStrategy.Default.WRAPPER);
1✔
6476
                }
6477
            }
6478

6479
            /**
6480
             * {@inheritDoc}
6481
             */
6482
            public <S extends ClassLoader> DynamicType.Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
6483
                return new Default.Loaded<T>(typeDescription,
1✔
6484
                        binaryRepresentation,
6485
                        loadedTypeInitializer,
6486
                        auxiliaryTypes,
6487
                        typeResolutionStrategy.initialize(this, classLoader, classLoadingStrategy));
1✔
6488
            }
6489

6490
            /**
6491
             * {@inheritDoc}
6492
             */
6493
            public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
6494
                return include(Arrays.asList(dynamicType));
1✔
6495
            }
6496

6497
            /**
6498
             * {@inheritDoc}
6499
             */
6500
            public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
6501
                return new Default.Unloaded<T>(typeDescription,
1✔
6502
                        binaryRepresentation,
6503
                        loadedTypeInitializer,
6504
                        CompoundList.of(auxiliaryTypes, dynamicType),
1✔
6505
                        typeResolutionStrategy);
6506
            }
6507
        }
6508

6509
        /**
6510
         * A default implementation of a loaded dynamic type.
6511
         *
6512
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6513
         *            type itself, an interface or the direct super class.
6514
         */
6515
        @HashCodeAndEqualsPlugin.Enhance
6516
        protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
6517

6518
            /**
6519
             * The loaded types for the given loaded dynamic type.
6520
             */
6521
            private final Map<TypeDescription, Class<?>> loadedTypes;
6522

6523
            /**
6524
             * Creates a new representation of a loaded dynamic type.
6525
             *
6526
             * @param typeDescription       A description of this dynamic type.
6527
             * @param typeByte              An array of byte of the binary representation of this dynamic type.
6528
             * @param loadedTypeInitializer The type initializer of this dynamic type.
6529
             * @param auxiliaryTypes        The auxiliary types that are required for this dynamic type.
6530
             * @param loadedTypes           A map of loaded types for this dynamic type and all its auxiliary types.
6531
             */
6532
            protected Loaded(TypeDescription typeDescription,
6533
                             byte[] typeByte,
6534
                             LoadedTypeInitializer loadedTypeInitializer,
6535
                             List<? extends DynamicType> auxiliaryTypes,
6536
                             Map<TypeDescription, Class<?>> loadedTypes) {
6537
                super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
1✔
6538
                this.loadedTypes = loadedTypes;
1✔
6539
            }
1✔
6540

6541
            /**
6542
             * {@inheritDoc}
6543
             */
6544
            @SuppressWarnings("unchecked")
6545
            public Class<? extends T> getLoaded() {
6546
                return (Class<? extends T>) loadedTypes.get(typeDescription);
1✔
6547
            }
6548

6549
            /**
6550
             * {@inheritDoc}
6551
             */
6552
            public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
6553
                Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
6554
                loadedAuxiliaryTypes.remove(typeDescription);
1✔
6555
                return loadedAuxiliaryTypes;
1✔
6556
            }
6557

6558
            /**
6559
             * {@inheritDoc}
6560
             */
6561
            public Map<TypeDescription, Class<?>> getAllLoaded() {
6562
                return new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
6563
            }
6564
        }
6565
    }
6566
}
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