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

raphw / byte-buddy / #641

19 Aug 2024 10:38PM CUT coverage: 85.389% (-0.06%) from 85.448%
#641

push

raphw
Disable validation for minor breakage of protected API.

28759 of 33680 relevant lines covered (85.39%)

0.85 hits per line

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

79.0
/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.*;
30
import net.bytebuddy.description.type.*;
31
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
32
import net.bytebuddy.dynamic.loading.InjectionClassLoader;
33
import net.bytebuddy.dynamic.scaffold.*;
34
import net.bytebuddy.implementation.*;
35
import net.bytebuddy.implementation.attribute.*;
36
import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
37
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
38
import net.bytebuddy.matcher.ElementMatcher;
39
import net.bytebuddy.matcher.LatentMatcher;
40
import net.bytebuddy.pool.TypePool;
41
import net.bytebuddy.utility.AsmClassReader;
42
import net.bytebuddy.utility.AsmClassWriter;
43
import net.bytebuddy.utility.CompoundList;
44
import net.bytebuddy.utility.FileSystem;
45
import net.bytebuddy.utility.nullability.MaybeNull;
46
import net.bytebuddy.utility.visitor.ContextClassVisitor;
47
import org.objectweb.asm.ClassVisitor;
48
import org.objectweb.asm.Opcodes;
49

50
import java.io.*;
51
import java.lang.annotation.Annotation;
52
import java.lang.reflect.*;
53
import java.util.*;
54
import java.util.jar.*;
55

56
import static net.bytebuddy.matcher.ElementMatchers.*;
57

58
/**
59
 * A dynamic type that is created at runtime, usually as the result of applying a
60
 * {@link net.bytebuddy.dynamic.DynamicType.Builder} or as the result of an
61
 * {@link net.bytebuddy.implementation.auxiliary.AuxiliaryType}.
62
 * <p>&nbsp;</p>
63
 * Note that the {@link TypeDescription}s will represent their
64
 * unloaded forms and therefore differ from the loaded types, especially with regards to annotations.
65
 */
66
public interface DynamicType extends ClassFileLocator {
67

68
    /**
69
     * <p>
70
     * Returns a description of this dynamic type.
71
     * </p>
72
     * <p>
73
     * <b>Note</b>: This description will most likely differ from the binary representation of this type. Normally,
74
     * annotations and intercepted methods are not added to this type description.
75
     * </p>
76
     *
77
     * @return A description of this dynamic type.
78
     */
79
    TypeDescription getTypeDescription();
80

81
    /**
82
     * Returns a byte array representing this dynamic type. This byte array might be reused by this dynamic type and
83
     * must therefore not be altered.
84
     *
85
     * @return A byte array of the type's binary representation.
86
     */
87
    byte[] getBytes();
88

89
    /**
90
     * <p>
91
     * Returns a map of all auxiliary types that are required for making use of the main type.
92
     * </p>
93
     * <p>
94
     * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
95
     * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
96
     * </p>
97
     *
98
     * @return A map of all auxiliary types by their descriptions to their binary representation.
99
     */
100
    Map<TypeDescription, byte[]> getAuxiliaryTypes();
101

102
    /**
103
     * Returns all types that are implied by this dynamic type.
104
     *
105
     * @return A mapping from all type descriptions, the actual type and its auxiliary types to their binary
106
     * representation
107
     */
108
    Map<TypeDescription, byte[]> getAllTypes();
109

110
    /**
111
     * <p>
112
     * Returns a map of all loaded type initializers for the main type and all auxiliary types, if any.
113
     * </p>
114
     * <p>
115
     * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
116
     * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
117
     * </p>
118
     *
119
     * @return A mapping of all types' descriptions to their loaded type initializers.
120
     */
121
    Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers();
122

123
    /**
124
     * Checks if a dynamic type requires some form of explicit type initialization, either for itself or for one
125
     * of its auxiliary types, if any. This is the case when this dynamic type was defined to delegate method calls
126
     * to a specific instance which is stored in a field of the created type. If this class serialized, it could not
127
     * be used without its loaded type initializers since the field value represents a specific runtime context.
128
     *
129
     * @return {@code true} if this type requires explicit type initialization.
130
     */
131
    boolean hasAliveLoadedTypeInitializers();
132

133
    /**
134
     * <p>
135
     * Saves a dynamic type in a given folder using the Java class file format while respecting the naming conventions
136
     * for saving compiled Java classes. All auxiliary types, if any, are saved in the same directory. The resulting
137
     * folder structure will resemble the structure that is required for Java run times, i.e. each folder representing
138
     * a segment of the package name. If the specified {@code folder} does not yet exist, it is created during the
139
     * call of this method.
140
     * </p>
141
     * <p>
142
     * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
143
     * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
144
     * </p>
145
     *
146
     * @param folder The base target folder for storing this dynamic type and its auxiliary types, if any.
147
     * @return A map of type descriptions pointing to files with their stored binary representations within {@code folder}.
148
     * @throws IOException Thrown if the underlying file operations cause an {@code IOException}.
149
     */
150
    Map<TypeDescription, File> saveIn(File folder) throws IOException;
151

152
    /**
153
     * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
154
     * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
155
     * patched version with a new central directory. No directory entries are added to the generated jar.
156
     *
157
     * @param sourceJar The original jar file.
158
     * @param targetJar The {@code source} jar file with the injected contents.
159
     * @return The {@code target} jar file.
160
     * @throws IOException If an I/O exception occurs while injecting from the source into the target.
161
     */
162
    File inject(File sourceJar, File targetJar) throws IOException;
163

164
    /**
165
     * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
166
     * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
167
     * patched version with a new central directory. No directory entries are added to the generated jar.
168
     *
169
     * @param jar The jar file to replace with an injected version.
170
     * @return The {@code jar} file.
171
     * @throws IOException If an I/O exception occurs while injecting into the jar.
172
     */
173
    File inject(File jar) throws IOException;
174

175
    /**
176
     * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
177
     * exist prior to calling this method. The jar file is created with a simple manifest that only contains a version
178
     * number. No directory entries are added to the generated jar.
179
     *
180
     * @param file The target file to which the <i>jar</i> is written to.
181
     * @return The given {@code file}.
182
     * @throws IOException If an I/O exception occurs while writing the file.
183
     */
184
    File toJar(File file) throws IOException;
185

186
    /**
187
     * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
188
     * exist prior to calling this method. No directory entries are added to the generated jar.
189
     *
190
     * @param file     The target file to which the <i>jar</i> is written to.
191
     * @param manifest The manifest of the created <i>jar</i>.
192
     * @return The given {@code file}.
193
     * @throws IOException If an I/O exception occurs while writing the file.
194
     */
195
    File toJar(File file, Manifest manifest) throws IOException;
196

197
    /**
198
     * {@inheritDoc}
199
     */
200
    void close();
201

202
    /**
203
     * A builder for creating a dynamic type.
204
     *
205
     * @param <T> A loaded type that the built type is guaranteed to be a subclass of.
206
     */
207
    interface Builder<T> {
208

209
        /**
210
         * Applies the supplied {@link AsmVisitorWrapper} onto the {@link org.objectweb.asm.ClassVisitor} during building a dynamic type.
211
         * Using an ASM visitor, it is possible to manipulate byte code directly. Byte Buddy does not validate directly created byte code
212
         * and it remains the responsibility of the visitor's implementor to generate legal byte code. If several ASM visitor wrappers
213
         * are registered, they are applied on top of another in their registration order.
214
         *
215
         * @param asmVisitorWrapper The ASM visitor wrapper to apply during
216
         * @return A new builder that is equal to this builder and applies the ASM visitor wrapper.
217
         */
218
        Builder<T> visit(AsmVisitorWrapper asmVisitorWrapper);
219

220
        /**
221
         * Names the dynamic type by the supplied name. The name needs to be fully qualified and in the binary format (packages separated
222
         * by dots: {@code foo.Bar}). A type's package determines what other types are visible to the instrumented type and what methods
223
         * can be overridden or be represented in method signatures or as field types.
224
         *
225
         * @param name The fully qualified name of the generated class in a binary format.
226
         * @return A new builder that is equal to this builder but with the instrumented type named by the supplied name.
227
         */
228
        Builder<T> name(String name);
229

230
        /**
231
         * Adds a suffix to the current type name without changing the type's package.
232
         *
233
         * @param suffix The suffix to append to the current type name.
234
         * @return A new builder that is equal to this builder but with the instrumented type named suffixed by the supplied suffix.
235
         */
236
        Builder<T> suffix(String suffix);
237

238
        /**
239
         * Defines the supplied modifiers as the modifiers of the instrumented type.
240
         *
241
         * @param modifierContributor The modifiers of the instrumented type.
242
         * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
243
         */
244
        Builder<T> modifiers(ModifierContributor.ForType... modifierContributor);
245

246
        /**
247
         * Defines the supplied modifiers as the modifiers of the instrumented type.
248
         *
249
         * @param modifierContributors The modifiers of the instrumented type.
250
         * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
251
         */
252
        Builder<T> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors);
253

254
        /**
255
         * Defines the supplied modifiers as the modifiers of the instrumented type.
256
         *
257
         * @param modifiers The modifiers of the instrumented type.
258
         * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
259
         */
260
        Builder<T> modifiers(int modifiers);
261

262
        /**
263
         * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
264
         * type's new modifiers.
265
         *
266
         * @param modifierContributor The modifiers of the instrumented type.
267
         * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
268
         */
269
        Builder<T> merge(ModifierContributor.ForType... modifierContributor);
270

271
        /**
272
         * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
273
         * type's new modifiers.
274
         *
275
         * @param modifierContributors The modifiers of the instrumented type.
276
         * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
277
         */
278
        Builder<T> merge(Collection<? extends ModifierContributor.ForType> modifierContributors);
279

280
        /**
281
         * <p>
282
         * Defines this type as a top-level type that is not declared by another type or enclosed by another member.
283
         * </p>
284
         * <p>
285
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
286
         * </p>
287
         * <p>
288
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
289
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
290
         * consistent among the definitions of connected types.
291
         * </p>
292
         *
293
         * @return A new builder that is equal to this builder but without any declaration of a declared or enclosed type.
294
         */
295
        Builder<T> topLevelType();
296

297
        /**
298
         * <p>
299
         * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is defined
300
         * as a local type.
301
         * </p>
302
         * <p>
303
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
304
         * </p>
305
         * <p>
306
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
307
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
308
         * consistent among the definitions of connected types.
309
         * </p>
310
         *
311
         * @param type The type to declare as the built type's outer type.
312
         * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
313
         */
314
        InnerTypeDefinition.ForType<T> innerTypeOf(Class<?> type);
315

316
        /**
317
         * <p>
318
         * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is
319
         * defined as a local type.
320
         * </p>
321
         * <p>
322
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
323
         * </p>
324
         * <p>
325
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
326
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
327
         * consistent among the definitions of connected types.
328
         * </p>
329
         *
330
         * @param type The type to declare as the built type's outer type.
331
         * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
332
         */
333
        InnerTypeDefinition.ForType<T> innerTypeOf(TypeDescription type);
334

335
        /**
336
         * <p>
337
         * Defines this type as an inner type that was declared within the supplied method.  Without any additional configuration, the type
338
         * declaration is defined as a local type.
339
         * </p>
340
         * <p>
341
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
342
         * </p>
343
         * <p>
344
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
345
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
346
         * consistent among the definitions of connected types.
347
         * </p>
348
         *
349
         * @param method The method to declare as the built type's declaring method.
350
         * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method.
351
         */
352
        InnerTypeDefinition<T> innerTypeOf(Method method);
353

354
        /**
355
         * <p>
356
         * Defines this type as an inner type that was declared within the supplied constructor. Without any additional configuration, the type
357
         * declaration is defined as a local type.
358
         * </p>
359
         * <p>
360
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
361
         * </p>
362
         * <p>
363
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
364
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
365
         * consistent among the definitions of connected types.
366
         * </p>
367
         *
368
         * @param constructor The constructor to declare as the built type's declaring method.
369
         * @return A new builder that is equal to this builder with the supplied method as the built type's declaring constructor.
370
         */
371
        InnerTypeDefinition<T> innerTypeOf(Constructor<?> constructor);
372

373
        /**
374
         * <p>
375
         * Defines this type as an inner type that was declared within the supplied method or constructor. Without any additional configuration,
376
         * the type declaration is defined as a local type.
377
         * </p>
378
         * <p>
379
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
380
         * </p>
381
         * <p>
382
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
383
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
384
         * consistent among the definitions of connected types.
385
         * </p>
386
         *
387
         * @param methodDescription The method or constructor to declare as the built type's declaring method.
388
         * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method or constructor.
389
         */
390
        InnerTypeDefinition<T> innerTypeOf(MethodDescription.InDefinedShape methodDescription);
391

392
        /**
393
         * <p>
394
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
395
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
396
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
397
         * </p>
398
         * <p>
399
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
400
         * </p>
401
         * <p>
402
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
403
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
404
         * consistent among the definitions of connected types.
405
         * </p>
406
         *
407
         * @param type The types being declared.
408
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
409
         */
410
        Builder<T> declaredTypes(Class<?>... type);
411

412
        /**
413
         * <p>
414
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
415
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
416
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
417
         * </p>
418
         * <p>
419
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
420
         * </p>
421
         * <p>
422
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
423
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
424
         * consistent among the definitions of connected types.
425
         * </p>
426
         *
427
         * @param type The types being declared.
428
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
429
         */
430
        Builder<T> declaredTypes(TypeDescription... type);
431

432
        /**
433
         * <p>
434
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
435
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
436
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
437
         * </p>
438
         * <p>
439
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
440
         * </p>
441
         * <p>
442
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
443
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
444
         * consistent among the definitions of connected types.
445
         * </p>
446
         *
447
         * @param types The types being declared.
448
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
449
         */
450
        Builder<T> declaredTypes(List<? extends Class<?>> types);
451

452
        /**
453
         * <p>
454
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
455
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
456
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
457
         * </p>
458
         * <p>
459
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
460
         * </p>
461
         * <p>
462
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
463
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
464
         * consistent among the definitions of connected types.
465
         * </p>
466
         *
467
         * @param types The types being declared.
468
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
469
         */
470
        Builder<T> declaredTypes(Collection<? extends TypeDescription> types);
471

472
        /**
473
         * <p>
474
         * Defines this type as self-hosted, i.e. as only being a nest mate of itself.
475
         * </p>
476
         * <p>
477
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
478
         * </p>
479
         * <p>
480
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
481
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
482
         * consistent among the definitions of connected types.
483
         * </p>
484
         *
485
         * @return A new builder that is equal to this builder but where the built type is a self-hosted nest mate.
486
         */
487
        Builder<T> noNestMate();
488

489
        /**
490
         * <p>
491
         * Defines this type as a nest member of the supplied type as a nest host.
492
         * </p>
493
         * <p>
494
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
495
         * </p>
496
         * <p>
497
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
498
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
499
         * consistent among the definitions of connected types.
500
         * </p>
501
         *
502
         * @param type The nest host.
503
         * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
504
         */
505
        Builder<T> nestHost(Class<?> type);
506

507
        /**
508
         * <p>
509
         * Defines this type as a nest member of the supplied type as a nest host.
510
         * </p>
511
         * <p>
512
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
513
         * </p>
514
         * <p>
515
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
516
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
517
         * consistent among the definitions of connected types.
518
         * </p>
519
         *
520
         * @param type The nest host.
521
         * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
522
         */
523
        Builder<T> nestHost(TypeDescription type);
524

525
        /**
526
         * <p>
527
         * Defines this type as a nest host for the supplied types.
528
         * </p>
529
         * <p>
530
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
531
         * </p>
532
         * <p>
533
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
534
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
535
         * consistent among the definitions of connected types.
536
         * </p>
537
         *
538
         * @param type The nest members.
539
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
540
         */
541
        Builder<T> nestMembers(Class<?>... type);
542

543
        /**
544
         * <p>
545
         * Defines this type as a nest host for the supplied types.
546
         * </p>
547
         * <p>
548
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
549
         * </p>
550
         * <p>
551
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
552
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
553
         * consistent among the definitions of connected types.
554
         * </p>
555
         *
556
         * @param type The nest members.
557
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
558
         */
559
        Builder<T> nestMembers(TypeDescription... type);
560

561
        /**
562
         * <p>
563
         * Defines this type as a nest host for the supplied types.
564
         * </p>
565
         * <p>
566
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
567
         * </p>
568
         * <p>
569
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
570
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
571
         * consistent among the definitions of connected types.
572
         * </p>
573
         *
574
         * @param types The nest members.
575
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
576
         */
577
        Builder<T> nestMembers(List<? extends Class<?>> types);
578

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

597
        /**
598
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
599
         * this type was not previously sealed, only the supplied subclasses are permitted.
600
         *
601
         * @param type The permitted subclasses.
602
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
603
         */
604
        Builder<T> permittedSubclass(Class<?>... type);
605

606
        /**
607
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
608
         * this type was not previously sealed, only the supplied subclasses are permitted.
609
         *
610
         * @param type The permitted subclasses.
611
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
612
         */
613
        Builder<T> permittedSubclass(TypeDescription... type);
614

615
        /**
616
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
617
         * this type was not previously sealed, only the supplied subclasses are permitted.
618
         *
619
         * @param types The permitted subclasses.
620
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
621
         */
622
        Builder<T> permittedSubclass(List<? extends Class<?>> types);
623

624
        /**
625
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
626
         * this type was not previously sealed, only the supplied subclasses are permitted.
627
         *
628
         * @param types The permitted subclasses.
629
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
630
         */
631
        Builder<T> permittedSubclass(Collection<? extends TypeDescription> types);
632

633
        /**
634
         * Unseales this type.
635
         *
636
         * @return A new builder that is equal to this builder but where the built type does not restrain its permitted subclasses.
637
         */
638
        Builder<T> unsealed();
639

640
        /**
641
         * Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
642
         * any type of meta data to a type, not only Java {@link Annotation}s.
643
         *
644
         * @param typeAttributeAppender The type attribute appender to apply.
645
         * @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
646
         */
647
        Builder<T> attribute(TypeAttributeAppender typeAttributeAppender);
648

649
        /**
650
         * Annotates the instrumented type with the supplied annotations.
651
         *
652
         * @param annotation The annotations to add to the instrumented type.
653
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
654
         */
655
        Builder<T> annotateType(Annotation... annotation);
656

657
        /**
658
         * Annotates the instrumented type with the supplied annotations.
659
         *
660
         * @param annotations The annotations to add to the instrumented type.
661
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
662
         */
663
        Builder<T> annotateType(List<? extends Annotation> annotations);
664

665
        /**
666
         * Annotates the instrumented type with the supplied annotations.
667
         *
668
         * @param annotation The annotations to add to the instrumented type.
669
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
670
         */
671
        Builder<T> annotateType(AnnotationDescription... annotation);
672

673
        /**
674
         * Annotates the instrumented type with the supplied annotations.
675
         *
676
         * @param annotations The annotations to add to the instrumented type.
677
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
678
         */
679
        Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
680

681
        /**
682
         * <p>
683
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
684
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
685
         * are explicitly ignored.
686
         * </p>
687
         * <p>
688
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
689
         * as raw types if they declare type variables or an owner type.
690
         * </p>
691
         *
692
         * @param interfaceType The interface types to implement.
693
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
694
         */
695
        MethodDefinition.ImplementationDefinition.Optional<T> implement(Type... interfaceType);
696

697
        /**
698
         * <p>
699
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
700
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
701
         * are explicitly ignored.
702
         * </p>
703
         * <p>
704
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
705
         * as raw types if they declare type variables or an owner type.
706
         * </p>
707
         *
708
         * @param interfaceTypes The interface types to implement.
709
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
710
         */
711
        MethodDefinition.ImplementationDefinition.Optional<T> implement(List<? extends Type> interfaceTypes);
712

713
        /**
714
         * <p>
715
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
716
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
717
         * are explicitly ignored.
718
         * </p>
719
         * <p>
720
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
721
         * implemented as raw types if they declare type variables or an owner type.
722
         * </p>
723
         *
724
         * @param interfaceType The interface types to implement.
725
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
726
         */
727
        MethodDefinition.ImplementationDefinition.Optional<T> implement(TypeDefinition... interfaceType);
728

729
        /**
730
         * <p>
731
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
732
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
733
         * are explicitly ignored.
734
         * </p>
735
         * <p>
736
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
737
         * implemented as raw types if they declare type variables or an owner type.
738
         * </p>
739
         *
740
         * @param interfaceTypes The interface types to implement.
741
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
742
         */
743
        MethodDefinition.ImplementationDefinition.Optional<T> implement(Collection<? extends TypeDefinition> interfaceTypes);
744

745
        /**
746
         * <p>
747
         * Executes the supplied byte code appender within the beginning of the instrumented type's type initializer. The
748
         * supplied byte code appender <b>must not return</b> from the method. If several byte code appenders are supplied,
749
         * they are executed within their application order.
750
         * </p>
751
         * <p>
752
         * This method should only be used for preparing an instrumented type with a specific configuration. Normally,
753
         * a byte code appender is applied via Byte Buddy's standard API by invoking {@link Builder#invokable(ElementMatcher)}
754
         * using the {@link net.bytebuddy.matcher.ElementMatchers#isTypeInitializer()} matcher.
755
         * </p>
756
         *
757
         * @param byteCodeAppender The byte code appender to execute within the instrumented type's type initializer.
758
         * @return A new builder that is equal to this builder but with the supplied byte code appender being executed within
759
         * the instrumented type's type initializer.
760
         */
761
        Builder<T> initializer(ByteCodeAppender byteCodeAppender);
762

763
        /**
764
         * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
765
         * type initializers are supplied, each loaded type initializer is executed in its registration order.
766
         *
767
         * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
768
         * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
769
         * loading the instrumented type.
770
         */
771
        Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
772

773
        /**
774
         * Explicitly requires another dynamic type for the creation of this type.
775
         *
776
         * @param type                 The type to require.
777
         * @param binaryRepresentation The type's binary representation.
778
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
779
         */
780
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation);
781

782
        /**
783
         * Explicitly requires another dynamic type for the creation of this type.
784
         *
785
         * @param type                 The type to require.
786
         * @param binaryRepresentation The type's binary representation.
787
         * @param typeInitializer      The type's loaded type initializer.
788
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
789
         */
790
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
791

792
        /**
793
         * Explicitly requires other dynamic types for the creation of this type.
794
         *
795
         * @param auxiliaryType The required dynamic types.
796
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
797
         */
798
        Builder<T> require(DynamicType... auxiliaryType);
799

800
        /**
801
         * Explicitly requires other dynamic types for the creation of this type.
802
         *
803
         * @param auxiliaryTypes The required dynamic types.
804
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
805
         */
806
        Builder<T> require(Collection<DynamicType> auxiliaryTypes);
807

808
        /**
809
         * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
810
         *
811
         * @param symbol The type variable's symbol.
812
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
813
         */
814
        TypeVariableDefinition<T> typeVariable(String symbol);
815

816
        /**
817
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
818
         *
819
         * @param symbol The type variable's symbol.
820
         * @param bound  The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
821
         *               should be equal to the currently instrumented type.
822
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
823
         */
824
        TypeVariableDefinition<T> typeVariable(String symbol, Type... bound);
825

826
        /**
827
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
828
         *
829
         * @param symbol The type variable's symbol.
830
         * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
831
         *               should be equal to the currently instrumented type.
832
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
833
         */
834
        TypeVariableDefinition<T> typeVariable(String symbol, List<? extends Type> bounds);
835

836
        /**
837
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
838
         *
839
         * @param symbol The type variable's symbol.
840
         * @param bound  The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
841
         *               should be equal to the currently instrumented type.
842
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
843
         */
844
        TypeVariableDefinition<T> typeVariable(String symbol, TypeDefinition... bound);
845

846
        /**
847
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
848
         *
849
         * @param symbol The type variable's symbol.
850
         * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
851
         *               should be equal to the currently instrumented type.
852
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
853
         */
854
        TypeVariableDefinition<T> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
855

856
        /**
857
         * Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
858
         *
859
         * @param matcher     The matcher to decide what type variables to transform.
860
         * @param transformer The transformer to apply to the matched type variables.
861
         * @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
862
         */
863
        Builder<T> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer);
864

865
        /**
866
         * Defines the specified field as a field of the built dynamic type.
867
         *
868
         * @param name                The name of the field.
869
         * @param type                The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
870
         *                            should be equal to the currently instrumented type.
871
         * @param modifierContributor The modifiers of the field.
872
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
873
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
874
         */
875
        FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor);
876

877
        /**
878
         * Defines the specified field as a field of the built dynamic type.
879
         *
880
         * @param name                 The name of the field.
881
         * @param type                 The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
882
         *                             should be equal to the currently instrumented type.
883
         * @param modifierContributors The modifiers of the field.
884
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
885
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
886
         */
887
        FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors);
888

889
        /**
890
         * Defines the specified field as a field of the built dynamic type.
891
         *
892
         * @param name      The name of the field.
893
         * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
894
         *                  should be equal to the currently instrumented type.
895
         * @param modifiers The modifiers of the field.
896
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
897
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
898
         */
899
        FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, int modifiers);
900

901
        /**
902
         * Defines the specified field as a field of the built dynamic type.
903
         *
904
         * @param name                The name of the field.
905
         * @param type                The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
906
         *                            should be equal to the currently instrumented type.
907
         * @param modifierContributor The modifiers of the field.
908
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
909
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
910
         */
911
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor);
912

913
        /**
914
         * Defines the specified field as a field of the built dynamic type.
915
         *
916
         * @param name                 The name of the field.
917
         * @param type                 The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
918
         *                             should be equal to the currently instrumented type.
919
         * @param modifierContributors The modifiers of the field.
920
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
921
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
922
         */
923
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors);
924

925
        /**
926
         * Defines the specified field as a field of the built dynamic type.
927
         *
928
         * @param name      The name of the field.
929
         * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
930
         *                  should be equal to the currently instrumented type.
931
         * @param modifiers The modifiers of the field.
932
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
933
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
934
         */
935
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, int modifiers);
936

937
        /**
938
         * Defines a field that is similar to the supplied field but without copying any annotations on the field.
939
         *
940
         * @param field The field to imitate as a field of the instrumented type.
941
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
942
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
943
         */
944
        FieldDefinition.Optional.Valuable<T> define(Field field);
945

946
        /**
947
         * Defines a field that is similar to the supplied field but without copying any annotations on the field.
948
         *
949
         * @param field The field to imitate as a field of the instrumented type.
950
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
951
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
952
         */
953
        FieldDefinition.Optional.Valuable<T> define(FieldDescription field);
954

955
        /**
956
         * Defines a private, static, final field for a serial version UID of the given value.
957
         *
958
         * @param serialVersionUid The serial version UID to define as a value.
959
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
960
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
961
         */
962
        FieldDefinition.Optional<T> serialVersionUid(long serialVersionUid);
963

964
        /**
965
         * <p>
966
         * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
967
         * default value, annotations or custom attributes.
968
         * </p>
969
         * <p>
970
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
971
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
972
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
973
         * altered, annotation retention must be disabled.
974
         * </p>
975
         * <p>
976
         * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
977
         * over the previous definition, i.e. the previous field definition is no longer applied.
978
         * </p>
979
         *
980
         * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
981
         * @return A builder that allows for changing a field's definition.
982
         */
983
        @SuppressWarnings("overloads")
984
        FieldDefinition.Valuable<T> field(ElementMatcher<? super FieldDescription> matcher);
985

986
        /**
987
         * <p>
988
         * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
989
         * default value, annotations or custom attributes. Using a latent matcher gives opportunity to resolve an
990
         * {@link ElementMatcher} based on the instrumented type before applying the matcher.
991
         * </p>
992
         * <p>
993
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
994
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
995
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
996
         * altered, annotation retention must be disabled.
997
         * </p>
998
         * <p>
999
         * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
1000
         * over the previous definition, i.e. the previous field definition is no longer applied.
1001
         * </p>
1002
         *
1003
         * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
1004
         * @return A builder that allows for changing a field's definition.
1005
         */
1006
        @SuppressWarnings("overloads")
1007
        FieldDefinition.Valuable<T> field(LatentMatcher<? super FieldDescription> matcher);
1008

1009
        /**
1010
         * <p>
1011
         * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1012
         * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1013
         * </p>
1014
         * <p>
1015
         * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1016
         * is to be ignored, this matcher is no longer executed.
1017
         * </p>
1018
         *
1019
         * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1020
         * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1021
         * instrumentation.
1022
         */
1023
        @SuppressWarnings("overloads")
1024
        Builder<T> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods);
1025

1026
        /**
1027
         * <p>
1028
         * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1029
         * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1030
         * Using a latent matcher gives opportunity to resolve an {@link ElementMatcher} based on the instrumented type before applying the
1031
         * matcher.
1032
         * </p>
1033
         * <p>
1034
         * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1035
         * is to be ignored, this matcher is no longer executed.
1036
         * </p>
1037
         *
1038
         * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1039
         * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1040
         * instrumentation.
1041
         */
1042
        @SuppressWarnings("overloads")
1043
        Builder<T> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods);
1044

1045
        /**
1046
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1047
         * type variables can be defined in subsequent steps.
1048
         *
1049
         * @param name                The name of the method.
1050
         * @param returnType          The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1051
         *                            should be equal to the currently instrumented type.
1052
         * @param modifierContributor The method's modifiers.
1053
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1054
         */
1055
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor);
1056

1057
        /**
1058
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1059
         * type variables can be defined in subsequent steps.
1060
         *
1061
         * @param name                 The name of the method.
1062
         * @param returnType           The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1063
         *                             should be equal to the currently instrumented type.
1064
         * @param modifierContributors The method's modifiers.
1065
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1066
         */
1067
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1068

1069
        /**
1070
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1071
         * type variables can be defined in subsequent steps.
1072
         *
1073
         * @param name       The name of the method.
1074
         * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1075
         *                   should be equal to the currently instrumented type.
1076
         * @param modifiers  The method's modifiers.
1077
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1078
         */
1079
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, int modifiers);
1080

1081
        /**
1082
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1083
         * type variables can be defined in subsequent steps.
1084
         *
1085
         * @param name                The name of the method.
1086
         * @param returnType          The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1087
         *                            should be equal to the currently instrumented type.
1088
         * @param modifierContributor The method's modifiers.
1089
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1090
         */
1091
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor);
1092

1093
        /**
1094
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1095
         * type variables can be defined in subsequent steps.
1096
         *
1097
         * @param name                 The name of the method.
1098
         * @param returnType           The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1099
         *                             should be equal to the currently instrumented type.
1100
         * @param modifierContributors The method's modifiers.
1101
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1102
         */
1103
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1104

1105
        /**
1106
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1107
         * type variables can be defined in subsequent steps.
1108
         *
1109
         * @param name       The name of the method.
1110
         * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1111
         *                   should be equal to the currently instrumented type.
1112
         * @param modifiers  The method's modifiers.
1113
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1114
         */
1115
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, int modifiers);
1116

1117
        /**
1118
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1119
         * type variables can be defined in subsequent steps.
1120
         *
1121
         * @param modifierContributor The constructor's modifiers.
1122
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1123
         */
1124
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(ModifierContributor.ForMethod... modifierContributor);
1125

1126
        /**
1127
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1128
         * type variables can be defined in subsequent steps.
1129
         *
1130
         * @param modifierContributors The constructor's modifiers.
1131
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1132
         */
1133
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1134

1135
        /**
1136
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1137
         * type variables can be defined in subsequent steps.
1138
         *
1139
         * @param modifiers The constructor's modifiers.
1140
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1141
         */
1142
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(int modifiers);
1143

1144
        /**
1145
         * Defines a method that is similar to the supplied method but without copying any annotations of the method or method parameters.
1146
         *
1147
         * @param method The method to imitate as a method of the instrumented type.
1148
         * @return A builder that allows for defining an implementation for the method.
1149
         */
1150
        MethodDefinition.ImplementationDefinition<T> define(Method method);
1151

1152
        /**
1153
         * Defines a constructor that is similar to the supplied constructor but without copying any annotations of the constructor or
1154
         * constructor parameters.
1155
         *
1156
         * @param constructor The constructor to imitate as a method of the instrumented type.
1157
         * @return A builder that allows for defining an implementation for the constructor.
1158
         */
1159
        MethodDefinition.ImplementationDefinition<T> define(Constructor<?> constructor);
1160

1161
        /**
1162
         * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
1163
         * the method/constructor or method/constructor parameters.
1164
         *
1165
         * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
1166
         * @return A builder that allows for defining an implementation for the method or constructor.
1167
         */
1168
        MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
1169

1170
        /**
1171
         * Defines a Java bean property with the specified name.
1172
         *
1173
         * @param name The name of the property.
1174
         * @param type The property type.
1175
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1176
         */
1177
        FieldDefinition.Optional<T> defineProperty(String name, Type type);
1178

1179
        /**
1180
         * Defines a Java bean property with the specified name.
1181
         *
1182
         * @param name     The name of the property.
1183
         * @param type     The property type.
1184
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1185
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1186
         */
1187
        FieldDefinition.Optional<T> defineProperty(String name, Type type, boolean readOnly);
1188

1189
        /**
1190
         * Defines a Java bean property with the specified name.
1191
         *
1192
         * @param name The name of the property.
1193
         * @param type The property type.
1194
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1195
         */
1196
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type);
1197

1198
        /**
1199
         * Defines a Java bean property with the specified name.
1200
         *
1201
         * @param name     The name of the property.
1202
         * @param type     The property type.
1203
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1204
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1205
         */
1206
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type, boolean readOnly);
1207

1208
        /**
1209
         * <p>
1210
         * Matches a method that is already declared or inherited by the instrumented type. This gives opportunity to change or to
1211
         * override that method's implementation, default value, annotations or custom attributes. It is also possible to make
1212
         * a method abstract.
1213
         * </p>
1214
         * <p>
1215
         * When a type is redefined or rebased, any annotations that the method declared previously is preserved
1216
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1217
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1218
         * altered, annotation retention must be disabled.
1219
         * </p>
1220
         * <p>
1221
         * If a method is already matched by a previously specified matcher, the new method definition gets precedence
1222
         * over the previous definition, i.e. the previous method definition is no longer applied.
1223
         * </p>
1224
         * <p>
1225
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1226
         * </p>
1227
         *
1228
         * @param matcher The matcher that determines what methods are affected by the subsequent specification.
1229
         * @return A builder that allows for changing a method's or constructor's definition.
1230
         */
1231
        MethodDefinition.ImplementationDefinition<T> method(ElementMatcher<? super MethodDescription> matcher);
1232

1233
        /**
1234
         * <p>
1235
         * Matches a constructor that is already declared by the instrumented type. This gives opportunity to change that constructor's
1236
         * implementation, default value, annotations or custom attributes.
1237
         * </p>
1238
         * <p>
1239
         * When a type is redefined or rebased, any annotations that the constructor declared previously is preserved
1240
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1241
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1242
         * altered, annotation retention must be disabled.
1243
         * </p>
1244
         * <p>
1245
         * If a constructor is already matched by a previously specified matcher, the new constructor definition gets precedence
1246
         * over the previous definition, i.e. the previous constructor definition is no longer applied.
1247
         * </p>
1248
         * <p>
1249
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1250
         * </p>
1251
         *
1252
         * @param matcher The matcher that determines what constructors are affected by the subsequent specification.
1253
         * @return A builder that allows for changing a method's or constructor's definition.
1254
         */
1255
        MethodDefinition.ImplementationDefinition<T> constructor(ElementMatcher<? super MethodDescription> matcher);
1256

1257
        /**
1258
         * <p>
1259
         * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1260
         * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1261
         * or custom attributes. It is also possible to make a method abstract.
1262
         * </p>
1263
         * <p>
1264
         * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1265
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1266
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1267
         * altered, annotation retention must be disabled.
1268
         * </p>
1269
         * <p>
1270
         * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1271
         * over the previous definition, i.e. the previous definition is no longer applied.
1272
         * </p>
1273
         * <p>
1274
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1275
         * </p>
1276
         * <p>
1277
         * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1278
         * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1279
         * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1280
         * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1281
         * </p>
1282
         *
1283
         * @param matcher The matcher that determines what methods or constructors are affected by the subsequent specification.
1284
         * @return A builder that allows for changing a method's or constructor's definition.
1285
         */
1286
        @SuppressWarnings("overloads")
1287
        MethodDefinition.ImplementationDefinition<T> invokable(ElementMatcher<? super MethodDescription> matcher);
1288

1289
        /**
1290
         * <p>
1291
         * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1292
         * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1293
         * or custom attributes. It is also possible to make a method abstract. Using a latent matcher gives opportunity
1294
         * to resolve an {@link ElementMatcher} based on the instrumented type before applying the matcher.
1295
         * </p>
1296
         * <p>
1297
         * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1298
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1299
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1300
         * altered, annotation retention must be disabled.
1301
         * </p>
1302
         * <p>
1303
         * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1304
         * over the previous definition, i.e. the previous definition is no longer applied.
1305
         * </p>
1306
         * <p>
1307
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1308
         * </p>
1309
         * <p>
1310
         * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1311
         * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1312
         * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1313
         * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1314
         * </p>
1315
         *
1316
         * @param matcher The matcher that determines what declared methods or constructors are affected by the subsequent specification.
1317
         * @return A builder that allows for changing a method's or constructor's definition.
1318
         */
1319
        @SuppressWarnings("overloads")
1320
        MethodDefinition.ImplementationDefinition<T> invokable(LatentMatcher<? super MethodDescription> matcher);
1321

1322
        /**
1323
         * Implements {@link Object#hashCode()} and {@link Object#equals(Object)} methods for the instrumented type if those
1324
         * methods are not declared as {@code final} by a super class. The implementations do not consider any implementations
1325
         * of a super class and compare a class field by field without considering synthetic fields.
1326
         *
1327
         * @return A new type builder that defines {@link Object#hashCode()} and {@link Object#equals(Object)} methods accordingly.
1328
         */
1329
        Builder<T> withHashCodeEquals();
1330

1331
        /**
1332
         * Implements a {@link Object#toString()} method for the instrumented type if such a method is not declared as {@code final}
1333
         * by a super class. The implementation prefixes the string with the simple class name and prints each non-synthetic field's
1334
         * value after the field's name.
1335
         *
1336
         * @return A new type builder that defines {@link Object#toString()} method accordingly.
1337
         */
1338
        Builder<T> withToString();
1339

1340
        /**
1341
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1342
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1343
         *
1344
         * @param name The record component's name.
1345
         * @param type The record component's type.
1346
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1347
         */
1348
        RecordComponentDefinition.Optional<T> defineRecordComponent(String name, Type type);
1349

1350
        /**
1351
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1352
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1353
         *
1354
         * @param name The record component's name.
1355
         * @param type The record component's type.
1356
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1357
         */
1358
        RecordComponentDefinition.Optional<T> defineRecordComponent(String name, TypeDefinition type);
1359

1360
        /**
1361
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1362
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1363
         *
1364
         * @param recordComponentDescription A description of the record component to immitate.
1365
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1366
         */
1367
        RecordComponentDefinition.Optional<T> define(RecordComponentDescription recordComponentDescription);
1368

1369
        /**
1370
         * <p>
1371
         * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1372
         * record component's annotations or custom attributes.
1373
         * </p>
1374
         * <p>
1375
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1376
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1377
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1378
         * altered, annotation retention must be disabled.
1379
         * </p>
1380
         * <p>
1381
         * If a record component is already matched by a previously specified record component matcher, the new record component
1382
         * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1383
         * </p>
1384
         *
1385
         * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1386
         * @return A builder that allows for changing a record component's definition.
1387
         */
1388
        @SuppressWarnings("overloads")
1389
        RecordComponentDefinition<T> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher);
1390

1391
        /**
1392
         * <p>
1393
         * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1394
         * record component's annotations or custom attributes.
1395
         * </p>
1396
         * <p>
1397
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1398
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1399
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1400
         * altered, annotation retention must be disabled.
1401
         * </p>
1402
         * <p>
1403
         * If a record component is already matched by a previously specified record component matcher, the new record component
1404
         * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1405
         * </p>
1406
         *
1407
         * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1408
         * @return A builder that allows for changing a record component's definition.
1409
         */
1410
        @SuppressWarnings("overloads")
1411
        RecordComponentDefinition<T> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher);
1412

1413
        /**
1414
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder, using a
1415
         * default {@link TypePool}. A wrapper might not apply all features that are normally applied by Byte
1416
         * Buddy, if those features require control of the class loading life cycle. Neither does a wrapper define
1417
         * auxiliary types. It is therefore recommended to use {@link Implementation.Context.Disabled}.
1418
         *
1419
         * @param classVisitor The class visitor to wrap.
1420
         * @return A new class visitor that wraps a representation of this dynamic type.
1421
         */
1422
        ContextClassVisitor wrap(ClassVisitor classVisitor);
1423

1424
        /**
1425
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder, using a
1426
         * default {@link TypePool}. A wrapper might not apply all features that are normally applied by Byte
1427
         * Buddy, if those features require control of the class loading life cycle. Neither does a wrapper define
1428
         * auxiliary types. It is therefore recommended to use {@link Implementation.Context.Disabled}.
1429
         *
1430
         * @param classVisitor The class visitor to wrap.
1431
         * @param writerFlags  The ASM writer flags to apply.
1432
         * @param readerFlags  The ASM reader flags to apply.
1433
         * @return A new class visitor that wraps a representation of this dynamic type.
1434
         */
1435
        ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags);
1436

1437
        /**
1438
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder. A wrapper
1439
         * might not apply all features that are normally applied by Byte Buddy, if those features require control of
1440
         * the class loading life cycle. Neither does a wrapper define auxiliary types.  It is therefore recommended
1441
         * to use {@link Implementation.Context.Disabled}.
1442
         *
1443
         * @param classVisitor The class visitor to wrap.
1444
         * @param typePool     A type pool that is used for computing stack map frames by the underlying class writer, if required.
1445
         * @return A new class visitor that wraps a representation of this dynamic type.
1446
         */
1447
        ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool);
1448

1449
        /**
1450
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder. A wrapper
1451
         * might not apply all features that are normally applied by Byte Buddy, if those features require control
1452
         * of the class loading life cycle. Neither does a wrapper define auxiliary types.  It is therefore
1453
         * recommended to use {@link Implementation.Context.Disabled}.
1454
         *
1455
         * @param classVisitor The class visitor to wrap.
1456
         * @param typePool     A type pool that is used for computing stack map frames by the underlying class writer, if required.
1457
         * @param writerFlags  The ASM writer flags to apply.
1458
         * @param readerFlags  The ASM reader flags to apply.
1459
         * @return A new class visitor that wraps a representation of this dynamic type.
1460
         */
1461
        ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags);
1462

1463
        /**
1464
         * <p>
1465
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1466
         * </p>
1467
         * <p>
1468
         * Other than {@link DynamicType.Builder#make(TypePool)}, this method supplies a context-dependant type pool to the underlying class writer.
1469
         * Supplying a type pool only makes sense if custom byte code is created by adding a custom {@link AsmVisitorWrapper} where ASM might be
1470
         * required to compute stack map frames by processing information over any mentioned type's class hierarchy.
1471
         * </p>
1472
         * <p>
1473
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1474
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1475
         * executing the initializer must rely on such an initializer.
1476
         * </p>
1477
         *
1478
         * @return An unloaded dynamic type representing the type specified by this builder.
1479
         */
1480
        DynamicType.Unloaded<T> make();
1481

1482
        /**
1483
         * <p>
1484
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1485
         * </p>
1486
         * <p>
1487
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1488
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1489
         * executing the initializer must rely on such an initializer.
1490
         * </p>
1491
         *
1492
         * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1493
         * @return An unloaded dynamic type representing the type specified by this builder.
1494
         */
1495
        DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy);
1496

1497
        /**
1498
         * <p>
1499
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1500
         * </p>
1501
         * <p>
1502
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1503
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1504
         * executing the initializer must rely on such an initializer.
1505
         * </p>
1506
         *
1507
         * @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
1508
         * @return An unloaded dynamic type representing the type specified by this builder.
1509
         */
1510
        DynamicType.Unloaded<T> make(TypePool typePool);
1511

1512
        /**
1513
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1514
         *
1515
         * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1516
         * @param typePool               A type pool that is used for computing stack map frames by the underlying class writer, if required.
1517
         * @return An unloaded dynamic type representing the type specified by this builder.
1518
         */
1519
        DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool);
1520

1521
        /**
1522
         * Returns a {@link TypeDescription} for the currently built type.
1523
         *
1524
         * @return A {@link TypeDescription} for the currently built type.
1525
         */
1526
        TypeDescription toTypeDescription();
1527

1528
        /**
1529
         * An inner type definition for defining a type that is contained within another type, method or constructor.
1530
         *
1531
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1532
         */
1533
        interface InnerTypeDefinition<S> extends Builder<S> {
1534

1535
            /**
1536
             * Defines this inner type declaration as an anonymous type.
1537
             *
1538
             * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
1539
             */
1540
            Builder<S> asAnonymousType();
1541

1542
            /**
1543
             * An inner type definition for defining a type that is contained within another type.
1544
             *
1545
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1546
             */
1547
            interface ForType<U> extends InnerTypeDefinition<U> {
1548

1549
                /**
1550
                 * Defines this inner type declaration as a member type.
1551
                 *
1552
                 * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
1553
                 */
1554
                Builder<U> asMemberType();
1555
            }
1556
        }
1557

1558
        /**
1559
         * A builder for a type variable definition.
1560
         *
1561
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1562
         */
1563
        interface TypeVariableDefinition<S> extends Builder<S> {
1564

1565
            /**
1566
             * Annotates the previously defined type variable with the supplied annotations.
1567
             *
1568
             * @param annotation The annotations to declare on the previously defined type variable.
1569
             * @return A new builder that is equal to this builder but with the given annotations declared
1570
             * on the previously defined type variable.
1571
             */
1572
            TypeVariableDefinition<S> annotateTypeVariable(Annotation... annotation);
1573

1574
            /**
1575
             * Annotates the previously defined type variable with the supplied annotations.
1576
             *
1577
             * @param annotations The annotations to declare on the previously defined type variable.
1578
             * @return A new builder that is equal to this builder but with the given annotations declared
1579
             * on the previously defined type variable.
1580
             */
1581
            TypeVariableDefinition<S> annotateTypeVariable(List<? extends Annotation> annotations);
1582

1583
            /**
1584
             * Annotates the previously defined type variable with the supplied annotations.
1585
             *
1586
             * @param annotation The annotations to declare on the previously defined type variable.
1587
             * @return A new builder that is equal to this builder but with the given annotations declared
1588
             * on the previously defined type variable.
1589
             */
1590
            TypeVariableDefinition<S> annotateTypeVariable(AnnotationDescription... annotation);
1591

1592
            /**
1593
             * Annotates the previously defined type variable with the supplied annotations.
1594
             *
1595
             * @param annotations The annotations to declare on the previously defined type variable.
1596
             * @return A new builder that is equal to this builder but with the given annotations declared
1597
             * on the previously defined type variable.
1598
             */
1599
            TypeVariableDefinition<S> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
1600

1601
            /**
1602
             * An abstract base implementation of a type variable definition.
1603
             *
1604
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1605
             */
1606
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
1✔
1607

1608
                /**
1609
                 * {@inheritDoc}
1610
                 */
1611
                public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
1612
                    return annotateTypeVariable(Arrays.asList(annotation));
×
1613
                }
1614

1615
                /**
1616
                 * {@inheritDoc}
1617
                 */
1618
                public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
1619
                    return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
1620
                }
1621

1622
                /**
1623
                 * {@inheritDoc}
1624
                 */
1625
                public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
1626
                    return annotateTypeVariable(Arrays.asList(annotation));
1✔
1627
                }
1628
            }
1629
        }
1630

1631
        /**
1632
         * A builder for a field definition.
1633
         *
1634
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1635
         */
1636
        interface FieldDefinition<S> {
1637

1638
            /**
1639
             * Annotates the previously defined or matched field with the supplied annotations.
1640
             *
1641
             * @param annotation The annotations to declare on the previously defined or matched field.
1642
             * @return A new builder that is equal to this builder but with the given annotations declared
1643
             * on the previously defined or matched field.
1644
             */
1645
            FieldDefinition.Optional<S> annotateField(Annotation... annotation);
1646

1647
            /**
1648
             * Annotates the previously defined or matched field with the supplied annotations.
1649
             *
1650
             * @param annotations The annotations to declare on the previously defined or matched field.
1651
             * @return A new builder that is equal to this builder but with the given annotations declared
1652
             * on the previously defined or matched field.
1653
             */
1654
            FieldDefinition.Optional<S> annotateField(List<? extends Annotation> annotations);
1655

1656
            /**
1657
             * Annotates the previously defined or matched field with the supplied annotations.
1658
             *
1659
             * @param annotation The annotations to declare on the previously defined or matched field.
1660
             * @return A new builder that is equal to this builder but with the given annotations declared
1661
             * on the previously defined or matched field.
1662
             */
1663
            FieldDefinition.Optional<S> annotateField(AnnotationDescription... annotation);
1664

1665
            /**
1666
             * Annotates the previously defined or matched field with the supplied annotations.
1667
             *
1668
             * @param annotations The annotations to declare on the previously defined or matched field.
1669
             * @return A new builder that is equal to this builder but with the given annotations declared
1670
             * on the previously defined or matched field.
1671
             */
1672
            FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
1673

1674
            /**
1675
             * Applies the supplied attribute appender factory onto the previously defined or matched field.
1676
             *
1677
             * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
1678
             *                                      previously defined or matched field.
1679
             * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
1680
             * applied to the previously defined or matched field.
1681
             */
1682
            FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
1683

1684
            /**
1685
             * Applies the supplied transformer onto the previously defined or matched field. The transformed
1686
             * field is written <i>as it is</i> and is not subject to any validations.
1687
             *
1688
             * @param transformer The transformer to apply to the previously defined or matched field.
1689
             * @return A new builder that is equal to this builder but with the supplied field transformer
1690
             * applied to the previously defined or matched field.
1691
             */
1692
            FieldDefinition.Optional<S> transform(Transformer<FieldDescription> transformer);
1693

1694
            /**
1695
             * A builder for a field definition that allows for defining a value.
1696
             *
1697
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1698
             */
1699
            interface Valuable<U> extends FieldDefinition<U> {
1700

1701
                /**
1702
                 * <p>
1703
                 * Defines the supplied {@code boolean} value as a default value of the previously defined or matched field. The value can only
1704
                 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int}. For non-boolean
1705
                 * fields, the field's value is set to {@code 0} for {@code false} or {@code 1} for {@code true}.
1706
                 * </p>
1707
                 * <p>
1708
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1709
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1710
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1711
                 * </p>
1712
                 *
1713
                 * @param value The value to define as a default value of the defined field.
1714
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1715
                 * previously defined or matched field.
1716
                 */
1717
                FieldDefinition.Optional<U> value(boolean value);
1718

1719
                /**
1720
                 * <p>
1721
                 * Defines the supplied {@code int} value as a default value of the previously defined or matched field. The value can only
1722
                 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int} where the
1723
                 * value must be within the numeric type's range. The {@code boolean} type is regarded as a numeric type with the possible
1724
                 * values of {@code 0} and {@code 1} representing {@code false} and {@code true}.
1725
                 * </p>
1726
                 * <p>
1727
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1728
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1729
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1730
                 * </p>
1731
                 *
1732
                 * @param value The value to define as a default value of the defined field.
1733
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1734
                 * previously defined or matched field.
1735
                 */
1736
                FieldDefinition.Optional<U> value(int value);
1737

1738
                /**
1739
                 * <p>
1740
                 * Defines the supplied {@code long} value as a default value of the previously defined or matched field.
1741
                 * </p>
1742
                 * <p>
1743
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1744
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1745
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1746
                 * </p>
1747
                 *
1748
                 * @param value The value to define as a default value of the defined field.
1749
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1750
                 * previously defined or matched field.
1751
                 */
1752
                FieldDefinition.Optional<U> value(long value);
1753

1754
                /**
1755
                 * <p>
1756
                 * Defines the supplied {@code float} value as a default value of the previously defined or matched field.
1757
                 * </p>
1758
                 * <p>
1759
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1760
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1761
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1762
                 * </p>
1763
                 *
1764
                 * @param value The value to define as a default value of the defined field.
1765
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1766
                 * previously defined or matched field.
1767
                 */
1768
                FieldDefinition.Optional<U> value(float value);
1769

1770
                /**
1771
                 * <p>
1772
                 * Defines the supplied {@code double} value as a default value of the previously defined or matched field.
1773
                 * </p>
1774
                 * <p>
1775
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1776
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1777
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1778
                 * </p>
1779
                 *
1780
                 * @param value The value to define as a default value of the defined field.
1781
                 * @return A new builder that is equal to this builder but with the given default value declared for the
1782
                 * previously defined or matched field.
1783
                 */
1784
                FieldDefinition.Optional<U> value(double value);
1785

1786
                /**
1787
                 * <p>
1788
                 * Defines the supplied {@link String} value as a default value of the previously defined or matched field.
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(String value);
1801
            }
1802

1803
            /**
1804
             * A builder for an optional field definition.
1805
             *
1806
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1807
             */
1808
            interface Optional<U> extends FieldDefinition<U>, Builder<U> {
1809

1810
                /**
1811
                 * A builder for an optional field definition that allows for defining a value.
1812
                 *
1813
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1814
                 */
1815
                interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
1816

1817
                    /**
1818
                     * An abstract base implementation of an optional field definition that allows for defining a value.
1819
                     *
1820
                     * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1821
                     */
1822
                    abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1✔
1823

1824
                        /**
1825
                         * {@inheritDoc}
1826
                         */
1827
                        public FieldDefinition.Optional<U> value(boolean value) {
1828
                            return defaultValue(value ? 1 : 0);
1✔
1829
                        }
1830

1831
                        /**
1832
                         * {@inheritDoc}
1833
                         */
1834
                        public FieldDefinition.Optional<U> value(int value) {
1835
                            return defaultValue(value);
1✔
1836
                        }
1837

1838
                        /**
1839
                         * {@inheritDoc}
1840
                         */
1841
                        public FieldDefinition.Optional<U> value(long value) {
1842
                            return defaultValue(value);
1✔
1843
                        }
1844

1845
                        /**
1846
                         * {@inheritDoc}
1847
                         */
1848
                        public FieldDefinition.Optional<U> value(float value) {
1849
                            return defaultValue(value);
1✔
1850
                        }
1851

1852
                        /**
1853
                         * {@inheritDoc}
1854
                         */
1855
                        public FieldDefinition.Optional<U> value(double value) {
1856
                            return defaultValue(value);
1✔
1857
                        }
1858

1859
                        /**
1860
                         * {@inheritDoc}
1861
                         */
1862
                        public FieldDefinition.Optional<U> value(String value) {
1863
                            if (value == null) {
1✔
1864
                                throw new IllegalArgumentException("Cannot define 'null' as constant value");
1✔
1865
                            }
1866
                            return defaultValue(value);
1✔
1867
                        }
1868

1869
                        /**
1870
                         * Defines the supplied value as a default value of the previously defined or matched field.
1871
                         *
1872
                         * @param defaultValue The value to define as a default value of the defined field.
1873
                         * @return A new builder that is equal to this builder but with the given default value declared for the
1874
                         * previously defined or matched field.
1875
                         */
1876
                        protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
1877

1878
                        /**
1879
                         * An adapter for an optional field definition that allows for defining a value.
1880
                         *
1881
                         * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1882
                         */
1883
                        @HashCodeAndEqualsPlugin.Enhance
1884
                        private abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
1885

1886
                            /**
1887
                             * The field attribute appender factory to apply.
1888
                             */
1889
                            protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
1890

1891
                            /**
1892
                             * The field transformer to apply.
1893
                             */
1894
                            protected final Transformer<FieldDescription> transformer;
1895

1896
                            /**
1897
                             * The field's default value or {@code null} if no value is to be defined.
1898
                             */
1899
                            @MaybeNull
1900
                            @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
1901
                            protected final Object defaultValue;
1902

1903
                            /**
1904
                             * Creates a new field adapter.
1905
                             *
1906
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1907
                             * @param transformer                   The field transformer to apply.
1908
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
1909
                             */
1910
                            protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
1911
                                              Transformer<FieldDescription> transformer,
1912
                                              @MaybeNull Object defaultValue) {
1✔
1913
                                this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
1✔
1914
                                this.transformer = transformer;
1✔
1915
                                this.defaultValue = defaultValue;
1✔
1916
                            }
1✔
1917

1918
                            /**
1919
                             * {@inheritDoc}
1920
                             */
1921
                            public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
1922
                                return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
1✔
1923
                            }
1924

1925
                            /**
1926
                             * {@inheritDoc}
1927
                             */
1928
                            @SuppressWarnings("unchecked") // In absence of @SafeVarargs
1929
                            public FieldDefinition.Optional<V> transform(Transformer<FieldDescription> transformer) {
1930
                                return materialize(fieldAttributeAppenderFactory, new Transformer.Compound<FieldDescription>(this.transformer, transformer), defaultValue);
1✔
1931
                            }
1932

1933
                            @Override
1934
                            protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
1935
                                return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
1936
                            }
1937

1938
                            /**
1939
                             * Creates a new optional field definition for which all of the supplied values are represented.
1940
                             *
1941
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1942
                             * @param transformer                   The field transformer to apply.
1943
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
1944
                             * @return A new field definition that represents the supplied values.
1945
                             */
1946
                            protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
1947
                                                                                       Transformer<FieldDescription> transformer,
1948
                                                                                       @MaybeNull Object defaultValue);
1949
                        }
1950
                    }
1951
                }
1952

1953
                /**
1954
                 * An abstract base implementation for an optional field definition.
1955
                 *
1956
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1957
                 */
1958
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1✔
1959

1960
                    /**
1961
                     * {@inheritDoc}
1962
                     */
1963
                    public FieldDefinition.Optional<U> annotateField(Annotation... annotation) {
1964
                        return annotateField(Arrays.asList(annotation));
1✔
1965
                    }
1966

1967
                    /**
1968
                     * {@inheritDoc}
1969
                     */
1970
                    public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
1971
                        return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
1972
                    }
1973

1974
                    /**
1975
                     * {@inheritDoc}
1976
                     */
1977
                    public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
1978
                        return annotateField(Arrays.asList(annotation));
1✔
1979
                    }
1980
                }
1981
            }
1982
        }
1983

1984
        /**
1985
         * A builder for a method definition.
1986
         *
1987
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1988
         */
1989
        interface MethodDefinition<S> extends Builder<S> {
1990

1991
            /**
1992
             * Annotates the previously defined or matched method with the supplied annotations.
1993
             *
1994
             * @param annotation The annotations to declare on the previously defined or matched method.
1995
             * @return A new builder that is equal to this builder but with the given annotations declared
1996
             * on the previously defined or matched method.
1997
             */
1998
            MethodDefinition<S> annotateMethod(Annotation... annotation);
1999

2000
            /**
2001
             * Annotates the previously defined or matched method with the supplied annotations.
2002
             *
2003
             * @param annotations The annotations to declare on the previously defined or matched method.
2004
             * @return A new builder that is equal to this builder but with the given annotations declared
2005
             * on the previously defined or matched method.
2006
             */
2007
            MethodDefinition<S> annotateMethod(List<? extends Annotation> annotations);
2008

2009
            /**
2010
             * Annotates the previously defined or matched method with the supplied annotations.
2011
             *
2012
             * @param annotation The annotations to declare on the previously defined or matched method.
2013
             * @return A new builder that is equal to this builder but with the given annotations declared
2014
             * on the previously defined or matched method.
2015
             */
2016
            MethodDefinition<S> annotateMethod(AnnotationDescription... annotation);
2017

2018
            /**
2019
             * Annotates the previously defined or matched method with the supplied annotations.
2020
             *
2021
             * @param annotations The annotations to declare on the previously defined or matched method.
2022
             * @return A new builder that is equal to this builder but with the given annotations declared
2023
             * on the previously defined or matched method.
2024
             */
2025
            MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
2026

2027
            /**
2028
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2029
             *
2030
             * @param index      The parameter's index.
2031
             * @param annotation The annotations to declare on the previously defined or matched method.
2032
             * @return A new builder that is equal to this builder but with the given annotations declared
2033
             * on the previously defined or matched method's parameter of the given index.
2034
             */
2035
            MethodDefinition<S> annotateParameter(int index, Annotation... annotation);
2036

2037
            /**
2038
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2039
             *
2040
             * @param index       The parameter's index.
2041
             * @param annotations The annotations to declare on the previously defined or matched method.
2042
             * @return A new builder that is equal to this builder but with the given annotations declared
2043
             * on the previously defined or matched method's parameter of the given index.
2044
             */
2045
            MethodDefinition<S> annotateParameter(int index, List<? extends Annotation> annotations);
2046

2047
            /**
2048
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2049
             *
2050
             * @param index      The parameter's index.
2051
             * @param annotation The annotations to declare on the previously defined or matched method.
2052
             * @return A new builder that is equal to this builder but with the given annotations declared
2053
             * on the previously defined or matched method's parameter of the given index.
2054
             */
2055
            MethodDefinition<S> annotateParameter(int index, AnnotationDescription... annotation);
2056

2057
            /**
2058
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2059
             *
2060
             * @param index       The parameter's index.
2061
             * @param annotations The annotations to declare on the previously defined or matched method.
2062
             * @return A new builder that is equal to this builder but with the given annotations declared
2063
             * on the previously defined or matched method's parameter of the given index.
2064
             */
2065
            MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
2066

2067
            /**
2068
             * Applies the supplied method attribute appender factory onto the previously defined or matched method.
2069
             *
2070
             * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
2071
             *                                       previously defined or matched method.
2072
             * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
2073
             * applied to the previously defined or matched method.
2074
             */
2075
            MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
2076

2077
            /**
2078
             * Applies the supplied transformer onto the previously defined or matched method. The transformed
2079
             * method is written <i>as it is</i> and it not subject to any validations.
2080
             *
2081
             * @param transformer The transformer to apply to the previously defined or matched method.
2082
             * @return A new builder that is equal to this builder but with the supplied transformer
2083
             * applied to the previously defined or matched method.
2084
             */
2085
            MethodDefinition<S> transform(Transformer<MethodDescription> transformer);
2086

2087
            /**
2088
             * A builder for a method definition with a receiver type.
2089
             *
2090
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2091
             */
2092
            interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
2093

2094
                /**
2095
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2096
                 *
2097
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2098
                 * @return A new builder that is equal to this builder but with the given type defined as the
2099
                 * receiver on the previously defined or matched method.
2100
                 */
2101
                MethodDefinition<U> receiverType(AnnotatedElement receiverType);
2102

2103
                /**
2104
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2105
                 *
2106
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2107
                 * @return A new builder that is equal to this builder but with the given type defined as the
2108
                 * receiver on the previously defined or matched method.
2109
                 */
2110
                MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
2111

2112
                /**
2113
                 * An abstract base implementation of a method definition that can accept a receiver type.
2114
                 *
2115
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2116
                 */
2117
                abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
1✔
2118

2119
                    /**
2120
                     * {@inheritDoc}
2121
                     */
2122
                    public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
2123
                        return receiverType(TypeDefinition.Sort.describeAnnotated(receiverType));
×
2124
                    }
2125
                }
2126
            }
2127

2128
            /**
2129
             * A builder for defining an implementation of a method.
2130
             *
2131
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2132
             */
2133
            interface ImplementationDefinition<U> {
2134

2135
                /**
2136
                 * Implements the previously defined or matched method by the supplied implementation. A method interception
2137
                 * is typically implemented in one of the following ways:
2138
                 * <ol>
2139
                 * <li>If a method is declared by the instrumented type and the type builder creates a subclass or redefinition,
2140
                 * any preexisting method is replaced by the given implementation. Any previously defined implementation is lost.</li>
2141
                 * <li>If a method is declared by the instrumented type and the type builder creates a rebased version of the
2142
                 * instrumented type, the original method is preserved within a private, synthetic method within the instrumented
2143
                 * type. The original method therefore remains invokeable and is treated as the direct super method of the new
2144
                 * method. When rebasing a type, it therefore becomes possible to invoke a non-virtual method's super method
2145
                 * when a preexisting method body is replaced.</li>
2146
                 * <li>If a virtual method is inherited from a super type, it is overridden. The overridden method is available
2147
                 * for super method invocation.</li>
2148
                 * </ol>
2149
                 *
2150
                 * @param implementation The implementation for implementing the previously defined or matched method.
2151
                 * @return A new builder where the previously defined or matched method is implemented by the
2152
                 * supplied implementation.
2153
                 */
2154
                MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation);
2155

2156
                /**
2157
                 * Defines the previously defined or matched method not to declare a method body. This implies the
2158
                 * method to be {@code abstract} unless it was already declared to be {@code native}.
2159
                 *
2160
                 * @return A new builder where the previously defined or matched method is implemented to be abstract.
2161
                 */
2162
                MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
2163

2164
                /**
2165
                 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2166
                 * value must be supplied in its unloaded state, i.e. enumerations as {@link net.bytebuddy.description.enumeration.EnumerationDescription},
2167
                 * types as {@link TypeDescription} and annotations as {@link AnnotationDescription}. For supplying loaded types, use
2168
                 * {@link ImplementationDefinition#defaultValue(Object, Class)} must be used.
2169
                 *
2170
                 * @param annotationValue The value to be defined as a default value.
2171
                 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2172
                 */
2173
                MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue);
2174

2175
                /**
2176
                 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2177
                 * value must be supplied in its loaded state paired with the property type of the value.
2178
                 *
2179
                 * @param value The value to be defined as a default value.
2180
                 * @param type  The type of the annotation property.
2181
                 * @param <W>   The type of the annotation property.
2182
                 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2183
                 */
2184
                <W> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(W value, Class<? extends W> type);
2185

2186
                /**
2187
                 * A builder for optionally defining an implementation of a method.
2188
                 *
2189
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2190
                 */
2191
                interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
2192
                    /* union type */
2193
                }
2194

2195
                /**
2196
                 * An abstract base implementation for a builder optionally defining an implementation of a method.
2197
                 *
2198
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2199
                 */
2200
                abstract class AbstractBase<V> implements ImplementationDefinition<V> {
1✔
2201

2202
                    /**
2203
                     * {@inheritDoc}
2204
                     */
2205
                    public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) {
2206
                        return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
1✔
2207
                    }
2208
                }
2209
            }
2210

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

2218
                /**
2219
                 * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
2220
                 *
2221
                 * @param symbol The symbol of the type variable.
2222
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2223
                 */
2224
                Annotatable<U> typeVariable(String symbol);
2225

2226
                /**
2227
                 * Defines a method variable to be declared by the currently defined method.
2228
                 *
2229
                 * @param symbol The symbol of the type variable.
2230
                 * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2231
                 *               if a bound type should be equal to the currently instrumented type.
2232
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2233
                 */
2234
                Annotatable<U> typeVariable(String symbol, Type... bound);
2235

2236
                /**
2237
                 * Defines a method variable to be declared by the currently defined method.
2238
                 *
2239
                 * @param symbol The symbol of the type variable.
2240
                 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2241
                 *               if a bound type should be equal to the currently instrumented type.
2242
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2243
                 */
2244
                Annotatable<U> typeVariable(String symbol, List<? extends Type> bounds);
2245

2246
                /**
2247
                 * Defines a method variable to be declared by the currently defined method.
2248
                 *
2249
                 * @param symbol The symbol of the type variable.
2250
                 * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2251
                 *               if a bound type should be equal to the currently instrumented type.
2252
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2253
                 */
2254
                Annotatable<U> typeVariable(String symbol, TypeDefinition... bound);
2255

2256
                /**
2257
                 * Defines a method variable to be declared by the currently defined method.
2258
                 *
2259
                 * @param symbol The symbol of the type variable.
2260
                 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2261
                 *               if a bound type should be equal to the currently instrumented type.
2262
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2263
                 */
2264
                Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
2265

2266
                /**
2267
                 * A builder for optionally defining an annotation for a type variable.
2268
                 *
2269
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2270
                 */
2271
                interface Annotatable<V> extends TypeVariableDefinition<V> {
2272

2273
                    /**
2274
                     * Annotates the previously defined type variable with the supplied annotations.
2275
                     *
2276
                     * @param annotation The annotations to declare on the previously defined type variable.
2277
                     * @return A new builder that is equal to this builder but with the given annotations declared
2278
                     * on the previously defined type variable.
2279
                     */
2280
                    Annotatable<V> annotateTypeVariable(Annotation... annotation);
2281

2282
                    /**
2283
                     * Annotates the previously defined type variable with the supplied annotations.
2284
                     *
2285
                     * @param annotations The annotations to declare on the previously defined type variable.
2286
                     * @return A new builder that is equal to this builder but with the given annotations declared
2287
                     * on the previously defined type variable.
2288
                     */
2289
                    Annotatable<V> annotateTypeVariable(List<? extends Annotation> annotations);
2290

2291
                    /**
2292
                     * Annotates the previously defined type variable with the supplied annotations.
2293
                     *
2294
                     * @param annotation The annotations to declare on the previously defined type variable.
2295
                     * @return A new builder that is equal to this builder but with the given annotations declared
2296
                     * on the previously defined type variable.
2297
                     */
2298
                    Annotatable<V> annotateTypeVariable(AnnotationDescription... annotation);
2299

2300
                    /**
2301
                     * Annotates the previously defined type variable with the supplied annotations.
2302
                     *
2303
                     * @param annotations The annotations to declare on the previously defined type variable.
2304
                     * @return A new builder that is equal to this builder but with the given annotations declared
2305
                     * on the previously defined type variable.
2306
                     */
2307
                    Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
2308

2309
                    /**
2310
                     * An abstract base implementation for defining an annotation on a parameter.
2311
                     *
2312
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2313
                     */
2314
                    abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
2315

2316
                        /**
2317
                         * {@inheritDoc}
2318
                         */
2319
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
2320
                            return annotateTypeVariable(Arrays.asList(annotation));
×
2321
                        }
2322

2323
                        /**
2324
                         * {@inheritDoc}
2325
                         */
2326
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
2327
                            return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
2328
                        }
2329

2330
                        /**
2331
                         * {@inheritDoc}
2332
                         */
2333
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
2334
                            return annotateTypeVariable(Arrays.asList(annotation));
1✔
2335
                        }
2336

2337
                        /**
2338
                         * An adapter implementation for an annotatable type variable definition.
2339
                         *
2340
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2341
                         */
2342
                        protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
1✔
2343

2344
                            /**
2345
                             * {@inheritDoc}
2346
                             */
2347
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2348
                                return materialize().typeVariable(symbol, bounds);
1✔
2349
                            }
2350

2351
                            /**
2352
                             * {@inheritDoc}
2353
                             */
2354
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2355
                                return materialize().intercept(implementation);
1✔
2356
                            }
2357

2358
                            /**
2359
                             * {@inheritDoc}
2360
                             */
2361
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2362
                                return materialize().withoutCode();
1✔
2363
                            }
2364

2365
                            /**
2366
                             * {@inheritDoc}
2367
                             */
2368
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2369
                                return materialize().defaultValue(annotationValue);
×
2370
                            }
2371

2372
                            /**
2373
                             * {@inheritDoc}
2374
                             */
2375
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2376
                                return materialize().defaultValue(value, type);
×
2377
                            }
2378

2379
                            /**
2380
                             * Materializes this instance as a parameter definition with the currently defined properties.
2381
                             *
2382
                             * @return A parameter definition with the currently defined properties.
2383
                             */
2384
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2385
                        }
2386
                    }
2387
                }
2388

2389
                /**
2390
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
2391
                 *
2392
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2393
                 */
2394
                abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
1✔
2395

2396
                    /**
2397
                     * {@inheritDoc}
2398
                     */
2399
                    public Annotatable<V> typeVariable(String symbol) {
2400
                        return typeVariable(symbol, Collections.singletonList(Object.class));
1✔
2401
                    }
2402

2403
                    /**
2404
                     * {@inheritDoc}
2405
                     */
2406
                    public Annotatable<V> typeVariable(String symbol, Type... bound) {
2407
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
2408
                    }
2409

2410
                    /**
2411
                     * {@inheritDoc}
2412
                     */
2413
                    public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
2414
                        return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
2415
                    }
2416

2417
                    /**
2418
                     * {@inheritDoc}
2419
                     */
2420
                    public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
2421
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
2422
                    }
2423
                }
2424
            }
2425

2426
            /**
2427
             * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
2428
             *
2429
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2430
             */
2431
            interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
2432

2433
                /**
2434
                 * Defines a method variable to be declared by the currently defined method.
2435
                 *
2436
                 * @param type The type of the exception being declared by the currently defined method.
2437
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2438
                 */
2439
                ExceptionDefinition<U> throwing(Type... type);
2440

2441
                /**
2442
                 * Defines a method variable to be declared by the currently defined method.
2443
                 *
2444
                 * @param types The type of the exception being declared by the currently defined method.
2445
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2446
                 */
2447
                ExceptionDefinition<U> throwing(List<? extends Type> types);
2448

2449
                /**
2450
                 * Defines a method variable to be declared by the currently defined method.
2451
                 *
2452
                 * @param type The type of the exception being declared by the currently defined method.
2453
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2454
                 */
2455
                ExceptionDefinition<U> throwing(TypeDefinition... type);
2456

2457
                /**
2458
                 * Defines a method variable to be declared by the currently defined method.
2459
                 *
2460
                 * @param types The type of the exception being declared by the currently defined method.
2461
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2462
                 */
2463
                ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
2464

2465
                /**
2466
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
2467
                 *
2468
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2469
                 */
2470
                abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
1✔
2471

2472
                    /**
2473
                     * {@inheritDoc}
2474
                     */
2475
                    public ExceptionDefinition<V> throwing(Type... type) {
2476
                        return throwing(Arrays.asList(type));
1✔
2477
                    }
2478

2479
                    /**
2480
                     * {@inheritDoc}
2481
                     */
2482
                    public ExceptionDefinition<V> throwing(List<? extends Type> types) {
2483
                        return throwing(new TypeList.Generic.ForLoadedTypes(types));
1✔
2484
                    }
2485

2486
                    /**
2487
                     * {@inheritDoc}
2488
                     */
2489
                    public ExceptionDefinition<V> throwing(TypeDefinition... type) {
2490
                        return throwing(Arrays.asList(type));
1✔
2491
                    }
2492
                }
2493
            }
2494

2495
            /**
2496
             * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2497
             *
2498
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2499
             */
2500
            interface ParameterDefinition<U> extends ExceptionDefinition<U> {
2501

2502
                /**
2503
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2504
                 *
2505
                 * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2506
                 *                            should be equal to the currently instrumented type.
2507
                 * @param name                The parameter's name.
2508
                 * @param modifierContributor The parameter's modifiers.
2509
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2510
                 */
2511
                Annotatable<U> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor);
2512

2513
                /**
2514
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2515
                 *
2516
                 * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2517
                 *                             should be equal to the currently instrumented type.
2518
                 * @param name                 The parameter's name.
2519
                 * @param modifierContributors The parameter's modifiers.
2520
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2521
                 */
2522
                Annotatable<U> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2523

2524
                /**
2525
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2526
                 *
2527
                 * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2528
                 *                  should be equal to the currently instrumented type.
2529
                 * @param name      The parameter's name.
2530
                 * @param modifiers The parameter's modifiers.
2531
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2532
                 */
2533
                Annotatable<U> withParameter(Type type, String name, int modifiers);
2534

2535
                /**
2536
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2537
                 *
2538
                 * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2539
                 *                            should be equal to the currently instrumented type.
2540
                 * @param name                The parameter's name.
2541
                 * @param modifierContributor The parameter's modifiers.
2542
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2543
                 */
2544
                Annotatable<U> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor);
2545

2546
                /**
2547
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2548
                 *
2549
                 * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2550
                 *                             should be equal to the currently instrumented type.
2551
                 * @param name                 The parameter's name.
2552
                 * @param modifierContributors The parameter's modifiers.
2553
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2554
                 */
2555
                Annotatable<U> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2556

2557
                /**
2558
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2559
                 *
2560
                 * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2561
                 *                  should be equal to the currently instrumented type.
2562
                 * @param name      The parameter's name.
2563
                 * @param modifiers The parameter's modifiers.
2564
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2565
                 */
2566
                Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers);
2567

2568
                /**
2569
                 * A builder for optionally defining an annotation on a parameter.
2570
                 *
2571
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2572
                 */
2573
                interface Annotatable<V> extends ParameterDefinition<V> {
2574

2575
                    /**
2576
                     * Annotates the previously defined parameter with the specified annotations.
2577
                     *
2578
                     * @param annotation The annotations to declare on the previously defined parameter.
2579
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2580
                     * the specified annotations.
2581
                     */
2582
                    Annotatable<V> annotateParameter(Annotation... annotation);
2583

2584
                    /**
2585
                     * Annotates the previously defined parameter with the specified annotations.
2586
                     *
2587
                     * @param annotations The annotations to declare on the previously defined parameter.
2588
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2589
                     * the specified annotations.
2590
                     */
2591
                    Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2592

2593
                    /**
2594
                     * Annotates the previously defined parameter with the specified annotations.
2595
                     *
2596
                     * @param annotation The annotations to declare on the previously defined parameter.
2597
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2598
                     * the specified annotations.
2599
                     */
2600
                    Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2601

2602
                    /**
2603
                     * Annotates the previously defined parameter with the specified annotations.
2604
                     *
2605
                     * @param annotations The annotations to declare on the previously defined parameter.
2606
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2607
                     * the specified annotations.
2608
                     */
2609
                    Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2610

2611
                    /**
2612
                     * An abstract base implementation for defining an annotation on a parameter.
2613
                     *
2614
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2615
                     */
2616
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
2617

2618
                        /**
2619
                         * {@inheritDoc}
2620
                         */
2621
                        public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
2622
                            return annotateParameter(Arrays.asList(annotation));
×
2623
                        }
2624

2625
                        /**
2626
                         * {@inheritDoc}
2627
                         */
2628
                        public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2629
                            return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
2630
                        }
2631

2632
                        /**
2633
                         * {@inheritDoc}
2634
                         */
2635
                        public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2636
                            return annotateParameter(Arrays.asList(annotation));
×
2637
                        }
2638

2639
                        /**
2640
                         * An adapter implementation for defining an annotation on a parameter.
2641
                         *
2642
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2643
                         */
2644
                        protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
1✔
2645

2646
                            /**
2647
                             * {@inheritDoc}
2648
                             */
2649
                            public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
2650
                                return materialize().withParameter(type, name, modifiers);
×
2651
                            }
2652

2653
                            /**
2654
                             * {@inheritDoc}
2655
                             */
2656
                            public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2657
                                return materialize().throwing(types);
1✔
2658
                            }
2659

2660
                            /**
2661
                             * {@inheritDoc}
2662
                             */
2663
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2664
                                return materialize().typeVariable(symbol, bounds);
×
2665
                            }
2666

2667
                            /**
2668
                             * {@inheritDoc}
2669
                             */
2670
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2671
                                return materialize().intercept(implementation);
×
2672
                            }
2673

2674
                            /**
2675
                             * {@inheritDoc}
2676
                             */
2677
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2678
                                return materialize().withoutCode();
×
2679
                            }
2680

2681
                            /**
2682
                             * {@inheritDoc}
2683
                             */
2684
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2685
                                return materialize().defaultValue(annotationValue);
×
2686
                            }
2687

2688
                            /**
2689
                             * {@inheritDoc}
2690
                             */
2691
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2692
                                return materialize().defaultValue(value, type);
×
2693
                            }
2694

2695
                            /**
2696
                             * Materializes this instance as a parameter definition with the currently defined properties.
2697
                             *
2698
                             * @return A parameter definition with the currently defined properties.
2699
                             */
2700
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2701
                        }
2702
                    }
2703
                }
2704

2705
                /**
2706
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
2707
                 *
2708
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2709
                 */
2710
                interface Simple<V> extends ExceptionDefinition<V> {
2711

2712
                    /**
2713
                     * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2714
                     *
2715
                     * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2716
                     *             should be equal to the currently instrumented type.
2717
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2718
                     */
2719
                    Annotatable<V> withParameter(Type type);
2720

2721
                    /**
2722
                     * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2723
                     *
2724
                     * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2725
                     *             should be equal to the currently instrumented type.
2726
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2727
                     */
2728
                    Annotatable<V> withParameter(TypeDefinition type);
2729

2730
                    /**
2731
                     * A builder for optionally defining an annotation on a parameter.
2732
                     *
2733
                     * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2734
                     */
2735
                    interface Annotatable<V> extends Simple<V> {
2736

2737
                        /**
2738
                         * Annotates the previously defined parameter with the specified annotations.
2739
                         *
2740
                         * @param annotation The annotations to declare on the previously defined parameter.
2741
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2742
                         * the specified annotations.
2743
                         */
2744
                        Annotatable<V> annotateParameter(Annotation... annotation);
2745

2746
                        /**
2747
                         * Annotates the previously defined parameter with the specified annotations.
2748
                         *
2749
                         * @param annotations The annotations to declare on the previously defined parameter.
2750
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2751
                         * the specified annotations.
2752
                         */
2753
                        Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2754

2755
                        /**
2756
                         * Annotates the previously defined parameter with the specified annotations.
2757
                         *
2758
                         * @param annotation The annotations to declare on the previously defined parameter.
2759
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2760
                         * the specified annotations.
2761
                         */
2762
                        Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2763

2764
                        /**
2765
                         * Annotates the previously defined parameter with the specified annotations.
2766
                         *
2767
                         * @param annotations The annotations to declare on the previously defined parameter.
2768
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2769
                         * the specified annotations.
2770
                         */
2771
                        Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2772

2773
                        /**
2774
                         * An abstract base implementation of a simple parameter definition.
2775
                         *
2776
                         * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2777
                         */
2778
                        abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
1✔
2779

2780
                            /**
2781
                             * {@inheritDoc}
2782
                             */
2783
                            public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
2784
                                return annotateParameter(Arrays.asList(annotation));
×
2785
                            }
2786

2787
                            /**
2788
                             * {@inheritDoc}
2789
                             */
2790
                            public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2791
                                return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
2792
                            }
2793

2794
                            /**
2795
                             * {@inheritDoc}
2796
                             */
2797
                            public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2798
                                return annotateParameter(Arrays.asList(annotation));
1✔
2799
                            }
2800

2801
                            /**
2802
                             * An adapter implementation of a simple parameter definition.
2803
                             *
2804
                             * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2805
                             */
2806
                            protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
1✔
2807

2808
                                /**
2809
                                 * {@inheritDoc}
2810
                                 */
2811
                                public Simple.Annotatable<X> withParameter(TypeDefinition type) {
2812
                                    return materialize().withParameter(type);
1✔
2813
                                }
2814

2815
                                /**
2816
                                 * {@inheritDoc}
2817
                                 */
2818
                                public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2819
                                    return materialize().throwing(types);
1✔
2820
                                }
2821

2822
                                /**
2823
                                 * {@inheritDoc}
2824
                                 */
2825
                                public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2826
                                    return materialize().typeVariable(symbol, bounds);
×
2827
                                }
2828

2829
                                /**
2830
                                 * {@inheritDoc}
2831
                                 */
2832
                                public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2833
                                    return materialize().intercept(implementation);
1✔
2834
                                }
2835

2836
                                /**
2837
                                 * {@inheritDoc}
2838
                                 */
2839
                                public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2840
                                    return materialize().withoutCode();
1✔
2841
                                }
2842

2843
                                /**
2844
                                 * {@inheritDoc}
2845
                                 */
2846
                                public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2847
                                    return materialize().defaultValue(annotationValue);
×
2848
                                }
2849

2850
                                /**
2851
                                 * {@inheritDoc}
2852
                                 */
2853
                                public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2854
                                    return materialize().defaultValue(value, type);
×
2855
                                }
2856

2857
                                /**
2858
                                 * Materializes this instance as a simple parameter definition with the currently defined properties.
2859
                                 *
2860
                                 * @return A simple parameter definition with the currently defined properties.
2861
                                 */
2862
                                protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
2863
                            }
2864
                        }
2865
                    }
2866

2867
                    /**
2868
                     * An abstract base implementation of an exception definition.
2869
                     *
2870
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2871
                     */
2872
                    abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
1✔
2873

2874
                        /**
2875
                         * {@inheritDoc}
2876
                         */
2877
                        public Simple.Annotatable<W> withParameter(Type type) {
2878
                            return withParameter(TypeDefinition.Sort.describe(type));
×
2879
                        }
2880
                    }
2881
                }
2882

2883
                /**
2884
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2885
                 * Implementations allow for the <i>one-by-one</i> definition of parameters what gives opportunity to annotate parameters in a fluent
2886
                 * style. Doing so, it is optionally possible to define parameter names and modifiers. This can be done for either all or no parameters.
2887
                 * Alternatively, parameters without annotations, names or modifiers can be defined by a single step.
2888
                 *
2889
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2890
                 */
2891
                interface Initial<V> extends ParameterDefinition<V>, Simple<V> {
2892

2893
                    /**
2894
                     * Defines the specified parameters for the currently defined method.
2895
                     *
2896
                     * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2897
                     *             should be equal to the currently instrumented type.
2898
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2899
                     */
2900
                    ExceptionDefinition<V> withParameters(Type... type);
2901

2902
                    /**
2903
                     * Defines the specified parameters for the currently defined method.
2904
                     *
2905
                     * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2906
                     *              should be equal to the currently instrumented type.
2907
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2908
                     */
2909
                    ExceptionDefinition<V> withParameters(List<? extends Type> types);
2910

2911
                    /**
2912
                     * Defines the specified parameters for the currently defined method.
2913
                     *
2914
                     * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2915
                     *             should be equal to the currently instrumented type.
2916
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2917
                     */
2918
                    ExceptionDefinition<V> withParameters(TypeDefinition... type);
2919

2920
                    /**
2921
                     * Defines the specified parameters for the currently defined method.
2922
                     *
2923
                     * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2924
                     *              should be equal to the currently instrumented type.
2925
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2926
                     */
2927
                    ExceptionDefinition<V> withParameters(Collection<? extends TypeDefinition> types);
2928

2929
                    /**
2930
                     * An abstract base implementation for an initial parameter definition.
2931
                     *
2932
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2933
                     */
2934
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
1✔
2935

2936
                        /**
2937
                         * {@inheritDoc}
2938
                         */
2939
                        public Simple.Annotatable<W> withParameter(Type type) {
2940
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
2941
                        }
2942

2943
                        /**
2944
                         * {@inheritDoc}
2945
                         */
2946
                        public ExceptionDefinition<W> withParameters(Type... type) {
2947
                            return withParameters(Arrays.asList(type));
1✔
2948
                        }
2949

2950
                        /**
2951
                         * {@inheritDoc}
2952
                         */
2953
                        public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
2954
                            return withParameters(new TypeList.Generic.ForLoadedTypes(types));
1✔
2955
                        }
2956

2957
                        /**
2958
                         * {@inheritDoc}
2959
                         */
2960
                        public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
2961
                            return withParameters(Arrays.asList(type));
1✔
2962
                        }
2963

2964
                        /**
2965
                         * {@inheritDoc}
2966
                         */
2967
                        public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
2968
                            ParameterDefinition.Simple<W> parameterDefinition = this;
1✔
2969
                            for (TypeDefinition type : types) {
1✔
2970
                                parameterDefinition = parameterDefinition.withParameter(type);
1✔
2971
                            }
1✔
2972
                            return parameterDefinition;
1✔
2973
                        }
2974
                    }
2975
                }
2976

2977
                /**
2978
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable, thrown exception or parameter type.
2979
                 *
2980
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2981
                 */
2982
                abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
1✔
2983

2984
                    /**
2985
                     * {@inheritDoc}
2986
                     */
2987
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
2988
                        return withParameter(type, name, Arrays.asList(modifierContributor));
1✔
2989
                    }
2990

2991
                    /**
2992
                     * {@inheritDoc}
2993
                     */
2994
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
2995
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
2996
                    }
2997

2998
                    /**
2999
                     * {@inheritDoc}
3000
                     */
3001
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
3002
                        return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
1✔
3003
                    }
3004

3005
                    /**
3006
                     * {@inheritDoc}
3007
                     */
3008
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
3009
                        return withParameter(type, name, Arrays.asList(modifierContributor));
×
3010
                    }
3011

3012
                    /**
3013
                     * {@inheritDoc}
3014
                     */
3015
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
3016
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
3017
                    }
3018
                }
3019
            }
3020

3021
            /**
3022
             * An abstract base implementation of a method definition.
3023
             *
3024
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3025
             */
3026
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
1✔
3027

3028
                /**
3029
                 * {@inheritDoc}
3030
                 */
3031
                public MethodDefinition<U> annotateMethod(Annotation... annotation) {
3032
                    return annotateMethod(Arrays.asList(annotation));
1✔
3033
                }
3034

3035
                /**
3036
                 * {@inheritDoc}
3037
                 */
3038
                public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
3039
                    return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
3040
                }
3041

3042
                /**
3043
                 * {@inheritDoc}
3044
                 */
3045
                public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
3046
                    return annotateMethod(Arrays.asList(annotation));
1✔
3047
                }
3048

3049
                /**
3050
                 * {@inheritDoc}
3051
                 */
3052
                public MethodDefinition<U> annotateParameter(int index, Annotation... annotation) {
3053
                    return annotateParameter(index, Arrays.asList(annotation));
×
3054
                }
3055

3056
                /**
3057
                 * {@inheritDoc}
3058
                 */
3059
                public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
3060
                    return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
×
3061
                }
3062

3063
                /**
3064
                 * {@inheritDoc}
3065
                 */
3066
                public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
3067
                    return annotateParameter(index, Arrays.asList(annotation));
×
3068
                }
3069

3070
                /**
3071
                 * An adapter implementation of a method definition.
3072
                 *
3073
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3074
                 */
3075
                @HashCodeAndEqualsPlugin.Enhance
3076
                protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
3077

3078
                    /**
3079
                     * The handler that determines how a method is implemented.
3080
                     */
3081
                    protected final MethodRegistry.Handler handler;
3082

3083
                    /**
3084
                     * The method attribute appender factory to apply onto the method that is currently being implemented.
3085
                     */
3086
                    protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
3087

3088
                    /**
3089
                     * The transformer to apply onto the method that is currently being implemented.
3090
                     */
3091
                    protected final Transformer<MethodDescription> transformer;
3092

3093
                    /**
3094
                     * Creates a new adapter for a method definition.
3095
                     *
3096
                     * @param handler                        The handler that determines how a method is implemented.
3097
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3098
                     * @param transformer                    The transformer to apply onto the method that is currently being implemented.
3099
                     */
3100
                    protected Adapter(MethodRegistry.Handler handler,
3101
                                      MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3102
                                      Transformer<MethodDescription> transformer) {
1✔
3103
                        this.handler = handler;
1✔
3104
                        this.methodAttributeAppenderFactory = methodAttributeAppenderFactory;
1✔
3105
                        this.transformer = transformer;
1✔
3106
                    }
1✔
3107

3108
                    /**
3109
                     * {@inheritDoc}
3110
                     */
3111
                    public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
3112
                        return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), transformer);
1✔
3113
                    }
3114

3115
                    /**
3116
                     * {@inheritDoc}
3117
                     */
3118
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
3119
                    public MethodDefinition<V> transform(Transformer<MethodDescription> transformer) {
3120
                        return materialize(handler, methodAttributeAppenderFactory, new Transformer.Compound<MethodDescription>(this.transformer, transformer));
1✔
3121
                    }
3122

3123
                    /**
3124
                     * Materializes the current builder as a method definition.
3125
                     *
3126
                     * @param handler                        The handler that determines how a method is implemented.
3127
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3128
                     * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
3129
                     * @return Returns a method definition for the supplied properties.
3130
                     */
3131
                    protected abstract MethodDefinition<V> materialize(MethodRegistry.Handler handler,
3132
                                                                       MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3133
                                                                       Transformer<MethodDescription> transformer);
3134
                }
3135
            }
3136
        }
3137

3138
        /**
3139
         * A builder for a record component definition.
3140
         *
3141
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3142
         */
3143
        interface RecordComponentDefinition<S> {
3144

3145
            /**
3146
             * Annotates the record component with the supplied annotations.
3147
             *
3148
             * @param annotation The annotations to declare.
3149
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3150
             */
3151
            Optional<S> annotateRecordComponent(Annotation... annotation);
3152

3153
            /**
3154
             * Annotates the record component with the supplied annotations.
3155
             *
3156
             * @param annotations The annotations to declare.
3157
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3158
             */
3159
            Optional<S> annotateRecordComponent(List<? extends Annotation> annotations);
3160

3161
            /**
3162
             * Annotates the record component with the supplied annotations.
3163
             *
3164
             * @param annotation The annotations to declare.
3165
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3166
             */
3167
            Optional<S> annotateRecordComponent(AnnotationDescription... annotation);
3168

3169
            /**
3170
             * Annotates the record component with the supplied annotations.
3171
             *
3172
             * @param annotations The annotations to declare.
3173
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3174
             */
3175
            Optional<S> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations);
3176

3177
            /**
3178
             * Applies the supplied record component attribute appender factory onto the previously defined record component.
3179
             *
3180
             * @param recordComponentAttributeAppenderFactory The record component attribute appender factory that should be applied on the
3181
             *                                                previously defined or matched method.
3182
             * @return A new builder that is equal to this builder but with the supplied record component attribute appender factory
3183
             * applied to the previously defined record component.
3184
             */
3185
            Optional<S> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory);
3186

3187
            /**
3188
             * Transforms a record component description before writing.
3189
             *
3190
             * @param transformer The transformer to apply.
3191
             * @return new builder that is equal to this builder but with the supplied transformer being applied.
3192
             */
3193
            Optional<S> transform(Transformer<RecordComponentDescription> transformer);
3194

3195
            /**
3196
             * A {@link RecordComponentDefinition} as an optional build step.
3197
             *
3198
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3199
             */
3200
            interface Optional<U> extends RecordComponentDefinition<U>, Builder<U> {
3201

3202
                /**
3203
                 * An abstract base implementation of a record definition.
3204
                 *
3205
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3206
                 */
3207
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements RecordComponentDefinition.Optional<U> {
×
3208

3209
                    /**
3210
                     * {@inheritDoc}
3211
                     */
3212
                    public Optional<U> annotateRecordComponent(Annotation... annotation) {
3213
                        return annotateRecordComponent(Arrays.asList(annotation));
×
3214
                    }
3215

3216
                    /**
3217
                     * {@inheritDoc}
3218
                     */
3219
                    public Optional<U> annotateRecordComponent(List<? extends Annotation> annotations) {
3220
                        return annotateRecordComponent(new AnnotationList.ForLoadedAnnotations(annotations));
×
3221
                    }
3222

3223
                    /**
3224
                     * {@inheritDoc}
3225
                     */
3226
                    public Optional<U> annotateRecordComponent(AnnotationDescription... annotation) {
3227
                        return annotateRecordComponent(Arrays.asList(annotation));
×
3228
                    }
3229
                }
3230
            }
3231
        }
3232

3233
        /**
3234
         * An abstract base implementation of a dynamic type builder.
3235
         *
3236
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3237
         */
3238
        abstract class AbstractBase<S> implements Builder<S> {
1✔
3239

3240
            /**
3241
             * {@inheritDoc}
3242
             */
3243
            public InnerTypeDefinition.ForType<S> innerTypeOf(Class<?> type) {
3244
                return innerTypeOf(TypeDescription.ForLoadedType.of(type));
1✔
3245
            }
3246

3247
            /**
3248
             * {@inheritDoc}
3249
             */
3250
            public InnerTypeDefinition<S> innerTypeOf(Method method) {
3251
                return innerTypeOf(new MethodDescription.ForLoadedMethod(method));
1✔
3252
            }
3253

3254
            /**
3255
             * {@inheritDoc}
3256
             */
3257
            public InnerTypeDefinition<S> innerTypeOf(Constructor<?> constructor) {
3258
                return innerTypeOf(new MethodDescription.ForLoadedConstructor(constructor));
1✔
3259
            }
3260

3261
            /**
3262
             * {@inheritDoc}
3263
             */
3264
            public Builder<S> declaredTypes(Class<?>... type) {
3265
                return declaredTypes(Arrays.asList(type));
×
3266
            }
3267

3268
            /**
3269
             * {@inheritDoc}
3270
             */
3271
            public Builder<S> declaredTypes(TypeDescription... type) {
3272
                return declaredTypes(Arrays.asList(type));
1✔
3273
            }
3274

3275
            /**
3276
             * {@inheritDoc}
3277
             */
3278
            public Builder<S> declaredTypes(List<? extends Class<?>> type) {
3279
                return declaredTypes(new TypeList.ForLoadedTypes(type));
×
3280
            }
3281

3282
            /**
3283
             * {@inheritDoc}
3284
             */
3285
            public Builder<S> noNestMate() {
3286
                return nestHost(TargetType.DESCRIPTION);
×
3287
            }
3288

3289
            /**
3290
             * {@inheritDoc}
3291
             */
3292
            public Builder<S> nestHost(Class<?> type) {
3293
                return nestHost(TypeDescription.ForLoadedType.of(type));
×
3294
            }
3295

3296
            /**
3297
             * {@inheritDoc}
3298
             */
3299
            public Builder<S> nestMembers(Class<?>... type) {
3300
                return nestMembers(Arrays.asList(type));
1✔
3301
            }
3302

3303
            /**
3304
             * {@inheritDoc}
3305
             */
3306
            public Builder<S> nestMembers(TypeDescription... type) {
3307
                return nestMembers(Arrays.asList(type));
×
3308
            }
3309

3310
            /**
3311
             * {@inheritDoc}
3312
             */
3313
            public Builder<S> nestMembers(List<? extends Class<?>> types) {
3314
                return nestMembers(new TypeList.ForLoadedTypes(types));
1✔
3315
            }
3316

3317
            /**
3318
             * {@inheritDoc}
3319
             */
3320
            public Builder<S> permittedSubclass(Class<?>... type) {
3321
                return permittedSubclass(Arrays.asList(type));
×
3322
            }
3323

3324
            /**
3325
             * {@inheritDoc}
3326
             */
3327
            public Builder<S> permittedSubclass(TypeDescription... type) {
3328
                return permittedSubclass(Arrays.asList(type));
×
3329
            }
3330

3331
            /**
3332
             * {@inheritDoc}
3333
             */
3334
            public Builder<S> permittedSubclass(List<? extends Class<?>> types) {
3335
                return permittedSubclass(new TypeList.ForLoadedTypes(types));
×
3336
            }
3337

3338
            /**
3339
             * {@inheritDoc}
3340
             */
3341
            public Builder<S> annotateType(Annotation... annotation) {
3342
                return annotateType(Arrays.asList(annotation));
1✔
3343
            }
3344

3345
            /**
3346
             * {@inheritDoc}
3347
             */
3348
            public Builder<S> annotateType(List<? extends Annotation> annotations) {
3349
                return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
3350
            }
3351

3352
            /**
3353
             * {@inheritDoc}
3354
             */
3355
            public Builder<S> annotateType(AnnotationDescription... annotation) {
3356
                return annotateType(Arrays.asList(annotation));
1✔
3357
            }
3358

3359
            /**
3360
             * {@inheritDoc}
3361
             */
3362
            public Builder<S> modifiers(ModifierContributor.ForType... modifierContributor) {
3363
                return modifiers(Arrays.asList(modifierContributor));
1✔
3364
            }
3365

3366
            /**
3367
             * {@inheritDoc}
3368
             */
3369
            public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3370
                return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3371
            }
3372

3373
            /**
3374
             * {@inheritDoc}
3375
             */
3376
            public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
3377
                return merge(Arrays.asList(modifierContributor));
1✔
3378
            }
3379

3380
            /**
3381
             * {@inheritDoc}
3382
             */
3383
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(Type... interfaceType) {
3384
                return implement(Arrays.asList(interfaceType));
1✔
3385
            }
3386

3387
            /**
3388
             * {@inheritDoc}
3389
             */
3390
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
3391
                return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
1✔
3392
            }
3393

3394
            /**
3395
             * {@inheritDoc}
3396
             */
3397
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
3398
                return implement(Arrays.asList(interfaceType));
1✔
3399
            }
3400

3401
            /**
3402
             * {@inheritDoc}
3403
             */
3404
            public TypeVariableDefinition<S> typeVariable(String symbol) {
3405
                return typeVariable(symbol, TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class));
1✔
3406
            }
3407

3408
            /**
3409
             * {@inheritDoc}
3410
             */
3411
            public TypeVariableDefinition<S> typeVariable(String symbol, Type... bound) {
3412
                return typeVariable(symbol, Arrays.asList(bound));
1✔
3413
            }
3414

3415
            /**
3416
             * {@inheritDoc}
3417
             */
3418
            public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
3419
                return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
3420
            }
3421

3422
            /**
3423
             * {@inheritDoc}
3424
             */
3425
            public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
3426
                return typeVariable(symbol, Arrays.asList(bound));
1✔
3427
            }
3428

3429
            /**
3430
             * {@inheritDoc}
3431
             */
3432
            public RecordComponentDefinition.Optional<S> defineRecordComponent(String name, Type type) {
3433
                return defineRecordComponent(name, TypeDefinition.Sort.describe(type));
×
3434
            }
3435

3436
            /**
3437
             * {@inheritDoc}
3438
             */
3439
            public RecordComponentDefinition.Optional<S> define(RecordComponentDescription recordComponentDescription) {
3440
                return defineRecordComponent(recordComponentDescription.getActualName(), recordComponentDescription.getType());
×
3441
            }
3442

3443
            /**
3444
             * {@inheritDoc}
3445
             */
3446
            public RecordComponentDefinition<S> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
3447
                return recordComponent(new LatentMatcher.Resolved<RecordComponentDescription>(matcher));
×
3448
            }
3449

3450
            /**
3451
             * {@inheritDoc}
3452
             */
3453
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor) {
3454
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
3455
            }
3456

3457
            /**
3458
             * {@inheritDoc}
3459
             */
3460
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3461
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3462
            }
3463

3464
            /**
3465
             * {@inheritDoc}
3466
             */
3467
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
3468
                return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
1✔
3469
            }
3470

3471
            /**
3472
             * {@inheritDoc}
3473
             */
3474
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
3475
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
3476
            }
3477

3478
            /**
3479
             * {@inheritDoc}
3480
             */
3481
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3482
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3483
            }
3484

3485
            /**
3486
             * {@inheritDoc}
3487
             */
3488
            public FieldDefinition.Optional.Valuable<S> define(Field field) {
3489
                return define(new FieldDescription.ForLoadedField(field));
×
3490
            }
3491

3492
            /**
3493
             * {@inheritDoc}
3494
             */
3495
            public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
3496
                return defineField(field.getName(), field.getType(), field.getModifiers());
×
3497
            }
3498

3499
            /**
3500
             * {@inheritDoc}
3501
             */
3502
            public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
3503
                return defineField("serialVersionUID", long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
1✔
3504
            }
3505

3506
            /**
3507
             * {@inheritDoc}
3508
             */
3509
            public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
3510
                return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
1✔
3511
            }
3512

3513
            /**
3514
             * {@inheritDoc}
3515
             */
3516
            public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3517
                return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
1✔
3518
            }
3519

3520
            /**
3521
             * {@inheritDoc}
3522
             */
3523
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor) {
3524
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
3525
            }
3526

3527
            /**
3528
             * {@inheritDoc}
3529
             */
3530
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3531
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3532
            }
3533

3534
            /**
3535
             * {@inheritDoc}
3536
             */
3537
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
3538
                return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
1✔
3539
            }
3540

3541
            /**
3542
             * {@inheritDoc}
3543
             */
3544
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
3545
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
3546
            }
3547

3548
            /**
3549
             * {@inheritDoc}
3550
             */
3551
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3552
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3553
            }
3554

3555
            /**
3556
             * {@inheritDoc}
3557
             */
3558
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
3559
                return defineConstructor(Arrays.asList(modifierContributor));
1✔
3560
            }
3561

3562
            /**
3563
             * {@inheritDoc}
3564
             */
3565
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3566
                return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3567
            }
3568

3569
            /**
3570
             * {@inheritDoc}
3571
             */
3572
            public MethodDefinition.ImplementationDefinition<S> define(Method method) {
3573
                return define(new MethodDescription.ForLoadedMethod(method));
×
3574
            }
3575

3576
            /**
3577
             * {@inheritDoc}
3578
             */
3579
            public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
3580
                return define(new MethodDescription.ForLoadedConstructor(constructor));
×
3581
            }
3582

3583
            /**
3584
             * {@inheritDoc}
3585
             */
3586
            public MethodDefinition.ImplementationDefinition<S> define(MethodDescription methodDescription) {
3587
                MethodDefinition.ParameterDefinition.Initial<S> initialParameterDefinition = methodDescription.isConstructor()
×
3588
                        ? defineConstructor(methodDescription.getModifiers())
×
3589
                        : defineMethod(methodDescription.getInternalName(), methodDescription.getReturnType(), methodDescription.getModifiers());
×
3590
                ParameterList<?> parameterList = methodDescription.getParameters();
×
3591
                MethodDefinition.ExceptionDefinition<S> exceptionDefinition;
3592
                if (parameterList.hasExplicitMetaData()) {
×
3593
                    MethodDefinition.ParameterDefinition<S> parameterDefinition = initialParameterDefinition;
×
3594
                    for (ParameterDescription parameter : parameterList) {
×
3595
                        parameterDefinition = parameterDefinition.withParameter(parameter.getType(), parameter.getName(), parameter.getModifiers());
×
3596
                    }
×
3597
                    exceptionDefinition = parameterDefinition;
×
3598
                } else {
×
3599
                    exceptionDefinition = initialParameterDefinition.withParameters(parameterList.asTypeList());
×
3600
                }
3601
                MethodDefinition.TypeVariableDefinition<S> typeVariableDefinition = exceptionDefinition.throwing(methodDescription.getExceptionTypes());
×
3602
                for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
×
3603
                    typeVariableDefinition = typeVariableDefinition.typeVariable(typeVariable.getSymbol(), typeVariable.getUpperBounds());
×
3604
                }
×
3605
                return typeVariableDefinition;
×
3606
            }
3607

3608
            /**
3609
             * {@inheritDoc}
3610
             */
3611
            public FieldDefinition.Optional<S> defineProperty(String name, Type type) {
3612
                return defineProperty(name, TypeDefinition.Sort.describe(type));
1✔
3613
            }
3614

3615
            /**
3616
             * {@inheritDoc}
3617
             */
3618
            public FieldDefinition.Optional<S> defineProperty(String name, Type type, boolean readOnly) {
3619
                return defineProperty(name, TypeDefinition.Sort.describe(type), readOnly);
1✔
3620
            }
3621

3622
            /**
3623
             * {@inheritDoc}
3624
             */
3625
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type) {
3626
                return defineProperty(name, type, false);
1✔
3627
            }
3628

3629
            /**
3630
             * {@inheritDoc}
3631
             */
3632
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type, boolean readOnly) {
3633
                if (name.length() == 0) {
1✔
3634
                    throw new IllegalArgumentException("A bean property cannot have an empty name");
1✔
3635
                } else if (type.represents(void.class)) {
1✔
3636
                    throw new IllegalArgumentException("A bean property cannot have a void type");
1✔
3637
                }
3638
                DynamicType.Builder<S> builder = this;
1✔
3639
                FieldManifestation fieldManifestation;
3640
                if (!readOnly) {
1✔
3641
                    builder = builder
1✔
3642
                            .defineMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), void.class, Visibility.PUBLIC)
1✔
3643
                            .withParameters(type)
1✔
3644
                            .intercept(FieldAccessor.ofField(name));
1✔
3645
                    fieldManifestation = FieldManifestation.PLAIN;
1✔
3646
                } else {
3647
                    fieldManifestation = FieldManifestation.FINAL;
1✔
3648
                }
3649
                return builder
1✔
3650
                        .defineMethod((type.represents(boolean.class)
1✔
3651
                                ? "is"
3652
                                : "get") + Character.toUpperCase(name.charAt(0)) + name.substring(1), type, Visibility.PUBLIC)
1✔
3653
                        .intercept(FieldAccessor.ofField(name))
1✔
3654
                        .defineField(name, type, Visibility.PRIVATE, fieldManifestation);
1✔
3655
            }
3656

3657
            /**
3658
             * {@inheritDoc}
3659
             */
3660
            public MethodDefinition.ImplementationDefinition<S> method(ElementMatcher<? super MethodDescription> matcher) {
3661
                return invokable(isMethod().and(matcher));
1✔
3662
            }
3663

3664
            /**
3665
             * {@inheritDoc}
3666
             */
3667
            public MethodDefinition.ImplementationDefinition<S> constructor(ElementMatcher<? super MethodDescription> matcher) {
3668
                return invokable(isConstructor().and(matcher));
1✔
3669
            }
3670

3671
            /**
3672
             * {@inheritDoc}
3673
             */
3674
            public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
3675
                return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
1✔
3676
            }
3677

3678
            /**
3679
             * {@inheritDoc}
3680
             */
3681
            public Builder<S> withHashCodeEquals() {
3682
                return method(isHashCode())
1✔
3683
                        .intercept(HashCodeMethod.usingDefaultOffset().withIgnoredFields(isSynthetic()))
1✔
3684
                        .method(isEquals())
1✔
3685
                        .intercept(EqualsMethod.isolated().withIgnoredFields(isSynthetic()));
1✔
3686
            }
3687

3688
            /**
3689
             * {@inheritDoc}
3690
             */
3691
            public Builder<S> withToString() {
3692
                return method(isToString()).intercept(ToStringMethod.prefixedBySimpleClassName());
1✔
3693
            }
3694

3695
            /**
3696
             * {@inheritDoc}
3697
             */
3698
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation) {
3699
                return require(type, binaryRepresentation, LoadedTypeInitializer.NoOp.INSTANCE);
1✔
3700
            }
3701

3702
            /**
3703
             * {@inheritDoc}
3704
             */
3705
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer) {
3706
                return require(new Default(type, binaryRepresentation, typeInitializer, Collections.<DynamicType>emptyList()));
1✔
3707
            }
3708

3709
            /**
3710
             * {@inheritDoc}
3711
             */
3712
            public Builder<S> require(DynamicType... auxiliaryType) {
3713
                return require(Arrays.asList(auxiliaryType));
1✔
3714
            }
3715

3716
            /**
3717
             * {@inheritDoc}
3718
             */
3719
            public ContextClassVisitor wrap(ClassVisitor classVisitor) {
3720
                return wrap(classVisitor, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
1✔
3721
            }
3722

3723
            /**
3724
             * {@inheritDoc}
3725
             */
3726
            public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool) {
3727
                return wrap(classVisitor, typePool, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
×
3728
            }
3729

3730
            /**
3731
             * {@inheritDoc}
3732
             */
3733
            public Unloaded<S> make(TypePool typePool) {
3734
                return make(TypeResolutionStrategy.Passive.INSTANCE, typePool);
1✔
3735
            }
3736

3737
            /**
3738
             * {@inheritDoc}
3739
             */
3740
            public Unloaded<S> make() {
3741
                return make(TypeResolutionStrategy.Passive.INSTANCE);
1✔
3742
            }
3743

3744
            /**
3745
             * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
3746
             *
3747
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3748
             */
3749
            public abstract static class Delegator<U> extends AbstractBase<U> {
1✔
3750

3751
                /**
3752
                 * {@inheritDoc}
3753
                 */
3754
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
3755
                    return materialize().visit(asmVisitorWrapper);
1✔
3756
                }
3757

3758
                /**
3759
                 * {@inheritDoc}
3760
                 */
3761
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
3762
                    return materialize().initializer(loadedTypeInitializer);
1✔
3763
                }
3764

3765
                /**
3766
                 * {@inheritDoc}
3767
                 */
3768
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
3769
                    return materialize().annotateType(annotations);
×
3770
                }
3771

3772
                /**
3773
                 * {@inheritDoc}
3774
                 */
3775
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
3776
                    return materialize().attribute(typeAttributeAppender);
×
3777
                }
3778

3779
                /**
3780
                 * {@inheritDoc}
3781
                 */
3782
                public Builder<U> modifiers(int modifiers) {
3783
                    return materialize().modifiers(modifiers);
1✔
3784
                }
3785

3786
                /**
3787
                 * {@inheritDoc}
3788
                 */
3789
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3790
                    return materialize().merge(modifierContributors);
×
3791
                }
3792

3793
                /**
3794
                 * {@inheritDoc}
3795
                 */
3796
                public Builder<U> suffix(String suffix) {
3797
                    return materialize().suffix(suffix);
×
3798
                }
3799

3800
                /**
3801
                 * {@inheritDoc}
3802
                 */
3803
                public Builder<U> name(String name) {
3804
                    return materialize().name(name);
1✔
3805
                }
3806

3807
                /**
3808
                 * {@inheritDoc}
3809
                 */
3810
                public Builder<U> topLevelType() {
3811
                    return materialize().topLevelType();
×
3812
                }
3813

3814
                /**
3815
                 * {@inheritDoc}
3816
                 */
3817
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
3818
                    return materialize().innerTypeOf(type);
×
3819
                }
3820

3821
                /**
3822
                 * {@inheritDoc}
3823
                 */
3824
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
3825
                    return materialize().innerTypeOf(methodDescription);
×
3826
                }
3827

3828
                /**
3829
                 * {@inheritDoc}
3830
                 */
3831
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
3832
                    return materialize().declaredTypes(types);
1✔
3833
                }
3834

3835
                /**
3836
                 * {@inheritDoc}
3837
                 */
3838
                public Builder<U> nestHost(TypeDescription type) {
3839
                    return materialize().nestHost(type);
×
3840
                }
3841

3842
                /**
3843
                 * {@inheritDoc}
3844
                 */
3845
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
3846
                    return materialize().nestMembers(types);
×
3847
                }
3848

3849
                /**
3850
                 * {@inheritDoc}
3851
                 */
3852
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
3853
                    return materialize().permittedSubclass(types);
×
3854
                }
3855

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

3863
                /**
3864
                 * {@inheritDoc}
3865
                 */
3866
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
3867
                    return materialize().implement(interfaceTypes);
1✔
3868
                }
3869

3870
                /**
3871
                 * {@inheritDoc}
3872
                 */
3873
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
3874
                    return materialize().initializer(byteCodeAppender);
1✔
3875
                }
3876

3877
                /**
3878
                 * {@inheritDoc}
3879
                 */
3880
                public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3881
                    return materialize().ignoreAlso(ignoredMethods);
1✔
3882
                }
3883

3884
                /**
3885
                 * {@inheritDoc}
3886
                 */
3887
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
3888
                    return materialize().ignoreAlso(ignoredMethods);
×
3889
                }
3890

3891
                /**
3892
                 * {@inheritDoc}
3893
                 */
3894
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3895
                    return materialize().typeVariable(symbol, bounds);
1✔
3896
                }
3897

3898
                /**
3899
                 * {@inheritDoc}
3900
                 */
3901
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
3902
                    return materialize().transform(matcher, transformer);
1✔
3903
                }
3904

3905
                /**
3906
                 * {@inheritDoc}
3907
                 */
3908
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
3909
                    return materialize().defineField(name, type, modifiers);
1✔
3910
                }
3911

3912
                /**
3913
                 * {@inheritDoc}
3914
                 */
3915
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
3916
                    return materialize().field(matcher);
1✔
3917
                }
3918

3919
                /**
3920
                 * {@inheritDoc}
3921
                 */
3922
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
3923
                    return materialize().defineMethod(name, returnType, modifiers);
1✔
3924
                }
3925

3926
                /**
3927
                 * {@inheritDoc}
3928
                 */
3929
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
3930
                    return materialize().defineConstructor(modifiers);
1✔
3931
                }
3932

3933
                /**
3934
                 * {@inheritDoc}
3935
                 */
3936
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
3937
                    return materialize().invokable(matcher);
1✔
3938
                }
3939

3940
                /**
3941
                 * {@inheritDoc}
3942
                 */
3943
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
3944
                    return materialize().require(auxiliaryTypes);
×
3945
                }
3946

3947
                /**
3948
                 * {@inheritDoc}
3949
                 */
3950
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
3951
                    return materialize().defineRecordComponent(name, type);
×
3952
                }
3953

3954
                /**
3955
                 * {@inheritDoc}
3956
                 */
3957
                public RecordComponentDefinition.Optional<U> define(RecordComponentDescription recordComponentDescription) {
3958
                    return materialize().define(recordComponentDescription);
×
3959
                }
3960

3961
                /**
3962
                 * {@inheritDoc}
3963
                 */
3964
                public RecordComponentDefinition<U> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
3965
                    return materialize().recordComponent(matcher);
×
3966
                }
3967

3968
                /**
3969
                 * {@inheritDoc}
3970
                 */
3971
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
3972
                    return materialize().recordComponent(matcher);
×
3973
                }
3974

3975
                /**
3976
                 * {@inheritDoc}
3977
                 */
3978
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
3979
                    return materialize().wrap(classVisitor, writerFlags, readerFlags);
1✔
3980
                }
3981

3982
                /**
3983
                 * {@inheritDoc}
3984
                 */
3985
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
3986
                    return materialize().wrap(classVisitor, typePool, writerFlags, readerFlags);
×
3987
                }
3988

3989
                /**
3990
                 * {@inheritDoc}
3991
                 */
3992
                public DynamicType.Unloaded<U> make() {
3993
                    return materialize().make();
1✔
3994
                }
3995

3996
                /**
3997
                 * {@inheritDoc}
3998
                 */
3999
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4000
                    return materialize().make(typeResolutionStrategy);
1✔
4001
                }
4002

4003
                /**
4004
                 * {@inheritDoc}
4005
                 */
4006
                public Unloaded<U> make(TypePool typePool) {
4007
                    return materialize().make(typePool);
×
4008
                }
4009

4010
                /**
4011
                 * {@inheritDoc}
4012
                 */
4013
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4014
                    return materialize().make(typeResolutionStrategy, typePool);
1✔
4015
                }
4016

4017
                /**
4018
                 * {@inheritDoc}
4019
                 */
4020
                public TypeDescription toTypeDescription() {
4021
                    return materialize().toTypeDescription();
1✔
4022
                }
4023

4024
                /**
4025
                 * Creates a new builder that realizes the current state of the builder.
4026
                 *
4027
                 * @return A new builder that realizes the current state of the builder.
4028
                 */
4029
                protected abstract Builder<U> materialize();
4030
            }
4031

4032
            /**
4033
             * A dynamic type writer that uses a {@link TypeWriter} to create a dynamic type.
4034
             *
4035
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4036
             */
4037
            public abstract static class UsingTypeWriter<U> extends AbstractBase<U> {
1✔
4038

4039
                /**
4040
                 * {@inheritDoc}
4041
                 */
4042
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4043
                    return toTypeWriter().wrap(classVisitor, writerFlags, readerFlags);
1✔
4044
                }
4045

4046
                /**
4047
                 * {@inheritDoc}
4048
                 */
4049
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
4050
                    return toTypeWriter(typePool).wrap(classVisitor, writerFlags, readerFlags);
×
4051
                }
4052

4053
                /**
4054
                 * {@inheritDoc}
4055
                 */
4056
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4057
                    return toTypeWriter().make(typeResolutionStrategy.resolve());
1✔
4058
                }
4059

4060
                /**
4061
                 * {@inheritDoc}
4062
                 */
4063
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4064
                    return toTypeWriter(typePool).make(typeResolutionStrategy.resolve());
1✔
4065
                }
4066

4067
                /**
4068
                 * Creates a {@link TypeWriter} without an explicitly specified {@link TypePool}.
4069
                 *
4070
                 * @return An appropriate {@link TypeWriter}.
4071
                 */
4072
                protected abstract TypeWriter<U> toTypeWriter();
4073

4074
                /**
4075
                 * Creates a {@link TypeWriter} given the specified {@link TypePool}.
4076
                 *
4077
                 * @param typePool The {@link TypePool} to use.
4078
                 * @return An appropriate {@link TypeWriter}.
4079
                 */
4080
                protected abstract TypeWriter<U> toTypeWriter(TypePool typePool);
4081
            }
4082

4083
            /**
4084
             * An adapter implementation of a dynamic type builder.
4085
             *
4086
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4087
             */
4088
            @HashCodeAndEqualsPlugin.Enhance
4089
            public abstract static class Adapter<U> extends UsingTypeWriter<U> {
4090

4091
                /**
4092
                 * The instrumented type to be created.
4093
                 */
4094
                protected final InstrumentedType.WithFlexibleName instrumentedType;
4095

4096
                /**
4097
                 * The current field registry.
4098
                 */
4099
                protected final FieldRegistry fieldRegistry;
4100

4101
                /**
4102
                 * The current method registry.
4103
                 */
4104
                protected final MethodRegistry methodRegistry;
4105

4106
                /**
4107
                 * The current record component registry.
4108
                 */
4109
                protected final RecordComponentRegistry recordComponentRegistry;
4110

4111
                /**
4112
                 * The type attribute appender to apply onto the instrumented type.
4113
                 */
4114
                protected final TypeAttributeAppender typeAttributeAppender;
4115

4116
                /**
4117
                 * The ASM visitor wrapper to apply onto the class writer.
4118
                 */
4119
                protected final AsmVisitorWrapper asmVisitorWrapper;
4120

4121
                /**
4122
                 * The class file version to define auxiliary types in.
4123
                 */
4124
                protected final ClassFileVersion classFileVersion;
4125

4126
                /**
4127
                 * The naming strategy for auxiliary types to apply.
4128
                 */
4129
                protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
4130

4131
                /**
4132
                 * The annotation value filter factory to apply.
4133
                 */
4134
                protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
4135

4136
                /**
4137
                 * The annotation retention to apply.
4138
                 */
4139
                protected final AnnotationRetention annotationRetention;
4140

4141
                /**
4142
                 * The implementation context factory to apply.
4143
                 */
4144
                protected final Implementation.Context.Factory implementationContextFactory;
4145

4146
                /**
4147
                 * The method graph compiler to use.
4148
                 */
4149
                protected final MethodGraph.Compiler methodGraphCompiler;
4150

4151
                /**
4152
                 * Determines if a type should be explicitly validated.
4153
                 */
4154
                protected final TypeValidation typeValidation;
4155

4156
                /**
4157
                 * The visibility bridge strategy to apply.
4158
                 */
4159
                protected final VisibilityBridgeStrategy visibilityBridgeStrategy;
4160

4161
                /**
4162
                 * The class reader factory to use.
4163
                 */
4164
                protected final AsmClassReader.Factory classReaderFactory;
4165

4166
                /**
4167
                 * The class writer factory to use.
4168
                 */
4169
                protected final AsmClassWriter.Factory classWriterFactory;
4170

4171
                /**
4172
                 * A matcher for identifying methods that should be excluded from instrumentation.
4173
                 */
4174
                protected final LatentMatcher<? super MethodDescription> ignoredMethods;
4175

4176
                /**
4177
                 * A list of explicitly defined auxiliary types.
4178
                 */
4179
                protected final List<? extends DynamicType> auxiliaryTypes;
4180

4181
                /**
4182
                 * Creates a new default type writer for creating a new type that is not based on an existing class file.
4183
                 *
4184
                 * @param instrumentedType             The instrumented type to be created.
4185
                 * @param fieldRegistry                The current field registry.
4186
                 * @param methodRegistry               The current method registry.
4187
                 * @param recordComponentRegistry      The record component pool to use.
4188
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
4189
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
4190
                 * @param classFileVersion             The class file version to define auxiliary types in.
4191
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
4192
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
4193
                 * @param annotationRetention          The annotation retention to apply.
4194
                 * @param implementationContextFactory The implementation context factory to apply.
4195
                 * @param methodGraphCompiler          The method graph compiler to use.
4196
                 * @param typeValidation               Determines if a type should be explicitly validated.
4197
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
4198
                 * @param classReaderFactory           The class reader factory to use.
4199
                 * @param classWriterFactory           The class writer factory to use.
4200
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
4201
                 * @param auxiliaryTypes               A list of explicitly defined auxiliary types.
4202
                 */
4203
                protected Adapter(InstrumentedType.WithFlexibleName instrumentedType,
4204
                                  FieldRegistry fieldRegistry,
4205
                                  MethodRegistry methodRegistry,
4206
                                  RecordComponentRegistry recordComponentRegistry,
4207
                                  TypeAttributeAppender typeAttributeAppender,
4208
                                  AsmVisitorWrapper asmVisitorWrapper,
4209
                                  ClassFileVersion classFileVersion,
4210
                                  AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4211
                                  AnnotationValueFilter.Factory annotationValueFilterFactory,
4212
                                  AnnotationRetention annotationRetention,
4213
                                  Implementation.Context.Factory implementationContextFactory,
4214
                                  MethodGraph.Compiler methodGraphCompiler,
4215
                                  TypeValidation typeValidation,
4216
                                  VisibilityBridgeStrategy visibilityBridgeStrategy,
4217
                                  AsmClassReader.Factory classReaderFactory,
4218
                                  AsmClassWriter.Factory classWriterFactory,
4219
                                  LatentMatcher<? super MethodDescription> ignoredMethods,
4220
                                  List<? extends DynamicType> auxiliaryTypes) {
1✔
4221
                    this.instrumentedType = instrumentedType;
1✔
4222
                    this.fieldRegistry = fieldRegistry;
1✔
4223
                    this.methodRegistry = methodRegistry;
1✔
4224
                    this.recordComponentRegistry = recordComponentRegistry;
1✔
4225
                    this.typeAttributeAppender = typeAttributeAppender;
1✔
4226
                    this.asmVisitorWrapper = asmVisitorWrapper;
1✔
4227
                    this.classFileVersion = classFileVersion;
1✔
4228
                    this.auxiliaryTypeNamingStrategy = auxiliaryTypeNamingStrategy;
1✔
4229
                    this.annotationValueFilterFactory = annotationValueFilterFactory;
1✔
4230
                    this.annotationRetention = annotationRetention;
1✔
4231
                    this.implementationContextFactory = implementationContextFactory;
1✔
4232
                    this.methodGraphCompiler = methodGraphCompiler;
1✔
4233
                    this.typeValidation = typeValidation;
1✔
4234
                    this.visibilityBridgeStrategy = visibilityBridgeStrategy;
1✔
4235
                    this.classReaderFactory = classReaderFactory;
1✔
4236
                    this.classWriterFactory = classWriterFactory;
1✔
4237
                    this.ignoredMethods = ignoredMethods;
1✔
4238
                    this.auxiliaryTypes = auxiliaryTypes;
1✔
4239
                }
1✔
4240

4241
                /**
4242
                 * {@inheritDoc}
4243
                 */
4244
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
4245
                    return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
1✔
4246
                }
4247

4248
                /**
4249
                 * {@inheritDoc}
4250
                 */
4251
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
4252
                    return new FieldMatchAdapter(matcher);
1✔
4253
                }
4254

4255
                /**
4256
                 * {@inheritDoc}
4257
                 */
4258
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4259
                    return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
1✔
4260
                }
4261

4262
                /**
4263
                 * {@inheritDoc}
4264
                 */
4265
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4266
                    return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
1✔
4267
                }
4268

4269
                /**
4270
                 * {@inheritDoc}
4271
                 */
4272
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4273
                    return new MethodMatchAdapter(matcher);
1✔
4274
                }
4275

4276
                /**
4277
                 * {@inheritDoc}
4278
                 */
4279
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
4280
                    return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
1✔
4281
                }
4282

4283
                /**
4284
                 * {@inheritDoc}
4285
                 */
4286
                @SuppressWarnings("unchecked") // In absence of @SafeVarargs
4287
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
4288
                    return materialize(instrumentedType,
1✔
4289
                            fieldRegistry,
4290
                            methodRegistry,
4291
                            recordComponentRegistry,
4292
                            typeAttributeAppender,
4293
                            asmVisitorWrapper,
4294
                            classFileVersion,
4295
                            auxiliaryTypeNamingStrategy,
4296
                            annotationValueFilterFactory,
4297
                            annotationRetention,
4298
                            implementationContextFactory,
4299
                            methodGraphCompiler,
4300
                            typeValidation,
4301
                            visibilityBridgeStrategy,
4302
                            classReaderFactory,
4303
                            classWriterFactory,
4304
                            new LatentMatcher.Disjunction<MethodDescription>(this.ignoredMethods, ignoredMethods),
4305
                            auxiliaryTypes);
4306
                }
4307

4308
                /**
4309
                 * {@inheritDoc}
4310
                 */
4311
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
4312
                    return new RecordComponentDefinitionAdapter(new RecordComponentDescription.Token(name, type.asGenericType()));
×
4313
                }
4314

4315
                /**
4316
                 * {@inheritDoc}
4317
                 */
4318
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
4319
                    return new RecordComponentMatchAdapter(matcher);
×
4320
                }
4321

4322
                /**
4323
                 * {@inheritDoc}
4324
                 */
4325
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
4326
                    return materialize(instrumentedType.withInitializer(byteCodeAppender),
1✔
4327
                            fieldRegistry,
4328
                            methodRegistry,
4329
                            recordComponentRegistry,
4330
                            typeAttributeAppender,
4331
                            asmVisitorWrapper,
4332
                            classFileVersion,
4333
                            auxiliaryTypeNamingStrategy,
4334
                            annotationValueFilterFactory,
4335
                            annotationRetention,
4336
                            implementationContextFactory,
4337
                            methodGraphCompiler,
4338
                            typeValidation,
4339
                            visibilityBridgeStrategy,
4340
                            classReaderFactory,
4341
                            classWriterFactory,
4342
                            ignoredMethods,
4343
                            auxiliaryTypes);
4344
                }
4345

4346
                /**
4347
                 * {@inheritDoc}
4348
                 */
4349
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
4350
                    return materialize(instrumentedType.withInitializer(loadedTypeInitializer),
1✔
4351
                            fieldRegistry,
4352
                            methodRegistry,
4353
                            recordComponentRegistry,
4354
                            typeAttributeAppender,
4355
                            asmVisitorWrapper,
4356
                            classFileVersion,
4357
                            auxiliaryTypeNamingStrategy,
4358
                            annotationValueFilterFactory,
4359
                            annotationRetention,
4360
                            implementationContextFactory,
4361
                            methodGraphCompiler,
4362
                            typeValidation,
4363
                            visibilityBridgeStrategy,
4364
                            classReaderFactory,
4365
                            classWriterFactory,
4366
                            ignoredMethods,
4367
                            auxiliaryTypes);
4368
                }
4369

4370
                /**
4371
                 * {@inheritDoc}
4372
                 */
4373
                public Builder<U> name(String name) {
4374
                    return materialize(instrumentedType.withName(name),
1✔
4375
                            fieldRegistry,
4376
                            methodRegistry,
4377
                            recordComponentRegistry,
4378
                            typeAttributeAppender,
4379
                            asmVisitorWrapper,
4380
                            classFileVersion,
4381
                            auxiliaryTypeNamingStrategy,
4382
                            annotationValueFilterFactory,
4383
                            annotationRetention,
4384
                            implementationContextFactory,
4385
                            methodGraphCompiler,
4386
                            typeValidation,
4387
                            visibilityBridgeStrategy,
4388
                            classReaderFactory,
4389
                            classWriterFactory,
4390
                            ignoredMethods,
4391
                            auxiliaryTypes);
4392
                }
4393

4394
                /**
4395
                 * {@inheritDoc}
4396
                 */
4397
                public Builder<U> suffix(String suffix) {
4398
                    return name(instrumentedType.getName() + "$" + suffix);
×
4399
                }
4400

4401
                /**
4402
                 * {@inheritDoc}
4403
                 */
4404
                public Builder<U> modifiers(int modifiers) {
4405
                    return materialize(instrumentedType.withModifiers(modifiers),
1✔
4406
                            fieldRegistry,
4407
                            methodRegistry,
4408
                            recordComponentRegistry,
4409
                            typeAttributeAppender,
4410
                            asmVisitorWrapper,
4411
                            classFileVersion,
4412
                            auxiliaryTypeNamingStrategy,
4413
                            annotationValueFilterFactory,
4414
                            annotationRetention,
4415
                            implementationContextFactory,
4416
                            methodGraphCompiler,
4417
                            typeValidation,
4418
                            visibilityBridgeStrategy,
4419
                            classReaderFactory,
4420
                            classWriterFactory,
4421
                            ignoredMethods,
4422
                            auxiliaryTypes);
4423
                }
4424

4425
                /**
4426
                 * {@inheritDoc}
4427
                 */
4428
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4429
                    return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
1✔
4430
                            fieldRegistry,
4431
                            methodRegistry,
4432
                            recordComponentRegistry,
4433
                            typeAttributeAppender,
4434
                            asmVisitorWrapper,
4435
                            classFileVersion,
4436
                            auxiliaryTypeNamingStrategy,
4437
                            annotationValueFilterFactory,
4438
                            annotationRetention,
4439
                            implementationContextFactory,
4440
                            methodGraphCompiler,
4441
                            typeValidation,
4442
                            visibilityBridgeStrategy,
4443
                            classReaderFactory,
4444
                            classWriterFactory,
4445
                            ignoredMethods,
4446
                            auxiliaryTypes);
4447
                }
4448

4449
                /**
4450
                 * {@inheritDoc}
4451
                 */
4452
                public Builder<U> topLevelType() {
4453
                    return Adapter.this.materialize(instrumentedType
1✔
4454
                                    .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4455
                                    .withEnclosingType(TypeDescription.UNDEFINED)
1✔
4456
                                    .withLocalClass(false),
1✔
4457
                            fieldRegistry,
4458
                            methodRegistry,
4459
                            recordComponentRegistry,
4460
                            typeAttributeAppender,
4461
                            asmVisitorWrapper,
4462
                            classFileVersion,
4463
                            auxiliaryTypeNamingStrategy,
4464
                            annotationValueFilterFactory,
4465
                            annotationRetention,
4466
                            implementationContextFactory,
4467
                            methodGraphCompiler,
4468
                            typeValidation,
4469
                            visibilityBridgeStrategy,
4470
                            classReaderFactory,
4471
                            classWriterFactory,
4472
                            ignoredMethods,
4473
                            auxiliaryTypes);
4474
                }
4475

4476
                /**
4477
                 * {@inheritDoc}
4478
                 */
4479
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
4480
                    return new InnerTypeDefinitionForTypeAdapter(type);
1✔
4481
                }
4482

4483
                /**
4484
                 * {@inheritDoc}
4485
                 */
4486
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
4487
                    return methodDescription.isTypeInitializer()
1✔
4488
                            ? new InnerTypeDefinitionForTypeAdapter(methodDescription.getDeclaringType())
1✔
4489
                            : new InnerTypeDefinitionForMethodAdapter(methodDescription);
4490
                }
4491

4492
                /**
4493
                 * {@inheritDoc}
4494
                 */
4495
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
4496
                    return materialize(instrumentedType.withDeclaredTypes(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
4497
                            fieldRegistry,
4498
                            methodRegistry,
4499
                            recordComponentRegistry,
4500
                            typeAttributeAppender,
4501
                            asmVisitorWrapper,
4502
                            classFileVersion,
4503
                            auxiliaryTypeNamingStrategy,
4504
                            annotationValueFilterFactory,
4505
                            annotationRetention,
4506
                            implementationContextFactory,
4507
                            methodGraphCompiler,
4508
                            typeValidation,
4509
                            visibilityBridgeStrategy,
4510
                            classReaderFactory,
4511
                            classWriterFactory,
4512
                            ignoredMethods,
4513
                            auxiliaryTypes);
4514
                }
4515

4516
                /**
4517
                 * {@inheritDoc}
4518
                 */
4519
                public Builder<U> nestHost(TypeDescription type) {
4520
                    return materialize(instrumentedType.withNestHost(type),
×
4521
                            fieldRegistry,
4522
                            methodRegistry,
4523
                            recordComponentRegistry,
4524
                            typeAttributeAppender,
4525
                            asmVisitorWrapper,
4526
                            classFileVersion,
4527
                            auxiliaryTypeNamingStrategy,
4528
                            annotationValueFilterFactory,
4529
                            annotationRetention,
4530
                            implementationContextFactory,
4531
                            methodGraphCompiler,
4532
                            typeValidation,
4533
                            visibilityBridgeStrategy,
4534
                            classReaderFactory,
4535
                            classWriterFactory,
4536
                            ignoredMethods,
4537
                            auxiliaryTypes);
4538
                }
4539

4540
                /**
4541
                 * {@inheritDoc}
4542
                 */
4543
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
4544
                    return materialize(instrumentedType.withNestMembers(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
4545
                            fieldRegistry,
4546
                            methodRegistry,
4547
                            recordComponentRegistry,
4548
                            typeAttributeAppender,
4549
                            asmVisitorWrapper,
4550
                            classFileVersion,
4551
                            auxiliaryTypeNamingStrategy,
4552
                            annotationValueFilterFactory,
4553
                            annotationRetention,
4554
                            implementationContextFactory,
4555
                            methodGraphCompiler,
4556
                            typeValidation,
4557
                            visibilityBridgeStrategy,
4558
                            classReaderFactory,
4559
                            classWriterFactory,
4560
                            ignoredMethods,
4561
                            auxiliaryTypes);
4562
                }
4563

4564
                /**
4565
                 * {@inheritDoc}
4566
                 */
4567
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
4568
                    return materialize(instrumentedType.withPermittedSubclasses(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
×
4569
                            fieldRegistry,
4570
                            methodRegistry,
4571
                            recordComponentRegistry,
4572
                            typeAttributeAppender,
4573
                            asmVisitorWrapper,
4574
                            classFileVersion,
4575
                            auxiliaryTypeNamingStrategy,
4576
                            annotationValueFilterFactory,
4577
                            annotationRetention,
4578
                            implementationContextFactory,
4579
                            methodGraphCompiler,
4580
                            typeValidation,
4581
                            visibilityBridgeStrategy,
4582
                            classReaderFactory,
4583
                            classWriterFactory,
4584
                            ignoredMethods,
4585
                            auxiliaryTypes);
4586
                }
4587

4588
                /**
4589
                 * {@inheritDoc}
4590
                 */
4591
                public Builder<U> unsealed() {
4592
                    return materialize(instrumentedType.withPermittedSubclasses(TypeList.UNDEFINED),
×
4593
                            fieldRegistry,
4594
                            methodRegistry,
4595
                            recordComponentRegistry,
4596
                            typeAttributeAppender,
4597
                            asmVisitorWrapper,
4598
                            classFileVersion,
4599
                            auxiliaryTypeNamingStrategy,
4600
                            annotationValueFilterFactory,
4601
                            annotationRetention,
4602
                            implementationContextFactory,
4603
                            methodGraphCompiler,
4604
                            typeValidation,
4605
                            visibilityBridgeStrategy,
4606
                            classReaderFactory,
4607
                            classWriterFactory,
4608
                            ignoredMethods,
4609
                            auxiliaryTypes);
4610
                }
4611

4612
                /**
4613
                 * {@inheritDoc}
4614
                 */
4615
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
4616
                    return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
4617
                }
4618

4619
                /**
4620
                 * {@inheritDoc}
4621
                 */
4622
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
4623
                    return materialize(instrumentedType.withTypeVariables(matcher, transformer),
1✔
4624
                            fieldRegistry,
4625
                            methodRegistry,
4626
                            recordComponentRegistry,
4627
                            typeAttributeAppender,
4628
                            asmVisitorWrapper,
4629
                            classFileVersion,
4630
                            auxiliaryTypeNamingStrategy,
4631
                            annotationValueFilterFactory,
4632
                            annotationRetention,
4633
                            implementationContextFactory,
4634
                            methodGraphCompiler,
4635
                            typeValidation,
4636
                            visibilityBridgeStrategy,
4637
                            classReaderFactory,
4638
                            classWriterFactory,
4639
                            ignoredMethods,
4640
                            auxiliaryTypes);
4641
                }
4642

4643
                /**
4644
                 * {@inheritDoc}
4645
                 */
4646
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
4647
                    return materialize(instrumentedType,
1✔
4648
                            fieldRegistry,
4649
                            methodRegistry,
4650
                            recordComponentRegistry,
4651
                            new TypeAttributeAppender.Compound(this.typeAttributeAppender, typeAttributeAppender),
4652
                            asmVisitorWrapper,
4653
                            classFileVersion,
4654
                            auxiliaryTypeNamingStrategy,
4655
                            annotationValueFilterFactory,
4656
                            annotationRetention,
4657
                            implementationContextFactory,
4658
                            methodGraphCompiler,
4659
                            typeValidation,
4660
                            visibilityBridgeStrategy,
4661
                            classReaderFactory,
4662
                            classWriterFactory,
4663
                            ignoredMethods,
4664
                            auxiliaryTypes);
4665
                }
4666

4667
                /**
4668
                 * {@inheritDoc}
4669
                 */
4670
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
4671
                    return materialize(instrumentedType.withAnnotations(new ArrayList<AnnotationDescription>(annotations)),
1✔
4672
                            fieldRegistry,
4673
                            methodRegistry,
4674
                            recordComponentRegistry,
4675
                            typeAttributeAppender,
4676
                            asmVisitorWrapper,
4677
                            classFileVersion,
4678
                            auxiliaryTypeNamingStrategy,
4679
                            annotationValueFilterFactory,
4680
                            annotationRetention,
4681
                            implementationContextFactory,
4682
                            methodGraphCompiler,
4683
                            typeValidation,
4684
                            visibilityBridgeStrategy,
4685
                            classReaderFactory,
4686
                            classWriterFactory,
4687
                            ignoredMethods,
4688
                            auxiliaryTypes);
4689
                }
4690

4691
                /**
4692
                 * {@inheritDoc}
4693
                 */
4694
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
4695
                    return materialize(instrumentedType,
1✔
4696
                            fieldRegistry,
4697
                            methodRegistry,
4698
                            recordComponentRegistry,
4699
                            typeAttributeAppender,
4700
                            new AsmVisitorWrapper.Compound(this.asmVisitorWrapper, asmVisitorWrapper),
4701
                            classFileVersion,
4702
                            auxiliaryTypeNamingStrategy,
4703
                            annotationValueFilterFactory,
4704
                            annotationRetention,
4705
                            implementationContextFactory,
4706
                            methodGraphCompiler,
4707
                            typeValidation,
4708
                            visibilityBridgeStrategy,
4709
                            classReaderFactory,
4710
                            classWriterFactory,
4711
                            ignoredMethods,
4712
                            auxiliaryTypes);
4713
                }
4714

4715
                /**
4716
                 * {@inheritDoc}
4717
                 */
4718
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
4719
                    return materialize(instrumentedType,
1✔
4720
                            fieldRegistry,
4721
                            methodRegistry,
4722
                            recordComponentRegistry,
4723
                            typeAttributeAppender,
4724
                            asmVisitorWrapper,
4725
                            classFileVersion,
4726
                            auxiliaryTypeNamingStrategy,
4727
                            annotationValueFilterFactory,
4728
                            annotationRetention,
4729
                            implementationContextFactory,
4730
                            methodGraphCompiler,
4731
                            typeValidation,
4732
                            visibilityBridgeStrategy,
4733
                            classReaderFactory,
4734
                            classWriterFactory,
4735
                            ignoredMethods,
4736
                            CompoundList.of(this.auxiliaryTypes, new ArrayList<DynamicType>(auxiliaryTypes)));
1✔
4737
                }
4738

4739
                /**
4740
                 * {@inheritDoc}
4741
                 */
4742
                public TypeDescription toTypeDescription() {
4743
                    return instrumentedType;
1✔
4744
                }
4745

4746
                /**
4747
                 * Materializes the supplied state of a dynamic type builder.
4748
                 *
4749
                 * @param instrumentedType             The instrumented type.
4750
                 * @param fieldRegistry                The current field registry.
4751
                 * @param methodRegistry               The current method registry.
4752
                 * @param recordComponentRegistry      The record component pool to use.
4753
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
4754
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
4755
                 * @param classFileVersion             The class file version to define auxiliary types in.
4756
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
4757
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
4758
                 * @param annotationRetention          The annotation retention to apply.
4759
                 * @param implementationContextFactory The implementation context factory to apply.
4760
                 * @param methodGraphCompiler          The method graph compiler to use.
4761
                 * @param typeValidation               The type validation state.
4762
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
4763
                 * @param classReaderFactory           The class reader factory to use.
4764
                 * @param classWriterFactory           The class writer factory to use.
4765
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
4766
                 * @param auxiliaryTypes               A list of explicitly required auxiliary types.
4767
                 * @return A type builder that represents the supplied arguments.
4768
                 */
4769
                protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
4770
                                                          FieldRegistry fieldRegistry,
4771
                                                          MethodRegistry methodRegistry,
4772
                                                          RecordComponentRegistry recordComponentRegistry,
4773
                                                          TypeAttributeAppender typeAttributeAppender,
4774
                                                          AsmVisitorWrapper asmVisitorWrapper,
4775
                                                          ClassFileVersion classFileVersion,
4776
                                                          AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4777
                                                          AnnotationValueFilter.Factory annotationValueFilterFactory,
4778
                                                          AnnotationRetention annotationRetention,
4779
                                                          Implementation.Context.Factory implementationContextFactory,
4780
                                                          MethodGraph.Compiler methodGraphCompiler,
4781
                                                          TypeValidation typeValidation,
4782
                                                          VisibilityBridgeStrategy visibilityBridgeStrategy,
4783
                                                          AsmClassReader.Factory classReaderFactory,
4784
                                                          AsmClassWriter.Factory classWriterFactory,
4785
                                                          LatentMatcher<? super MethodDescription> ignoredMethods,
4786
                                                          List<? extends DynamicType> auxiliaryTypes);
4787

4788
                /**
4789
                 * An adapter for applying an inner type definition for an outer type.
4790
                 */
4791
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4792
                protected class InnerTypeDefinitionForTypeAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition.ForType<U> {
4793

4794
                    /**
4795
                     * A description of the type that is the defined outer type.
4796
                     */
4797
                    private final TypeDescription typeDescription;
4798

4799
                    /**
4800
                     * Creates a new adapter for an inner type definition for an outer type.
4801
                     *
4802
                     * @param typeDescription A description of the type that is the defined outer type.
4803
                     */
4804
                    protected InnerTypeDefinitionForTypeAdapter(TypeDescription typeDescription) {
1✔
4805
                        this.typeDescription = typeDescription;
1✔
4806
                    }
1✔
4807

4808
                    /**
4809
                     * {@inheritDoc}
4810
                     */
4811
                    public Builder<U> asAnonymousType() {
4812
                        return Adapter.this.materialize(instrumentedType
1✔
4813
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4814
                                        .withEnclosingType(typeDescription)
1✔
4815
                                        .withAnonymousClass(true),
1✔
4816
                                fieldRegistry,
4817
                                methodRegistry,
4818
                                recordComponentRegistry,
4819
                                typeAttributeAppender,
4820
                                asmVisitorWrapper,
4821
                                classFileVersion,
4822
                                auxiliaryTypeNamingStrategy,
4823
                                annotationValueFilterFactory,
4824
                                annotationRetention,
4825
                                implementationContextFactory,
4826
                                methodGraphCompiler,
4827
                                typeValidation,
4828
                                visibilityBridgeStrategy,
4829
                                classReaderFactory,
4830
                                classWriterFactory,
4831
                                ignoredMethods,
4832
                                auxiliaryTypes);
4833
                    }
4834

4835
                    /**
4836
                     * {@inheritDoc}
4837
                     */
4838
                    public Builder<U> asMemberType() {
4839
                        return Adapter.this.materialize(instrumentedType
1✔
4840
                                        .withDeclaringType(typeDescription)
1✔
4841
                                        .withEnclosingType(typeDescription)
1✔
4842
                                        .withAnonymousClass(false)
1✔
4843
                                        .withLocalClass(false),
1✔
4844
                                fieldRegistry,
4845
                                methodRegistry,
4846
                                recordComponentRegistry,
4847
                                typeAttributeAppender,
4848
                                asmVisitorWrapper,
4849
                                classFileVersion,
4850
                                auxiliaryTypeNamingStrategy,
4851
                                annotationValueFilterFactory,
4852
                                annotationRetention,
4853
                                implementationContextFactory,
4854
                                methodGraphCompiler,
4855
                                typeValidation,
4856
                                visibilityBridgeStrategy,
4857
                                classReaderFactory,
4858
                                classWriterFactory,
4859
                                ignoredMethods,
4860
                                auxiliaryTypes);
4861
                    }
4862

4863
                    @Override
4864
                    protected Builder<U> materialize() {
4865
                        return Adapter.this.materialize(instrumentedType
1✔
4866
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4867
                                        .withEnclosingType(typeDescription)
1✔
4868
                                        .withLocalClass(true),
1✔
4869
                                fieldRegistry,
4870
                                methodRegistry,
4871
                                recordComponentRegistry,
4872
                                typeAttributeAppender,
4873
                                asmVisitorWrapper,
4874
                                classFileVersion,
4875
                                auxiliaryTypeNamingStrategy,
4876
                                annotationValueFilterFactory,
4877
                                annotationRetention,
4878
                                implementationContextFactory,
4879
                                methodGraphCompiler,
4880
                                typeValidation,
4881
                                visibilityBridgeStrategy,
4882
                                classReaderFactory,
4883
                                classWriterFactory,
4884
                                ignoredMethods,
4885
                                auxiliaryTypes);
4886
                    }
4887
                }
4888

4889
                /**
4890
                 * An adapter for applying an inner type definition for an outer method or constructor.
4891
                 */
4892
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4893
                protected class InnerTypeDefinitionForMethodAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition<U> {
4894

4895
                    /**
4896
                     * A description of the declaring method or constructor.
4897
                     */
4898
                    private final MethodDescription.InDefinedShape methodDescription;
4899

4900
                    /**
4901
                     * Creates a new adapter for defining a type that is declared within a method or constructor.
4902
                     *
4903
                     * @param methodDescription A description of the declaring method or constructor.
4904
                     */
4905
                    protected InnerTypeDefinitionForMethodAdapter(MethodDescription.InDefinedShape methodDescription) {
1✔
4906
                        this.methodDescription = methodDescription;
1✔
4907
                    }
1✔
4908

4909
                    /**
4910
                     * {@inheritDoc}
4911
                     */
4912
                    public Builder<U> asAnonymousType() {
4913
                        return Adapter.this.materialize(instrumentedType
1✔
4914
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4915
                                        .withEnclosingMethod(methodDescription)
1✔
4916
                                        .withAnonymousClass(true),
1✔
4917
                                fieldRegistry,
4918
                                methodRegistry,
4919
                                recordComponentRegistry,
4920
                                typeAttributeAppender,
4921
                                asmVisitorWrapper,
4922
                                classFileVersion,
4923
                                auxiliaryTypeNamingStrategy,
4924
                                annotationValueFilterFactory,
4925
                                annotationRetention,
4926
                                implementationContextFactory,
4927
                                methodGraphCompiler,
4928
                                typeValidation,
4929
                                visibilityBridgeStrategy,
4930
                                classReaderFactory,
4931
                                classWriterFactory,
4932
                                ignoredMethods,
4933
                                auxiliaryTypes);
4934
                    }
4935

4936
                    @Override
4937
                    protected Builder<U> materialize() {
4938
                        return Adapter.this.materialize(instrumentedType
1✔
4939
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
4940
                                        .withEnclosingMethod(methodDescription)
1✔
4941
                                        .withLocalClass(true),
1✔
4942
                                fieldRegistry,
4943
                                methodRegistry,
4944
                                recordComponentRegistry,
4945
                                typeAttributeAppender,
4946
                                asmVisitorWrapper,
4947
                                classFileVersion,
4948
                                auxiliaryTypeNamingStrategy,
4949
                                annotationValueFilterFactory,
4950
                                annotationRetention,
4951
                                implementationContextFactory,
4952
                                methodGraphCompiler,
4953
                                typeValidation,
4954
                                visibilityBridgeStrategy,
4955
                                classReaderFactory,
4956
                                classWriterFactory,
4957
                                ignoredMethods,
4958
                                auxiliaryTypes);
4959
                    }
4960
                }
4961

4962
                /**
4963
                 * An adapter for defining a new type variable for the instrumented type.
4964
                 */
4965
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4966
                protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
4967

4968
                    /**
4969
                     * The current definition of the type variable.
4970
                     */
4971
                    private final TypeVariableToken token;
4972

4973
                    /**
4974
                     * Creates a new type variable definition adapter.
4975
                     *
4976
                     * @param token The current definition of the type variable.
4977
                     */
4978
                    protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
1✔
4979
                        this.token = token;
1✔
4980
                    }
1✔
4981

4982
                    /**
4983
                     * {@inheritDoc}
4984
                     */
4985
                    public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
4986
                        return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
1✔
4987
                                token.getBounds(),
1✔
4988
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
4989
                    }
4990

4991
                    @Override
4992
                    protected Builder<U> materialize() {
4993
                        return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
1✔
4994
                                fieldRegistry,
4995
                                methodRegistry,
4996
                                recordComponentRegistry,
4997
                                typeAttributeAppender,
4998
                                asmVisitorWrapper,
4999
                                classFileVersion,
5000
                                auxiliaryTypeNamingStrategy,
5001
                                annotationValueFilterFactory,
5002
                                annotationRetention,
5003
                                implementationContextFactory,
5004
                                methodGraphCompiler,
5005
                                typeValidation,
5006
                                visibilityBridgeStrategy,
5007
                                classReaderFactory,
5008
                                classWriterFactory,
5009
                                ignoredMethods,
5010
                                auxiliaryTypes);
5011
                    }
5012
                }
5013

5014
                /**
5015
                 * An adapter for defining a new field.
5016
                 */
5017
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5018
                protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
5019

5020
                    /**
5021
                     * The token representing the current field definition.
5022
                     */
5023
                    private final FieldDescription.Token token;
5024

5025
                    /**
5026
                     * Creates a new field definition adapter.
5027
                     *
5028
                     * @param token The token representing the current field definition.
5029
                     */
5030
                    protected FieldDefinitionAdapter(FieldDescription.Token token) {
5031
                        this(FieldAttributeAppender.ForInstrumentedField.INSTANCE,
1✔
5032
                                Transformer.NoOp.<FieldDescription>make(),
1✔
5033
                                FieldDescription.NO_DEFAULT_VALUE,
5034
                                token);
5035
                    }
1✔
5036

5037
                    /**
5038
                     * Creates a new field definition adapter.
5039
                     *
5040
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
5041
                     * @param transformer                   The field transformer to apply.
5042
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
5043
                     * @param token                         The token representing the current field definition.
5044
                     */
5045
                    protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5046
                                                     Transformer<FieldDescription> transformer,
5047
                                                     @MaybeNull Object defaultValue,
5048
                                                     FieldDescription.Token token) {
1✔
5049
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
5050
                        this.token = token;
1✔
5051
                    }
1✔
5052

5053
                    /**
5054
                     * {@inheritDoc}
5055
                     */
5056
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
5057
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, new FieldDescription.Token(token.getName(),
1✔
5058
                                token.getModifiers(),
1✔
5059
                                token.getType(),
1✔
5060
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
5061
                    }
5062

5063
                    @Override
5064
                    protected Builder<U> materialize() {
5065
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
1✔
5066
                                fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
5067
                                methodRegistry,
5068
                                recordComponentRegistry,
5069
                                typeAttributeAppender,
5070
                                asmVisitorWrapper,
5071
                                classFileVersion,
5072
                                auxiliaryTypeNamingStrategy,
5073
                                annotationValueFilterFactory,
5074
                                annotationRetention,
5075
                                implementationContextFactory,
5076
                                methodGraphCompiler,
5077
                                typeValidation,
5078
                                visibilityBridgeStrategy,
5079
                                classReaderFactory,
5080
                                classWriterFactory,
5081
                                ignoredMethods,
5082
                                auxiliaryTypes);
5083
                    }
5084

5085
                    @Override
5086
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5087
                                                      Transformer<FieldDescription> transformer,
5088
                                                      @MaybeNull Object defaultValue) {
5089
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
1✔
5090
                    }
5091
                }
5092

5093
                /**
5094
                 * An adapter for matching an existing field.
5095
                 */
5096
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5097
                protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
5098

5099
                    /**
5100
                     * The matcher for any fields to apply this matcher to.
5101
                     */
5102
                    private final LatentMatcher<? super FieldDescription> matcher;
5103

5104
                    /**
5105
                     * Creates a new field match adapter.
5106
                     *
5107
                     * @param matcher The matcher for any fields to apply this matcher to.
5108
                     */
5109
                    protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
5110
                        this(FieldAttributeAppender.NoOp.INSTANCE,
1✔
5111
                                Transformer.NoOp.<FieldDescription>make(),
1✔
5112
                                FieldDescription.NO_DEFAULT_VALUE,
5113
                                matcher);
5114
                    }
1✔
5115

5116
                    /**
5117
                     * Creates a new field match adapter.
5118
                     *
5119
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
5120
                     * @param transformer                   The field transformer to apply.
5121
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
5122
                     * @param matcher                       The matcher for any fields to apply this matcher to.
5123
                     */
5124
                    protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5125
                                                Transformer<FieldDescription> transformer,
5126
                                                @MaybeNull Object defaultValue,
5127
                                                LatentMatcher<? super FieldDescription> matcher) {
1✔
5128
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
5129
                        this.matcher = matcher;
1✔
5130
                    }
1✔
5131

5132
                    /**
5133
                     * {@inheritDoc}
5134
                     */
5135
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
5136
                        return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
1✔
5137
                    }
5138

5139
                    @Override
5140
                    protected Builder<U> materialize() {
5141
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
5142
                                fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
5143
                                methodRegistry,
5144
                                recordComponentRegistry,
5145
                                typeAttributeAppender,
5146
                                asmVisitorWrapper,
5147
                                classFileVersion,
5148
                                auxiliaryTypeNamingStrategy,
5149
                                annotationValueFilterFactory,
5150
                                annotationRetention,
5151
                                implementationContextFactory,
5152
                                methodGraphCompiler,
5153
                                typeValidation,
5154
                                visibilityBridgeStrategy,
5155
                                classReaderFactory,
5156
                                classWriterFactory,
5157
                                ignoredMethods,
5158
                                auxiliaryTypes);
5159
                    }
5160

5161
                    @Override
5162
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
5163
                                                      Transformer<FieldDescription> transformer,
5164
                                                      @MaybeNull Object defaultValue) {
5165
                        return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
1✔
5166
                    }
5167
                }
5168

5169
                /**
5170
                 * An adapter for defining a new method.
5171
                 */
5172
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5173
                protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
5174

5175
                    /**
5176
                     * A token representing the currently defined method.
5177
                     */
5178
                    private final MethodDescription.Token token;
5179

5180
                    /**
5181
                     * Creates a new method definition adapter.
5182
                     *
5183
                     * @param token A token representing the currently defined method.
5184
                     */
5185
                    protected MethodDefinitionAdapter(MethodDescription.Token token) {
1✔
5186
                        this.token = token;
1✔
5187
                    }
1✔
5188

5189
                    /**
5190
                     * {@inheritDoc}
5191
                     */
5192
                    public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
5193
                        return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
1✔
5194
                    }
5195

5196
                    /**
5197
                     * {@inheritDoc}
5198
                     */
5199
                    public Simple.Annotatable<U> withParameter(TypeDefinition type) {
5200
                        return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
1✔
5201
                    }
5202

5203
                    /**
5204
                     * {@inheritDoc}
5205
                     */
5206
                    public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
5207
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5208
                                token.getModifiers(),
1✔
5209
                                token.getTypeVariableTokens(),
1✔
5210
                                token.getReturnType(),
1✔
5211
                                token.getParameterTokens(),
1✔
5212
                                CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
1✔
5213
                                token.getAnnotations(),
1✔
5214
                                token.getDefaultValue(),
1✔
5215
                                token.getReceiverType()));
1✔
5216
                    }
5217

5218
                    /**
5219
                     * {@inheritDoc}
5220
                     */
5221
                    public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
5222
                        return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
5223
                    }
5224

5225
                    /**
5226
                     * {@inheritDoc}
5227
                     */
5228
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5229
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
5230
                    }
5231

5232
                    /**
5233
                     * {@inheritDoc}
5234
                     */
5235
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5236
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5237
                                (token.getModifiers() & Opcodes.ACC_NATIVE) == 0
1✔
5238
                                        ? ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers())
1✔
5239
                                        : token.getModifiers(),
1✔
5240
                                token.getTypeVariableTokens(),
1✔
5241
                                token.getReturnType(),
1✔
5242
                                token.getParameterTokens(),
1✔
5243
                                token.getExceptionTypes(),
1✔
5244
                                token.getAnnotations(),
1✔
5245
                                token.getDefaultValue(),
1✔
5246
                                token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
5247
                    }
5248

5249
                    /**
5250
                     * {@inheritDoc}
5251
                     */
5252
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5253
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5254
                                ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
1✔
5255
                                token.getTypeVariableTokens(),
1✔
5256
                                token.getReturnType(),
1✔
5257
                                token.getParameterTokens(),
1✔
5258
                                token.getExceptionTypes(),
1✔
5259
                                token.getAnnotations(),
1✔
5260
                                annotationValue,
5261
                                token.getReceiverType())).materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
5262
                    }
5263

5264
                    /**
5265
                     * Materializes the given handler as the implementation.
5266
                     *
5267
                     * @param handler The handler for implementing the method.
5268
                     * @return A method definition for the given handler.
5269
                     */
5270
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5271
                        return new AnnotationAdapter(handler);
1✔
5272
                    }
5273

5274
                    /**
5275
                     * An adapter for defining a new type variable for the currently defined method.
5276
                     */
5277
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5278
                    protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
5279

5280
                        /**
5281
                         * The currently defined type variable.
5282
                         */
5283
                        private final TypeVariableToken token;
5284

5285
                        /**
5286
                         * Creates a new type variable annotation adapter.
5287
                         *
5288
                         * @param token The currently defined type variable.
5289
                         */
5290
                        protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
1✔
5291
                            this.token = token;
1✔
5292
                        }
1✔
5293

5294
                        @Override
5295
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
5296
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
5297
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
5298
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getTypeVariableTokens(), token),
1✔
5299
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
5300
                                    MethodDefinitionAdapter.this.token.getParameterTokens(),
1✔
5301
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
5302
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
5303
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
5304
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
5305
                        }
5306

5307
                        /**
5308
                         * {@inheritDoc}
5309
                         */
5310
                        public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
5311
                            return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
1✔
5312
                                    token.getBounds(),
1✔
5313
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
5314
                        }
5315
                    }
5316

5317
                    /**
5318
                     * An annotation adapter for a parameter definition.
5319
                     */
5320
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5321
                    protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
5322

5323
                        /**
5324
                         * The token of the currently defined parameter.
5325
                         */
5326
                        private final ParameterDescription.Token token;
5327

5328
                        /**
5329
                         * Creates a new parameter annotation adapter.
5330
                         *
5331
                         * @param token The token of the currently defined parameter.
5332
                         */
5333
                        protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
5334
                            this.token = token;
1✔
5335
                        }
1✔
5336

5337
                        /**
5338
                         * {@inheritDoc}
5339
                         */
5340
                        public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5341
                            return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
×
5342
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
5343
                                    token.getName(),
×
5344
                                    token.getModifiers()));
×
5345
                        }
5346

5347
                        @Override
5348
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
5349
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
5350
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
5351
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
5352
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
5353
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
5354
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
5355
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
5356
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
5357
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
5358
                        }
5359
                    }
5360

5361
                    /**
5362
                     * An annotation adapter for a simple parameter definition.
5363
                     */
5364
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5365
                    protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
5366

5367
                        /**
5368
                         * The token of the currently defined parameter.
5369
                         */
5370
                        private final ParameterDescription.Token token;
5371

5372
                        /**
5373
                         * Creates a new simple parameter annotation adapter.
5374
                         *
5375
                         * @param token The token of the currently defined parameter.
5376
                         */
5377
                        protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
5378
                            this.token = token;
1✔
5379
                        }
1✔
5380

5381
                        /**
5382
                         * {@inheritDoc}
5383
                         */
5384
                        public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5385
                            return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
1✔
5386
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
5387
                                    token.getName(),
1✔
5388
                                    token.getModifiers()));
1✔
5389
                        }
5390

5391
                        @Override
5392
                        protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
5393
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
5394
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
5395
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
5396
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
5397
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
5398
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
5399
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
5400
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
5401
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
5402
                        }
5403
                    }
5404

5405
                    /**
5406
                     * An annotation adapter for a method definition.
5407
                     */
5408
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5409
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5410

5411
                        /**
5412
                         * Creates a new annotation adapter.
5413
                         *
5414
                         * @param handler The handler that determines how a method is implemented.
5415
                         */
5416
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
5417
                            this(handler,
1✔
5418
                                    MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER,
5419
                                    Transformer.NoOp.<MethodDescription>make());
1✔
5420
                        }
1✔
5421

5422
                        /**
5423
                         * Creates a new annotation adapter.
5424
                         *
5425
                         * @param handler                        The handler that determines how a method is implemented.
5426
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5427
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
5428
                         */
5429
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
5430
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5431
                                                    Transformer<MethodDescription> transformer) {
1✔
5432
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
5433
                        }
1✔
5434

5435
                        /**
5436
                         * {@inheritDoc}
5437
                         */
5438
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5439
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5440
                                    token.getModifiers(),
1✔
5441
                                    token.getTypeVariableTokens(),
1✔
5442
                                    token.getReturnType(),
1✔
5443
                                    token.getParameterTokens(),
1✔
5444
                                    token.getExceptionTypes(),
1✔
5445
                                    token.getAnnotations(),
1✔
5446
                                    token.getDefaultValue(),
1✔
5447
                                    receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5448
                        }
5449

5450
                        /**
5451
                         * {@inheritDoc}
5452
                         */
5453
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5454
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
5455
                                    token.getModifiers(),
1✔
5456
                                    token.getTypeVariableTokens(),
1✔
5457
                                    token.getReturnType(),
1✔
5458
                                    token.getParameterTokens(),
1✔
5459
                                    token.getExceptionTypes(),
1✔
5460
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
5461
                                    token.getDefaultValue(),
1✔
5462
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
5463
                        }
5464

5465
                        /**
5466
                         * {@inheritDoc}
5467
                         */
5468
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5469
                            List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
×
5470
                            parameterTokens.set(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
×
5471
                                    CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
5472
                                    token.getParameterTokens().get(index).getName(),
×
5473
                                    token.getParameterTokens().get(index).getModifiers()));
×
5474
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
×
5475
                                    token.getModifiers(),
×
5476
                                    token.getTypeVariableTokens(),
×
5477
                                    token.getReturnType(),
×
5478
                                    parameterTokens,
5479
                                    token.getExceptionTypes(),
×
5480
                                    token.getAnnotations(),
×
5481
                                    token.getDefaultValue(),
×
5482
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
5483
                        }
5484

5485
                        @Override
5486
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5487
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5488
                                                                  Transformer<MethodDescription> transformer) {
5489
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
5490
                        }
5491

5492
                        @Override
5493
                        protected Builder<U> materialize() {
5494
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
1✔
5495
                                    fieldRegistry,
5496
                                    methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
1✔
5497
                                            handler,
5498
                                            methodAttributeAppenderFactory,
5499
                                            transformer),
5500
                                    recordComponentRegistry,
5501
                                    typeAttributeAppender,
5502
                                    asmVisitorWrapper,
5503
                                    classFileVersion,
5504
                                    auxiliaryTypeNamingStrategy,
5505
                                    annotationValueFilterFactory,
5506
                                    annotationRetention,
5507
                                    implementationContextFactory,
5508
                                    methodGraphCompiler,
5509
                                    typeValidation,
5510
                                    visibilityBridgeStrategy,
5511
                                    classReaderFactory,
5512
                                    classWriterFactory,
5513
                                    ignoredMethods,
5514
                                    auxiliaryTypes);
5515
                        }
5516
                    }
5517
                }
5518

5519
                /**
5520
                 * An adapter for matching an existing method.
5521
                 */
5522
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5523
                protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
5524

5525
                    /**
5526
                     * The method matcher of this adapter.
5527
                     */
5528
                    private final LatentMatcher<? super MethodDescription> matcher;
5529

5530
                    /**
5531
                     * Creates a new method match adapter.
5532
                     *
5533
                     * @param matcher The method matcher of this adapter.
5534
                     */
5535
                    protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
1✔
5536
                        this.matcher = matcher;
1✔
5537
                    }
1✔
5538

5539
                    /**
5540
                     * {@inheritDoc}
5541
                     */
5542
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5543
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
5544
                    }
5545

5546
                    /**
5547
                     * {@inheritDoc}
5548
                     */
5549
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5550
                        return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
5551
                    }
5552

5553
                    /**
5554
                     * {@inheritDoc}
5555
                     */
5556
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5557
                        return materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
5558
                    }
5559

5560
                    /**
5561
                     * Materializes the method definition with the supplied handler.
5562
                     *
5563
                     * @param handler The handler that implements any method matched by this instances matcher.
5564
                     * @return A method definition where any matched method is implemented by the supplied handler.
5565
                     */
5566
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5567
                        return new AnnotationAdapter(handler);
1✔
5568
                    }
5569

5570
                    /**
5571
                     * An annotation adapter for implementing annotations during a method definition.
5572
                     */
5573
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5574
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5575

5576
                        /**
5577
                         * Creates a new annotation adapter.
5578
                         *
5579
                         * @param handler The handler that determines how a method is implemented.
5580
                         */
5581
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
5582
                            this(handler, MethodAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<MethodDescription>make());
1✔
5583
                        }
1✔
5584

5585
                        /**
5586
                         * Creates a new annotation adapter.
5587
                         *
5588
                         * @param handler                        The handler that determines how a method is implemented.
5589
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5590
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
5591
                         */
5592
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
5593
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5594
                                                    Transformer<MethodDescription> transformer) {
1✔
5595
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
5596
                        }
1✔
5597

5598
                        /**
5599
                         * {@inheritDoc}
5600
                         */
5601
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5602
                            return new AnnotationAdapter(handler,
1✔
5603
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
5604
                                    transformer);
5605
                        }
5606

5607
                        /**
5608
                         * {@inheritDoc}
5609
                         */
5610
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5611
                            return new AnnotationAdapter(handler,
1✔
5612
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
5613
                                    transformer);
5614
                        }
5615

5616
                        /**
5617
                         * {@inheritDoc}
5618
                         */
5619
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5620
                            return new AnnotationAdapter(handler,
×
5621
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
5622
                                    transformer);
5623
                        }
5624

5625
                        @Override
5626
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5627
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5628
                                                                  Transformer<MethodDescription> transformer) {
5629
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
5630
                        }
5631

5632
                        @Override
5633
                        protected Builder<U> materialize() {
5634
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
5635
                                    fieldRegistry,
5636
                                    methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, transformer),
1✔
5637
                                    recordComponentRegistry,
5638
                                    typeAttributeAppender,
5639
                                    asmVisitorWrapper,
5640
                                    classFileVersion,
5641
                                    auxiliaryTypeNamingStrategy,
5642
                                    annotationValueFilterFactory,
5643
                                    annotationRetention,
5644
                                    implementationContextFactory,
5645
                                    methodGraphCompiler,
5646
                                    typeValidation,
5647
                                    visibilityBridgeStrategy,
5648
                                    classReaderFactory,
5649
                                    classWriterFactory,
5650
                                    ignoredMethods,
5651
                                    auxiliaryTypes);
5652
                        }
5653
                    }
5654
                }
5655

5656
                /**
5657
                 * An adapter for optionally matching methods defined by declared interfaces.
5658
                 */
5659
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5660
                protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
5661

5662
                    /**
5663
                     * The interfaces whose methods are optionally matched.
5664
                     */
5665
                    private final TypeList.Generic interfaces;
5666

5667
                    /**
5668
                     * Creates a new optional method match adapter.
5669
                     *
5670
                     * @param interfaces The interfaces whose methods are optionally matched.
5671
                     */
5672
                    protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
1✔
5673
                        this.interfaces = interfaces;
1✔
5674
                    }
1✔
5675

5676
                    @Override
5677
                    protected Builder<U> materialize() {
5678
                        return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
1✔
5679
                                fieldRegistry,
5680
                                methodRegistry,
5681
                                recordComponentRegistry,
5682
                                typeAttributeAppender,
5683
                                asmVisitorWrapper,
5684
                                classFileVersion,
5685
                                auxiliaryTypeNamingStrategy,
5686
                                annotationValueFilterFactory,
5687
                                annotationRetention,
5688
                                implementationContextFactory,
5689
                                methodGraphCompiler,
5690
                                typeValidation,
5691
                                visibilityBridgeStrategy,
5692
                                classReaderFactory,
5693
                                classWriterFactory,
5694
                                ignoredMethods,
5695
                                auxiliaryTypes);
5696
                    }
5697

5698
                    /**
5699
                     * {@inheritDoc}
5700
                     */
5701
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5702
                        return interfaceType().intercept(implementation);
1✔
5703
                    }
5704

5705
                    /**
5706
                     * {@inheritDoc}
5707
                     */
5708
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5709
                        return interfaceType().withoutCode();
×
5710
                    }
5711

5712
                    /**
5713
                     * {@inheritDoc}
5714
                     */
5715
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5716
                        return interfaceType().defaultValue(annotationValue);
×
5717
                    }
5718

5719
                    /**
5720
                     * {@inheritDoc}
5721
                     */
5722
                    public <V> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(V value, Class<? extends V> type) {
5723
                        return interfaceType().defaultValue(value, type);
×
5724
                    }
5725

5726
                    /**
5727
                     * Returns a matcher for the interfaces' methods.
5728
                     *
5729
                     * @return A matcher for the interfaces' methods.
5730
                     */
5731
                    private MethodDefinition.ImplementationDefinition<U> interfaceType() {
5732
                        ElementMatcher.Junction<TypeDescription> elementMatcher = none();
1✔
5733
                        for (TypeDescription typeDescription : interfaces.asErasures()) {
1✔
5734
                            elementMatcher = elementMatcher.or(isSuperTypeOf(typeDescription));
1✔
5735
                        }
1✔
5736
                        return materialize().invokable(isDeclaredBy(isInterface().and(elementMatcher)));
1✔
5737
                    }
5738
                }
5739

5740
                /**
5741
                 * An adapter for defining a record component.
5742
                 */
5743
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5744
                protected class RecordComponentDefinitionAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5745

5746
                    /**
5747
                     * The record component attribute appender factory to apply.
5748
                     */
5749
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5750

5751
                    /**
5752
                     * A token representing the defined record component.
5753
                     */
5754
                    private final RecordComponentDescription.Token token;
5755

5756
                    /**
5757
                     * A transformer to apply on matched record component descriptions.
5758
                     */
5759
                    private final Transformer<RecordComponentDescription> transformer;
5760

5761
                    /**
5762
                     * Creates a new record component definition adapter.
5763
                     *
5764
                     * @param token A token representing the defined record component.
5765
                     */
5766
                    protected RecordComponentDefinitionAdapter(RecordComponentDescription.Token token) {
5767
                        this(RecordComponentAttributeAppender.ForInstrumentedRecordComponent.INSTANCE,
×
5768
                                Transformer.NoOp.<RecordComponentDescription>make(),
×
5769
                                token);
5770
                    }
×
5771

5772
                    /**
5773
                     * Creates a new record component definition adapter.
5774
                     *
5775
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5776
                     * @param transformer                             A transformer to apply on matched record component descriptions.
5777
                     * @param token                                   A token representing the defined record component.
5778
                     */
5779
                    protected RecordComponentDefinitionAdapter(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5780
                                                               Transformer<RecordComponentDescription> transformer,
5781
                                                               RecordComponentDescription.Token token) {
×
5782
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
5783
                        this.transformer = transformer;
×
5784
                        this.token = token;
×
5785
                    }
×
5786

5787
                    /**
5788
                     * {@inheritDoc}
5789
                     */
5790
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5791
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory, transformer, new RecordComponentDescription.Token(token.getName(),
×
5792
                                token.getType(),
×
5793
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
×
5794
                    }
5795

5796
                    /**
5797
                     * {@inheritDoc}
5798
                     */
5799
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5800
                        return new RecordComponentDefinitionAdapter(new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
5801
                                recordComponentAttributeAppenderFactory), transformer, token);
5802
                    }
5803

5804
                    /**
5805
                     * {@inheritDoc}
5806
                     */
5807
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
5808
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5809
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory,
×
5810
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer),
5811
                                token);
5812
                    }
5813

5814
                    @Override
5815
                    protected Builder<U> materialize() {
5816
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withRecordComponent(token),
×
5817
                                fieldRegistry,
5818
                                methodRegistry,
5819
                                recordComponentRegistry.prepend(new LatentMatcher.ForRecordComponentToken(token),
×
5820
                                        recordComponentAttributeAppenderFactory,
5821
                                        transformer),
5822
                                typeAttributeAppender,
5823
                                asmVisitorWrapper,
5824
                                classFileVersion,
5825
                                auxiliaryTypeNamingStrategy,
5826
                                annotationValueFilterFactory,
5827
                                annotationRetention,
5828
                                implementationContextFactory,
5829
                                methodGraphCompiler,
5830
                                typeValidation,
5831
                                visibilityBridgeStrategy,
5832
                                classReaderFactory,
5833
                                classWriterFactory,
5834
                                ignoredMethods,
5835
                                auxiliaryTypes);
5836
                    }
5837
                }
5838

5839
                /**
5840
                 * An adapter for matching record components.
5841
                 */
5842
                protected class RecordComponentMatchAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5843

5844
                    /**
5845
                     * The matcher for identifying record components to match.
5846
                     */
5847
                    private final LatentMatcher<? super RecordComponentDescription> matcher;
5848

5849
                    /**
5850
                     * The record component attribute appender factory to apply.
5851
                     */
5852
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5853

5854
                    /**
5855
                     * A transformer to apply on matched record component descriptions.
5856
                     */
5857
                    private final Transformer<RecordComponentDescription> transformer;
5858

5859
                    /**
5860
                     * Creates a new record component match adapter.
5861
                     *
5862
                     * @param matcher The matcher for identifying record components to match.
5863
                     */
5864
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher) {
5865
                        this(matcher, RecordComponentAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<RecordComponentDescription>make());
×
5866
                    }
×
5867

5868
                    /**
5869
                     * Creates a new record component match adapter.
5870
                     *
5871
                     * @param matcher                                 The matcher for identifying record components to match.
5872
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5873
                     * @param transformer                             A transformer to apply on matched record component descriptions.
5874
                     */
5875
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher,
5876
                                                          RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5877
                                                          Transformer<RecordComponentDescription> transformer) {
×
5878
                        this.matcher = matcher;
×
5879
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
5880
                        this.transformer = transformer;
×
5881
                    }
×
5882

5883
                    /**
5884
                     * {@inheritDoc}
5885
                     */
5886
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5887
                        return attribute(new RecordComponentAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
×
5888
                    }
5889

5890
                    /**
5891
                     * {@inheritDoc}
5892
                     */
5893
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5894
                        return new RecordComponentMatchAdapter(matcher, new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
5895
                                recordComponentAttributeAppenderFactory), transformer);
5896
                    }
5897

5898
                    /**
5899
                     * {@inheritDoc}
5900
                     */
5901
                    @SuppressWarnings("unchecked")  // In absence of @SafeVarargs
5902
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5903
                        return new RecordComponentMatchAdapter(matcher,
×
5904
                                recordComponentAttributeAppenderFactory,
5905
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer));
5906
                    }
5907

5908
                    @Override
5909
                    protected Builder<U> materialize() {
5910
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
×
5911
                                fieldRegistry,
5912
                                methodRegistry,
5913
                                recordComponentRegistry.prepend(matcher, recordComponentAttributeAppenderFactory, transformer),
×
5914
                                typeAttributeAppender,
5915
                                asmVisitorWrapper,
5916
                                classFileVersion,
5917
                                auxiliaryTypeNamingStrategy,
5918
                                annotationValueFilterFactory,
5919
                                annotationRetention,
5920
                                implementationContextFactory,
5921
                                methodGraphCompiler,
5922
                                typeValidation,
5923
                                visibilityBridgeStrategy,
5924
                                classReaderFactory,
5925
                                classWriterFactory,
5926
                                ignoredMethods,
5927
                                auxiliaryTypes);
5928
                    }
5929
                }
5930
            }
5931
        }
5932
    }
5933

5934
    /**
5935
     * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
5936
     *
5937
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
5938
     *            type itself, an interface or the direct super class.
5939
     */
5940
    interface Unloaded<T> extends DynamicType {
5941

5942
        /**
5943
         * <p>
5944
         * Attempts to load this dynamic type including all of its auxiliary types, if any. If the class loader is an
5945
         * unsealed instance of {@link InjectionClassLoader}, the classes are injected directy into the class loader, otherwise,
5946
         * a new class loader is created where the supplied class loader is set as parent.
5947
         * </p>
5948
         * <p>
5949
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
5950
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
5951
         * </p>
5952
         *
5953
         * @param classLoader The class loader to use for this class loading or {@code null} for using the boot loader.
5954
         * @return This dynamic type in its loaded state.
5955
         */
5956
        Loaded<T> load(@MaybeNull ClassLoader classLoader);
5957

5958
        /**
5959
         * <p>
5960
         * Attempts to load this dynamic type including all of its auxiliary types, if any.
5961
         * </p>
5962
         * <p>
5963
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
5964
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
5965
         * </p>
5966
         *
5967
         * @param classLoader          The class loader to use for this class loading.
5968
         * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
5969
         * @param <S>                  The least specific type of class loader this strategy can apply to.
5970
         * @return This dynamic type in its loaded state.
5971
         * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
5972
         */
5973
        <S extends ClassLoader> Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
5974

5975
        /**
5976
         * Includes the provided dynamic types as auxiliary types of this instance.
5977
         *
5978
         * @param dynamicType The dynamic types to include.
5979
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
5980
         */
5981
        Unloaded<T> include(DynamicType... dynamicType);
5982

5983
        /**
5984
         * Includes the provided dynamic types as auxiliary types of this instance.
5985
         *
5986
         * @param dynamicTypes The dynamic types to include.
5987
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
5988
         */
5989
        Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
5990
    }
5991

5992
    /**
5993
     * A dynamic type that has been loaded into the running instance of the Java virtual machine.
5994
     *
5995
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
5996
     *            type itself, an interface or the direct super class.
5997
     */
5998
    interface Loaded<T> extends DynamicType {
5999

6000
        /**
6001
         * Returns the loaded main class.
6002
         *
6003
         * @return A loaded class representation of this dynamic type.
6004
         */
6005
        Class<? extends T> getLoaded();
6006

6007
        /**
6008
         * <p>
6009
         * Returns a map of all loaded auxiliary types to this dynamic type.
6010
         * </p>
6011
         * <p>
6012
         * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
6013
         * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
6014
         * </p>
6015
         *
6016
         * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
6017
         */
6018
        Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
6019

6020
        /**
6021
         * Returns all loaded types that are implied by this dynamic type.
6022
         *
6023
         * @return All loaded types that are implied by this dynamic type.
6024
         */
6025
        Map<TypeDescription, Class<?>> getAllLoaded();
6026
    }
6027

6028
    /**
6029
     * A default implementation of a dynamic type.
6030
     */
6031
    @HashCodeAndEqualsPlugin.Enhance
6032
    class Default implements DynamicType {
6033

6034
        /**
6035
         * The file name extension for Java class files.
6036
         */
6037
        private static final String CLASS_FILE_EXTENSION = ".class";
6038

6039
        /**
6040
         * The default version of a jar file manifest.
6041
         */
6042
        private static final String MANIFEST_VERSION = "1.0";
6043

6044
        /**
6045
         * The size of a writing buffer.
6046
         */
6047
        private static final int BUFFER_SIZE = 1024;
6048

6049
        /**
6050
         * A convenience index for the beginning of an array to improve the readability of the code.
6051
         */
6052
        private static final int FROM_BEGINNING = 0;
6053

6054
        /**
6055
         * A convenience representative of an {@link java.io.InputStream}'s end to improve the readability of the code.
6056
         */
6057
        private static final int END_OF_FILE = -1;
6058

6059
        /**
6060
         * A suffix for temporary files.
6061
         */
6062
        private static final String TEMP_SUFFIX = "tmp";
6063

6064
        /**
6065
         * A type description of this dynamic type.
6066
         */
6067
        protected final TypeDescription typeDescription;
6068

6069
        /**
6070
         * The byte array representing this dynamic type.
6071
         */
6072
        protected final byte[] binaryRepresentation;
6073

6074
        /**
6075
         * The loaded type initializer for this dynamic type.
6076
         */
6077
        protected final LoadedTypeInitializer loadedTypeInitializer;
6078

6079
        /**
6080
         * A list of auxiliary types for this dynamic type.
6081
         */
6082
        protected final List<? extends DynamicType> auxiliaryTypes;
6083

6084
        /**
6085
         * Creates a new dynamic type.
6086
         *
6087
         * @param typeDescription       A description of this dynamic type.
6088
         * @param binaryRepresentation  A byte array containing the binary representation of this dynamic type. The array must not be modified.
6089
         * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
6090
         * @param auxiliaryTypes        The auxiliary type required for this dynamic type.
6091
         */
6092
        @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not modified by class contract.")
6093
        public Default(TypeDescription typeDescription,
6094
                       byte[] binaryRepresentation,
6095
                       LoadedTypeInitializer loadedTypeInitializer,
6096
                       List<? extends DynamicType> auxiliaryTypes) {
1✔
6097
            this.typeDescription = typeDescription;
1✔
6098
            this.binaryRepresentation = binaryRepresentation;
1✔
6099
            this.loadedTypeInitializer = loadedTypeInitializer;
1✔
6100
            this.auxiliaryTypes = auxiliaryTypes;
1✔
6101
        }
1✔
6102

6103
        /**
6104
         * {@inheritDoc}
6105
         */
6106
        public Resolution locate(String name) throws IOException {
6107
            if (typeDescription.getName().equals(name)) {
1✔
6108
                return new Resolution.Explicit(binaryRepresentation);
1✔
6109
            }
6110
            for (DynamicType auxiliaryType : auxiliaryTypes) {
1✔
6111
                Resolution resolution = auxiliaryType.locate(name);
1✔
6112
                if (resolution.isResolved()) {
1✔
6113
                    return resolution;
1✔
6114
                }
6115
            }
1✔
6116
            return new Resolution.Illegal(name);
1✔
6117
        }
6118

6119
        /**
6120
         * {@inheritDoc}
6121
         */
6122
        public void close() {
6123
            /* do nothing */
6124
        }
×
6125

6126
        /**
6127
         * {@inheritDoc}
6128
         */
6129
        public TypeDescription getTypeDescription() {
6130
            return typeDescription;
1✔
6131
        }
6132

6133
        /**
6134
         * {@inheritDoc}
6135
         */
6136
        public Map<TypeDescription, byte[]> getAllTypes() {
6137
            Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
1✔
6138
            allTypes.put(typeDescription, binaryRepresentation);
1✔
6139
            for (DynamicType auxiliaryType : auxiliaryTypes) {
1✔
6140
                allTypes.putAll(auxiliaryType.getAllTypes());
1✔
6141
            }
1✔
6142
            return allTypes;
1✔
6143
        }
6144

6145
        /**
6146
         * {@inheritDoc}
6147
         */
6148
        public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
6149
            Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
1✔
6150
            for (DynamicType auxiliaryType : auxiliaryTypes) {
1✔
6151
                classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
1✔
6152
            }
1✔
6153
            classLoadingCallbacks.put(typeDescription, loadedTypeInitializer);
1✔
6154
            return classLoadingCallbacks;
1✔
6155
        }
6156

6157
        /**
6158
         * {@inheritDoc}
6159
         */
6160
        public boolean hasAliveLoadedTypeInitializers() {
6161
            for (LoadedTypeInitializer loadedTypeInitializer : getLoadedTypeInitializers().values()) {
1✔
6162
                if (loadedTypeInitializer.isAlive()) {
1✔
6163
                    return true;
1✔
6164
                }
6165
            }
1✔
6166
            return false;
1✔
6167
        }
6168

6169
        /**
6170
         * {@inheritDoc}
6171
         */
6172
        @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not modified by class contract.")
6173
        public byte[] getBytes() {
6174
            return binaryRepresentation;
1✔
6175
        }
6176

6177
        /**
6178
         * {@inheritDoc}
6179
         */
6180
        public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
6181
            Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
1✔
6182
            for (DynamicType auxiliaryType : this.auxiliaryTypes) {
1✔
6183
                auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
1✔
6184
                auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
1✔
6185
            }
1✔
6186
            return auxiliaryTypes;
1✔
6187
        }
6188

6189
        /**
6190
         * {@inheritDoc}
6191
         */
6192
        public Map<TypeDescription, File> saveIn(File folder) throws IOException {
6193
            Map<TypeDescription, File> files = new HashMap<TypeDescription, File>();
1✔
6194
            File target = new File(folder, typeDescription.getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
1✔
6195
            if (target.getParentFile() != null && !target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
1✔
6196
                throw new IllegalArgumentException("Could not create directory: " + target.getParentFile());
×
6197
            }
6198
            OutputStream outputStream = new FileOutputStream(target);
1✔
6199
            try {
6200
                outputStream.write(binaryRepresentation);
1✔
6201
            } finally {
1✔
6202
                outputStream.close();
1✔
6203
            }
1✔
6204
            files.put(typeDescription, target);
1✔
6205
            for (DynamicType auxiliaryType : auxiliaryTypes) {
1✔
6206
                files.putAll(auxiliaryType.saveIn(folder));
1✔
6207
            }
1✔
6208
            return files;
1✔
6209
        }
6210

6211
        /**
6212
         * {@inheritDoc}
6213
         */
6214
        public File inject(File sourceJar, File targetJar) throws IOException {
6215
            return sourceJar.equals(targetJar)
1✔
6216
                    ? inject(sourceJar)
1✔
6217
                    : doInject(sourceJar, targetJar);
1✔
6218
        }
6219

6220
        /**
6221
         * {@inheritDoc}
6222
         */
6223
        public File inject(File jar) throws IOException {
6224
            FileSystem.getInstance().move(doInject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX)), jar);
1✔
6225
            return jar;
1✔
6226
        }
6227

6228
        /**
6229
         * Injects this dynamic type into a source jar and writes the result to the target jar.
6230
         *
6231
         * @param sourceJar The source jar.
6232
         * @param targetJar The target jar.
6233
         * @return The jar file that was written to.
6234
         * @throws IOException If an I/O error occurs.
6235
         */
6236
        private File doInject(File sourceJar, File targetJar) throws IOException {
6237
            JarInputStream inputStream = new JarInputStream(new FileInputStream(sourceJar));
1✔
6238
            try {
6239
                if (!targetJar.isFile() && !targetJar.createNewFile()) {
1✔
6240
                    throw new IllegalArgumentException("Could not create file: " + targetJar);
×
6241
                }
6242
                Manifest manifest = inputStream.getManifest();
1✔
6243
                JarOutputStream outputStream = manifest == null
1✔
6244
                        ? new JarOutputStream(new FileOutputStream(targetJar))
6245
                        : new JarOutputStream(new FileOutputStream(targetJar), manifest);
6246
                try {
6247
                    Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
1✔
6248
                    Map<String, byte[]> files = new HashMap<String, byte[]>();
1✔
6249
                    for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
1✔
6250
                        files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
1✔
6251
                    }
1✔
6252
                    files.put(typeDescription.getInternalName() + CLASS_FILE_EXTENSION, binaryRepresentation);
1✔
6253
                    JarEntry jarEntry;
6254
                    while ((jarEntry = inputStream.getNextJarEntry()) != null) {
1✔
6255
                        byte[] replacement = files.remove(jarEntry.getName());
1✔
6256
                        if (replacement == null) {
1✔
6257
                            outputStream.putNextEntry(jarEntry);
1✔
6258
                            byte[] buffer = new byte[BUFFER_SIZE];
1✔
6259
                            int index;
6260
                            while ((index = inputStream.read(buffer)) != END_OF_FILE) {
1✔
6261
                                outputStream.write(buffer, FROM_BEGINNING, index);
1✔
6262
                            }
6263
                        } else {
1✔
6264
                            outputStream.putNextEntry(new JarEntry(jarEntry.getName()));
1✔
6265
                            outputStream.write(replacement);
1✔
6266
                        }
6267
                        inputStream.closeEntry();
1✔
6268
                        outputStream.closeEntry();
1✔
6269
                    }
1✔
6270
                    for (Map.Entry<String, byte[]> entry : files.entrySet()) {
1✔
6271
                        outputStream.putNextEntry(new JarEntry(entry.getKey()));
1✔
6272
                        outputStream.write(entry.getValue());
1✔
6273
                        outputStream.closeEntry();
1✔
6274
                    }
1✔
6275
                } finally {
1✔
6276
                    outputStream.close();
1✔
6277
                }
1✔
6278
            } finally {
1✔
6279
                inputStream.close();
1✔
6280
            }
1✔
6281
            return targetJar;
1✔
6282
        }
6283

6284
        /**
6285
         * {@inheritDoc}
6286
         */
6287
        public File toJar(File file) throws IOException {
6288
            Manifest manifest = new Manifest();
1✔
6289
            manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
1✔
6290
            return toJar(file, manifest);
1✔
6291
        }
6292

6293
        /**
6294
         * {@inheritDoc}
6295
         */
6296
        public File toJar(File file, Manifest manifest) throws IOException {
6297
            if (!file.isFile() && !file.createNewFile()) {
1✔
6298
                throw new IllegalArgumentException("Could not create file: " + file);
×
6299
            }
6300
            JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(file), manifest);
1✔
6301
            try {
6302
                for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
1✔
6303
                    outputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
1✔
6304
                    outputStream.write(entry.getValue());
1✔
6305
                    outputStream.closeEntry();
1✔
6306
                }
1✔
6307
                outputStream.putNextEntry(new JarEntry(typeDescription.getInternalName() + CLASS_FILE_EXTENSION));
1✔
6308
                outputStream.write(binaryRepresentation);
1✔
6309
                outputStream.closeEntry();
1✔
6310
            } finally {
1✔
6311
                outputStream.close();
1✔
6312
            }
1✔
6313
            return file;
1✔
6314
        }
6315

6316
        /**
6317
         * A default implementation of an unloaded dynamic type.
6318
         *
6319
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6320
         *            type itself, an interface or the direct super class.
6321
         */
6322
        @HashCodeAndEqualsPlugin.Enhance
6323
        public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
6324

6325
            /**
6326
             * The type resolution strategy to use for initializing the dynamic type.
6327
             */
6328
            private final TypeResolutionStrategy.Resolved typeResolutionStrategy;
6329

6330
            /**
6331
             * Creates a new unloaded representation of a dynamic type.
6332
             *
6333
             * @param typeDescription        A description of this dynamic type.
6334
             * @param binaryRepresentation   An array of byte of the binary representation of this dynamic type.
6335
             * @param loadedTypeInitializer  The type initializer of this dynamic type.
6336
             * @param auxiliaryTypes         The auxiliary types that are required for this dynamic type.
6337
             * @param typeResolutionStrategy The type resolution strategy to use for initializing the dynamic type.
6338
             */
6339
            public Unloaded(TypeDescription typeDescription,
6340
                            byte[] binaryRepresentation,
6341
                            LoadedTypeInitializer loadedTypeInitializer,
6342
                            List<? extends DynamicType> auxiliaryTypes,
6343
                            TypeResolutionStrategy.Resolved typeResolutionStrategy) {
6344
                super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
1✔
6345
                this.typeResolutionStrategy = typeResolutionStrategy;
1✔
6346
            }
1✔
6347

6348
            /**
6349
             * {@inheritDoc}
6350
             */
6351
            public DynamicType.Loaded<T> load(@MaybeNull ClassLoader classLoader) {
6352
                if (classLoader instanceof InjectionClassLoader && !((InjectionClassLoader) classLoader).isSealed()) {
1✔
6353
                    return load((InjectionClassLoader) classLoader, InjectionClassLoader.Strategy.INSTANCE);
1✔
6354
                } else {
6355
                    return load(classLoader, ClassLoadingStrategy.Default.WRAPPER);
1✔
6356
                }
6357
            }
6358

6359
            /**
6360
             * {@inheritDoc}
6361
             */
6362
            public <S extends ClassLoader> DynamicType.Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
6363
                return new Default.Loaded<T>(typeDescription,
1✔
6364
                        binaryRepresentation,
6365
                        loadedTypeInitializer,
6366
                        auxiliaryTypes,
6367
                        typeResolutionStrategy.initialize(this, classLoader, classLoadingStrategy));
1✔
6368
            }
6369

6370
            /**
6371
             * {@inheritDoc}
6372
             */
6373
            public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
6374
                return include(Arrays.asList(dynamicType));
1✔
6375
            }
6376

6377
            /**
6378
             * {@inheritDoc}
6379
             */
6380
            public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
6381
                return new Default.Unloaded<T>(typeDescription,
1✔
6382
                        binaryRepresentation,
6383
                        loadedTypeInitializer,
6384
                        CompoundList.of(auxiliaryTypes, dynamicType),
1✔
6385
                        typeResolutionStrategy);
6386
            }
6387
        }
6388

6389
        /**
6390
         * A default implementation of a loaded dynamic type.
6391
         *
6392
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6393
         *            type itself, an interface or the direct super class.
6394
         */
6395
        @HashCodeAndEqualsPlugin.Enhance
6396
        protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
6397

6398
            /**
6399
             * The loaded types for the given loaded dynamic type.
6400
             */
6401
            private final Map<TypeDescription, Class<?>> loadedTypes;
6402

6403
            /**
6404
             * Creates a new representation of a loaded dynamic type.
6405
             *
6406
             * @param typeDescription       A description of this dynamic type.
6407
             * @param typeByte              An array of byte of the binary representation of this dynamic type.
6408
             * @param loadedTypeInitializer The type initializer of this dynamic type.
6409
             * @param auxiliaryTypes        The auxiliary types that are required for this dynamic type.
6410
             * @param loadedTypes           A map of loaded types for this dynamic type and all its auxiliary types.
6411
             */
6412
            protected Loaded(TypeDescription typeDescription,
6413
                             byte[] typeByte,
6414
                             LoadedTypeInitializer loadedTypeInitializer,
6415
                             List<? extends DynamicType> auxiliaryTypes,
6416
                             Map<TypeDescription, Class<?>> loadedTypes) {
6417
                super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
1✔
6418
                this.loadedTypes = loadedTypes;
1✔
6419
            }
1✔
6420

6421
            /**
6422
             * {@inheritDoc}
6423
             */
6424
            @SuppressWarnings("unchecked")
6425
            public Class<? extends T> getLoaded() {
6426
                return (Class<? extends T>) loadedTypes.get(typeDescription);
1✔
6427
            }
6428

6429
            /**
6430
             * {@inheritDoc}
6431
             */
6432
            public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
6433
                Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
6434
                loadedAuxiliaryTypes.remove(typeDescription);
1✔
6435
                return loadedAuxiliaryTypes;
1✔
6436
            }
6437

6438
            /**
6439
             * {@inheritDoc}
6440
             */
6441
            public Map<TypeDescription, Class<?>> getAllLoaded() {
6442
                return new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
6443
            }
6444
        }
6445
    }
6446
}
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

© 2025 Coveralls, Inc