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

raphw / byte-buddy / #809

02 Nov 2025 10:24PM UTC coverage: 84.035% (-0.6%) from 84.614%
#809

push

raphw
Clean up code.

5 of 7 new or added lines in 4 files covered. (71.43%)

958 existing lines in 10 files now uncovered.

29803 of 35465 relevant lines covered (84.03%)

0.84 hits per line

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

63.19
/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/DynamicType.java
1
/*
2
 * Copyright 2014 - Present Rafael Winterhalter
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package net.bytebuddy.dynamic;
17

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

364
        /**
365
         * Includes a module definition in this class file. This is normally only meaningful for classes named {@code module-info}.
366
         *
367
         * @param name                 The name of the module.
368
         * @param modifierContributors The modifiers of the module. Those modifiers will override the modifiers of the class file.
369
         * @return A new builder that is equal to this builder but which adds the specified module information.
370
         */
371
        ModuleDefinition<T> module(String name, ModifierContributor.ForModule... modifierContributors);
372

373
        /**
374
         * Includes a module definition in this class file. This is normally only meaningful for classes named {@code module-info}.
375
         *
376
         * @param name                 The name of the module.
377
         * @param modifierContributors The modifiers of the module. Those modifiers will override the modifiers of the class file.
378
         * @return A new builder that is equal to this builder but which adds the specified module information.
379
         */
380
        ModuleDefinition<T> module(String name, Collection<? extends ModifierContributor.ForModule> modifierContributors);
381

382
        /**
383
         * Includes a module definition in this class file. This is normally only meaningful for classes named {@code module-info}.
384
         *
385
         * @param name      The name of the module.
386
         * @param modifiers The modifiers of the module. Those modifiers will override the modifiers of the class file.
387
         * @return A new builder that is equal to this builder but which adds the specified module information.
388
         */
389
        ModuleDefinition<T> module(String name, int modifiers);
390

391
        /**
392
         * <p>
393
         * Defines this type as a top-level type that is not declared by another type or enclosed by another member.
394
         * </p>
395
         * <p>
396
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
397
         * </p>
398
         * <p>
399
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
400
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
401
         * consistent among the definitions of connected types.
402
         * </p>
403
         *
404
         * @return A new builder that is equal to this builder but without any declaration of a declared or enclosed type.
405
         */
406
        Builder<T> topLevelType();
407

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

427
        /**
428
         * <p>
429
         * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is
430
         * defined as a local type.
431
         * </p>
432
         * <p>
433
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
434
         * </p>
435
         * <p>
436
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
437
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
438
         * consistent among the definitions of connected types.
439
         * </p>
440
         *
441
         * @param type The type to declare as the built type's outer type.
442
         * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
443
         */
444
        InnerTypeDefinition.ForType<T> innerTypeOf(TypeDescription type);
445

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

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

484
        /**
485
         * <p>
486
         * Defines this type as an inner type that was declared within the supplied method or constructor. Without any additional configuration,
487
         * the type declaration is defined as a local type.
488
         * </p>
489
         * <p>
490
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
491
         * </p>
492
         * <p>
493
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
494
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
495
         * consistent among the definitions of connected types.
496
         * </p>
497
         *
498
         * @param methodDescription The method or constructor to declare as the built type's declaring method.
499
         * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method or constructor.
500
         */
501
        InnerTypeDefinition<T> innerTypeOf(MethodDescription.InDefinedShape methodDescription);
502

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

523
        /**
524
         * <p>
525
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
526
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
527
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
528
         * </p>
529
         * <p>
530
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
531
         * </p>
532
         * <p>
533
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
534
         * declared types about any nesting of a declaration. 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 types being declared.
539
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
540
         */
541
        Builder<T> declaredTypes(TypeDescription... type);
542

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

563
        /**
564
         * <p>
565
         * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
566
         * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
567
         * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
568
         * </p>
569
         * <p>
570
         * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
571
         * </p>
572
         * <p>
573
         * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
574
         * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
575
         * consistent among the definitions of connected types.
576
         * </p>
577
         *
578
         * @param types The types being declared.
579
         * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
580
         */
581
        Builder<T> declaredTypes(Collection<? extends TypeDescription> types);
582

583
        /**
584
         * <p>
585
         * Defines this type as self-hosted, i.e. as only being a nest mate of itself.
586
         * </p>
587
         * <p>
588
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
589
         * </p>
590
         * <p>
591
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
592
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
593
         * consistent among the definitions of connected types.
594
         * </p>
595
         *
596
         * @return A new builder that is equal to this builder but where the built type is a self-hosted nest mate.
597
         */
598
        Builder<T> noNestMate();
599

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

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

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

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

672
        /**
673
         * <p>
674
         * Defines this type as a nest host for the supplied types.
675
         * </p>
676
         * <p>
677
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
678
         * </p>
679
         * <p>
680
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
681
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
682
         * consistent among the definitions of connected types.
683
         * </p>
684
         *
685
         * @param types The nest members.
686
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
687
         */
688
        Builder<T> nestMembers(List<? extends Class<?>> types);
689

690
        /**
691
         * <p>
692
         * Defines this type as a nest host for the supplied types.
693
         * </p>
694
         * <p>
695
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
696
         * </p>
697
         * <p>
698
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
699
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
700
         * consistent among the definitions of connected types.
701
         * </p>
702
         *
703
         * @param types The nest members.
704
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
705
         */
706
        Builder<T> nestMembers(Collection<? extends TypeDescription> types);
707

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

717
        /**
718
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
719
         * this type was not previously sealed, only the supplied subclasses are permitted.
720
         *
721
         * @param type The permitted subclasses.
722
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
723
         */
724
        Builder<T> permittedSubclass(TypeDescription... type);
725

726
        /**
727
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
728
         * this type was not previously sealed, only the supplied subclasses are permitted.
729
         *
730
         * @param types The permitted subclasses.
731
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
732
         */
733
        Builder<T> permittedSubclass(List<? extends Class<?>> types);
734

735
        /**
736
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
737
         * this type was not previously sealed, only the supplied subclasses are permitted.
738
         *
739
         * @param types The permitted subclasses.
740
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
741
         */
742
        Builder<T> permittedSubclass(Collection<? extends TypeDescription> types);
743

744
        /**
745
         * Unseales this type.
746
         *
747
         * @return A new builder that is equal to this builder but where the built type does not restrain its permitted subclasses.
748
         */
749
        Builder<T> unsealed();
750

751
        /**
752
         * Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
753
         * any type of meta data to a type, not only Java {@link Annotation}s.
754
         *
755
         * @param typeAttributeAppender The type attribute appender to apply.
756
         * @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
757
         */
758
        Builder<T> attribute(TypeAttributeAppender typeAttributeAppender);
759

760
        /**
761
         * Annotates the instrumented type with the supplied annotations.
762
         *
763
         * @param annotation The annotations to add to the instrumented type.
764
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
765
         */
766
        Builder<T> annotateType(Annotation... annotation);
767

768
        /**
769
         * Annotates the instrumented type with the supplied annotations.
770
         *
771
         * @param annotations The annotations to add to the instrumented type.
772
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
773
         */
774
        Builder<T> annotateType(List<? extends Annotation> annotations);
775

776
        /**
777
         * Annotates the instrumented type with the supplied annotations.
778
         *
779
         * @param annotation The annotations to add to the instrumented type.
780
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
781
         */
782
        Builder<T> annotateType(AnnotationDescription... annotation);
783

784
        /**
785
         * Annotates the instrumented type with the supplied annotations.
786
         *
787
         * @param annotations The annotations to add to the instrumented type.
788
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
789
         */
790
        Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
791

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

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

824
        /**
825
         * <p>
826
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
827
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
828
         * are explicitly ignored.
829
         * </p>
830
         * <p>
831
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
832
         * implemented as raw types if they declare type variables or an owner type.
833
         * </p>
834
         *
835
         * @param interfaceType The interface types to implement.
836
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
837
         */
838
        MethodDefinition.ImplementationDefinition.Optional<T> implement(TypeDefinition... interfaceType);
839

840
        /**
841
         * <p>
842
         * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
843
         * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
844
         * are explicitly ignored.
845
         * </p>
846
         * <p>
847
         * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
848
         * implemented as raw types if they declare type variables or an owner type.
849
         * </p>
850
         *
851
         * @param interfaceTypes The interface types to implement.
852
         * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
853
         */
854
        MethodDefinition.ImplementationDefinition.Optional<T> implement(Collection<? extends TypeDefinition> interfaceTypes);
855

856
        /**
857
         * <p>
858
         * Executes the supplied byte code appender within the beginning of the instrumented type's type initializer. The
859
         * supplied byte code appender <b>must not return</b> from the method. If several byte code appenders are supplied,
860
         * they are executed within their application order.
861
         * </p>
862
         * <p>
863
         * This method should only be used for preparing an instrumented type with a specific configuration. Normally,
864
         * a byte code appender is applied via Byte Buddy's standard API by invoking {@link Builder#invokable(ElementMatcher)}
865
         * using the {@link net.bytebuddy.matcher.ElementMatchers#isTypeInitializer()} matcher.
866
         * </p>
867
         *
868
         * @param byteCodeAppender The byte code appender to execute within the instrumented type's type initializer.
869
         * @return A new builder that is equal to this builder but with the supplied byte code appender being executed within
870
         * the instrumented type's type initializer.
871
         */
872
        Builder<T> initializer(ByteCodeAppender byteCodeAppender);
873

874
        /**
875
         * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
876
         * type initializers are supplied, each loaded type initializer is executed in its registration order.
877
         *
878
         * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
879
         * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
880
         * loading the instrumented type.
881
         */
882
        Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
883

884
        /**
885
         * Explicitly requires another dynamic type for the creation of this type.
886
         *
887
         * @param type                 The type to require.
888
         * @param binaryRepresentation The type's binary representation.
889
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
890
         */
891
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation);
892

893
        /**
894
         * Explicitly requires another dynamic type for the creation of this type.
895
         *
896
         * @param type                 The type to require.
897
         * @param binaryRepresentation The type's binary representation.
898
         * @param typeInitializer      The type's loaded type initializer.
899
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
900
         */
901
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
902

903
        /**
904
         * Explicitly requires other dynamic types for the creation of this type.
905
         *
906
         * @param auxiliaryType The required dynamic types.
907
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
908
         */
909
        Builder<T> require(DynamicType... auxiliaryType);
910

911
        /**
912
         * Explicitly requires other dynamic types for the creation of this type.
913
         *
914
         * @param auxiliaryTypes The required dynamic types.
915
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
916
         */
917
        Builder<T> require(Collection<DynamicType> auxiliaryTypes);
918

919
        /**
920
         * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
921
         *
922
         * @param symbol The type variable's symbol.
923
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
924
         */
925
        TypeVariableDefinition<T> typeVariable(String symbol);
926

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

937
        /**
938
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
939
         *
940
         * @param symbol The type variable's symbol.
941
         * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
942
         *               should be equal to the currently instrumented type.
943
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
944
         */
945
        TypeVariableDefinition<T> typeVariable(String symbol, List<? extends Type> bounds);
946

947
        /**
948
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
949
         *
950
         * @param symbol The type variable's symbol.
951
         * @param bound  The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
952
         *               should be equal to the currently instrumented type.
953
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
954
         */
955
        TypeVariableDefinition<T> typeVariable(String symbol, TypeDefinition... bound);
956

957
        /**
958
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
959
         *
960
         * @param symbol The type variable's symbol.
961
         * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
962
         *               should be equal to the currently instrumented type.
963
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
964
         */
965
        TypeVariableDefinition<T> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
966

967
        /**
968
         * Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
969
         *
970
         * @param matcher     The matcher to decide what type variables to transform.
971
         * @param transformer The transformer to apply to the matched type variables.
972
         * @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
973
         */
974
        Builder<T> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer);
975

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

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

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

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

1024
        /**
1025
         * Defines the specified field as a field of the built dynamic type.
1026
         *
1027
         * @param name                 The name of the field.
1028
         * @param type                 The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
1029
         *                             should be equal to the currently instrumented type.
1030
         * @param modifierContributors The modifiers of the field.
1031
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1032
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1033
         */
1034
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors);
1035

1036
        /**
1037
         * Defines the specified field as a field of the built dynamic type.
1038
         *
1039
         * @param name      The name of the field.
1040
         * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
1041
         *                  should be equal to the currently instrumented type.
1042
         * @param modifiers The modifiers of the field.
1043
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1044
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1045
         */
1046
        FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, int modifiers);
1047

1048
        /**
1049
         * Defines a field that is similar to the supplied field but without copying any annotations on the field.
1050
         *
1051
         * @param field The field to imitate as a field of the instrumented type.
1052
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1053
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1054
         */
1055
        FieldDefinition.Optional.Valuable<T> define(Field field);
1056

1057
        /**
1058
         * Defines a field that is similar to the supplied field but without copying any annotations on the field.
1059
         *
1060
         * @param field The field to imitate as a field of the instrumented type.
1061
         * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
1062
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1063
         */
1064
        FieldDefinition.Optional.Valuable<T> define(FieldDescription field);
1065

1066
        /**
1067
         * Defines a private, static, final field for a serial version UID of the given value.
1068
         *
1069
         * @param serialVersionUid The serial version UID to define as a value.
1070
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
1071
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1072
         */
1073
        FieldDefinition.Optional<T> serialVersionUid(long serialVersionUid);
1074

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

1097
        /**
1098
         * <p>
1099
         * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
1100
         * default value, annotations or custom attributes. Using a latent matcher gives opportunity to resolve an
1101
         * {@link ElementMatcher} based on the instrumented type before applying the matcher.
1102
         * </p>
1103
         * <p>
1104
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1105
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1106
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1107
         * altered, annotation retention must be disabled.
1108
         * </p>
1109
         * <p>
1110
         * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
1111
         * over the previous definition, i.e. the previous field definition is no longer applied.
1112
         * </p>
1113
         *
1114
         * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
1115
         * @return A builder that allows for changing a field's definition.
1116
         */
1117
        @SuppressWarnings("overloads")
1118
        FieldDefinition.Valuable<T> field(LatentMatcher<? super FieldDescription> matcher);
1119

1120
        /**
1121
         * <p>
1122
         * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1123
         * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1124
         * </p>
1125
         * <p>
1126
         * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1127
         * is to be ignored, this matcher is no longer executed.
1128
         * </p>
1129
         *
1130
         * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1131
         * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1132
         * instrumentation.
1133
         */
1134
        @SuppressWarnings("overloads")
1135
        Builder<T> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods);
1136

1137
        /**
1138
         * <p>
1139
         * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1140
         * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1141
         * Using a latent matcher gives opportunity to resolve an {@link ElementMatcher} based on the instrumented type before applying the
1142
         * matcher.
1143
         * </p>
1144
         * <p>
1145
         * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1146
         * is to be ignored, this matcher is no longer executed.
1147
         * </p>
1148
         *
1149
         * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1150
         * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1151
         * instrumentation.
1152
         */
1153
        @SuppressWarnings("overloads")
1154
        Builder<T> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods);
1155

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

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

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

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

1204
        /**
1205
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1206
         * type variables can be defined in subsequent steps.
1207
         *
1208
         * @param name                 The name of the method.
1209
         * @param returnType           The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1210
         *                             should be equal to the currently instrumented type.
1211
         * @param modifierContributors The method's modifiers.
1212
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1213
         */
1214
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1215

1216
        /**
1217
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1218
         * type variables can be defined in subsequent steps.
1219
         *
1220
         * @param name       The name of the method.
1221
         * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1222
         *                   should be equal to the currently instrumented type.
1223
         * @param modifiers  The method's modifiers.
1224
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1225
         */
1226
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, int modifiers);
1227

1228
        /**
1229
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1230
         * type variables can be defined in subsequent steps.
1231
         *
1232
         * @param modifierContributor The constructor's modifiers.
1233
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1234
         */
1235
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(ModifierContributor.ForMethod... modifierContributor);
1236

1237
        /**
1238
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1239
         * type variables can be defined in subsequent steps.
1240
         *
1241
         * @param modifierContributors The constructor's modifiers.
1242
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1243
         */
1244
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1245

1246
        /**
1247
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1248
         * type variables can be defined in subsequent steps.
1249
         *
1250
         * @param modifiers The constructor's modifiers.
1251
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1252
         */
1253
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(int modifiers);
1254

1255
        /**
1256
         * Defines a method that is similar to the supplied method but without copying any annotations of the method or method parameters.
1257
         *
1258
         * @param method The method to imitate as a method of the instrumented type.
1259
         * @return A builder that allows for defining an implementation for the method.
1260
         */
1261
        MethodDefinition.ImplementationDefinition<T> define(Method method);
1262

1263
        /**
1264
         * Defines a constructor that is similar to the supplied constructor but without copying any annotations of the constructor or
1265
         * constructor parameters.
1266
         *
1267
         * @param constructor The constructor to imitate as a method of the instrumented type.
1268
         * @return A builder that allows for defining an implementation for the constructor.
1269
         */
1270
        MethodDefinition.ImplementationDefinition<T> define(Constructor<?> constructor);
1271

1272
        /**
1273
         * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
1274
         * the method/constructor or method/constructor parameters.
1275
         *
1276
         * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
1277
         * @return A builder that allows for defining an implementation for the method or constructor.
1278
         */
1279
        MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
1280

1281
        /**
1282
         * Defines a Java bean property with the specified name.
1283
         *
1284
         * @param name The name of the property.
1285
         * @param type The property type.
1286
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1287
         */
1288
        FieldDefinition.Optional<T> defineProperty(String name, Type type);
1289

1290
        /**
1291
         * Defines a Java bean property with the specified name.
1292
         *
1293
         * @param name     The name of the property.
1294
         * @param type     The property type.
1295
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1296
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1297
         */
1298
        FieldDefinition.Optional<T> defineProperty(String name, Type type, boolean readOnly);
1299

1300
        /**
1301
         * Defines a Java bean property with the specified name.
1302
         *
1303
         * @param name The name of the property.
1304
         * @param type The property type.
1305
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1306
         */
1307
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type);
1308

1309
        /**
1310
         * Defines a Java bean property with the specified name.
1311
         *
1312
         * @param name     The name of the property.
1313
         * @param type     The property type.
1314
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1315
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1316
         */
1317
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type, boolean readOnly);
1318

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

1344
        /**
1345
         * <p>
1346
         * Matches a constructor that is already declared by the instrumented type. This gives opportunity to change that constructor's
1347
         * implementation, default value, annotations or custom attributes.
1348
         * </p>
1349
         * <p>
1350
         * When a type is redefined or rebased, any annotations that the constructor declared previously is preserved
1351
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1352
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1353
         * altered, annotation retention must be disabled.
1354
         * </p>
1355
         * <p>
1356
         * If a constructor is already matched by a previously specified matcher, the new constructor definition gets precedence
1357
         * over the previous definition, i.e. the previous constructor definition is no longer applied.
1358
         * </p>
1359
         * <p>
1360
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1361
         * </p>
1362
         *
1363
         * @param matcher The matcher that determines what constructors are affected by the subsequent specification.
1364
         * @return A builder that allows for changing a method's or constructor's definition.
1365
         */
1366
        MethodDefinition.ImplementationDefinition<T> constructor(ElementMatcher<? super MethodDescription> matcher);
1367

1368
        /**
1369
         * <p>
1370
         * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1371
         * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1372
         * or custom attributes. It is also possible to make a method abstract.
1373
         * </p>
1374
         * <p>
1375
         * When a type is redefined or rebased, any annotations that the method or constructor 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 method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1382
         * over the previous definition, i.e. the previous definition is no longer applied.
1383
         * </p>
1384
         * <p>
1385
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1386
         * </p>
1387
         * <p>
1388
         * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1389
         * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1390
         * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1391
         * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1392
         * </p>
1393
         *
1394
         * @param matcher The matcher that determines what methods or constructors are affected by the subsequent specification.
1395
         * @return A builder that allows for changing a method's or constructor's definition.
1396
         */
1397
        @SuppressWarnings("overloads")
1398
        MethodDefinition.ImplementationDefinition<T> invokable(ElementMatcher<? super MethodDescription> matcher);
1399

1400
        /**
1401
         * <p>
1402
         * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1403
         * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1404
         * or custom attributes. It is also possible to make a method abstract. Using a latent matcher gives opportunity
1405
         * to resolve an {@link ElementMatcher} based on the instrumented type before applying the matcher.
1406
         * </p>
1407
         * <p>
1408
         * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1409
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1410
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1411
         * altered, annotation retention must be disabled.
1412
         * </p>
1413
         * <p>
1414
         * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1415
         * over the previous definition, i.e. the previous definition is no longer applied.
1416
         * </p>
1417
         * <p>
1418
         * Note that the specified definition does never apply for methods that are explicitly ignored.
1419
         * </p>
1420
         * <p>
1421
         * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1422
         * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1423
         * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1424
         * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1425
         * </p>
1426
         *
1427
         * @param matcher The matcher that determines what declared methods or constructors are affected by the subsequent specification.
1428
         * @return A builder that allows for changing a method's or constructor's definition.
1429
         */
1430
        @SuppressWarnings("overloads")
1431
        MethodDefinition.ImplementationDefinition<T> invokable(LatentMatcher<? super MethodDescription> matcher);
1432

1433
        /**
1434
         * Implements {@link Object#hashCode()} and {@link Object#equals(Object)} methods for the instrumented type if those
1435
         * methods are not declared as {@code final} by a super class. The implementations do not consider any implementations
1436
         * of a super class and compare a class field by field without considering synthetic fields.
1437
         *
1438
         * @return A new type builder that defines {@link Object#hashCode()} and {@link Object#equals(Object)} methods accordingly.
1439
         */
1440
        Builder<T> withHashCodeEquals();
1441

1442
        /**
1443
         * Implements a {@link Object#toString()} method for the instrumented type if such a method is not declared as {@code final}
1444
         * by a super class. The implementation prefixes the string with the simple class name and prints each non-synthetic field's
1445
         * value after the field's name.
1446
         *
1447
         * @return A new type builder that defines {@link Object#toString()} method accordingly.
1448
         */
1449
        Builder<T> withToString();
1450

1451
        /**
1452
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1453
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1454
         *
1455
         * @param name The record component's name.
1456
         * @param type The record component's type.
1457
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1458
         */
1459
        RecordComponentDefinition.Optional<T> defineRecordComponent(String name, Type type);
1460

1461
        /**
1462
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1463
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1464
         *
1465
         * @param name The record component's name.
1466
         * @param type The record component's type.
1467
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1468
         */
1469
        RecordComponentDefinition.Optional<T> defineRecordComponent(String name, TypeDefinition type);
1470

1471
        /**
1472
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1473
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1474
         *
1475
         * @param recordComponentDescription A description of the record component to immitate.
1476
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1477
         */
1478
        RecordComponentDefinition.Optional<T> define(RecordComponentDescription recordComponentDescription);
1479

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

1502
        /**
1503
         * <p>
1504
         * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1505
         * record component's annotations or custom attributes.
1506
         * </p>
1507
         * <p>
1508
         * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1509
         * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1510
         * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1511
         * altered, annotation retention must be disabled.
1512
         * </p>
1513
         * <p>
1514
         * If a record component is already matched by a previously specified record component matcher, the new record component
1515
         * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1516
         * </p>
1517
         *
1518
         * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1519
         * @return A builder that allows for changing a record component's definition.
1520
         */
1521
        @SuppressWarnings("overloads")
1522
        RecordComponentDefinition<T> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher);
1523

1524
        /**
1525
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder, using a
1526
         * default {@link TypePool}. A wrapper might not apply all features that are normally applied by Byte
1527
         * Buddy, if those features require control of the class loading life cycle. Neither does a wrapper define
1528
         * auxiliary types. It is therefore recommended to use {@link Implementation.Context.Disabled}.
1529
         *
1530
         * @param classVisitor The class visitor to wrap.
1531
         * @return A new class visitor that wraps a representation of this dynamic type.
1532
         */
1533
        ContextClassVisitor wrap(ClassVisitor classVisitor);
1534

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

1548
        /**
1549
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder. A wrapper
1550
         * might not apply all features that are normally applied by Byte Buddy, if those features require control of
1551
         * the class loading life cycle. Neither does a wrapper define auxiliary types.  It is therefore recommended
1552
         * to use {@link Implementation.Context.Disabled}.
1553
         *
1554
         * @param classVisitor The class visitor to wrap.
1555
         * @param typePool     A type pool that is used for computing stack map frames by the underlying class writer, if required.
1556
         * @return A new class visitor that wraps a representation of this dynamic type.
1557
         */
1558
        ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool);
1559

1560
        /**
1561
         * Wraps a class visitor with the configuration that is represented by this dynamic type builder. A wrapper
1562
         * might not apply all features that are normally applied by Byte Buddy, if those features require control
1563
         * of the class loading life cycle. Neither does a wrapper define auxiliary types.  It is therefore
1564
         * recommended to use {@link Implementation.Context.Disabled}.
1565
         *
1566
         * @param classVisitor The class visitor to wrap.
1567
         * @param typePool     A type pool that is used for computing stack map frames by the underlying class writer, if required.
1568
         * @param writerFlags  The ASM writer flags to apply.
1569
         * @param readerFlags  The ASM reader flags to apply.
1570
         * @return A new class visitor that wraps a representation of this dynamic type.
1571
         */
1572
        ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags);
1573

1574
        /**
1575
         * <p>
1576
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1577
         * </p>
1578
         * <p>
1579
         * Other than {@link DynamicType.Builder#make(TypePool)}, this method supplies a context-dependant type pool to the underlying class writer.
1580
         * Supplying a type pool only makes sense if custom byte code is created by adding a custom {@link AsmVisitorWrapper} where ASM might be
1581
         * required to compute stack map frames by processing information over any mentioned type's class hierarchy.
1582
         * </p>
1583
         * <p>
1584
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1585
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1586
         * executing the initializer must rely on such an initializer.
1587
         * </p>
1588
         *
1589
         * @return An unloaded dynamic type representing the type specified by this builder.
1590
         */
1591
        DynamicType.Unloaded<T> make();
1592

1593
        /**
1594
         * <p>
1595
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1596
         * </p>
1597
         * <p>
1598
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1599
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1600
         * executing the initializer must rely on such an initializer.
1601
         * </p>
1602
         *
1603
         * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1604
         * @return An unloaded dynamic type representing the type specified by this builder.
1605
         */
1606
        DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy);
1607

1608
        /**
1609
         * <p>
1610
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1611
         * </p>
1612
         * <p>
1613
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1614
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1615
         * executing the initializer must rely on such an initializer.
1616
         * </p>
1617
         *
1618
         * @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
1619
         * @return An unloaded dynamic type representing the type specified by this builder.
1620
         */
1621
        DynamicType.Unloaded<T> make(TypePool typePool);
1622

1623
        /**
1624
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1625
         *
1626
         * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1627
         * @param typePool               A type pool that is used for computing stack map frames by the underlying class writer, if required.
1628
         * @return An unloaded dynamic type representing the type specified by this builder.
1629
         */
1630
        DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool);
1631

1632
        /**
1633
         * Returns a {@link TypeDescription} for the currently built type.
1634
         *
1635
         * @return A {@link TypeDescription} for the currently built type.
1636
         */
1637
        TypeDescription toTypeDescription();
1638

1639
        /**
1640
         * A specification of a Java module.
1641
         *
1642
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1643
         */
1644
        interface ModuleDefinition<S> extends Builder<S> {
1645

1646
            /**
1647
             * Specifies the version of the module being defined.
1648
             *
1649
             * @param version The version of the module or {@code null} if no version is to be specified.
1650
             * @return A new builder that is equal to this builder but with the given version specification.
1651
             */
1652
            ModuleDefinition<S> version(@MaybeNull String version);
1653

1654
            /**
1655
             * Specifies the main class of the module being defined.
1656
             *
1657
             * @param type The main class of the module or {@code null} if no main class is to be specified.
1658
             * @return A new builder that is equal to this builder but with the given main class specification.
1659
             */
1660
            ModuleDefinition<S> mainClass(@MaybeNull Class<?> type);
1661

1662
            /**
1663
             * Specifies the main class of the module being defined.
1664
             *
1665
             * @param typeDescription The main class of the module or {@code null} if no main class is to be specified.
1666
             * @return A new builder that is equal to this builder but with the given main class specification.
1667
             */
1668
            ModuleDefinition<S> mainClass(@MaybeNull TypeDescription typeDescription);
1669

1670
            /**
1671
             * Specifies the main class of the module being defined.
1672
             *
1673
             * @param name The name of the main class of the module or {@code null} if no main class is to be specified.
1674
             * @return A new builder that is equal to this builder but with the given main class specification.
1675
             */
1676
            ModuleDefinition<S> mainClass(@MaybeNull String name);
1677

1678
            /**
1679
             * Specifies the packages that are contained within the module being defined.
1680
             *
1681
             * @param aPackage The names of the packages contained within the module.
1682
             * @return A new builder that is equal to this builder but with the given package specifications.
1683
             */
1684
            ModuleDefinition<S> packages(String... aPackage);
1685

1686
            /**
1687
             * Specifies the packages that are contained within the module being defined.
1688
             *
1689
             * @param packages The names of the packages contained within the module.
1690
             * @return A new builder that is equal to this builder but with the given package specifications.
1691
             */
1692
            ModuleDefinition<S> packages(Collection<String> packages);
1693

1694
            /**
1695
             * Specifies the modules that are required by the module being defined.
1696
             *
1697
             * @param module The names of the modules that are required.
1698
             * @return A new builder that is equal to this builder but with the given module requirements.
1699
             */
1700
            ModuleDefinition<S> requires(String... module);
1701

1702
            /**
1703
             * Specifies the modules that are required by the module being defined.
1704
             *
1705
             * @param modules The names of the modules that are required.
1706
             * @return A new builder that is equal to this builder but with the given module requirements.
1707
             */
1708
            ModuleDefinition<S> requires(Collection<String> modules);
1709

1710
            /**
1711
             * Specifies a module requirement with additional modifiers.
1712
             *
1713
             * @param module The name of the module that is required.
1714
             * @param modifierContributor The modifiers to apply to the module requirement.
1715
             * @return A builder for defining the module requirement.
1716
             */
1717
            RequiresDefinition<S> require(String module, ModifierContributor.ForModule.OfRequire... modifierContributor);
1718

1719
            /**
1720
             * Specifies a module requirement with additional modifiers.
1721
             *
1722
             * @param module The name of the module that is required.
1723
             * @param modifierContributors The modifiers to apply to the module requirement.
1724
             * @return A builder for defining the module requirement.
1725
             */
1726
            RequiresDefinition<S> require(String module, Collection<? extends ModifierContributor.ForModule.OfRequire> modifierContributors);
1727

1728
            /**
1729
             * Specifies a module requirement with explicit modifiers.
1730
             *
1731
             * @param module The name of the module that is required.
1732
             * @param modifiers The modifiers to apply to the module requirement.
1733
             * @return A builder for defining the module requirement.
1734
             */
1735
            RequiresDefinition<S> require(String module, int modifiers);
1736

1737
            /**
1738
             * Specifies packages that are exported by the module being defined.
1739
             *
1740
             * @param aPackage The names of the packages to export.
1741
             * @return A new builder that is equal to this builder but with the given package exports.
1742
             */
1743
            ModuleDefinition<S> exports(String... aPackage);
1744

1745
            /**
1746
             * Specifies packages that are exported by the module being defined.
1747
             *
1748
             * @param packages The names of the packages to export.
1749
             * @return A new builder that is equal to this builder but with the given package exports.
1750
             */
1751
            ModuleDefinition<S> exports(Collection<String> packages);
1752

1753
            /**
1754
             * Specifies a package export with additional modifiers.
1755
             *
1756
             * @param aPackage The name of the package to export.
1757
             * @param modifierContributor The modifiers to apply to the package export.
1758
             * @return A new builder that is equal to this builder but with the given package export.
1759
             */
1760
            ModuleDefinition<S> export(String aPackage, ModifierContributor.ForModule.OfExport... modifierContributor);
1761

1762
            /**
1763
             * Specifies a package export with additional modifiers.
1764
             *
1765
             * @param aPackage The name of the package to export.
1766
             * @param modifierContributors The modifiers to apply to the package export.
1767
             * @return A new builder that is equal to this builder but with the given package export.
1768
             */
1769
            ModuleDefinition<S> export(String aPackage, Collection<? extends ModifierContributor.ForModule.OfExport> modifierContributors);
1770

1771
            /**
1772
             * Specifies a package export with explicit modifiers.
1773
             *
1774
             * @param aPackage The name of the package to export.
1775
             * @param modifiers The modifiers to apply to the package export.
1776
             * @return A new builder that is equal to this builder but with the given package export.
1777
             */
1778
            ModuleDefinition<S> export(String aPackage, int modifiers);
1779

1780
            /**
1781
             * Specifies packages that are opened by the module being defined.
1782
             *
1783
             * @param aPackage The names of the packages to open.
1784
             * @return A new builder that is equal to this builder but with the given package openings.
1785
             */
1786
            ModuleDefinition<S> opens(String... aPackage);
1787

1788
            /**
1789
             * Specifies packages that are opened by the module being defined.
1790
             *
1791
             * @param packages The names of the packages to open.
1792
             * @return A new builder that is equal to this builder but with the given package openings.
1793
             */
1794
            ModuleDefinition<S> opens(Collection<String> packages);
1795

1796
            /**
1797
             * Specifies a package opening with additional modifiers.
1798
             *
1799
             * @param aPackage The name of the package to open.
1800
             * @param modifierContributor The modifiers to apply to the package opening.
1801
             * @return A new builder that is equal to this builder but with the given package opening.
1802
             */
1803
            ModuleDefinition<S> open(String aPackage, ModifierContributor.ForModule.OfOpen... modifierContributor);
1804

1805
            /**
1806
             * Specifies a package opening with additional modifiers.
1807
             *
1808
             * @param aPackage The name of the package to open.
1809
             * @param modifierContributors The modifiers to apply to the package opening.
1810
             * @return A new builder that is equal to this builder but with the given package opening.
1811
             */
1812
            ModuleDefinition<S> open(String aPackage, Collection<? extends ModifierContributor.ForModule.OfOpen> modifierContributors);
1813

1814
            /**
1815
             * Specifies a package opening with explicit modifiers.
1816
             *
1817
             * @param aPackage The name of the package to open.
1818
             * @param modifiers The modifiers to apply to the package opening.
1819
             * @return A new builder that is equal to this builder but with the given package opening.
1820
             */
1821
            ModuleDefinition<S> open(String aPackage, int modifiers);
1822

1823
            /**
1824
             * Specifies services that are used by the module being defined.
1825
             *
1826
             * @param service The types of the services to use.
1827
             * @return A new builder that is equal to this builder but with the given service uses.
1828
             */
1829
            ModuleDefinition<S> uses(Class<?>... service);
1830

1831
            /**
1832
             * Specifies services that are used by the module being defined.
1833
             *
1834
             * @param service The descriptions of the types of the services to use.
1835
             * @return A new builder that is equal to this builder but with the given service uses.
1836
             */
1837
            ModuleDefinition<S> uses(TypeDescription... service);
1838

1839
            /**
1840
             * Specifies services that are used by the module being defined.
1841
             *
1842
             * @param service The names of the types of the services to use.
1843
             * @return A new builder that is equal to this builder but with the given service uses.
1844
             */
1845
            ModuleDefinition<S> uses(String... service);
1846

1847
            /**
1848
             * Specifies services that are used by the module being defined.
1849
             *
1850
             * @param services The names of the types of the services to use.
1851
             * @return A new builder that is equal to this builder but with the given service uses.
1852
             */
1853
            ModuleDefinition<S> uses(Collection<String> services);
1854

1855
            /**
1856
             * Specifies service implementations that are provided by the module being defined.
1857
             *
1858
             * @param service The type of the service for which implementations are provided.
1859
             * @param implementation The types of the implementations that are provided.
1860
             * @return A new builder that is equal to this builder but with the given service provision.
1861
             */
1862
            ModuleDefinition<S> provides(Class<?> service, Class<?>... implementation);
1863

1864
            /**
1865
             * Specifies service implementations that are provided by the module being defined.
1866
             *
1867
             * @param service The type of the service for which implementations are provided.
1868
             * @param implementations The types of the implementations that are provided.
1869
             * @return A new builder that is equal to this builder but with the given service provision.
1870
             */
1871
            ModuleDefinition<S> provides(Class<?> service, Collection<Class<?>> implementations);
1872

1873
            /**
1874
             * Specifies service implementations that are provided by the module being defined.
1875
             *
1876
             * @param service The description of the type of the service for which implementations are provided.
1877
             * @param implementation The descriptions of the types of the implementations that are provided.
1878
             * @return A new builder that is equal to this builder but with the given service provision.
1879
             */
1880
            ModuleDefinition<S> provides(TypeDescription service, TypeDescription... implementation);
1881

1882
            /**
1883
             * Specifies service implementations that are provided by the module being defined.
1884
             *
1885
             * @param service The description of the type of the service for which implementations are provided.
1886
             * @param implementations The descriptions of the types of the implementations that are provided.
1887
             * @return A new builder that is equal to this builder but with the given service provision.
1888
             */
1889
            ModuleDefinition<S> provides(TypeDescription service, Collection<TypeDescription> implementations);
1890

1891
            /**
1892
             * Specifies service implementations that are provided by the module being defined.
1893
             *
1894
             * @param service The name of the type of the service for which implementations are provided.
1895
             * @param implementation The names of the types of the implementations that are provided.
1896
             * @return A new builder that is equal to this builder but with the given service provision.
1897
             */
1898
            ModuleDefinition<S> provides(String service, String... implementation);
1899

1900
            /**
1901
             * Specifies service implementations that are provided by the module being defined.
1902
             *
1903
             * @param service The name of the type of the service for which implementations are provided.
1904
             * @param implementations The names of the types of the implementations that are provided.
1905
             * @return A new builder that is equal to this builder but with the given service provision.
1906
             */
1907
            ModuleDefinition<S> provides(String service, Collection<String> implementations);
1908

1909
            /**
1910
             * A specification of a module requirement.
1911
             *
1912
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1913
             */
1914
            interface RequiresDefinition<U> extends ModuleDefinition<U> {
1915

1916
                /**
1917
                 * Specifies the version of the required module.
1918
                 *
1919
                 * @param version The version of the required module or {@code null} if no version is to be specified.
1920
                 * @return A new builder that is equal to this builder but with the given version specification.
1921
                 */
1922
                RequiresDefinition<U> requiredVersion(@MaybeNull String version);
1923

1924
                /**
1925
                 * An abstract base implementation of a {@link RequiresDefinition}.
1926
                 *
1927
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1928
                 */
UNCOV
1929
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements RequiresDefinition<V> {
×
1930
                    /* empty */
1931
                }
1932
            }
1933

1934
            /**
1935
             * A specification of a module export.
1936
             *
1937
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1938
             */
1939
            interface ExportsDefinition<U> extends ModuleDefinition<U> {
1940

1941
                /**
1942
                 * Specifies the modules to which the previously defined package is exported.
1943
                 *
1944
                 * @param module The names of the modules to which the package is exported.
1945
                 * @return A new builder that is equal to this builder but with the given modules specified.
1946
                 */
1947
                ExportsDefinition<U> to(String... module);
1948

1949
                /**
1950
                 * Specifies the modules to which the previously defined package is exported.
1951
                 *
1952
                 * @param modules The names of the modules to which the package is exported.
1953
                 * @return A new builder that is equal to this builder but with the given modules specified.
1954
                 */
1955
                ExportsDefinition<U> to(Collection<String> modules);
1956

1957
                /**
1958
                 * An abstract base implementation of a {@link OpensDefinition}.
1959
                 *
1960
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1961
                 */
UNCOV
1962
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements ExportsDefinition<V> {
×
1963

1964
                    /**
1965
                     * {@inheritDoc}ModuleDefinition
1966
                     */
1967
                    public ExportsDefinition<V> to(String... module) {
UNCOV
1968
                        return to(Arrays.asList(module));
×
1969
                    }
1970
                }
1971
            }
1972

1973
            /**
1974
             * A specification of a module opening.
1975
             *
1976
             * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1977
             */
1978
            interface OpensDefinition<S> extends ModuleDefinition<S> {
1979

1980
                /**
1981
                 * Specifies the modules to which the previously defined package is opened.
1982
                 *
1983
                 * @param module The names of the modules to which the package is opened.
1984
                 * @return A new builder that is equal to this builder but with the given modules specified.
1985
                 */
1986
                OpensDefinition<S> to(String... module);
1987

1988
                /**
1989
                 * Specifies the modules to which the previously defined package is opened.
1990
                 *
1991
                 * @param modules The names of the modules to which the package is opened.
1992
                 * @return A new builder that is equal to this builder but with the given modules specified.
1993
                 */
1994
                OpensDefinition<S> to(Collection<String> modules);
1995

1996
                /**
1997
                 * An abstract base implementation of a {@link OpensDefinition}.
1998
                 *
1999
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2000
                 */
UNCOV
2001
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements OpensDefinition<V> {
×
2002

2003
                    /**
2004
                     * {@inheritDoc}
2005
                     */
2006
                    public OpensDefinition<V> to(String... module) {
UNCOV
2007
                        return to(Arrays.asList(module));
×
2008
                    }
2009
                }
2010
            }
2011

2012
            /**
2013
             * An abstract base implementation of a {@link ModuleDefinition}.
2014
             *
2015
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2016
             */
UNCOV
2017
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements ModuleDefinition<U> {
×
2018

2019
                /**
2020
                 * {@inheritDoc}
2021
                 */
2022
                public ModuleDefinition<U> mainClass(@MaybeNull Class<?> type) {
UNCOV
2023
                    return mainClass(type == null
×
2024
                            ? null
UNCOV
2025
                            : TypeDescription.ForLoadedType.of(type));
×
2026
                }
2027

2028
                /**
2029
                 * {@inheritDoc}
2030
                 */
2031
                public ModuleDefinition<U> mainClass(@MaybeNull TypeDescription typeDescription) {
UNCOV
2032
                    if (typeDescription != null && (typeDescription.isArray() || typeDescription.isPrimitive())) {
×
UNCOV
2033
                        throw new IllegalArgumentException("Cannot use primitive types for main class: " + typeDescription);
×
2034
                    }
UNCOV
2035
                    return mainClass(typeDescription == null
×
2036
                            ? null
UNCOV
2037
                            : typeDescription.getName());
×
2038
                }
2039

2040
                /**
2041
                 * {@inheritDoc}
2042
                 */
2043
                public ModuleDefinition<U> packages(String... aPackage) {
UNCOV
2044
                    return packages(Arrays.asList(aPackage));
×
2045
                }
2046

2047
                /**
2048
                 * {@inheritDoc}
2049
                 */
2050
                public ModuleDefinition<U> requires(String... module) {
UNCOV
2051
                    return requires(Arrays.asList(module));
×
2052
                }
2053

2054
                /**
2055
                 * {@inheritDoc}
2056
                 */
2057
                public ModuleDefinition<U> requires(Collection<String> modules) {
UNCOV
2058
                    ModuleDefinition<U> definition = this;
×
UNCOV
2059
                    for (String module : modules) {
×
UNCOV
2060
                        definition = definition.requires(module);
×
UNCOV
2061
                    }
×
UNCOV
2062
                    return definition;
×
2063
                }
2064

2065
                /**
2066
                 * {@inheritDoc}
2067
                 */
2068
                public RequiresDefinition<U> require(String module, ModifierContributor.ForModule.OfRequire... modifierContributor) {
UNCOV
2069
                    return require(module, Arrays.asList(modifierContributor));
×
2070
                }
2071

2072
                /**
2073
                 * {@inheritDoc}
2074
                 */
2075
                public RequiresDefinition<U> require(String module, Collection<? extends ModifierContributor.ForModule.OfRequire> modifierContributors) {
UNCOV
2076
                    return require(module, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2077
                }
2078

2079
                /**
2080
                 * {@inheritDoc}
2081
                 */
2082
                public ModuleDefinition<U> exports(String... aPackage) {
UNCOV
2083
                    return exports(Arrays.asList(aPackage));
×
2084
                }
2085

2086
                /**
2087
                 * {@inheritDoc}
2088
                 */
2089
                public ModuleDefinition<U> exports(Collection<String> packages) {
UNCOV
2090
                    ModuleDefinition<U> definition = this;
×
UNCOV
2091
                    for (String aPackage : packages) {
×
UNCOV
2092
                        definition = definition.export(aPackage);
×
UNCOV
2093
                    }
×
UNCOV
2094
                    return definition;
×
2095
                }
2096

2097
                /**
2098
                 * {@inheritDoc}
2099
                 */
2100
                public ModuleDefinition<U> export(String aPackage, ModifierContributor.ForModule.OfExport... modifierContributor) {
UNCOV
2101
                    return export(aPackage, Arrays.asList(modifierContributor));
×
2102
                }
2103

2104
                /**
2105
                 * {@inheritDoc}
2106
                 */
2107
                public ModuleDefinition<U> export(String aPackage, Collection<? extends ModifierContributor.ForModule.OfExport> modifierContributors) {
UNCOV
2108
                    return export(aPackage, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2109
                }
2110

2111
                /**
2112
                 * {@inheritDoc}
2113
                 */
2114
                public ModuleDefinition<U> opens(String... aPackage) {
UNCOV
2115
                    return opens(Arrays.asList(aPackage));
×
2116
                }
2117

2118
                /**
2119
                 * {@inheritDoc}
2120
                 */
2121
                public ModuleDefinition<U> opens(Collection<String> packages) {
UNCOV
2122
                    ModuleDefinition<U> definition = this;
×
UNCOV
2123
                    for (String aPackage : packages) {
×
UNCOV
2124
                        definition = definition.open(aPackage);
×
UNCOV
2125
                    }
×
UNCOV
2126
                    return definition;
×
2127
                }
2128

2129
                /**
2130
                 * {@inheritDoc}
2131
                 */
2132
                public ModuleDefinition<U> open(String aPackage, ModifierContributor.ForModule.OfOpen... modifierContributor) {
UNCOV
2133
                    return open(aPackage, Arrays.asList(modifierContributor));
×
2134
                }
2135

2136
                /**
2137
                 * {@inheritDoc}
2138
                 */
2139
                public ModuleDefinition<U> open(String aPackage, Collection<? extends ModifierContributor.ForModule.OfOpen> modifierContributors) {
UNCOV
2140
                    return open(aPackage, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2141
                }
2142

2143
                /**
2144
                 * {@inheritDoc}
2145
                 */
2146
                public ModuleDefinition<U> uses(Class<?>... service) {
UNCOV
2147
                    return uses(new TypeList.ForLoadedTypes(service));
×
2148
                }
2149

2150
                /**
2151
                 * {@inheritDoc}
2152
                 */
2153
                public ModuleDefinition<U> uses(TypeDescription... service) {
UNCOV
2154
                    return uses(Arrays.asList(service));
×
2155
                }
2156

2157
                /**
2158
                 * Includes the provided type in the usage of the module description.
2159
                 *
2160
                 * @param services The services to use.
2161
                 * @return A module description where these services are included.
2162
                 */
2163
                private ModuleDefinition<U> uses(List<TypeDescription> services) {
UNCOV
2164
                    List<String> names = new ArrayList<String>(services.size());
×
UNCOV
2165
                    for (TypeDescription service : services) {
×
UNCOV
2166
                        if (service.isArray() || service.isPrimitive()) {
×
UNCOV
2167
                            throw new IllegalArgumentException("A service can only be provided by a regular class: " + service);
×
2168
                        }
UNCOV
2169
                        names.add(service.getName());
×
UNCOV
2170
                    }
×
UNCOV
2171
                    return uses(names);
×
2172
                }
2173

2174
                /**
2175
                 * {@inheritDoc}
2176
                 */
2177
                public ModuleDefinition<U> uses(String... service) {
UNCOV
2178
                    return uses(Arrays.asList(service));
×
2179
                }
2180

2181
                /**
2182
                 * {@inheritDoc}
2183
                 */
2184
                public ModuleDefinition<U> provides(Class<?> service, Class<?>... implementations) {
UNCOV
2185
                    return provides(service, Arrays.asList(implementations));
×
2186
                }
2187

2188
                /**
2189
                 * {@inheritDoc}
2190
                 */
2191
                public ModuleDefinition<U> provides(Class<?> service, Collection<Class<?>> implementations) {
UNCOV
2192
                    return provides(TypeDescription.ForLoadedType.of(service), new TypeList.ForLoadedTypes(new ArrayList<Class<?>>(implementations)));
×
2193
                }
2194

2195
                /**
2196
                 * {@inheritDoc}
2197
                 */
2198
                public ModuleDefinition<U> provides(TypeDescription service, TypeDescription... implementation) {
UNCOV
2199
                    return provides(service, Arrays.asList(implementation));
×
2200
                }
2201

2202
                /**
2203
                 * {@inheritDoc}
2204
                 */
2205
                public ModuleDefinition<U> provides(TypeDescription service, Collection<TypeDescription> implementations) {
2206
                    if (service.isArray() || service.isPrimitive()) {
×
UNCOV
2207
                        throw new IllegalArgumentException("Service must be a regular class: " + service);
×
2208
                    }
UNCOV
2209
                    List<String> names = new ArrayList<String>(implementations.size());
×
UNCOV
2210
                    for (TypeDescription implementation : implementations) {
×
UNCOV
2211
                        if (implementation.isArray() || implementation.isPrimitive() || implementation.isAbstract()) {
×
UNCOV
2212
                            throw new IllegalArgumentException("Service implementation must be a regular, non-abstract class: " + implementation);
×
2213
                        }
UNCOV
2214
                        names.add(implementation.getName());
×
UNCOV
2215
                    }
×
UNCOV
2216
                    return provides(service.getName(), names);
×
2217
                }
2218

2219
                /**
2220
                 * {@inheritDoc}
2221
                 */
2222
                public ModuleDefinition<U> provides(String service, String... implementations) {
UNCOV
2223
                    return provides(service, Arrays.asList(implementations));
×
2224
                }
2225

2226
                /**
2227
                 * An adapter for a {@link ModuleDefinition}.
2228
                 *
2229
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2230
                 */
UNCOV
2231
                public abstract static class Delegator<V> extends ModuleDefinition.AbstractBase<V> {
×
2232

2233
                    /**
2234
                     * {@inheritDoc}
2235
                     */
2236
                    public ModuleDefinition<V> version(@MaybeNull String version) {
UNCOV
2237
                        return materialize().version(version);
×
2238
                    }
2239

2240
                    /**
2241
                     * {@inheritDoc}
2242
                     */
2243
                    public ModuleDefinition<V> mainClass(@MaybeNull String name) {
UNCOV
2244
                        return materialize().mainClass(name);
×
2245
                    }
2246

2247
                    /**
2248
                     * {@inheritDoc}
2249
                     */
2250
                    public ModuleDefinition<V> packages(Collection<String> packages) {
UNCOV
2251
                        return materialize().packages(packages);
×
2252
                    }
2253

2254
                    /**
2255
                     * {@inheritDoc}
2256
                     */
2257
                    public RequiresDefinition<V> require(String module, int modifiers) {
UNCOV
2258
                        return materialize().require(module, modifiers);
×
2259
                    }
2260

2261
                    /**
2262
                     * {@inheritDoc}
2263
                     */
2264
                    public ModuleDefinition<V> export(String aPackage, int modifiers) {
UNCOV
2265
                        return materialize().export(aPackage, modifiers);
×
2266
                    }
2267

2268
                    /**
2269
                     * {@inheritDoc}
2270
                     */
2271
                    public ModuleDefinition<V> open(String aPackage, int modifiers) {
UNCOV
2272
                        return materialize().open(aPackage, modifiers);
×
2273
                    }
2274

2275
                    /**
2276
                     * {@inheritDoc}
2277
                     */
2278
                    public ModuleDefinition<V> uses(Collection<String> services) {
UNCOV
2279
                        return materialize().uses(services);
×
2280
                    }
2281

2282
                    /**
2283
                     * {@inheritDoc}
2284
                     */
2285
                    public ModuleDefinition<V> provides(String service, Collection<String> implementations) {
UNCOV
2286
                        return materialize().provides(service, implementations);
×
2287
                    }
2288

2289
                    @Override
2290
                    protected abstract ModuleDefinition<V> materialize();
2291
                }
2292
            }
2293
        }
2294

2295
        /**
2296
         * An inner type definition for defining a type that is contained within another type, method or constructor.
2297
         *
2298
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2299
         */
2300
        interface InnerTypeDefinition<S> extends Builder<S> {
2301

2302
            /**
2303
             * Defines this inner type declaration as an anonymous type.
2304
             *
2305
             * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
2306
             */
2307
            Builder<S> asAnonymousType();
2308

2309
            /**
2310
             * An inner type definition for defining a type that is contained within another type.
2311
             *
2312
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2313
             */
2314
            interface ForType<U> extends InnerTypeDefinition<U> {
2315

2316
                /**
2317
                 * Defines this inner type declaration as a member type.
2318
                 *
2319
                 * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
2320
                 */
2321
                Builder<U> asMemberType();
2322
            }
2323
        }
2324

2325
        /**
2326
         * A builder for a type variable definition.
2327
         *
2328
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2329
         */
2330
        interface TypeVariableDefinition<S> extends Builder<S> {
2331

2332
            /**
2333
             * Annotates the previously defined type variable with the supplied annotations.
2334
             *
2335
             * @param annotation The annotations to declare on the previously defined type variable.
2336
             * @return A new builder that is equal to this builder but with the given annotations declared
2337
             * on the previously defined type variable.
2338
             */
2339
            TypeVariableDefinition<S> annotateTypeVariable(Annotation... annotation);
2340

2341
            /**
2342
             * Annotates the previously defined type variable with the supplied annotations.
2343
             *
2344
             * @param annotations The annotations to declare on the previously defined type variable.
2345
             * @return A new builder that is equal to this builder but with the given annotations declared
2346
             * on the previously defined type variable.
2347
             */
2348
            TypeVariableDefinition<S> annotateTypeVariable(List<? extends Annotation> annotations);
2349

2350
            /**
2351
             * Annotates the previously defined type variable with the supplied annotations.
2352
             *
2353
             * @param annotation The annotations to declare on the previously defined type variable.
2354
             * @return A new builder that is equal to this builder but with the given annotations declared
2355
             * on the previously defined type variable.
2356
             */
2357
            TypeVariableDefinition<S> annotateTypeVariable(AnnotationDescription... annotation);
2358

2359
            /**
2360
             * Annotates the previously defined type variable with the supplied annotations.
2361
             *
2362
             * @param annotations The annotations to declare on the previously defined type variable.
2363
             * @return A new builder that is equal to this builder but with the given annotations declared
2364
             * on the previously defined type variable.
2365
             */
2366
            TypeVariableDefinition<S> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
2367

2368
            /**
2369
             * An abstract base implementation of a type variable definition.
2370
             *
2371
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2372
             */
2373
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
1✔
2374

2375
                /**
2376
                 * {@inheritDoc}
2377
                 */
2378
                public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
UNCOV
2379
                    return annotateTypeVariable(Arrays.asList(annotation));
×
2380
                }
2381

2382
                /**
2383
                 * {@inheritDoc}
2384
                 */
2385
                public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
UNCOV
2386
                    return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
2387
                }
2388

2389
                /**
2390
                 * {@inheritDoc}
2391
                 */
2392
                public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
2393
                    return annotateTypeVariable(Arrays.asList(annotation));
1✔
2394
                }
2395
            }
2396
        }
2397

2398
        /**
2399
         * A builder for a field definition.
2400
         *
2401
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2402
         */
2403
        interface FieldDefinition<S> {
2404

2405
            /**
2406
             * Annotates the previously defined or matched field with the supplied annotations.
2407
             *
2408
             * @param annotation The annotations to declare on the previously defined or matched field.
2409
             * @return A new builder that is equal to this builder but with the given annotations declared
2410
             * on the previously defined or matched field.
2411
             */
2412
            FieldDefinition.Optional<S> annotateField(Annotation... annotation);
2413

2414
            /**
2415
             * Annotates the previously defined or matched field with the supplied annotations.
2416
             *
2417
             * @param annotations The annotations to declare on the previously defined or matched field.
2418
             * @return A new builder that is equal to this builder but with the given annotations declared
2419
             * on the previously defined or matched field.
2420
             */
2421
            FieldDefinition.Optional<S> annotateField(List<? extends Annotation> annotations);
2422

2423
            /**
2424
             * Annotates the previously defined or matched field with the supplied annotations.
2425
             *
2426
             * @param annotation The annotations to declare on the previously defined or matched field.
2427
             * @return A new builder that is equal to this builder but with the given annotations declared
2428
             * on the previously defined or matched field.
2429
             */
2430
            FieldDefinition.Optional<S> annotateField(AnnotationDescription... annotation);
2431

2432
            /**
2433
             * Annotates the previously defined or matched field with the supplied annotations.
2434
             *
2435
             * @param annotations The annotations to declare on the previously defined or matched field.
2436
             * @return A new builder that is equal to this builder but with the given annotations declared
2437
             * on the previously defined or matched field.
2438
             */
2439
            FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
2440

2441
            /**
2442
             * Applies the supplied attribute appender factory onto the previously defined or matched field.
2443
             *
2444
             * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
2445
             *                                      previously defined or matched field.
2446
             * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
2447
             * applied to the previously defined or matched field.
2448
             */
2449
            FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
2450

2451
            /**
2452
             * Applies the supplied transformer onto the previously defined or matched field. The transformed
2453
             * field is written <i>as it is</i> and is not subject to any validations.
2454
             *
2455
             * @param transformer The transformer to apply to the previously defined or matched field.
2456
             * @return A new builder that is equal to this builder but with the supplied field transformer
2457
             * applied to the previously defined or matched field.
2458
             */
2459
            FieldDefinition.Optional<S> transform(Transformer<FieldDescription> transformer);
2460

2461
            /**
2462
             * A builder for a field definition that allows for defining a value.
2463
             *
2464
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2465
             */
2466
            interface Valuable<U> extends FieldDefinition<U> {
2467

2468
                /**
2469
                 * <p>
2470
                 * Defines the supplied {@code boolean} value as a default value of the previously defined or matched field. The value can only
2471
                 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int}. For non-boolean
2472
                 * fields, the field's value is set to {@code 0} for {@code false} or {@code 1} for {@code true}.
2473
                 * </p>
2474
                 * <p>
2475
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
2476
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
2477
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
2478
                 * </p>
2479
                 *
2480
                 * @param value The value to define as a default value of the defined field.
2481
                 * @return A new builder that is equal to this builder but with the given default value declared for the
2482
                 * previously defined or matched field.
2483
                 */
2484
                FieldDefinition.Optional<U> value(boolean value);
2485

2486
                /**
2487
                 * <p>
2488
                 * Defines the supplied {@code int} value as a default value of the previously defined or matched field. The value can only
2489
                 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int} where the
2490
                 * value must be within the numeric type's range. The {@code boolean} type is regarded as a numeric type with the possible
2491
                 * values of {@code 0} and {@code 1} representing {@code false} and {@code true}.
2492
                 * </p>
2493
                 * <p>
2494
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
2495
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
2496
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
2497
                 * </p>
2498
                 *
2499
                 * @param value The value to define as a default value of the defined field.
2500
                 * @return A new builder that is equal to this builder but with the given default value declared for the
2501
                 * previously defined or matched field.
2502
                 */
2503
                FieldDefinition.Optional<U> value(int value);
2504

2505
                /**
2506
                 * <p>
2507
                 * Defines the supplied {@code long} value as a default value of the previously defined or matched field.
2508
                 * </p>
2509
                 * <p>
2510
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
2511
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
2512
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
2513
                 * </p>
2514
                 *
2515
                 * @param value The value to define as a default value of the defined field.
2516
                 * @return A new builder that is equal to this builder but with the given default value declared for the
2517
                 * previously defined or matched field.
2518
                 */
2519
                FieldDefinition.Optional<U> value(long value);
2520

2521
                /**
2522
                 * <p>
2523
                 * Defines the supplied {@code float} value as a default value of the previously defined or matched field.
2524
                 * </p>
2525
                 * <p>
2526
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
2527
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
2528
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
2529
                 * </p>
2530
                 *
2531
                 * @param value The value to define as a default value of the defined field.
2532
                 * @return A new builder that is equal to this builder but with the given default value declared for the
2533
                 * previously defined or matched field.
2534
                 */
2535
                FieldDefinition.Optional<U> value(float value);
2536

2537
                /**
2538
                 * <p>
2539
                 * Defines the supplied {@code double} value as a default value of the previously defined or matched field.
2540
                 * </p>
2541
                 * <p>
2542
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
2543
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
2544
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
2545
                 * </p>
2546
                 *
2547
                 * @param value The value to define as a default value of the defined field.
2548
                 * @return A new builder that is equal to this builder but with the given default value declared for the
2549
                 * previously defined or matched field.
2550
                 */
2551
                FieldDefinition.Optional<U> value(double value);
2552

2553
                /**
2554
                 * <p>
2555
                 * Defines the supplied {@link String} value as a default value of the previously defined or matched field.
2556
                 * </p>
2557
                 * <p>
2558
                 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
2559
                 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
2560
                 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
2561
                 * </p>
2562
                 *
2563
                 * @param value The value to define as a default value of the defined field.
2564
                 * @return A new builder that is equal to this builder but with the given default value declared for the
2565
                 * previously defined or matched field.
2566
                 */
2567
                FieldDefinition.Optional<U> value(String value);
2568
            }
2569

2570
            /**
2571
             * A builder for an optional field definition.
2572
             *
2573
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2574
             */
2575
            interface Optional<U> extends FieldDefinition<U>, Builder<U> {
2576

2577
                /**
2578
                 * A builder for an optional field definition that allows for defining a value.
2579
                 *
2580
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2581
                 */
2582
                interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
2583

2584
                    /**
2585
                     * An abstract base implementation of an optional field definition that allows for defining a value.
2586
                     *
2587
                     * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2588
                     */
2589
                    abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1✔
2590

2591
                        /**
2592
                         * {@inheritDoc}
2593
                         */
2594
                        public FieldDefinition.Optional<U> value(boolean value) {
2595
                            return defaultValue(value ? 1 : 0);
1✔
2596
                        }
2597

2598
                        /**
2599
                         * {@inheritDoc}
2600
                         */
2601
                        public FieldDefinition.Optional<U> value(int value) {
2602
                            return defaultValue(value);
1✔
2603
                        }
2604

2605
                        /**
2606
                         * {@inheritDoc}
2607
                         */
2608
                        public FieldDefinition.Optional<U> value(long value) {
2609
                            return defaultValue(value);
1✔
2610
                        }
2611

2612
                        /**
2613
                         * {@inheritDoc}
2614
                         */
2615
                        public FieldDefinition.Optional<U> value(float value) {
2616
                            return defaultValue(value);
1✔
2617
                        }
2618

2619
                        /**
2620
                         * {@inheritDoc}
2621
                         */
2622
                        public FieldDefinition.Optional<U> value(double value) {
2623
                            return defaultValue(value);
1✔
2624
                        }
2625

2626
                        /**
2627
                         * {@inheritDoc}
2628
                         */
2629
                        public FieldDefinition.Optional<U> value(String value) {
2630
                            if (value == null) {
1✔
2631
                                throw new IllegalArgumentException("Cannot define 'null' as constant value");
1✔
2632
                            }
2633
                            return defaultValue(value);
1✔
2634
                        }
2635

2636
                        /**
2637
                         * Defines the supplied value as a default value of the previously defined or matched field.
2638
                         *
2639
                         * @param defaultValue The value to define as a default value of the defined field.
2640
                         * @return A new builder that is equal to this builder but with the given default value declared for the
2641
                         * previously defined or matched field.
2642
                         */
2643
                        protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
2644

2645
                        /**
2646
                         * An adapter for an optional field definition that allows for defining a value.
2647
                         *
2648
                         * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2649
                         */
2650
                        @HashCodeAndEqualsPlugin.Enhance
2651
                        private abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
2652

2653
                            /**
2654
                             * The field attribute appender factory to apply.
2655
                             */
2656
                            protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
2657

2658
                            /**
2659
                             * The field transformer to apply.
2660
                             */
2661
                            protected final Transformer<FieldDescription> transformer;
2662

2663
                            /**
2664
                             * The field's default value or {@code null} if no value is to be defined.
2665
                             */
2666
                            @MaybeNull
2667
                            @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
2668
                            protected final Object defaultValue;
2669

2670
                            /**
2671
                             * Creates a new field adapter.
2672
                             *
2673
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
2674
                             * @param transformer                   The field transformer to apply.
2675
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
2676
                             */
2677
                            protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
2678
                                              Transformer<FieldDescription> transformer,
2679
                                              @MaybeNull Object defaultValue) {
1✔
2680
                                this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
1✔
2681
                                this.transformer = transformer;
1✔
2682
                                this.defaultValue = defaultValue;
1✔
2683
                            }
1✔
2684

2685
                            /**
2686
                             * {@inheritDoc}
2687
                             */
2688
                            public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
2689
                                return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
1✔
2690
                            }
2691

2692
                            /**
2693
                             * {@inheritDoc}
2694
                             */
2695
                            @SuppressWarnings("unchecked") // In absence of @SafeVarargs
2696
                            public FieldDefinition.Optional<V> transform(Transformer<FieldDescription> transformer) {
2697
                                return materialize(fieldAttributeAppenderFactory, new Transformer.Compound<FieldDescription>(this.transformer, transformer), defaultValue);
1✔
2698
                            }
2699

2700
                            @Override
2701
                            protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
2702
                                return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
2703
                            }
2704

2705
                            /**
2706
                             * Creates a new optional field definition for which all of the supplied values are represented.
2707
                             *
2708
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
2709
                             * @param transformer                   The field transformer to apply.
2710
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
2711
                             * @return A new field definition that represents the supplied values.
2712
                             */
2713
                            protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
2714
                                                                                       Transformer<FieldDescription> transformer,
2715
                                                                                       @MaybeNull Object defaultValue);
2716
                        }
2717
                    }
2718
                }
2719

2720
                /**
2721
                 * An abstract base implementation for an optional field definition.
2722
                 *
2723
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2724
                 */
2725
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1✔
2726

2727
                    /**
2728
                     * {@inheritDoc}
2729
                     */
2730
                    public FieldDefinition.Optional<U> annotateField(Annotation... annotation) {
2731
                        return annotateField(Arrays.asList(annotation));
1✔
2732
                    }
2733

2734
                    /**
2735
                     * {@inheritDoc}
2736
                     */
2737
                    public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
2738
                        return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
2739
                    }
2740

2741
                    /**
2742
                     * {@inheritDoc}
2743
                     */
2744
                    public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
2745
                        return annotateField(Arrays.asList(annotation));
1✔
2746
                    }
2747
                }
2748
            }
2749
        }
2750

2751
        /**
2752
         * A builder for a method definition.
2753
         *
2754
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2755
         */
2756
        interface MethodDefinition<S> extends Builder<S> {
2757

2758
            /**
2759
             * Annotates the previously defined or matched method with the supplied annotations.
2760
             *
2761
             * @param annotation The annotations to declare on the previously defined or matched method.
2762
             * @return A new builder that is equal to this builder but with the given annotations declared
2763
             * on the previously defined or matched method.
2764
             */
2765
            MethodDefinition<S> annotateMethod(Annotation... annotation);
2766

2767
            /**
2768
             * Annotates the previously defined or matched method with the supplied annotations.
2769
             *
2770
             * @param annotations The annotations to declare on the previously defined or matched method.
2771
             * @return A new builder that is equal to this builder but with the given annotations declared
2772
             * on the previously defined or matched method.
2773
             */
2774
            MethodDefinition<S> annotateMethod(List<? extends Annotation> annotations);
2775

2776
            /**
2777
             * Annotates the previously defined or matched method with the supplied annotations.
2778
             *
2779
             * @param annotation The annotations to declare on the previously defined or matched method.
2780
             * @return A new builder that is equal to this builder but with the given annotations declared
2781
             * on the previously defined or matched method.
2782
             */
2783
            MethodDefinition<S> annotateMethod(AnnotationDescription... annotation);
2784

2785
            /**
2786
             * Annotates the previously defined or matched method with the supplied annotations.
2787
             *
2788
             * @param annotations The annotations to declare on the previously defined or matched method.
2789
             * @return A new builder that is equal to this builder but with the given annotations declared
2790
             * on the previously defined or matched method.
2791
             */
2792
            MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
2793

2794
            /**
2795
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2796
             *
2797
             * @param index      The parameter's index.
2798
             * @param annotation The annotations to declare on the previously defined or matched method.
2799
             * @return A new builder that is equal to this builder but with the given annotations declared
2800
             * on the previously defined or matched method's parameter of the given index.
2801
             */
2802
            MethodDefinition<S> annotateParameter(int index, Annotation... annotation);
2803

2804
            /**
2805
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2806
             *
2807
             * @param index       The parameter's index.
2808
             * @param annotations The annotations to declare on the previously defined or matched method.
2809
             * @return A new builder that is equal to this builder but with the given annotations declared
2810
             * on the previously defined or matched method's parameter of the given index.
2811
             */
2812
            MethodDefinition<S> annotateParameter(int index, List<? extends Annotation> annotations);
2813

2814
            /**
2815
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2816
             *
2817
             * @param index      The parameter's index.
2818
             * @param annotation The annotations to declare on the previously defined or matched method.
2819
             * @return A new builder that is equal to this builder but with the given annotations declared
2820
             * on the previously defined or matched method's parameter of the given index.
2821
             */
2822
            MethodDefinition<S> annotateParameter(int index, AnnotationDescription... annotation);
2823

2824
            /**
2825
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2826
             *
2827
             * @param index       The parameter's index.
2828
             * @param annotations The annotations to declare on the previously defined or matched method.
2829
             * @return A new builder that is equal to this builder but with the given annotations declared
2830
             * on the previously defined or matched method's parameter of the given index.
2831
             */
2832
            MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
2833

2834
            /**
2835
             * Applies the supplied method attribute appender factory onto the previously defined or matched method.
2836
             *
2837
             * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
2838
             *                                       previously defined or matched method.
2839
             * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
2840
             * applied to the previously defined or matched method.
2841
             */
2842
            MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
2843

2844
            /**
2845
             * Applies the supplied transformer onto the previously defined or matched method. The transformed
2846
             * method is written <i>as it is</i> and it not subject to any validations.
2847
             *
2848
             * @param transformer The transformer to apply to the previously defined or matched method.
2849
             * @return A new builder that is equal to this builder but with the supplied transformer
2850
             * applied to the previously defined or matched method.
2851
             */
2852
            MethodDefinition<S> transform(Transformer<MethodDescription> transformer);
2853

2854
            /**
2855
             * A builder for a method definition with a receiver type.
2856
             *
2857
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2858
             */
2859
            interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
2860

2861
                /**
2862
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2863
                 *
2864
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2865
                 * @return A new builder that is equal to this builder but with the given type defined as the
2866
                 * receiver on the previously defined or matched method.
2867
                 */
2868
                MethodDefinition<U> receiverType(AnnotatedElement receiverType);
2869

2870
                /**
2871
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2872
                 *
2873
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2874
                 * @return A new builder that is equal to this builder but with the given type defined as the
2875
                 * receiver on the previously defined or matched method.
2876
                 */
2877
                MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
2878

2879
                /**
2880
                 * An abstract base implementation of a method definition that can accept a receiver type.
2881
                 *
2882
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2883
                 */
2884
                abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
1✔
2885

2886
                    /**
2887
                     * {@inheritDoc}
2888
                     */
2889
                    public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
UNCOV
2890
                        return receiverType(TypeDefinition.Sort.describeAnnotated(receiverType));
×
2891
                    }
2892
                }
2893
            }
2894

2895
            /**
2896
             * A builder for defining an implementation of a method.
2897
             *
2898
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2899
             */
2900
            interface ImplementationDefinition<U> {
2901

2902
                /**
2903
                 * Implements the previously defined or matched method by the supplied implementation. A method interception
2904
                 * is typically implemented in one of the following ways:
2905
                 * <ol>
2906
                 * <li>If a method is declared by the instrumented type and the type builder creates a subclass or redefinition,
2907
                 * any preexisting method is replaced by the given implementation. Any previously defined implementation is lost.</li>
2908
                 * <li>If a method is declared by the instrumented type and the type builder creates a rebased version of the
2909
                 * instrumented type, the original method is preserved within a private, synthetic method within the instrumented
2910
                 * type. The original method therefore remains invokeable and is treated as the direct super method of the new
2911
                 * method. When rebasing a type, it therefore becomes possible to invoke a non-virtual method's super method
2912
                 * when a preexisting method body is replaced.</li>
2913
                 * <li>If a virtual method is inherited from a super type, it is overridden. The overridden method is available
2914
                 * for super method invocation.</li>
2915
                 * </ol>
2916
                 *
2917
                 * @param implementation The implementation for implementing the previously defined or matched method.
2918
                 * @return A new builder where the previously defined or matched method is implemented by the
2919
                 * supplied implementation.
2920
                 */
2921
                MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation);
2922

2923
                /**
2924
                 * Defines the previously defined or matched method not to declare a method body. This implies the
2925
                 * method to be {@code abstract} unless it was already declared to be {@code native}.
2926
                 *
2927
                 * @return A new builder where the previously defined or matched method is implemented to be abstract.
2928
                 */
2929
                MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
2930

2931
                /**
2932
                 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2933
                 * value must be supplied in its unloaded state, i.e. enumerations as {@link net.bytebuddy.description.enumeration.EnumerationDescription},
2934
                 * types as {@link TypeDescription} and annotations as {@link AnnotationDescription}. For supplying loaded types, use
2935
                 * {@link ImplementationDefinition#defaultValue(Object, Class)} must be used.
2936
                 *
2937
                 * @param annotationValue The value to be defined as a default value.
2938
                 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2939
                 */
2940
                MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue);
2941

2942
                /**
2943
                 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2944
                 * value must be supplied in its loaded state paired with the property type of the value.
2945
                 *
2946
                 * @param value The value to be defined as a default value.
2947
                 * @param type  The type of the annotation property.
2948
                 * @param <W>   The type of the annotation property.
2949
                 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2950
                 */
2951
                <W> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(W value, Class<? extends W> type);
2952

2953
                /**
2954
                 * A builder for optionally defining an implementation of a method.
2955
                 *
2956
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2957
                 */
2958
                interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
2959
                    /* union type */
2960
                }
2961

2962
                /**
2963
                 * An abstract base implementation for a builder optionally defining an implementation of a method.
2964
                 *
2965
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2966
                 */
2967
                abstract class AbstractBase<V> implements ImplementationDefinition<V> {
1✔
2968

2969
                    /**
2970
                     * {@inheritDoc}
2971
                     */
2972
                    public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) {
2973
                        return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
1✔
2974
                    }
2975
                }
2976
            }
2977

2978
            /**
2979
             * A builder for defining an implementation of a method and optionally defining a type variable.
2980
             *
2981
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2982
             */
2983
            interface TypeVariableDefinition<U> extends ImplementationDefinition<U> {
2984

2985
                /**
2986
                 * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
2987
                 *
2988
                 * @param symbol The symbol of the type variable.
2989
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2990
                 */
2991
                Annotatable<U> typeVariable(String symbol);
2992

2993
                /**
2994
                 * Defines a method variable to be declared by the currently defined method.
2995
                 *
2996
                 * @param symbol The symbol of the type variable.
2997
                 * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2998
                 *               if a bound type should be equal to the currently instrumented type.
2999
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
3000
                 */
3001
                Annotatable<U> typeVariable(String symbol, Type... bound);
3002

3003
                /**
3004
                 * Defines a method variable to be declared by the currently defined method.
3005
                 *
3006
                 * @param symbol The symbol of the type variable.
3007
                 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
3008
                 *               if a bound type should be equal to the currently instrumented type.
3009
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
3010
                 */
3011
                Annotatable<U> typeVariable(String symbol, List<? extends Type> bounds);
3012

3013
                /**
3014
                 * Defines a method variable to be declared by the currently defined method.
3015
                 *
3016
                 * @param symbol The symbol of the type variable.
3017
                 * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
3018
                 *               if a bound type should be equal to the currently instrumented type.
3019
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
3020
                 */
3021
                Annotatable<U> typeVariable(String symbol, TypeDefinition... bound);
3022

3023
                /**
3024
                 * Defines a method variable to be declared by the currently defined method.
3025
                 *
3026
                 * @param symbol The symbol of the type variable.
3027
                 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
3028
                 *               if a bound type should be equal to the currently instrumented type.
3029
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
3030
                 */
3031
                Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
3032

3033
                /**
3034
                 * A builder for optionally defining an annotation for a type variable.
3035
                 *
3036
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3037
                 */
3038
                interface Annotatable<V> extends TypeVariableDefinition<V> {
3039

3040
                    /**
3041
                     * Annotates the previously defined type variable with the supplied annotations.
3042
                     *
3043
                     * @param annotation The annotations to declare on the previously defined type variable.
3044
                     * @return A new builder that is equal to this builder but with the given annotations declared
3045
                     * on the previously defined type variable.
3046
                     */
3047
                    Annotatable<V> annotateTypeVariable(Annotation... annotation);
3048

3049
                    /**
3050
                     * Annotates the previously defined type variable with the supplied annotations.
3051
                     *
3052
                     * @param annotations The annotations to declare on the previously defined type variable.
3053
                     * @return A new builder that is equal to this builder but with the given annotations declared
3054
                     * on the previously defined type variable.
3055
                     */
3056
                    Annotatable<V> annotateTypeVariable(List<? extends Annotation> annotations);
3057

3058
                    /**
3059
                     * Annotates the previously defined type variable with the supplied annotations.
3060
                     *
3061
                     * @param annotation The annotations to declare on the previously defined type variable.
3062
                     * @return A new builder that is equal to this builder but with the given annotations declared
3063
                     * on the previously defined type variable.
3064
                     */
3065
                    Annotatable<V> annotateTypeVariable(AnnotationDescription... annotation);
3066

3067
                    /**
3068
                     * Annotates the previously defined type variable with the supplied annotations.
3069
                     *
3070
                     * @param annotations The annotations to declare on the previously defined type variable.
3071
                     * @return A new builder that is equal to this builder but with the given annotations declared
3072
                     * on the previously defined type variable.
3073
                     */
3074
                    Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
3075

3076
                    /**
3077
                     * An abstract base implementation for defining an annotation on a parameter.
3078
                     *
3079
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3080
                     */
3081
                    abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
3082

3083
                        /**
3084
                         * {@inheritDoc}
3085
                         */
3086
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
UNCOV
3087
                            return annotateTypeVariable(Arrays.asList(annotation));
×
3088
                        }
3089

3090
                        /**
3091
                         * {@inheritDoc}
3092
                         */
3093
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
UNCOV
3094
                            return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
3095
                        }
3096

3097
                        /**
3098
                         * {@inheritDoc}
3099
                         */
3100
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
3101
                            return annotateTypeVariable(Arrays.asList(annotation));
1✔
3102
                        }
3103

3104
                        /**
3105
                         * An adapter implementation for an annotatable type variable definition.
3106
                         *
3107
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3108
                         */
3109
                        protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
1✔
3110

3111
                            /**
3112
                             * {@inheritDoc}
3113
                             */
3114
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3115
                                return materialize().typeVariable(symbol, bounds);
1✔
3116
                            }
3117

3118
                            /**
3119
                             * {@inheritDoc}
3120
                             */
3121
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
3122
                                return materialize().intercept(implementation);
1✔
3123
                            }
3124

3125
                            /**
3126
                             * {@inheritDoc}
3127
                             */
3128
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3129
                                return materialize().withoutCode();
1✔
3130
                            }
3131

3132
                            /**
3133
                             * {@inheritDoc}
3134
                             */
3135
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
3136
                                return materialize().defaultValue(annotationValue);
×
3137
                            }
3138

3139
                            /**
3140
                             * {@inheritDoc}
3141
                             */
3142
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
3143
                                return materialize().defaultValue(value, type);
×
3144
                            }
3145

3146
                            /**
3147
                             * Materializes this instance as a parameter definition with the currently defined properties.
3148
                             *
3149
                             * @return A parameter definition with the currently defined properties.
3150
                             */
3151
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
3152
                        }
3153
                    }
3154
                }
3155

3156
                /**
3157
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
3158
                 *
3159
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3160
                 */
3161
                abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
1✔
3162

3163
                    /**
3164
                     * {@inheritDoc}
3165
                     */
3166
                    public Annotatable<V> typeVariable(String symbol) {
3167
                        return typeVariable(symbol, Collections.singletonList(Object.class));
1✔
3168
                    }
3169

3170
                    /**
3171
                     * {@inheritDoc}
3172
                     */
3173
                    public Annotatable<V> typeVariable(String symbol, Type... bound) {
3174
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
3175
                    }
3176

3177
                    /**
3178
                     * {@inheritDoc}
3179
                     */
3180
                    public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
3181
                        return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
3182
                    }
3183

3184
                    /**
3185
                     * {@inheritDoc}
3186
                     */
3187
                    public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
3188
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
3189
                    }
3190
                }
3191
            }
3192

3193
            /**
3194
             * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
3195
             *
3196
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3197
             */
3198
            interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
3199

3200
                /**
3201
                 * Defines a method variable to be declared by the currently defined method.
3202
                 *
3203
                 * @param type The type of the exception being declared by the currently defined method.
3204
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
3205
                 */
3206
                ExceptionDefinition<U> throwing(Type... type);
3207

3208
                /**
3209
                 * Defines a method variable to be declared by the currently defined method.
3210
                 *
3211
                 * @param types The type of the exception being declared by the currently defined method.
3212
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
3213
                 */
3214
                ExceptionDefinition<U> throwing(List<? extends Type> types);
3215

3216
                /**
3217
                 * Defines a method variable to be declared by the currently defined method.
3218
                 *
3219
                 * @param type The type of the exception being declared by the currently defined method.
3220
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
3221
                 */
3222
                ExceptionDefinition<U> throwing(TypeDefinition... type);
3223

3224
                /**
3225
                 * Defines a method variable to be declared by the currently defined method.
3226
                 *
3227
                 * @param types The type of the exception being declared by the currently defined method.
3228
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
3229
                 */
3230
                ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
3231

3232
                /**
3233
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
3234
                 *
3235
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3236
                 */
3237
                abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
1✔
3238

3239
                    /**
3240
                     * {@inheritDoc}
3241
                     */
3242
                    public ExceptionDefinition<V> throwing(Type... type) {
3243
                        return throwing(Arrays.asList(type));
1✔
3244
                    }
3245

3246
                    /**
3247
                     * {@inheritDoc}
3248
                     */
3249
                    public ExceptionDefinition<V> throwing(List<? extends Type> types) {
3250
                        return throwing(new TypeList.Generic.ForLoadedTypes(types));
1✔
3251
                    }
3252

3253
                    /**
3254
                     * {@inheritDoc}
3255
                     */
3256
                    public ExceptionDefinition<V> throwing(TypeDefinition... type) {
3257
                        return throwing(Arrays.asList(type));
1✔
3258
                    }
3259
                }
3260
            }
3261

3262
            /**
3263
             * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
3264
             *
3265
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3266
             */
3267
            interface ParameterDefinition<U> extends ExceptionDefinition<U> {
3268

3269
                /**
3270
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3271
                 *
3272
                 * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3273
                 *                            should be equal to the currently instrumented type.
3274
                 * @param name                The parameter's name.
3275
                 * @param modifierContributor The parameter's modifiers.
3276
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3277
                 */
3278
                Annotatable<U> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor);
3279

3280
                /**
3281
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3282
                 *
3283
                 * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3284
                 *                             should be equal to the currently instrumented type.
3285
                 * @param name                 The parameter's name.
3286
                 * @param modifierContributors The parameter's modifiers.
3287
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3288
                 */
3289
                Annotatable<U> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
3290

3291
                /**
3292
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3293
                 *
3294
                 * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3295
                 *                  should be equal to the currently instrumented type.
3296
                 * @param name      The parameter's name.
3297
                 * @param modifiers The parameter's modifiers.
3298
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3299
                 */
3300
                Annotatable<U> withParameter(Type type, String name, int modifiers);
3301

3302
                /**
3303
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3304
                 *
3305
                 * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3306
                 *                            should be equal to the currently instrumented type.
3307
                 * @param name                The parameter's name.
3308
                 * @param modifierContributor The parameter's modifiers.
3309
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3310
                 */
3311
                Annotatable<U> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor);
3312

3313
                /**
3314
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3315
                 *
3316
                 * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3317
                 *                             should be equal to the currently instrumented type.
3318
                 * @param name                 The parameter's name.
3319
                 * @param modifierContributors The parameter's modifiers.
3320
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3321
                 */
3322
                Annotatable<U> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
3323

3324
                /**
3325
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3326
                 *
3327
                 * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3328
                 *                  should be equal to the currently instrumented type.
3329
                 * @param name      The parameter's name.
3330
                 * @param modifiers The parameter's modifiers.
3331
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3332
                 */
3333
                Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers);
3334

3335
                /**
3336
                 * A builder for optionally defining an annotation on a parameter.
3337
                 *
3338
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3339
                 */
3340
                interface Annotatable<V> extends ParameterDefinition<V> {
3341

3342
                    /**
3343
                     * Annotates the previously defined parameter with the specified annotations.
3344
                     *
3345
                     * @param annotation The annotations to declare on the previously defined parameter.
3346
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3347
                     * the specified annotations.
3348
                     */
3349
                    Annotatable<V> annotateParameter(Annotation... annotation);
3350

3351
                    /**
3352
                     * Annotates the previously defined parameter with the specified annotations.
3353
                     *
3354
                     * @param annotations The annotations to declare on the previously defined parameter.
3355
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3356
                     * the specified annotations.
3357
                     */
3358
                    Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
3359

3360
                    /**
3361
                     * Annotates the previously defined parameter with the specified annotations.
3362
                     *
3363
                     * @param annotation The annotations to declare on the previously defined parameter.
3364
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3365
                     * the specified annotations.
3366
                     */
3367
                    Annotatable<V> annotateParameter(AnnotationDescription... annotation);
3368

3369
                    /**
3370
                     * Annotates the previously defined parameter with the specified annotations.
3371
                     *
3372
                     * @param annotations The annotations to declare on the previously defined parameter.
3373
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3374
                     * the specified annotations.
3375
                     */
3376
                    Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
3377

3378
                    /**
3379
                     * An abstract base implementation for defining an annotation on a parameter.
3380
                     *
3381
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3382
                     */
3383
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
3384

3385
                        /**
3386
                         * {@inheritDoc}
3387
                         */
3388
                        public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
UNCOV
3389
                            return annotateParameter(Arrays.asList(annotation));
×
3390
                        }
3391

3392
                        /**
3393
                         * {@inheritDoc}
3394
                         */
3395
                        public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
UNCOV
3396
                            return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
3397
                        }
3398

3399
                        /**
3400
                         * {@inheritDoc}
3401
                         */
3402
                        public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
UNCOV
3403
                            return annotateParameter(Arrays.asList(annotation));
×
3404
                        }
3405

3406
                        /**
3407
                         * An adapter implementation for defining an annotation on a parameter.
3408
                         *
3409
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3410
                         */
3411
                        protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
1✔
3412

3413
                            /**
3414
                             * {@inheritDoc}
3415
                             */
3416
                            public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
UNCOV
3417
                                return materialize().withParameter(type, name, modifiers);
×
3418
                            }
3419

3420
                            /**
3421
                             * {@inheritDoc}
3422
                             */
3423
                            public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
3424
                                return materialize().throwing(types);
1✔
3425
                            }
3426

3427
                            /**
3428
                             * {@inheritDoc}
3429
                             */
3430
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
UNCOV
3431
                                return materialize().typeVariable(symbol, bounds);
×
3432
                            }
3433

3434
                            /**
3435
                             * {@inheritDoc}
3436
                             */
3437
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
UNCOV
3438
                                return materialize().intercept(implementation);
×
3439
                            }
3440

3441
                            /**
3442
                             * {@inheritDoc}
3443
                             */
3444
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
UNCOV
3445
                                return materialize().withoutCode();
×
3446
                            }
3447

3448
                            /**
3449
                             * {@inheritDoc}
3450
                             */
3451
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
UNCOV
3452
                                return materialize().defaultValue(annotationValue);
×
3453
                            }
3454

3455
                            /**
3456
                             * {@inheritDoc}
3457
                             */
3458
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
UNCOV
3459
                                return materialize().defaultValue(value, type);
×
3460
                            }
3461

3462
                            /**
3463
                             * Materializes this instance as a parameter definition with the currently defined properties.
3464
                             *
3465
                             * @return A parameter definition with the currently defined properties.
3466
                             */
3467
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
3468
                        }
3469
                    }
3470
                }
3471

3472
                /**
3473
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
3474
                 *
3475
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3476
                 */
3477
                interface Simple<V> extends ExceptionDefinition<V> {
3478

3479
                    /**
3480
                     * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3481
                     *
3482
                     * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3483
                     *             should be equal to the currently instrumented type.
3484
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3485
                     */
3486
                    Annotatable<V> withParameter(Type type);
3487

3488
                    /**
3489
                     * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3490
                     *
3491
                     * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3492
                     *             should be equal to the currently instrumented type.
3493
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3494
                     */
3495
                    Annotatable<V> withParameter(TypeDefinition type);
3496

3497
                    /**
3498
                     * A builder for optionally defining an annotation on a parameter.
3499
                     *
3500
                     * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3501
                     */
3502
                    interface Annotatable<V> extends Simple<V> {
3503

3504
                        /**
3505
                         * Annotates the previously defined parameter with the specified annotations.
3506
                         *
3507
                         * @param annotation The annotations to declare on the previously defined parameter.
3508
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3509
                         * the specified annotations.
3510
                         */
3511
                        Annotatable<V> annotateParameter(Annotation... annotation);
3512

3513
                        /**
3514
                         * Annotates the previously defined parameter with the specified annotations.
3515
                         *
3516
                         * @param annotations The annotations to declare on the previously defined parameter.
3517
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3518
                         * the specified annotations.
3519
                         */
3520
                        Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
3521

3522
                        /**
3523
                         * Annotates the previously defined parameter with the specified annotations.
3524
                         *
3525
                         * @param annotation The annotations to declare on the previously defined parameter.
3526
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3527
                         * the specified annotations.
3528
                         */
3529
                        Annotatable<V> annotateParameter(AnnotationDescription... annotation);
3530

3531
                        /**
3532
                         * Annotates the previously defined parameter with the specified annotations.
3533
                         *
3534
                         * @param annotations The annotations to declare on the previously defined parameter.
3535
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3536
                         * the specified annotations.
3537
                         */
3538
                        Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
3539

3540
                        /**
3541
                         * An abstract base implementation of a simple parameter definition.
3542
                         *
3543
                         * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3544
                         */
3545
                        abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
1✔
3546

3547
                            /**
3548
                             * {@inheritDoc}
3549
                             */
3550
                            public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
UNCOV
3551
                                return annotateParameter(Arrays.asList(annotation));
×
3552
                            }
3553

3554
                            /**
3555
                             * {@inheritDoc}
3556
                             */
3557
                            public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
UNCOV
3558
                                return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
3559
                            }
3560

3561
                            /**
3562
                             * {@inheritDoc}
3563
                             */
3564
                            public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
3565
                                return annotateParameter(Arrays.asList(annotation));
1✔
3566
                            }
3567

3568
                            /**
3569
                             * An adapter implementation of a simple parameter definition.
3570
                             *
3571
                             * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3572
                             */
3573
                            protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
1✔
3574

3575
                                /**
3576
                                 * {@inheritDoc}
3577
                                 */
3578
                                public Simple.Annotatable<X> withParameter(TypeDefinition type) {
3579
                                    return materialize().withParameter(type);
1✔
3580
                                }
3581

3582
                                /**
3583
                                 * {@inheritDoc}
3584
                                 */
3585
                                public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
3586
                                    return materialize().throwing(types);
1✔
3587
                                }
3588

3589
                                /**
3590
                                 * {@inheritDoc}
3591
                                 */
3592
                                public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
UNCOV
3593
                                    return materialize().typeVariable(symbol, bounds);
×
3594
                                }
3595

3596
                                /**
3597
                                 * {@inheritDoc}
3598
                                 */
3599
                                public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
3600
                                    return materialize().intercept(implementation);
1✔
3601
                                }
3602

3603
                                /**
3604
                                 * {@inheritDoc}
3605
                                 */
3606
                                public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3607
                                    return materialize().withoutCode();
1✔
3608
                                }
3609

3610
                                /**
3611
                                 * {@inheritDoc}
3612
                                 */
3613
                                public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
UNCOV
3614
                                    return materialize().defaultValue(annotationValue);
×
3615
                                }
3616

3617
                                /**
3618
                                 * {@inheritDoc}
3619
                                 */
3620
                                public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
UNCOV
3621
                                    return materialize().defaultValue(value, type);
×
3622
                                }
3623

3624
                                /**
3625
                                 * Materializes this instance as a simple parameter definition with the currently defined properties.
3626
                                 *
3627
                                 * @return A simple parameter definition with the currently defined properties.
3628
                                 */
3629
                                protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
3630
                            }
3631
                        }
3632
                    }
3633

3634
                    /**
3635
                     * An abstract base implementation of an exception definition.
3636
                     *
3637
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3638
                     */
3639
                    abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
1✔
3640

3641
                        /**
3642
                         * {@inheritDoc}
3643
                         */
3644
                        public Simple.Annotatable<W> withParameter(Type type) {
3645
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
3646
                        }
3647
                    }
3648
                }
3649

3650
                /**
3651
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
3652
                 * Implementations allow for the <i>one-by-one</i> definition of parameters what gives opportunity to annotate parameters in a fluent
3653
                 * style. Doing so, it is optionally possible to define parameter names and modifiers. This can be done for either all or no parameters.
3654
                 * Alternatively, parameters without annotations, names or modifiers can be defined by a single step.
3655
                 *
3656
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3657
                 */
3658
                interface Initial<V> extends ParameterDefinition<V>, Simple<V> {
3659

3660
                    /**
3661
                     * Defines the specified parameters for the currently defined method.
3662
                     *
3663
                     * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3664
                     *             should be equal to the currently instrumented type.
3665
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
3666
                     */
3667
                    ExceptionDefinition<V> withParameters(Type... type);
3668

3669
                    /**
3670
                     * Defines the specified parameters for the currently defined method.
3671
                     *
3672
                     * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3673
                     *              should be equal to the currently instrumented type.
3674
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
3675
                     */
3676
                    ExceptionDefinition<V> withParameters(List<? extends Type> types);
3677

3678
                    /**
3679
                     * Defines the specified parameters for the currently defined method.
3680
                     *
3681
                     * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3682
                     *             should be equal to the currently instrumented type.
3683
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
3684
                     */
3685
                    ExceptionDefinition<V> withParameters(TypeDefinition... type);
3686

3687
                    /**
3688
                     * Defines the specified parameters for the currently defined method.
3689
                     *
3690
                     * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3691
                     *              should be equal to the currently instrumented type.
3692
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
3693
                     */
3694
                    ExceptionDefinition<V> withParameters(Collection<? extends TypeDefinition> types);
3695

3696
                    /**
3697
                     * An abstract base implementation for an initial parameter definition.
3698
                     *
3699
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3700
                     */
3701
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
1✔
3702

3703
                        /**
3704
                         * {@inheritDoc}
3705
                         */
3706
                        public Simple.Annotatable<W> withParameter(Type type) {
3707
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
3708
                        }
3709

3710
                        /**
3711
                         * {@inheritDoc}
3712
                         */
3713
                        public ExceptionDefinition<W> withParameters(Type... type) {
3714
                            return withParameters(Arrays.asList(type));
1✔
3715
                        }
3716

3717
                        /**
3718
                         * {@inheritDoc}
3719
                         */
3720
                        public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
3721
                            return withParameters(new TypeList.Generic.ForLoadedTypes(types));
1✔
3722
                        }
3723

3724
                        /**
3725
                         * {@inheritDoc}
3726
                         */
3727
                        public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
3728
                            return withParameters(Arrays.asList(type));
1✔
3729
                        }
3730

3731
                        /**
3732
                         * {@inheritDoc}
3733
                         */
3734
                        public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
3735
                            ParameterDefinition.Simple<W> parameterDefinition = this;
1✔
3736
                            for (TypeDefinition type : types) {
1✔
3737
                                parameterDefinition = parameterDefinition.withParameter(type);
1✔
3738
                            }
1✔
3739
                            return parameterDefinition;
1✔
3740
                        }
3741
                    }
3742
                }
3743

3744
                /**
3745
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable, thrown exception or parameter type.
3746
                 *
3747
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3748
                 */
3749
                abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
1✔
3750

3751
                    /**
3752
                     * {@inheritDoc}
3753
                     */
3754
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
3755
                        return withParameter(type, name, Arrays.asList(modifierContributor));
1✔
3756
                    }
3757

3758
                    /**
3759
                     * {@inheritDoc}
3760
                     */
3761
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
3762
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3763
                    }
3764

3765
                    /**
3766
                     * {@inheritDoc}
3767
                     */
3768
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
3769
                        return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
1✔
3770
                    }
3771

3772
                    /**
3773
                     * {@inheritDoc}
3774
                     */
3775
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
UNCOV
3776
                        return withParameter(type, name, Arrays.asList(modifierContributor));
×
3777
                    }
3778

3779
                    /**
3780
                     * {@inheritDoc}
3781
                     */
3782
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
UNCOV
3783
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
3784
                    }
3785
                }
3786
            }
3787

3788
            /**
3789
             * An abstract base implementation of a method definition.
3790
             *
3791
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3792
             */
3793
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
1✔
3794

3795
                /**
3796
                 * {@inheritDoc}
3797
                 */
3798
                public MethodDefinition<U> annotateMethod(Annotation... annotation) {
3799
                    return annotateMethod(Arrays.asList(annotation));
1✔
3800
                }
3801

3802
                /**
3803
                 * {@inheritDoc}
3804
                 */
3805
                public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
3806
                    return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
3807
                }
3808

3809
                /**
3810
                 * {@inheritDoc}
3811
                 */
3812
                public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
3813
                    return annotateMethod(Arrays.asList(annotation));
1✔
3814
                }
3815

3816
                /**
3817
                 * {@inheritDoc}
3818
                 */
3819
                public MethodDefinition<U> annotateParameter(int index, Annotation... annotation) {
UNCOV
3820
                    return annotateParameter(index, Arrays.asList(annotation));
×
3821
                }
3822

3823
                /**
3824
                 * {@inheritDoc}
3825
                 */
3826
                public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
UNCOV
3827
                    return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
×
3828
                }
3829

3830
                /**
3831
                 * {@inheritDoc}
3832
                 */
3833
                public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
UNCOV
3834
                    return annotateParameter(index, Arrays.asList(annotation));
×
3835
                }
3836

3837
                /**
3838
                 * An adapter implementation of a method definition.
3839
                 *
3840
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3841
                 */
3842
                @HashCodeAndEqualsPlugin.Enhance
3843
                protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
3844

3845
                    /**
3846
                     * The handler that determines how a method is implemented.
3847
                     */
3848
                    protected final MethodRegistry.Handler handler;
3849

3850
                    /**
3851
                     * The method attribute appender factory to apply onto the method that is currently being implemented.
3852
                     */
3853
                    protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
3854

3855
                    /**
3856
                     * The transformer to apply onto the method that is currently being implemented.
3857
                     */
3858
                    protected final Transformer<MethodDescription> transformer;
3859

3860
                    /**
3861
                     * Creates a new adapter for a method definition.
3862
                     *
3863
                     * @param handler                        The handler that determines how a method is implemented.
3864
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3865
                     * @param transformer                    The transformer to apply onto the method that is currently being implemented.
3866
                     */
3867
                    protected Adapter(MethodRegistry.Handler handler,
3868
                                      MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3869
                                      Transformer<MethodDescription> transformer) {
1✔
3870
                        this.handler = handler;
1✔
3871
                        this.methodAttributeAppenderFactory = methodAttributeAppenderFactory;
1✔
3872
                        this.transformer = transformer;
1✔
3873
                    }
1✔
3874

3875
                    /**
3876
                     * {@inheritDoc}
3877
                     */
3878
                    public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
3879
                        return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), transformer);
1✔
3880
                    }
3881

3882
                    /**
3883
                     * {@inheritDoc}
3884
                     */
3885
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
3886
                    public MethodDefinition<V> transform(Transformer<MethodDescription> transformer) {
3887
                        return materialize(handler, methodAttributeAppenderFactory, new Transformer.Compound<MethodDescription>(this.transformer, transformer));
1✔
3888
                    }
3889

3890
                    /**
3891
                     * Materializes the current builder as a method definition.
3892
                     *
3893
                     * @param handler                        The handler that determines how a method is implemented.
3894
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3895
                     * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
3896
                     * @return Returns a method definition for the supplied properties.
3897
                     */
3898
                    protected abstract MethodDefinition<V> materialize(MethodRegistry.Handler handler,
3899
                                                                       MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3900
                                                                       Transformer<MethodDescription> transformer);
3901
                }
3902
            }
3903
        }
3904

3905
        /**
3906
         * A builder for a record component definition.
3907
         *
3908
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3909
         */
3910
        interface RecordComponentDefinition<S> {
3911

3912
            /**
3913
             * Annotates the record component with the supplied annotations.
3914
             *
3915
             * @param annotation The annotations to declare.
3916
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3917
             */
3918
            Optional<S> annotateRecordComponent(Annotation... annotation);
3919

3920
            /**
3921
             * Annotates the record component with the supplied annotations.
3922
             *
3923
             * @param annotations The annotations to declare.
3924
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3925
             */
3926
            Optional<S> annotateRecordComponent(List<? extends Annotation> annotations);
3927

3928
            /**
3929
             * Annotates the record component with the supplied annotations.
3930
             *
3931
             * @param annotation The annotations to declare.
3932
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3933
             */
3934
            Optional<S> annotateRecordComponent(AnnotationDescription... annotation);
3935

3936
            /**
3937
             * Annotates the record component with the supplied annotations.
3938
             *
3939
             * @param annotations The annotations to declare.
3940
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3941
             */
3942
            Optional<S> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations);
3943

3944
            /**
3945
             * Applies the supplied record component attribute appender factory onto the previously defined record component.
3946
             *
3947
             * @param recordComponentAttributeAppenderFactory The record component attribute appender factory that should be applied on the
3948
             *                                                previously defined or matched method.
3949
             * @return A new builder that is equal to this builder but with the supplied record component attribute appender factory
3950
             * applied to the previously defined record component.
3951
             */
3952
            Optional<S> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory);
3953

3954
            /**
3955
             * Transforms a record component description before writing.
3956
             *
3957
             * @param transformer The transformer to apply.
3958
             * @return new builder that is equal to this builder but with the supplied transformer being applied.
3959
             */
3960
            Optional<S> transform(Transformer<RecordComponentDescription> transformer);
3961

3962
            /**
3963
             * A {@link RecordComponentDefinition} as an optional build step.
3964
             *
3965
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3966
             */
3967
            interface Optional<U> extends RecordComponentDefinition<U>, Builder<U> {
3968

3969
                /**
3970
                 * An abstract base implementation of a record definition.
3971
                 *
3972
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3973
                 */
UNCOV
3974
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements RecordComponentDefinition.Optional<U> {
×
3975

3976
                    /**
3977
                     * {@inheritDoc}
3978
                     */
3979
                    public Optional<U> annotateRecordComponent(Annotation... annotation) {
UNCOV
3980
                        return annotateRecordComponent(Arrays.asList(annotation));
×
3981
                    }
3982

3983
                    /**
3984
                     * {@inheritDoc}
3985
                     */
3986
                    public Optional<U> annotateRecordComponent(List<? extends Annotation> annotations) {
UNCOV
3987
                        return annotateRecordComponent(new AnnotationList.ForLoadedAnnotations(annotations));
×
3988
                    }
3989

3990
                    /**
3991
                     * {@inheritDoc}
3992
                     */
3993
                    public Optional<U> annotateRecordComponent(AnnotationDescription... annotation) {
UNCOV
3994
                        return annotateRecordComponent(Arrays.asList(annotation));
×
3995
                    }
3996
                }
3997
            }
3998
        }
3999

4000
        /**
4001
         * An abstract base implementation of a dynamic type builder.
4002
         *
4003
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
4004
         */
4005
        abstract class AbstractBase<S> implements Builder<S> {
1✔
4006

4007
            /**
4008
             * {@inheritDoc}
4009
             */
4010
            public ModuleDefinition<S> module(String name, ModifierContributor.ForModule... modifierContributors) {
UNCOV
4011
                return module(name, Arrays.asList(modifierContributors));
×
4012
            }
4013

4014
            /**
4015
             * {@inheritDoc}
4016
             */
4017
            public ModuleDefinition<S> module(String name, Collection<? extends ModifierContributor.ForModule> modifierContributors) {
UNCOV
4018
                return module(name, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
4019
            }
4020

4021
            /**
4022
             * {@inheritDoc}
4023
             */
4024
            public InnerTypeDefinition.ForType<S> innerTypeOf(Class<?> type) {
4025
                return innerTypeOf(TypeDescription.ForLoadedType.of(type));
1✔
4026
            }
4027

4028
            /**
4029
             * {@inheritDoc}
4030
             */
4031
            public InnerTypeDefinition<S> innerTypeOf(Method method) {
4032
                return innerTypeOf(new MethodDescription.ForLoadedMethod(method));
1✔
4033
            }
4034

4035
            /**
4036
             * {@inheritDoc}
4037
             */
4038
            public InnerTypeDefinition<S> innerTypeOf(Constructor<?> constructor) {
4039
                return innerTypeOf(new MethodDescription.ForLoadedConstructor(constructor));
1✔
4040
            }
4041

4042
            /**
4043
             * {@inheritDoc}
4044
             */
4045
            public Builder<S> declaredTypes(Class<?>... type) {
UNCOV
4046
                return declaredTypes(Arrays.asList(type));
×
4047
            }
4048

4049
            /**
4050
             * {@inheritDoc}
4051
             */
4052
            public Builder<S> declaredTypes(TypeDescription... type) {
4053
                return declaredTypes(Arrays.asList(type));
1✔
4054
            }
4055

4056
            /**
4057
             * {@inheritDoc}
4058
             */
4059
            public Builder<S> declaredTypes(List<? extends Class<?>> type) {
UNCOV
4060
                return declaredTypes(new TypeList.ForLoadedTypes(type));
×
4061
            }
4062

4063
            /**
4064
             * {@inheritDoc}
4065
             */
4066
            public Builder<S> noNestMate() {
UNCOV
4067
                return nestHost(TargetType.DESCRIPTION);
×
4068
            }
4069

4070
            /**
4071
             * {@inheritDoc}
4072
             */
4073
            public Builder<S> nestHost(Class<?> type) {
UNCOV
4074
                return nestHost(TypeDescription.ForLoadedType.of(type));
×
4075
            }
4076

4077
            /**
4078
             * {@inheritDoc}
4079
             */
4080
            public Builder<S> nestMembers(Class<?>... type) {
4081
                return nestMembers(Arrays.asList(type));
1✔
4082
            }
4083

4084
            /**
4085
             * {@inheritDoc}
4086
             */
4087
            public Builder<S> nestMembers(TypeDescription... type) {
UNCOV
4088
                return nestMembers(Arrays.asList(type));
×
4089
            }
4090

4091
            /**
4092
             * {@inheritDoc}
4093
             */
4094
            public Builder<S> nestMembers(List<? extends Class<?>> types) {
4095
                return nestMembers(new TypeList.ForLoadedTypes(types));
1✔
4096
            }
4097

4098
            /**
4099
             * {@inheritDoc}
4100
             */
4101
            public Builder<S> permittedSubclass(Class<?>... type) {
UNCOV
4102
                return permittedSubclass(Arrays.asList(type));
×
4103
            }
4104

4105
            /**
4106
             * {@inheritDoc}
4107
             */
4108
            public Builder<S> permittedSubclass(TypeDescription... type) {
UNCOV
4109
                return permittedSubclass(Arrays.asList(type));
×
4110
            }
4111

4112
            /**
4113
             * {@inheritDoc}
4114
             */
4115
            public Builder<S> permittedSubclass(List<? extends Class<?>> types) {
UNCOV
4116
                return permittedSubclass(new TypeList.ForLoadedTypes(types));
×
4117
            }
4118

4119
            /**
4120
             * {@inheritDoc}
4121
             */
4122
            public Builder<S> annotateType(Annotation... annotation) {
4123
                return annotateType(Arrays.asList(annotation));
1✔
4124
            }
4125

4126
            /**
4127
             * {@inheritDoc}
4128
             */
4129
            public Builder<S> annotateType(List<? extends Annotation> annotations) {
4130
                return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
4131
            }
4132

4133
            /**
4134
             * {@inheritDoc}
4135
             */
4136
            public Builder<S> annotateType(AnnotationDescription... annotation) {
4137
                return annotateType(Arrays.asList(annotation));
1✔
4138
            }
4139

4140
            /**
4141
             * {@inheritDoc}
4142
             */
4143
            public Builder<S> modifiers(ModifierContributor.ForType... modifierContributor) {
4144
                return modifiers(Arrays.asList(modifierContributor));
1✔
4145
            }
4146

4147
            /**
4148
             * {@inheritDoc}
4149
             */
4150
            public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4151
                return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4152
            }
4153

4154
            /**
4155
             * {@inheritDoc}
4156
             */
4157
            public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
4158
                return merge(Arrays.asList(modifierContributor));
1✔
4159
            }
4160

4161
            /**
4162
             * {@inheritDoc}
4163
             */
4164
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(Type... interfaceType) {
4165
                return implement(Arrays.asList(interfaceType));
1✔
4166
            }
4167

4168
            /**
4169
             * {@inheritDoc}
4170
             */
4171
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
4172
                return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
1✔
4173
            }
4174

4175
            /**
4176
             * {@inheritDoc}
4177
             */
4178
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
4179
                return implement(Arrays.asList(interfaceType));
1✔
4180
            }
4181

4182
            /**
4183
             * {@inheritDoc}
4184
             */
4185
            public TypeVariableDefinition<S> typeVariable(String symbol) {
4186
                return typeVariable(symbol, TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class));
1✔
4187
            }
4188

4189
            /**
4190
             * {@inheritDoc}
4191
             */
4192
            public TypeVariableDefinition<S> typeVariable(String symbol, Type... bound) {
4193
                return typeVariable(symbol, Arrays.asList(bound));
1✔
4194
            }
4195

4196
            /**
4197
             * {@inheritDoc}
4198
             */
4199
            public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
4200
                return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
4201
            }
4202

4203
            /**
4204
             * {@inheritDoc}
4205
             */
4206
            public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
4207
                return typeVariable(symbol, Arrays.asList(bound));
1✔
4208
            }
4209

4210
            /**
4211
             * {@inheritDoc}
4212
             */
4213
            public RecordComponentDefinition.Optional<S> defineRecordComponent(String name, Type type) {
UNCOV
4214
                return defineRecordComponent(name, TypeDefinition.Sort.describe(type));
×
4215
            }
4216

4217
            /**
4218
             * {@inheritDoc}
4219
             */
4220
            public RecordComponentDefinition.Optional<S> define(RecordComponentDescription recordComponentDescription) {
UNCOV
4221
                return defineRecordComponent(recordComponentDescription.getActualName(), recordComponentDescription.getType());
×
4222
            }
4223

4224
            /**
4225
             * {@inheritDoc}
4226
             */
4227
            public RecordComponentDefinition<S> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
UNCOV
4228
                return recordComponent(new LatentMatcher.Resolved<RecordComponentDescription>(matcher));
×
4229
            }
4230

4231
            /**
4232
             * {@inheritDoc}
4233
             */
4234
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor) {
4235
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
4236
            }
4237

4238
            /**
4239
             * {@inheritDoc}
4240
             */
4241
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
4242
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4243
            }
4244

4245
            /**
4246
             * {@inheritDoc}
4247
             */
4248
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
4249
                return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
1✔
4250
            }
4251

4252
            /**
4253
             * {@inheritDoc}
4254
             */
4255
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
4256
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
4257
            }
4258

4259
            /**
4260
             * {@inheritDoc}
4261
             */
4262
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
4263
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4264
            }
4265

4266
            /**
4267
             * {@inheritDoc}
4268
             */
4269
            public FieldDefinition.Optional.Valuable<S> define(Field field) {
UNCOV
4270
                return define(new FieldDescription.ForLoadedField(field));
×
4271
            }
4272

4273
            /**
4274
             * {@inheritDoc}
4275
             */
4276
            public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
UNCOV
4277
                return defineField(field.getName(), field.getType(), field.getModifiers());
×
4278
            }
4279

4280
            /**
4281
             * {@inheritDoc}
4282
             */
4283
            public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
4284
                return defineField("serialVersionUID", long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
1✔
4285
            }
4286

4287
            /**
4288
             * {@inheritDoc}
4289
             */
4290
            public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
4291
                return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
1✔
4292
            }
4293

4294
            /**
4295
             * {@inheritDoc}
4296
             */
4297
            public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
4298
                return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
1✔
4299
            }
4300

4301
            /**
4302
             * {@inheritDoc}
4303
             */
4304
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor) {
4305
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
4306
            }
4307

4308
            /**
4309
             * {@inheritDoc}
4310
             */
4311
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4312
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4313
            }
4314

4315
            /**
4316
             * {@inheritDoc}
4317
             */
4318
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
4319
                return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
1✔
4320
            }
4321

4322
            /**
4323
             * {@inheritDoc}
4324
             */
4325
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
4326
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
4327
            }
4328

4329
            /**
4330
             * {@inheritDoc}
4331
             */
4332
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4333
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4334
            }
4335

4336
            /**
4337
             * {@inheritDoc}
4338
             */
4339
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
4340
                return defineConstructor(Arrays.asList(modifierContributor));
1✔
4341
            }
4342

4343
            /**
4344
             * {@inheritDoc}
4345
             */
4346
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4347
                return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4348
            }
4349

4350
            /**
4351
             * {@inheritDoc}
4352
             */
4353
            public MethodDefinition.ImplementationDefinition<S> define(Method method) {
UNCOV
4354
                return define(new MethodDescription.ForLoadedMethod(method));
×
4355
            }
4356

4357
            /**
4358
             * {@inheritDoc}
4359
             */
4360
            public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
UNCOV
4361
                return define(new MethodDescription.ForLoadedConstructor(constructor));
×
4362
            }
4363

4364
            /**
4365
             * {@inheritDoc}
4366
             */
4367
            public MethodDefinition.ImplementationDefinition<S> define(MethodDescription methodDescription) {
UNCOV
4368
                MethodDefinition.ParameterDefinition.Initial<S> initialParameterDefinition = methodDescription.isConstructor()
×
UNCOV
4369
                        ? defineConstructor(methodDescription.getModifiers())
×
UNCOV
4370
                        : defineMethod(methodDescription.getInternalName(), methodDescription.getReturnType(), methodDescription.getModifiers());
×
UNCOV
4371
                ParameterList<?> parameterList = methodDescription.getParameters();
×
4372
                MethodDefinition.ExceptionDefinition<S> exceptionDefinition;
UNCOV
4373
                if (parameterList.hasExplicitMetaData()) {
×
UNCOV
4374
                    MethodDefinition.ParameterDefinition<S> parameterDefinition = initialParameterDefinition;
×
UNCOV
4375
                    for (ParameterDescription parameter : parameterList) {
×
UNCOV
4376
                        parameterDefinition = parameterDefinition.withParameter(parameter.getType(), parameter.getName(), parameter.getModifiers());
×
UNCOV
4377
                    }
×
UNCOV
4378
                    exceptionDefinition = parameterDefinition;
×
UNCOV
4379
                } else {
×
UNCOV
4380
                    exceptionDefinition = initialParameterDefinition.withParameters(parameterList.asTypeList());
×
4381
                }
UNCOV
4382
                MethodDefinition.TypeVariableDefinition<S> typeVariableDefinition = exceptionDefinition.throwing(methodDescription.getExceptionTypes());
×
UNCOV
4383
                for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
×
UNCOV
4384
                    typeVariableDefinition = typeVariableDefinition.typeVariable(typeVariable.getSymbol(), typeVariable.getUpperBounds());
×
UNCOV
4385
                }
×
UNCOV
4386
                return typeVariableDefinition;
×
4387
            }
4388

4389
            /**
4390
             * {@inheritDoc}
4391
             */
4392
            public FieldDefinition.Optional<S> defineProperty(String name, Type type) {
4393
                return defineProperty(name, TypeDefinition.Sort.describe(type));
1✔
4394
            }
4395

4396
            /**
4397
             * {@inheritDoc}
4398
             */
4399
            public FieldDefinition.Optional<S> defineProperty(String name, Type type, boolean readOnly) {
4400
                return defineProperty(name, TypeDefinition.Sort.describe(type), readOnly);
1✔
4401
            }
4402

4403
            /**
4404
             * {@inheritDoc}
4405
             */
4406
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type) {
4407
                return defineProperty(name, type, false);
1✔
4408
            }
4409

4410
            /**
4411
             * {@inheritDoc}
4412
             */
4413
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type, boolean readOnly) {
4414
                if (name.length() == 0) {
1✔
4415
                    throw new IllegalArgumentException("A bean property cannot have an empty name");
1✔
4416
                } else if (type.represents(void.class)) {
1✔
4417
                    throw new IllegalArgumentException("A bean property cannot have a void type");
1✔
4418
                }
4419
                DynamicType.Builder<S> builder = this;
1✔
4420
                FieldManifestation fieldManifestation;
4421
                if (!readOnly) {
1✔
4422
                    builder = builder
1✔
4423
                            .defineMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), void.class, Visibility.PUBLIC)
1✔
4424
                            .withParameters(type)
1✔
4425
                            .intercept(FieldAccessor.ofField(name));
1✔
4426
                    fieldManifestation = FieldManifestation.PLAIN;
1✔
4427
                } else {
4428
                    fieldManifestation = FieldManifestation.FINAL;
1✔
4429
                }
4430
                return builder
1✔
4431
                        .defineMethod((type.represents(boolean.class)
1✔
4432
                                ? "is"
4433
                                : "get") + Character.toUpperCase(name.charAt(0)) + name.substring(1), type, Visibility.PUBLIC)
1✔
4434
                        .intercept(FieldAccessor.ofField(name))
1✔
4435
                        .defineField(name, type, Visibility.PRIVATE, fieldManifestation);
1✔
4436
            }
4437

4438
            /**
4439
             * {@inheritDoc}
4440
             */
4441
            public MethodDefinition.ImplementationDefinition<S> method(ElementMatcher<? super MethodDescription> matcher) {
4442
                return invokable(isMethod().and(matcher));
1✔
4443
            }
4444

4445
            /**
4446
             * {@inheritDoc}
4447
             */
4448
            public MethodDefinition.ImplementationDefinition<S> constructor(ElementMatcher<? super MethodDescription> matcher) {
4449
                return invokable(isConstructor().and(matcher));
1✔
4450
            }
4451

4452
            /**
4453
             * {@inheritDoc}
4454
             */
4455
            public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
4456
                return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
1✔
4457
            }
4458

4459
            /**
4460
             * {@inheritDoc}
4461
             */
4462
            public Builder<S> withHashCodeEquals() {
4463
                return method(isHashCode())
1✔
4464
                        .intercept(HashCodeMethod.usingDefaultOffset().withIgnoredFields(isSynthetic()))
1✔
4465
                        .method(isEquals())
1✔
4466
                        .intercept(EqualsMethod.isolated().withIgnoredFields(isSynthetic()));
1✔
4467
            }
4468

4469
            /**
4470
             * {@inheritDoc}
4471
             */
4472
            public Builder<S> withToString() {
4473
                return method(isToString()).intercept(ToStringMethod.prefixedBySimpleClassName());
1✔
4474
            }
4475

4476
            /**
4477
             * {@inheritDoc}
4478
             */
4479
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation) {
4480
                return require(type, binaryRepresentation, LoadedTypeInitializer.NoOp.INSTANCE);
1✔
4481
            }
4482

4483
            /**
4484
             * {@inheritDoc}
4485
             */
4486
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer) {
4487
                return require(new Default(type, binaryRepresentation, typeInitializer, Collections.<DynamicType>emptyList()));
1✔
4488
            }
4489

4490
            /**
4491
             * {@inheritDoc}
4492
             */
4493
            public Builder<S> require(DynamicType... auxiliaryType) {
4494
                return require(Arrays.asList(auxiliaryType));
1✔
4495
            }
4496

4497
            /**
4498
             * {@inheritDoc}
4499
             */
4500
            public ContextClassVisitor wrap(ClassVisitor classVisitor) {
4501
                return wrap(classVisitor, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
1✔
4502
            }
4503

4504
            /**
4505
             * {@inheritDoc}
4506
             */
4507
            public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool) {
UNCOV
4508
                return wrap(classVisitor, typePool, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
×
4509
            }
4510

4511
            /**
4512
             * {@inheritDoc}
4513
             */
4514
            public Unloaded<S> make(TypePool typePool) {
4515
                return make(TypeResolutionStrategy.Passive.INSTANCE, typePool);
1✔
4516
            }
4517

4518
            /**
4519
             * {@inheritDoc}
4520
             */
4521
            public Unloaded<S> make() {
4522
                return make(TypeResolutionStrategy.Passive.INSTANCE);
1✔
4523
            }
4524

4525
            /**
4526
             * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
4527
             *
4528
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4529
             */
4530
            public abstract static class Delegator<U> extends AbstractBase<U> {
1✔
4531

4532
                /**
4533
                 * {@inheritDoc}
4534
                 */
4535
                public ModuleDefinition<U> module(String name, int modifiers) {
UNCOV
4536
                    return materialize().module(name, modifiers);
×
4537
                }
4538

4539
                /**
4540
                 * {@inheritDoc}
4541
                 */
4542
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
4543
                    return materialize().visit(asmVisitorWrapper);
1✔
4544
                }
4545

4546
                /**
4547
                 * {@inheritDoc}
4548
                 */
4549
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
4550
                    return materialize().initializer(loadedTypeInitializer);
1✔
4551
                }
4552

4553
                /**
4554
                 * {@inheritDoc}
4555
                 */
4556
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
UNCOV
4557
                    return materialize().annotateType(annotations);
×
4558
                }
4559

4560
                /**
4561
                 * {@inheritDoc}
4562
                 */
4563
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
UNCOV
4564
                    return materialize().attribute(typeAttributeAppender);
×
4565
                }
4566

4567
                /**
4568
                 * {@inheritDoc}
4569
                 */
4570
                public Builder<U> modifiers(int modifiers) {
4571
                    return materialize().modifiers(modifiers);
1✔
4572
                }
4573

4574
                /**
4575
                 * {@inheritDoc}
4576
                 */
4577
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
UNCOV
4578
                    return materialize().merge(modifierContributors);
×
4579
                }
4580

4581
                /**
4582
                 * {@inheritDoc}
4583
                 */
4584
                public Builder<U> suffix(String suffix) {
UNCOV
4585
                    return materialize().suffix(suffix);
×
4586
                }
4587

4588
                /**
4589
                 * {@inheritDoc}
4590
                 */
4591
                public Builder<U> name(String name) {
4592
                    return materialize().name(name);
1✔
4593
                }
4594

4595
                /**
4596
                 * {@inheritDoc}
4597
                 */
4598
                public Builder<U> topLevelType() {
UNCOV
4599
                    return materialize().topLevelType();
×
4600
                }
4601

4602
                /**
4603
                 * {@inheritDoc}
4604
                 */
4605
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
UNCOV
4606
                    return materialize().innerTypeOf(type);
×
4607
                }
4608

4609
                /**
4610
                 * {@inheritDoc}
4611
                 */
4612
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
UNCOV
4613
                    return materialize().innerTypeOf(methodDescription);
×
4614
                }
4615

4616
                /**
4617
                 * {@inheritDoc}
4618
                 */
4619
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
4620
                    return materialize().declaredTypes(types);
1✔
4621
                }
4622

4623
                /**
4624
                 * {@inheritDoc}
4625
                 */
4626
                public Builder<U> nestHost(TypeDescription type) {
UNCOV
4627
                    return materialize().nestHost(type);
×
4628
                }
4629

4630
                /**
4631
                 * {@inheritDoc}
4632
                 */
4633
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
UNCOV
4634
                    return materialize().nestMembers(types);
×
4635
                }
4636

4637
                /**
4638
                 * {@inheritDoc}
4639
                 */
4640
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
UNCOV
4641
                    return materialize().permittedSubclass(types);
×
4642
                }
4643

4644
                /**
4645
                 * {@inheritDoc}
4646
                 */
4647
                public Builder<U> unsealed() {
UNCOV
4648
                    return materialize().unsealed();
×
4649
                }
4650

4651
                /**
4652
                 * {@inheritDoc}
4653
                 */
4654
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
4655
                    return materialize().implement(interfaceTypes);
1✔
4656
                }
4657

4658
                /**
4659
                 * {@inheritDoc}
4660
                 */
4661
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
4662
                    return materialize().initializer(byteCodeAppender);
1✔
4663
                }
4664

4665
                /**
4666
                 * {@inheritDoc}
4667
                 */
4668
                public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
4669
                    return materialize().ignoreAlso(ignoredMethods);
1✔
4670
                }
4671

4672
                /**
4673
                 * {@inheritDoc}
4674
                 */
4675
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
UNCOV
4676
                    return materialize().ignoreAlso(ignoredMethods);
×
4677
                }
4678

4679
                /**
4680
                 * {@inheritDoc}
4681
                 */
4682
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
4683
                    return materialize().typeVariable(symbol, bounds);
1✔
4684
                }
4685

4686
                /**
4687
                 * {@inheritDoc}
4688
                 */
4689
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
4690
                    return materialize().transform(matcher, transformer);
1✔
4691
                }
4692

4693
                /**
4694
                 * {@inheritDoc}
4695
                 */
4696
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
4697
                    return materialize().defineField(name, type, modifiers);
1✔
4698
                }
4699

4700
                /**
4701
                 * {@inheritDoc}
4702
                 */
4703
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
4704
                    return materialize().field(matcher);
1✔
4705
                }
4706

4707
                /**
4708
                 * {@inheritDoc}
4709
                 */
4710
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4711
                    return materialize().defineMethod(name, returnType, modifiers);
1✔
4712
                }
4713

4714
                /**
4715
                 * {@inheritDoc}
4716
                 */
4717
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4718
                    return materialize().defineConstructor(modifiers);
1✔
4719
                }
4720

4721
                /**
4722
                 * {@inheritDoc}
4723
                 */
4724
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4725
                    return materialize().invokable(matcher);
1✔
4726
                }
4727

4728
                /**
4729
                 * {@inheritDoc}
4730
                 */
4731
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
UNCOV
4732
                    return materialize().require(auxiliaryTypes);
×
4733
                }
4734

4735
                /**
4736
                 * {@inheritDoc}
4737
                 */
4738
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
UNCOV
4739
                    return materialize().defineRecordComponent(name, type);
×
4740
                }
4741

4742
                /**
4743
                 * {@inheritDoc}
4744
                 */
4745
                public RecordComponentDefinition.Optional<U> define(RecordComponentDescription recordComponentDescription) {
UNCOV
4746
                    return materialize().define(recordComponentDescription);
×
4747
                }
4748

4749
                /**
4750
                 * {@inheritDoc}
4751
                 */
4752
                public RecordComponentDefinition<U> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
UNCOV
4753
                    return materialize().recordComponent(matcher);
×
4754
                }
4755

4756
                /**
4757
                 * {@inheritDoc}
4758
                 */
4759
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
UNCOV
4760
                    return materialize().recordComponent(matcher);
×
4761
                }
4762

4763
                /**
4764
                 * {@inheritDoc}
4765
                 */
4766
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4767
                    return materialize().wrap(classVisitor, writerFlags, readerFlags);
1✔
4768
                }
4769

4770
                /**
4771
                 * {@inheritDoc}
4772
                 */
4773
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
UNCOV
4774
                    return materialize().wrap(classVisitor, typePool, writerFlags, readerFlags);
×
4775
                }
4776

4777
                /**
4778
                 * {@inheritDoc}
4779
                 */
4780
                public DynamicType.Unloaded<U> make() {
4781
                    return materialize().make();
1✔
4782
                }
4783

4784
                /**
4785
                 * {@inheritDoc}
4786
                 */
4787
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4788
                    return materialize().make(typeResolutionStrategy);
1✔
4789
                }
4790

4791
                /**
4792
                 * {@inheritDoc}
4793
                 */
4794
                public Unloaded<U> make(TypePool typePool) {
UNCOV
4795
                    return materialize().make(typePool);
×
4796
                }
4797

4798
                /**
4799
                 * {@inheritDoc}
4800
                 */
4801
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4802
                    return materialize().make(typeResolutionStrategy, typePool);
1✔
4803
                }
4804

4805
                /**
4806
                 * {@inheritDoc}
4807
                 */
4808
                public TypeDescription toTypeDescription() {
4809
                    return materialize().toTypeDescription();
1✔
4810
                }
4811

4812
                /**
4813
                 * Creates a new builder that realizes the current state of the builder.
4814
                 *
4815
                 * @return A new builder that realizes the current state of the builder.
4816
                 */
4817
                protected abstract Builder<U> materialize();
4818
            }
4819

4820
            /**
4821
             * A dynamic type writer that uses a {@link TypeWriter} to create a dynamic type.
4822
             *
4823
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4824
             */
4825
            public abstract static class UsingTypeWriter<U> extends AbstractBase<U> {
1✔
4826

4827
                /**
4828
                 * {@inheritDoc}
4829
                 */
4830
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4831
                    return toTypeWriter().wrap(classVisitor, writerFlags, readerFlags);
1✔
4832
                }
4833

4834
                /**
4835
                 * {@inheritDoc}
4836
                 */
4837
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
UNCOV
4838
                    return toTypeWriter(typePool).wrap(classVisitor, writerFlags, readerFlags);
×
4839
                }
4840

4841
                /**
4842
                 * {@inheritDoc}
4843
                 */
4844
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4845
                    return toTypeWriter().make(typeResolutionStrategy.resolve());
1✔
4846
                }
4847

4848
                /**
4849
                 * {@inheritDoc}
4850
                 */
4851
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4852
                    return toTypeWriter(typePool).make(typeResolutionStrategy.resolve());
1✔
4853
                }
4854

4855
                /**
4856
                 * Creates a {@link TypeWriter} without an explicitly specified {@link TypePool}.
4857
                 *
4858
                 * @return An appropriate {@link TypeWriter}.
4859
                 */
4860
                protected abstract TypeWriter<U> toTypeWriter();
4861

4862
                /**
4863
                 * Creates a {@link TypeWriter} given the specified {@link TypePool}.
4864
                 *
4865
                 * @param typePool The {@link TypePool} to use.
4866
                 * @return An appropriate {@link TypeWriter}.
4867
                 */
4868
                protected abstract TypeWriter<U> toTypeWriter(TypePool typePool);
4869
            }
4870

4871
            /**
4872
             * An adapter implementation of a dynamic type builder.
4873
             *
4874
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4875
             */
4876
            @HashCodeAndEqualsPlugin.Enhance
4877
            public abstract static class Adapter<U> extends UsingTypeWriter<U> {
4878

4879
                /**
4880
                 * The instrumented type to be created.
4881
                 */
4882
                protected final InstrumentedType.WithFlexibleName instrumentedType;
4883

4884
                /**
4885
                 * The current field registry.
4886
                 */
4887
                protected final FieldRegistry fieldRegistry;
4888

4889
                /**
4890
                 * The current method registry.
4891
                 */
4892
                protected final MethodRegistry methodRegistry;
4893

4894
                /**
4895
                 * The current record component registry.
4896
                 */
4897
                protected final RecordComponentRegistry recordComponentRegistry;
4898

4899
                /**
4900
                 * The type attribute appender to apply onto the instrumented type.
4901
                 */
4902
                protected final TypeAttributeAppender typeAttributeAppender;
4903

4904
                /**
4905
                 * The ASM visitor wrapper to apply onto the class writer.
4906
                 */
4907
                protected final AsmVisitorWrapper asmVisitorWrapper;
4908

4909
                /**
4910
                 * The class file version to define auxiliary types in.
4911
                 */
4912
                protected final ClassFileVersion classFileVersion;
4913

4914
                /**
4915
                 * The naming strategy for auxiliary types to apply.
4916
                 */
4917
                protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
4918

4919
                /**
4920
                 * The annotation value filter factory to apply.
4921
                 */
4922
                protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
4923

4924
                /**
4925
                 * The annotation retention to apply.
4926
                 */
4927
                protected final AnnotationRetention annotationRetention;
4928

4929
                /**
4930
                 * The implementation context factory to apply.
4931
                 */
4932
                protected final Implementation.Context.Factory implementationContextFactory;
4933

4934
                /**
4935
                 * The method graph compiler to use.
4936
                 */
4937
                protected final MethodGraph.Compiler methodGraphCompiler;
4938

4939
                /**
4940
                 * Determines if a type should be explicitly validated.
4941
                 */
4942
                protected final TypeValidation typeValidation;
4943

4944
                /**
4945
                 * The visibility bridge strategy to apply.
4946
                 */
4947
                protected final VisibilityBridgeStrategy visibilityBridgeStrategy;
4948

4949
                /**
4950
                 * The class reader factory to use.
4951
                 */
4952
                protected final AsmClassReader.Factory classReaderFactory;
4953

4954
                /**
4955
                 * The class writer factory to use.
4956
                 */
4957
                protected final AsmClassWriter.Factory classWriterFactory;
4958

4959
                /**
4960
                 * A matcher for identifying methods that should be excluded from instrumentation.
4961
                 */
4962
                protected final LatentMatcher<? super MethodDescription> ignoredMethods;
4963

4964
                /**
4965
                 * A list of explicitly defined auxiliary types.
4966
                 */
4967
                protected final List<? extends DynamicType> auxiliaryTypes;
4968

4969
                /**
4970
                 * Creates a new default type writer for creating a new type that is not based on an existing class file.
4971
                 *
4972
                 * @param instrumentedType             The instrumented type to be created.
4973
                 * @param fieldRegistry                The current field registry.
4974
                 * @param methodRegistry               The current method registry.
4975
                 * @param recordComponentRegistry      The record component pool to use.
4976
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
4977
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
4978
                 * @param classFileVersion             The class file version to define auxiliary types in.
4979
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
4980
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
4981
                 * @param annotationRetention          The annotation retention to apply.
4982
                 * @param implementationContextFactory The implementation context factory to apply.
4983
                 * @param methodGraphCompiler          The method graph compiler to use.
4984
                 * @param typeValidation               Determines if a type should be explicitly validated.
4985
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
4986
                 * @param classReaderFactory           The class reader factory to use.
4987
                 * @param classWriterFactory           The class writer factory to use.
4988
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
4989
                 * @param auxiliaryTypes               A list of explicitly defined auxiliary types.
4990
                 */
4991
                protected Adapter(InstrumentedType.WithFlexibleName instrumentedType,
4992
                                  FieldRegistry fieldRegistry,
4993
                                  MethodRegistry methodRegistry,
4994
                                  RecordComponentRegistry recordComponentRegistry,
4995
                                  TypeAttributeAppender typeAttributeAppender,
4996
                                  AsmVisitorWrapper asmVisitorWrapper,
4997
                                  ClassFileVersion classFileVersion,
4998
                                  AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4999
                                  AnnotationValueFilter.Factory annotationValueFilterFactory,
5000
                                  AnnotationRetention annotationRetention,
5001
                                  Implementation.Context.Factory implementationContextFactory,
5002
                                  MethodGraph.Compiler methodGraphCompiler,
5003
                                  TypeValidation typeValidation,
5004
                                  VisibilityBridgeStrategy visibilityBridgeStrategy,
5005
                                  AsmClassReader.Factory classReaderFactory,
5006
                                  AsmClassWriter.Factory classWriterFactory,
5007
                                  LatentMatcher<? super MethodDescription> ignoredMethods,
5008
                                  List<? extends DynamicType> auxiliaryTypes) {
1✔
5009
                    this.instrumentedType = instrumentedType;
1✔
5010
                    this.fieldRegistry = fieldRegistry;
1✔
5011
                    this.methodRegistry = methodRegistry;
1✔
5012
                    this.recordComponentRegistry = recordComponentRegistry;
1✔
5013
                    this.typeAttributeAppender = typeAttributeAppender;
1✔
5014
                    this.asmVisitorWrapper = asmVisitorWrapper;
1✔
5015
                    this.classFileVersion = classFileVersion;
1✔
5016
                    this.auxiliaryTypeNamingStrategy = auxiliaryTypeNamingStrategy;
1✔
5017
                    this.annotationValueFilterFactory = annotationValueFilterFactory;
1✔
5018
                    this.annotationRetention = annotationRetention;
1✔
5019
                    this.implementationContextFactory = implementationContextFactory;
1✔
5020
                    this.methodGraphCompiler = methodGraphCompiler;
1✔
5021
                    this.typeValidation = typeValidation;
1✔
5022
                    this.visibilityBridgeStrategy = visibilityBridgeStrategy;
1✔
5023
                    this.classReaderFactory = classReaderFactory;
1✔
5024
                    this.classWriterFactory = classWriterFactory;
1✔
5025
                    this.ignoredMethods = ignoredMethods;
1✔
5026
                    this.auxiliaryTypes = auxiliaryTypes;
1✔
5027
                }
1✔
5028

5029
                /**
5030
                 * {@inheritDoc}
5031
                 */
5032
                public ModuleDefinition<U> module(String name, int modifiers) {
UNCOV
5033
                    return new ModuleDefinitionAdapter(name, modifiers);
×
5034
                }
5035

5036
                /**
5037
                 * {@inheritDoc}
5038
                 */
5039
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
5040
                    return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
1✔
5041
                }
5042

5043
                /**
5044
                 * {@inheritDoc}
5045
                 */
5046
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
5047
                    return new FieldMatchAdapter(matcher);
1✔
5048
                }
5049

5050
                /**
5051
                 * {@inheritDoc}
5052
                 */
5053
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
5054
                    return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
1✔
5055
                }
5056

5057
                /**
5058
                 * {@inheritDoc}
5059
                 */
5060
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
5061
                    return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
1✔
5062
                }
5063

5064
                /**
5065
                 * {@inheritDoc}
5066
                 */
5067
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
5068
                    return new MethodMatchAdapter(matcher);
1✔
5069
                }
5070

5071
                /**
5072
                 * {@inheritDoc}
5073
                 */
5074
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
5075
                    return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
1✔
5076
                }
5077

5078
                /**
5079
                 * {@inheritDoc}
5080
                 */
5081
                @SuppressWarnings("unchecked") // In absence of @SafeVarargs
5082
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
5083
                    return materialize(instrumentedType,
1✔
5084
                            fieldRegistry,
5085
                            methodRegistry,
5086
                            recordComponentRegistry,
5087
                            typeAttributeAppender,
5088
                            asmVisitorWrapper,
5089
                            classFileVersion,
5090
                            auxiliaryTypeNamingStrategy,
5091
                            annotationValueFilterFactory,
5092
                            annotationRetention,
5093
                            implementationContextFactory,
5094
                            methodGraphCompiler,
5095
                            typeValidation,
5096
                            visibilityBridgeStrategy,
5097
                            classReaderFactory,
5098
                            classWriterFactory,
5099
                            new LatentMatcher.Disjunction<MethodDescription>(this.ignoredMethods, ignoredMethods),
5100
                            auxiliaryTypes);
5101
                }
5102

5103
                /**
5104
                 * {@inheritDoc}
5105
                 */
5106
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
UNCOV
5107
                    return new RecordComponentDefinitionAdapter(new RecordComponentDescription.Token(name, type.asGenericType()));
×
5108
                }
5109

5110
                /**
5111
                 * {@inheritDoc}
5112
                 */
5113
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
UNCOV
5114
                    return new RecordComponentMatchAdapter(matcher);
×
5115
                }
5116

5117
                /**
5118
                 * {@inheritDoc}
5119
                 */
5120
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
5121
                    return materialize(instrumentedType.withInitializer(byteCodeAppender),
1✔
5122
                            fieldRegistry,
5123
                            methodRegistry,
5124
                            recordComponentRegistry,
5125
                            typeAttributeAppender,
5126
                            asmVisitorWrapper,
5127
                            classFileVersion,
5128
                            auxiliaryTypeNamingStrategy,
5129
                            annotationValueFilterFactory,
5130
                            annotationRetention,
5131
                            implementationContextFactory,
5132
                            methodGraphCompiler,
5133
                            typeValidation,
5134
                            visibilityBridgeStrategy,
5135
                            classReaderFactory,
5136
                            classWriterFactory,
5137
                            ignoredMethods,
5138
                            auxiliaryTypes);
5139
                }
5140

5141
                /**
5142
                 * {@inheritDoc}
5143
                 */
5144
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
5145
                    return materialize(instrumentedType.withInitializer(loadedTypeInitializer),
1✔
5146
                            fieldRegistry,
5147
                            methodRegistry,
5148
                            recordComponentRegistry,
5149
                            typeAttributeAppender,
5150
                            asmVisitorWrapper,
5151
                            classFileVersion,
5152
                            auxiliaryTypeNamingStrategy,
5153
                            annotationValueFilterFactory,
5154
                            annotationRetention,
5155
                            implementationContextFactory,
5156
                            methodGraphCompiler,
5157
                            typeValidation,
5158
                            visibilityBridgeStrategy,
5159
                            classReaderFactory,
5160
                            classWriterFactory,
5161
                            ignoredMethods,
5162
                            auxiliaryTypes);
5163
                }
5164

5165
                /**
5166
                 * {@inheritDoc}
5167
                 */
5168
                public Builder<U> name(String name) {
5169
                    return materialize(instrumentedType.withName(name),
1✔
5170
                            fieldRegistry,
5171
                            methodRegistry,
5172
                            recordComponentRegistry,
5173
                            typeAttributeAppender,
5174
                            asmVisitorWrapper,
5175
                            classFileVersion,
5176
                            auxiliaryTypeNamingStrategy,
5177
                            annotationValueFilterFactory,
5178
                            annotationRetention,
5179
                            implementationContextFactory,
5180
                            methodGraphCompiler,
5181
                            typeValidation,
5182
                            visibilityBridgeStrategy,
5183
                            classReaderFactory,
5184
                            classWriterFactory,
5185
                            ignoredMethods,
5186
                            auxiliaryTypes);
5187
                }
5188

5189
                /**
5190
                 * {@inheritDoc}
5191
                 */
5192
                public Builder<U> suffix(String suffix) {
UNCOV
5193
                    return name(instrumentedType.getName() + "$" + suffix);
×
5194
                }
5195

5196
                /**
5197
                 * {@inheritDoc}
5198
                 */
5199
                public Builder<U> modifiers(int modifiers) {
5200
                    return materialize(instrumentedType.withModifiers(modifiers),
1✔
5201
                            fieldRegistry,
5202
                            methodRegistry,
5203
                            recordComponentRegistry,
5204
                            typeAttributeAppender,
5205
                            asmVisitorWrapper,
5206
                            classFileVersion,
5207
                            auxiliaryTypeNamingStrategy,
5208
                            annotationValueFilterFactory,
5209
                            annotationRetention,
5210
                            implementationContextFactory,
5211
                            methodGraphCompiler,
5212
                            typeValidation,
5213
                            visibilityBridgeStrategy,
5214
                            classReaderFactory,
5215
                            classWriterFactory,
5216
                            ignoredMethods,
5217
                            auxiliaryTypes);
5218
                }
5219

5220
                /**
5221
                 * {@inheritDoc}
5222
                 */
5223
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
5224
                    return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
1✔
5225
                            fieldRegistry,
5226
                            methodRegistry,
5227
                            recordComponentRegistry,
5228
                            typeAttributeAppender,
5229
                            asmVisitorWrapper,
5230
                            classFileVersion,
5231
                            auxiliaryTypeNamingStrategy,
5232
                            annotationValueFilterFactory,
5233
                            annotationRetention,
5234
                            implementationContextFactory,
5235
                            methodGraphCompiler,
5236
                            typeValidation,
5237
                            visibilityBridgeStrategy,
5238
                            classReaderFactory,
5239
                            classWriterFactory,
5240
                            ignoredMethods,
5241
                            auxiliaryTypes);
5242
                }
5243

5244
                /**
5245
                 * {@inheritDoc}
5246
                 */
5247
                public Builder<U> topLevelType() {
5248
                    return Adapter.this.materialize(instrumentedType
1✔
5249
                                    .withDeclaringType(TypeDescription.UNDEFINED)
1✔
5250
                                    .withEnclosingType(TypeDescription.UNDEFINED)
1✔
5251
                                    .withLocalClass(false),
1✔
5252
                            fieldRegistry,
5253
                            methodRegistry,
5254
                            recordComponentRegistry,
5255
                            typeAttributeAppender,
5256
                            asmVisitorWrapper,
5257
                            classFileVersion,
5258
                            auxiliaryTypeNamingStrategy,
5259
                            annotationValueFilterFactory,
5260
                            annotationRetention,
5261
                            implementationContextFactory,
5262
                            methodGraphCompiler,
5263
                            typeValidation,
5264
                            visibilityBridgeStrategy,
5265
                            classReaderFactory,
5266
                            classWriterFactory,
5267
                            ignoredMethods,
5268
                            auxiliaryTypes);
5269
                }
5270

5271
                /**
5272
                 * {@inheritDoc}
5273
                 */
5274
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
5275
                    return new InnerTypeDefinitionForTypeAdapter(type);
1✔
5276
                }
5277

5278
                /**
5279
                 * {@inheritDoc}
5280
                 */
5281
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
5282
                    return methodDescription.isTypeInitializer()
1✔
5283
                            ? new InnerTypeDefinitionForTypeAdapter(methodDescription.getDeclaringType())
1✔
5284
                            : new InnerTypeDefinitionForMethodAdapter(methodDescription);
5285
                }
5286

5287
                /**
5288
                 * {@inheritDoc}
5289
                 */
5290
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
5291
                    return materialize(instrumentedType.withDeclaredTypes(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
5292
                            fieldRegistry,
5293
                            methodRegistry,
5294
                            recordComponentRegistry,
5295
                            typeAttributeAppender,
5296
                            asmVisitorWrapper,
5297
                            classFileVersion,
5298
                            auxiliaryTypeNamingStrategy,
5299
                            annotationValueFilterFactory,
5300
                            annotationRetention,
5301
                            implementationContextFactory,
5302
                            methodGraphCompiler,
5303
                            typeValidation,
5304
                            visibilityBridgeStrategy,
5305
                            classReaderFactory,
5306
                            classWriterFactory,
5307
                            ignoredMethods,
5308
                            auxiliaryTypes);
5309
                }
5310

5311
                /**
5312
                 * {@inheritDoc}
5313
                 */
5314
                public Builder<U> nestHost(TypeDescription type) {
UNCOV
5315
                    return materialize(instrumentedType.withNestHost(type),
×
5316
                            fieldRegistry,
5317
                            methodRegistry,
5318
                            recordComponentRegistry,
5319
                            typeAttributeAppender,
5320
                            asmVisitorWrapper,
5321
                            classFileVersion,
5322
                            auxiliaryTypeNamingStrategy,
5323
                            annotationValueFilterFactory,
5324
                            annotationRetention,
5325
                            implementationContextFactory,
5326
                            methodGraphCompiler,
5327
                            typeValidation,
5328
                            visibilityBridgeStrategy,
5329
                            classReaderFactory,
5330
                            classWriterFactory,
5331
                            ignoredMethods,
5332
                            auxiliaryTypes);
5333
                }
5334

5335
                /**
5336
                 * {@inheritDoc}
5337
                 */
5338
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
5339
                    return materialize(instrumentedType.withNestMembers(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
5340
                            fieldRegistry,
5341
                            methodRegistry,
5342
                            recordComponentRegistry,
5343
                            typeAttributeAppender,
5344
                            asmVisitorWrapper,
5345
                            classFileVersion,
5346
                            auxiliaryTypeNamingStrategy,
5347
                            annotationValueFilterFactory,
5348
                            annotationRetention,
5349
                            implementationContextFactory,
5350
                            methodGraphCompiler,
5351
                            typeValidation,
5352
                            visibilityBridgeStrategy,
5353
                            classReaderFactory,
5354
                            classWriterFactory,
5355
                            ignoredMethods,
5356
                            auxiliaryTypes);
5357
                }
5358

5359
                /**
5360
                 * {@inheritDoc}
5361
                 */
5362
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
UNCOV
5363
                    return materialize(instrumentedType.withPermittedSubclasses(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
×
5364
                            fieldRegistry,
5365
                            methodRegistry,
5366
                            recordComponentRegistry,
5367
                            typeAttributeAppender,
5368
                            asmVisitorWrapper,
5369
                            classFileVersion,
5370
                            auxiliaryTypeNamingStrategy,
5371
                            annotationValueFilterFactory,
5372
                            annotationRetention,
5373
                            implementationContextFactory,
5374
                            methodGraphCompiler,
5375
                            typeValidation,
5376
                            visibilityBridgeStrategy,
5377
                            classReaderFactory,
5378
                            classWriterFactory,
5379
                            ignoredMethods,
5380
                            auxiliaryTypes);
5381
                }
5382

5383
                /**
5384
                 * {@inheritDoc}
5385
                 */
5386
                public Builder<U> unsealed() {
UNCOV
5387
                    return materialize(instrumentedType.withPermittedSubclasses(TypeList.UNDEFINED),
×
5388
                            fieldRegistry,
5389
                            methodRegistry,
5390
                            recordComponentRegistry,
5391
                            typeAttributeAppender,
5392
                            asmVisitorWrapper,
5393
                            classFileVersion,
5394
                            auxiliaryTypeNamingStrategy,
5395
                            annotationValueFilterFactory,
5396
                            annotationRetention,
5397
                            implementationContextFactory,
5398
                            methodGraphCompiler,
5399
                            typeValidation,
5400
                            visibilityBridgeStrategy,
5401
                            classReaderFactory,
5402
                            classWriterFactory,
5403
                            ignoredMethods,
5404
                            auxiliaryTypes);
5405
                }
5406

5407
                /**
5408
                 * {@inheritDoc}
5409
                 */
5410
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
5411
                    return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
5412
                }
5413

5414
                /**
5415
                 * {@inheritDoc}
5416
                 */
5417
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
5418
                    return materialize(instrumentedType.withTypeVariables(matcher, transformer),
1✔
5419
                            fieldRegistry,
5420
                            methodRegistry,
5421
                            recordComponentRegistry,
5422
                            typeAttributeAppender,
5423
                            asmVisitorWrapper,
5424
                            classFileVersion,
5425
                            auxiliaryTypeNamingStrategy,
5426
                            annotationValueFilterFactory,
5427
                            annotationRetention,
5428
                            implementationContextFactory,
5429
                            methodGraphCompiler,
5430
                            typeValidation,
5431
                            visibilityBridgeStrategy,
5432
                            classReaderFactory,
5433
                            classWriterFactory,
5434
                            ignoredMethods,
5435
                            auxiliaryTypes);
5436
                }
5437

5438
                /**
5439
                 * {@inheritDoc}
5440
                 */
5441
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
5442
                    return materialize(instrumentedType,
1✔
5443
                            fieldRegistry,
5444
                            methodRegistry,
5445
                            recordComponentRegistry,
5446
                            new TypeAttributeAppender.Compound(this.typeAttributeAppender, typeAttributeAppender),
5447
                            asmVisitorWrapper,
5448
                            classFileVersion,
5449
                            auxiliaryTypeNamingStrategy,
5450
                            annotationValueFilterFactory,
5451
                            annotationRetention,
5452
                            implementationContextFactory,
5453
                            methodGraphCompiler,
5454
                            typeValidation,
5455
                            visibilityBridgeStrategy,
5456
                            classReaderFactory,
5457
                            classWriterFactory,
5458
                            ignoredMethods,
5459
                            auxiliaryTypes);
5460
                }
5461

5462
                /**
5463
                 * {@inheritDoc}
5464
                 */
5465
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
5466
                    ModuleDescription moduleDescription = instrumentedType.toModuleDescription();
1✔
5467
                    return materialize(instrumentedType
1✔
5468
                                    .withAnnotations(new ArrayList<AnnotationDescription>(annotations))
1✔
5469
                                    .withModuleDescription(moduleDescription == null ? ModuleDescription.UNDEFINED : new ModuleDescription.Latent(moduleDescription.getActualName(),
1✔
UNCOV
5470
                                            moduleDescription.getModifiers(),
×
UNCOV
5471
                                            moduleDescription.getVersion(),
×
UNCOV
5472
                                            moduleDescription.getMainClass(),
×
UNCOV
5473
                                            moduleDescription.getPackages(),
×
UNCOV
5474
                                            moduleDescription.getRequires(),
×
UNCOV
5475
                                            moduleDescription.getExports(),
×
UNCOV
5476
                                            moduleDescription.getOpens(),
×
UNCOV
5477
                                            moduleDescription.getUses(),
×
UNCOV
5478
                                            moduleDescription.getProvides(),
×
UNCOV
5479
                                            CompoundList.of(instrumentedType.getDeclaredAnnotations(), new ArrayList<AnnotationDescription>(annotations)))),
×
5480
                            fieldRegistry,
5481
                            methodRegistry,
5482
                            recordComponentRegistry,
5483
                            typeAttributeAppender,
5484
                            asmVisitorWrapper,
5485
                            classFileVersion,
5486
                            auxiliaryTypeNamingStrategy,
5487
                            annotationValueFilterFactory,
5488
                            annotationRetention,
5489
                            implementationContextFactory,
5490
                            methodGraphCompiler,
5491
                            typeValidation,
5492
                            visibilityBridgeStrategy,
5493
                            classReaderFactory,
5494
                            classWriterFactory,
5495
                            ignoredMethods,
5496
                            auxiliaryTypes);
5497
                }
5498

5499
                /**
5500
                 * {@inheritDoc}
5501
                 */
5502
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
5503
                    return materialize(instrumentedType,
1✔
5504
                            fieldRegistry,
5505
                            methodRegistry,
5506
                            recordComponentRegistry,
5507
                            typeAttributeAppender,
5508
                            new AsmVisitorWrapper.Compound(this.asmVisitorWrapper, asmVisitorWrapper),
5509
                            classFileVersion,
5510
                            auxiliaryTypeNamingStrategy,
5511
                            annotationValueFilterFactory,
5512
                            annotationRetention,
5513
                            implementationContextFactory,
5514
                            methodGraphCompiler,
5515
                            typeValidation,
5516
                            visibilityBridgeStrategy,
5517
                            classReaderFactory,
5518
                            classWriterFactory,
5519
                            ignoredMethods,
5520
                            auxiliaryTypes);
5521
                }
5522

5523
                /**
5524
                 * {@inheritDoc}
5525
                 */
5526
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
5527
                    return materialize(instrumentedType,
1✔
5528
                            fieldRegistry,
5529
                            methodRegistry,
5530
                            recordComponentRegistry,
5531
                            typeAttributeAppender,
5532
                            asmVisitorWrapper,
5533
                            classFileVersion,
5534
                            auxiliaryTypeNamingStrategy,
5535
                            annotationValueFilterFactory,
5536
                            annotationRetention,
5537
                            implementationContextFactory,
5538
                            methodGraphCompiler,
5539
                            typeValidation,
5540
                            visibilityBridgeStrategy,
5541
                            classReaderFactory,
5542
                            classWriterFactory,
5543
                            ignoredMethods,
5544
                            CompoundList.of(this.auxiliaryTypes, new ArrayList<DynamicType>(auxiliaryTypes)));
1✔
5545
                }
5546

5547
                /**
5548
                 * {@inheritDoc}
5549
                 */
5550
                public TypeDescription toTypeDescription() {
5551
                    return instrumentedType;
1✔
5552
                }
5553

5554
                /**
5555
                 * Materializes the supplied state of a dynamic type builder.
5556
                 *
5557
                 * @param instrumentedType             The instrumented type.
5558
                 * @param fieldRegistry                The current field registry.
5559
                 * @param methodRegistry               The current method registry.
5560
                 * @param recordComponentRegistry      The record component pool to use.
5561
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
5562
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
5563
                 * @param classFileVersion             The class file version to define auxiliary types in.
5564
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
5565
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
5566
                 * @param annotationRetention          The annotation retention to apply.
5567
                 * @param implementationContextFactory The implementation context factory to apply.
5568
                 * @param methodGraphCompiler          The method graph compiler to use.
5569
                 * @param typeValidation               The type validation state.
5570
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
5571
                 * @param classReaderFactory           The class reader factory to use.
5572
                 * @param classWriterFactory           The class writer factory to use.
5573
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
5574
                 * @param auxiliaryTypes               A list of explicitly required auxiliary types.
5575
                 * @return A type builder that represents the supplied arguments.
5576
                 */
5577
                protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
5578
                                                          FieldRegistry fieldRegistry,
5579
                                                          MethodRegistry methodRegistry,
5580
                                                          RecordComponentRegistry recordComponentRegistry,
5581
                                                          TypeAttributeAppender typeAttributeAppender,
5582
                                                          AsmVisitorWrapper asmVisitorWrapper,
5583
                                                          ClassFileVersion classFileVersion,
5584
                                                          AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
5585
                                                          AnnotationValueFilter.Factory annotationValueFilterFactory,
5586
                                                          AnnotationRetention annotationRetention,
5587
                                                          Implementation.Context.Factory implementationContextFactory,
5588
                                                          MethodGraph.Compiler methodGraphCompiler,
5589
                                                          TypeValidation typeValidation,
5590
                                                          VisibilityBridgeStrategy visibilityBridgeStrategy,
5591
                                                          AsmClassReader.Factory classReaderFactory,
5592
                                                          AsmClassWriter.Factory classWriterFactory,
5593
                                                          LatentMatcher<? super MethodDescription> ignoredMethods,
5594
                                                          List<? extends DynamicType> auxiliaryTypes);
5595

5596
                /**
5597
                 * An adapter for defining a module.
5598
                 */
5599
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5600
                protected class ModuleDefinitionAdapter extends ModuleDefinition.AbstractBase<U> {
5601

5602
                    /**
5603
                     * The name of the module.
5604
                     */
5605
                    private final String name;
5606

5607
                    /**
5608
                     * The modifiers of the module.
5609
                     */
5610
                    private final int modifiers;
5611

5612
                    /**
5613
                     * The module version or {@code null} if no version was specified.
5614
                     */
5615
                    @MaybeNull
5616
                    @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5617
                    private final String version;
5618

5619
                    /**
5620
                     * The module's main class or {@code null} if no main class was specified.
5621
                     */
5622
                    @MaybeNull
5623
                    @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5624
                    private final String mainClass;
5625

5626
                    /**
5627
                     * The module's packages.
5628
                     */
5629
                    private final Set<String> packages;
5630

5631
                    /**
5632
                     * The modules that this module requires.
5633
                     */
5634
                    private final Map<String, ModuleDescription.Requires> requires;
5635

5636
                    /**
5637
                     * The packages that this module exports.
5638
                     */
5639
                    private final Map<String, ModuleDescription.Exports> exports;
5640

5641
                    /**
5642
                     * The packages that this module opens.
5643
                     */
5644
                    private final Map<String, ModuleDescription.Opens> opens;
5645

5646
                    /**
5647
                     * The services that this module uses.
5648
                     */
5649
                    private final Set<String> uses;
5650

5651
                    /**
5652
                     * The services that this module provides.
5653
                     */
5654
                    private final Map<String, ModuleDescription.Provides> provides;
5655

5656
                    protected ModuleDefinitionAdapter(String name, int modifiers) {
UNCOV
5657
                        this(name,
×
5658
                                modifiers,
5659
                                null,
5660
                                null,
UNCOV
5661
                                Collections.<String>emptySet(),
×
UNCOV
5662
                                "java.base".equals(name)
×
UNCOV
5663
                                        ? Collections.<String, ModuleDescription.Requires>emptyMap()
×
UNCOV
5664
                                        : Collections.<String, ModuleDescription.Requires>singletonMap("java.base", new ModuleDescription.Requires.Simple(null, Opcodes.ACC_MANDATED)),
×
UNCOV
5665
                                Collections.<String, ModuleDescription.Exports>emptyMap(),
×
UNCOV
5666
                                Collections.<String, ModuleDescription.Opens>emptyMap(),
×
UNCOV
5667
                                Collections.<String>emptySet(),
×
UNCOV
5668
                                Collections.<String, ModuleDescription.Provides>emptyMap());
×
UNCOV
5669
                    }
×
5670

5671
                    /**
5672
                     * Creates a new module definition adapter.
5673
                     *
5674
                     * @param name      The name of the module.
5675
                     * @param modifiers The modifiers of the module.
5676
                     * @param version   The module version or {@code null} if no version was specified.
5677
                     * @param mainClass The module's main class or {@code null} if no main class was specified.
5678
                     * @param packages  The module's packages.
5679
                     * @param requires  The modules that this module requires.
5680
                     * @param exports   The packages that this module exports.
5681
                     * @param opens     The packages that this module opens.
5682
                     * @param uses      The services that this module uses.
5683
                     * @param provides  The services that this module provides.
5684
                     */
5685
                    protected ModuleDefinitionAdapter(String name,
5686
                                                      int modifiers,
5687
                                                      @MaybeNull String version,
5688
                                                      @MaybeNull String mainClass,
5689
                                                      Set<String> packages,
5690
                                                      Map<String, ModuleDescription.Requires> requires,
5691
                                                      Map<String, ModuleDescription.Exports> exports,
5692
                                                      Map<String, ModuleDescription.Opens> opens,
5693
                                                      Set<String> uses,
UNCOV
5694
                                                      Map<String, ModuleDescription.Provides> provides) {
×
UNCOV
5695
                        this.name = name;
×
UNCOV
5696
                        this.modifiers = modifiers;
×
UNCOV
5697
                        this.version = version;
×
UNCOV
5698
                        this.mainClass = mainClass;
×
UNCOV
5699
                        this.packages = packages;
×
UNCOV
5700
                        this.requires = requires;
×
UNCOV
5701
                        this.exports = exports;
×
UNCOV
5702
                        this.opens = opens;
×
5703
                        this.uses = uses;
×
UNCOV
5704
                        this.provides = provides;
×
UNCOV
5705
                    }
×
5706

5707
                    /**
5708
                     * {@inheritDoc}
5709
                     */
5710
                    public ModuleDefinition<U> version(@MaybeNull String version) {
UNCOV
5711
                        return new ModuleDefinitionAdapter(name,
×
5712
                                modifiers,
5713
                                version,
5714
                                mainClass,
5715
                                packages,
5716
                                requires,
5717
                                exports,
5718
                                opens,
5719
                                uses,
5720
                                provides);
5721
                    }
5722

5723
                    /**
5724
                     * {@inheritDoc}
5725
                     */
5726
                    public ModuleDefinition<U> mainClass(@MaybeNull String name) {
UNCOV
5727
                        return new ModuleDefinitionAdapter(this.name,
×
5728
                                modifiers,
5729
                                version,
5730
                                name,
5731
                                packages,
5732
                                requires,
5733
                                exports,
5734
                                opens,
5735
                                uses,
5736
                                provides);
5737
                    }
5738

5739
                    /**
5740
                     * {@inheritDoc}
5741
                     */
5742
                    public ModuleDefinition<U> packages(Collection<String> packages) {
UNCOV
5743
                        Set<String> merged = new LinkedHashSet<String>(this.packages);
×
UNCOV
5744
                        merged.addAll(packages);
×
UNCOV
5745
                        return new ModuleDefinitionAdapter(name,
×
5746
                                modifiers,
5747
                                version,
5748
                                mainClass,
5749
                                merged,
5750
                                requires,
5751
                                exports,
5752
                                opens,
5753
                                uses,
5754
                                provides);
5755
                    }
5756

5757
                    /**
5758
                     * {@inheritDoc}
5759
                     */
5760
                    public RequiresDefinition<U> require(String module, int modifiers) {
UNCOV
5761
                        return new RequiresDefinitionAdapter(module, modifiers);
×
5762
                    }
5763

5764
                    /**
5765
                     * {@inheritDoc}
5766
                     */
5767
                    public ExportsDefinition<U> export(String aPackage, int modifiers) {
UNCOV
5768
                        return new ExportsDefinitionAdapter(aPackage, modifiers);
×
5769
                    }
5770

5771
                    /**
5772
                     * {@inheritDoc}
5773
                     */
5774
                    public OpensDefinition<U> open(String aPackage, int modifiers) {
UNCOV
5775
                        return new OpensDefinitionAdapter(aPackage, modifiers);
×
5776
                    }
5777

5778
                    /**
5779
                     * {@inheritDoc}
5780
                     */
5781
                    public ModuleDefinition<U> uses(Collection<String> services) {
NEW
5782
                        Set<String> uses = new LinkedHashSet<String>(this.uses);
×
NEW
5783
                        uses.addAll(services);
×
UNCOV
5784
                        return new ModuleDefinitionAdapter(name,
×
5785
                                modifiers,
5786
                                version,
5787
                                mainClass,
5788
                                packages,
5789
                                requires,
5790
                                exports,
5791
                                opens,
5792
                                uses,
5793
                                provides);
5794
                    }
5795

5796
                    /**
5797
                     * {@inheritDoc}
5798
                     */
5799
                    public ModuleDefinition<U> provides(String service, Collection<String> implementations) {
UNCOV
5800
                        Map<String, ModuleDescription.Provides> provides = new LinkedHashMap<String, ModuleDescription.Provides>(this.provides);
×
UNCOV
5801
                        provides.put(service, new ModuleDescription.Provides.Simple(new LinkedHashSet<String>(implementations)));
×
UNCOV
5802
                        return new ModuleDefinitionAdapter(name,
×
5803
                                modifiers,
5804
                                version,
5805
                                mainClass,
5806
                                packages,
5807
                                requires,
5808
                                exports,
5809
                                opens,
5810
                                uses,
5811
                                provides);
5812
                    }
5813

5814
                    @Override
5815
                    protected Builder<U> materialize() {
UNCOV
5816
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withModuleDescription(new ModuleDescription.Latent(name,
×
5817
                                        modifiers,
5818
                                        version,
5819
                                        mainClass,
5820
                                        packages,
5821
                                        requires,
5822
                                        exports,
5823
                                        opens,
5824
                                        uses,
5825
                                        provides,
UNCOV
5826
                                        instrumentedType.getDeclaredAnnotations())).withModifiers(modifiers),
×
5827
                                fieldRegistry,
5828
                                methodRegistry,
5829
                                recordComponentRegistry,
5830
                                typeAttributeAppender,
5831
                                asmVisitorWrapper,
5832
                                classFileVersion,
5833
                                auxiliaryTypeNamingStrategy,
5834
                                annotationValueFilterFactory,
5835
                                annotationRetention,
5836
                                implementationContextFactory,
5837
                                methodGraphCompiler,
5838
                                typeValidation,
5839
                                visibilityBridgeStrategy,
5840
                                classReaderFactory,
5841
                                classWriterFactory,
5842
                                ignoredMethods,
5843
                                auxiliaryTypes);
5844
                    }
5845

5846
                    /**
5847
                     * An adapter for definining a module requirement.
5848
                     */
5849
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5850
                    protected class RequiresDefinitionAdapter extends RequiresDefinition.Delegator<U> {
5851

5852
                        /**
5853
                         * The module that is being required.
5854
                         */
5855
                        private final String module;
5856

5857
                        /**
5858
                         * The modifiers of the required module.
5859
                         */
5860
                        private final int modifiers;
5861

5862
                        /**
5863
                         * The version of the required module or {@code null} if no particular version is required.
5864
                         */
5865
                        @MaybeNull
5866
                        @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5867
                        private final String version;
5868

5869
                        /**
5870
                         * Creates a new module requirement definition.
5871
                         *
5872
                         * @param module    The module that is being required.
5873
                         * @param modifiers The modifiers of the required module.
5874
                         */
5875
                        protected RequiresDefinitionAdapter(String module, int modifiers) {
5876
                            this(module, modifiers, null);
×
UNCOV
5877
                        }
×
5878

5879
                        /**
5880
                         * Creates a new module requirement definition.
5881
                         *
5882
                         * @param module    The module that is being required.
5883
                         * @param modifiers The modifiers of the required module.
5884
                         * @param version   The version of the required module or {@code null} if no particular version is required.
5885
                         */
UNCOV
5886
                        protected RequiresDefinitionAdapter(String module, int modifiers, @MaybeNull String version) {
×
UNCOV
5887
                            this.module = module;
×
UNCOV
5888
                            this.modifiers = modifiers;
×
UNCOV
5889
                            this.version = version;
×
UNCOV
5890
                        }
×
5891

5892
                        /**
5893
                         * {@inheritDoc}
5894
                         */
5895
                        public RequiresDefinition<U> requiredVersion(@MaybeNull String version) {
UNCOV
5896
                            return new RequiresDefinitionAdapter(module, modifiers, version);
×
5897
                        }
5898

5899
                        @Override
5900
                        protected ModuleDefinition<U> materialize() {
UNCOV
5901
                            Map<String, ModuleDescription.Requires> requires = new LinkedHashMap<String, ModuleDescription.Requires>(ModuleDefinitionAdapter.this.requires);
×
5902
                            requires.put(name, new ModuleDescription.Requires.Simple(version, modifiers));
×
UNCOV
5903
                            return new ModuleDefinitionAdapter(ModuleDefinitionAdapter.this.name,
×
UNCOV
5904
                                    ModuleDefinitionAdapter.this.modifiers,
×
UNCOV
5905
                                    ModuleDefinitionAdapter.this.version,
×
UNCOV
5906
                                    mainClass,
×
UNCOV
5907
                                    packages,
×
5908
                                    requires,
UNCOV
5909
                                    exports,
×
UNCOV
5910
                                    opens,
×
UNCOV
5911
                                    uses,
×
UNCOV
5912
                                    provides);
×
5913
                        }
5914
                    }
5915

5916
                    /**
5917
                     * An adapter for defining a module export.
5918
                     */
5919
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5920
                    protected class ExportsDefinitionAdapter extends ExportsDefinition.Delegator<U> {
5921

5922
                        /**
5923
                         * The package that is being exported.
5924
                         */
5925
                        private final String aPackage;
5926

5927
                        /**
5928
                         * The modifiers for the exporting declaration.
5929
                         */
5930
                        private final int modifiers;
5931

5932
                        /**
5933
                         * The modules to which the package is exported, or no modules if exported to all modules.
5934
                         */
5935
                        private final Set<String> targets;
5936

5937
                        /**
5938
                         * Creates a new exporting definition adapter.
5939
                         *
5940
                         * @param aPackage  The package that is being exported.
5941
                         * @param modifiers The modifiers for the exporting declaration.
5942
                         */
5943
                        protected ExportsDefinitionAdapter(String aPackage, int modifiers) {
UNCOV
5944
                            this(aPackage, modifiers, Collections.<String>emptySet());
×
UNCOV
5945
                        }
×
5946

5947
                        /**
5948
                         * Creates a new exporting definition adapter.
5949
                         *
5950
                         * @param aPackage  The package that is being exported.
5951
                         * @param modifiers The modifiers for the exporting declaration.
5952
                         * @param targets   The modules to which the package is exported, or no modules if exported to all modules.
5953
                         */
UNCOV
5954
                        protected ExportsDefinitionAdapter(String aPackage, int modifiers, Set<String> targets) {
×
UNCOV
5955
                            this.aPackage = aPackage;
×
UNCOV
5956
                            this.modifiers = modifiers;
×
UNCOV
5957
                            this.targets = targets;
×
UNCOV
5958
                        }
×
5959

5960
                        /**
5961
                         * {@inheritDoc}
5962
                         */
5963
                        public ExportsDefinition<U> to(Collection<String> modules) {
5964
                            Set<String> targets = new LinkedHashSet<String>(this.targets);
×
UNCOV
5965
                            targets.addAll(modules);
×
UNCOV
5966
                            return new ExportsDefinitionAdapter(aPackage, modifiers, targets);
×
5967
                        }
5968

5969
                        @Override
5970
                        protected ModuleDefinition<U> materialize() {
UNCOV
5971
                            Map<String, ModuleDescription.Exports> exports = new LinkedHashMap<String, ModuleDescription.Exports>(ModuleDefinitionAdapter.this.exports);
×
UNCOV
5972
                            exports.put(aPackage, new ModuleDescription.Exports.Simple(targets, modifiers));
×
UNCOV
5973
                            return new ModuleDefinitionAdapter(name,
×
UNCOV
5974
                                    ModuleDefinitionAdapter.this.modifiers,
×
UNCOV
5975
                                    version,
×
UNCOV
5976
                                    mainClass,
×
5977
                                    packages,
×
UNCOV
5978
                                    requires,
×
5979
                                    exports,
UNCOV
5980
                                    opens,
×
UNCOV
5981
                                    uses,
×
UNCOV
5982
                                    provides);
×
5983
                        }
5984
                    }
5985

5986
                    /**
5987
                     * An adapter for defining a module opening.
5988
                     */
5989
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5990
                    protected class OpensDefinitionAdapter extends OpensDefinition.Delegator<U> {
5991

5992
                        /**
5993
                         * The package that is being opened.
5994
                         */
5995
                        private final String aPackage;
5996

5997
                        /**
5998
                         * The modifiers for the opening declaration.
5999
                         */
6000
                        private final int modifiers;
6001

6002
                        /**
6003
                         * The modules to which the package is opened, or no modules if opened to all modules.
6004
                         */
6005
                        private final Set<String> targets;
6006

6007
                        /**
6008
                         * Creates a new opens definition adapter.
6009
                         *
6010
                         * @param aPackage  The package that is being opened.
6011
                         * @param modifiers The modifiers for the opening declaration.
6012
                         */
6013
                        protected OpensDefinitionAdapter(String aPackage, int modifiers) {
UNCOV
6014
                            this(aPackage, modifiers, Collections.<String>emptySet());
×
UNCOV
6015
                        }
×
6016

6017
                        /**
6018
                         * Creates a new opens definition adapter.
6019
                         *
6020
                         * @param aPackage  The package that is being opened.
6021
                         * @param modifiers The modifiers for the opening declaration.
6022
                         * @param targets   The modules to which the package is opened, or no modules if opened to all modules.
6023
                         */
UNCOV
6024
                        protected OpensDefinitionAdapter(String aPackage, int modifiers, Set<String> targets) {
×
UNCOV
6025
                            this.aPackage = aPackage;
×
UNCOV
6026
                            this.modifiers = modifiers;
×
UNCOV
6027
                            this.targets = targets;
×
UNCOV
6028
                        }
×
6029

6030
                        /**
6031
                         * {@inheritDoc}
6032
                         */
6033
                        public OpensDefinition<U> to(Collection<String> modules) {
UNCOV
6034
                            Set<String> targets = new LinkedHashSet<String>(this.targets);
×
UNCOV
6035
                            targets.addAll(modules);
×
UNCOV
6036
                            return new OpensDefinitionAdapter(aPackage, modifiers, targets);
×
6037
                        }
6038

6039
                        @Override
6040
                        protected ModuleDefinition<U> materialize() {
UNCOV
6041
                            Map<String, ModuleDescription.Opens> opens = new LinkedHashMap<String, ModuleDescription.Opens>(ModuleDefinitionAdapter.this.opens);
×
UNCOV
6042
                            opens.put(aPackage, new ModuleDescription.Opens.Simple(targets, modifiers));
×
UNCOV
6043
                            return new ModuleDefinitionAdapter(name,
×
UNCOV
6044
                                    ModuleDefinitionAdapter.this.modifiers,
×
UNCOV
6045
                                    version,
×
UNCOV
6046
                                    mainClass,
×
UNCOV
6047
                                    packages,
×
UNCOV
6048
                                    requires,
×
UNCOV
6049
                                    exports,
×
6050
                                    opens,
UNCOV
6051
                                    uses,
×
UNCOV
6052
                                    provides);
×
6053
                        }
6054
                    }
6055
                }
6056

6057
                /**
6058
                 * An adapter for applying an inner type definition for an outer type.
6059
                 */
6060
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6061
                protected class InnerTypeDefinitionForTypeAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition.ForType<U> {
6062

6063
                    /**
6064
                     * A description of the type that is the defined outer type.
6065
                     */
6066
                    private final TypeDescription typeDescription;
6067

6068
                    /**
6069
                     * Creates a new adapter for an inner type definition for an outer type.
6070
                     *
6071
                     * @param typeDescription A description of the type that is the defined outer type.
6072
                     */
6073
                    protected InnerTypeDefinitionForTypeAdapter(TypeDescription typeDescription) {
1✔
6074
                        this.typeDescription = typeDescription;
1✔
6075
                    }
1✔
6076

6077
                    /**
6078
                     * {@inheritDoc}
6079
                     */
6080
                    public Builder<U> asAnonymousType() {
6081
                        return Adapter.this.materialize(instrumentedType
1✔
6082
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6083
                                        .withEnclosingType(typeDescription)
1✔
6084
                                        .withAnonymousClass(true),
1✔
6085
                                fieldRegistry,
6086
                                methodRegistry,
6087
                                recordComponentRegistry,
6088
                                typeAttributeAppender,
6089
                                asmVisitorWrapper,
6090
                                classFileVersion,
6091
                                auxiliaryTypeNamingStrategy,
6092
                                annotationValueFilterFactory,
6093
                                annotationRetention,
6094
                                implementationContextFactory,
6095
                                methodGraphCompiler,
6096
                                typeValidation,
6097
                                visibilityBridgeStrategy,
6098
                                classReaderFactory,
6099
                                classWriterFactory,
6100
                                ignoredMethods,
6101
                                auxiliaryTypes);
6102
                    }
6103

6104
                    /**
6105
                     * {@inheritDoc}
6106
                     */
6107
                    public Builder<U> asMemberType() {
6108
                        return Adapter.this.materialize(instrumentedType
1✔
6109
                                        .withDeclaringType(typeDescription)
1✔
6110
                                        .withEnclosingType(typeDescription)
1✔
6111
                                        .withAnonymousClass(false)
1✔
6112
                                        .withLocalClass(false),
1✔
6113
                                fieldRegistry,
6114
                                methodRegistry,
6115
                                recordComponentRegistry,
6116
                                typeAttributeAppender,
6117
                                asmVisitorWrapper,
6118
                                classFileVersion,
6119
                                auxiliaryTypeNamingStrategy,
6120
                                annotationValueFilterFactory,
6121
                                annotationRetention,
6122
                                implementationContextFactory,
6123
                                methodGraphCompiler,
6124
                                typeValidation,
6125
                                visibilityBridgeStrategy,
6126
                                classReaderFactory,
6127
                                classWriterFactory,
6128
                                ignoredMethods,
6129
                                auxiliaryTypes);
6130
                    }
6131

6132
                    @Override
6133
                    protected Builder<U> materialize() {
6134
                        return Adapter.this.materialize(instrumentedType
1✔
6135
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6136
                                        .withEnclosingType(typeDescription)
1✔
6137
                                        .withLocalClass(true),
1✔
6138
                                fieldRegistry,
6139
                                methodRegistry,
6140
                                recordComponentRegistry,
6141
                                typeAttributeAppender,
6142
                                asmVisitorWrapper,
6143
                                classFileVersion,
6144
                                auxiliaryTypeNamingStrategy,
6145
                                annotationValueFilterFactory,
6146
                                annotationRetention,
6147
                                implementationContextFactory,
6148
                                methodGraphCompiler,
6149
                                typeValidation,
6150
                                visibilityBridgeStrategy,
6151
                                classReaderFactory,
6152
                                classWriterFactory,
6153
                                ignoredMethods,
6154
                                auxiliaryTypes);
6155
                    }
6156
                }
6157

6158
                /**
6159
                 * An adapter for applying an inner type definition for an outer method or constructor.
6160
                 */
6161
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6162
                protected class InnerTypeDefinitionForMethodAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition<U> {
6163

6164
                    /**
6165
                     * A description of the declaring method or constructor.
6166
                     */
6167
                    private final MethodDescription.InDefinedShape methodDescription;
6168

6169
                    /**
6170
                     * Creates a new adapter for defining a type that is declared within a method or constructor.
6171
                     *
6172
                     * @param methodDescription A description of the declaring method or constructor.
6173
                     */
6174
                    protected InnerTypeDefinitionForMethodAdapter(MethodDescription.InDefinedShape methodDescription) {
1✔
6175
                        this.methodDescription = methodDescription;
1✔
6176
                    }
1✔
6177

6178
                    /**
6179
                     * {@inheritDoc}
6180
                     */
6181
                    public Builder<U> asAnonymousType() {
6182
                        return Adapter.this.materialize(instrumentedType
1✔
6183
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6184
                                        .withEnclosingMethod(methodDescription)
1✔
6185
                                        .withAnonymousClass(true),
1✔
6186
                                fieldRegistry,
6187
                                methodRegistry,
6188
                                recordComponentRegistry,
6189
                                typeAttributeAppender,
6190
                                asmVisitorWrapper,
6191
                                classFileVersion,
6192
                                auxiliaryTypeNamingStrategy,
6193
                                annotationValueFilterFactory,
6194
                                annotationRetention,
6195
                                implementationContextFactory,
6196
                                methodGraphCompiler,
6197
                                typeValidation,
6198
                                visibilityBridgeStrategy,
6199
                                classReaderFactory,
6200
                                classWriterFactory,
6201
                                ignoredMethods,
6202
                                auxiliaryTypes);
6203
                    }
6204

6205
                    @Override
6206
                    protected Builder<U> materialize() {
6207
                        return Adapter.this.materialize(instrumentedType
1✔
6208
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6209
                                        .withEnclosingMethod(methodDescription)
1✔
6210
                                        .withLocalClass(true),
1✔
6211
                                fieldRegistry,
6212
                                methodRegistry,
6213
                                recordComponentRegistry,
6214
                                typeAttributeAppender,
6215
                                asmVisitorWrapper,
6216
                                classFileVersion,
6217
                                auxiliaryTypeNamingStrategy,
6218
                                annotationValueFilterFactory,
6219
                                annotationRetention,
6220
                                implementationContextFactory,
6221
                                methodGraphCompiler,
6222
                                typeValidation,
6223
                                visibilityBridgeStrategy,
6224
                                classReaderFactory,
6225
                                classWriterFactory,
6226
                                ignoredMethods,
6227
                                auxiliaryTypes);
6228
                    }
6229
                }
6230

6231
                /**
6232
                 * An adapter for defining a new type variable for the instrumented type.
6233
                 */
6234
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6235
                protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
6236

6237
                    /**
6238
                     * The current definition of the type variable.
6239
                     */
6240
                    private final TypeVariableToken token;
6241

6242
                    /**
6243
                     * Creates a new type variable definition adapter.
6244
                     *
6245
                     * @param token The current definition of the type variable.
6246
                     */
6247
                    protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
1✔
6248
                        this.token = token;
1✔
6249
                    }
1✔
6250

6251
                    /**
6252
                     * {@inheritDoc}
6253
                     */
6254
                    public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
6255
                        return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
1✔
6256
                                token.getBounds(),
1✔
6257
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6258
                    }
6259

6260
                    @Override
6261
                    protected Builder<U> materialize() {
6262
                        return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
1✔
6263
                                fieldRegistry,
6264
                                methodRegistry,
6265
                                recordComponentRegistry,
6266
                                typeAttributeAppender,
6267
                                asmVisitorWrapper,
6268
                                classFileVersion,
6269
                                auxiliaryTypeNamingStrategy,
6270
                                annotationValueFilterFactory,
6271
                                annotationRetention,
6272
                                implementationContextFactory,
6273
                                methodGraphCompiler,
6274
                                typeValidation,
6275
                                visibilityBridgeStrategy,
6276
                                classReaderFactory,
6277
                                classWriterFactory,
6278
                                ignoredMethods,
6279
                                auxiliaryTypes);
6280
                    }
6281
                }
6282

6283
                /**
6284
                 * An adapter for defining a new field.
6285
                 */
6286
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6287
                protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
6288

6289
                    /**
6290
                     * The token representing the current field definition.
6291
                     */
6292
                    private final FieldDescription.Token token;
6293

6294
                    /**
6295
                     * Creates a new field definition adapter.
6296
                     *
6297
                     * @param token The token representing the current field definition.
6298
                     */
6299
                    protected FieldDefinitionAdapter(FieldDescription.Token token) {
6300
                        this(FieldAttributeAppender.ForInstrumentedField.INSTANCE,
1✔
6301
                                Transformer.NoOp.<FieldDescription>make(),
1✔
6302
                                FieldDescription.NO_DEFAULT_VALUE,
6303
                                token);
6304
                    }
1✔
6305

6306
                    /**
6307
                     * Creates a new field definition adapter.
6308
                     *
6309
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
6310
                     * @param transformer                   The field transformer to apply.
6311
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
6312
                     * @param token                         The token representing the current field definition.
6313
                     */
6314
                    protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6315
                                                     Transformer<FieldDescription> transformer,
6316
                                                     @MaybeNull Object defaultValue,
6317
                                                     FieldDescription.Token token) {
1✔
6318
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
6319
                        this.token = token;
1✔
6320
                    }
1✔
6321

6322
                    /**
6323
                     * {@inheritDoc}
6324
                     */
6325
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
6326
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, new FieldDescription.Token(token.getName(),
1✔
6327
                                token.getModifiers(),
1✔
6328
                                token.getType(),
1✔
6329
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6330
                    }
6331

6332
                    @Override
6333
                    protected Builder<U> materialize() {
6334
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
1✔
6335
                                fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
6336
                                methodRegistry,
6337
                                recordComponentRegistry,
6338
                                typeAttributeAppender,
6339
                                asmVisitorWrapper,
6340
                                classFileVersion,
6341
                                auxiliaryTypeNamingStrategy,
6342
                                annotationValueFilterFactory,
6343
                                annotationRetention,
6344
                                implementationContextFactory,
6345
                                methodGraphCompiler,
6346
                                typeValidation,
6347
                                visibilityBridgeStrategy,
6348
                                classReaderFactory,
6349
                                classWriterFactory,
6350
                                ignoredMethods,
6351
                                auxiliaryTypes);
6352
                    }
6353

6354
                    @Override
6355
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6356
                                                      Transformer<FieldDescription> transformer,
6357
                                                      @MaybeNull Object defaultValue) {
6358
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
1✔
6359
                    }
6360
                }
6361

6362
                /**
6363
                 * An adapter for matching an existing field.
6364
                 */
6365
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6366
                protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
6367

6368
                    /**
6369
                     * The matcher for any fields to apply this matcher to.
6370
                     */
6371
                    private final LatentMatcher<? super FieldDescription> matcher;
6372

6373
                    /**
6374
                     * Creates a new field match adapter.
6375
                     *
6376
                     * @param matcher The matcher for any fields to apply this matcher to.
6377
                     */
6378
                    protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
6379
                        this(FieldAttributeAppender.NoOp.INSTANCE,
1✔
6380
                                Transformer.NoOp.<FieldDescription>make(),
1✔
6381
                                FieldDescription.NO_DEFAULT_VALUE,
6382
                                matcher);
6383
                    }
1✔
6384

6385
                    /**
6386
                     * Creates a new field match adapter.
6387
                     *
6388
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
6389
                     * @param transformer                   The field transformer to apply.
6390
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
6391
                     * @param matcher                       The matcher for any fields to apply this matcher to.
6392
                     */
6393
                    protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6394
                                                Transformer<FieldDescription> transformer,
6395
                                                @MaybeNull Object defaultValue,
6396
                                                LatentMatcher<? super FieldDescription> matcher) {
1✔
6397
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
6398
                        this.matcher = matcher;
1✔
6399
                    }
1✔
6400

6401
                    /**
6402
                     * {@inheritDoc}
6403
                     */
6404
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
6405
                        return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
1✔
6406
                    }
6407

6408
                    @Override
6409
                    protected Builder<U> materialize() {
6410
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
6411
                                fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
6412
                                methodRegistry,
6413
                                recordComponentRegistry,
6414
                                typeAttributeAppender,
6415
                                asmVisitorWrapper,
6416
                                classFileVersion,
6417
                                auxiliaryTypeNamingStrategy,
6418
                                annotationValueFilterFactory,
6419
                                annotationRetention,
6420
                                implementationContextFactory,
6421
                                methodGraphCompiler,
6422
                                typeValidation,
6423
                                visibilityBridgeStrategy,
6424
                                classReaderFactory,
6425
                                classWriterFactory,
6426
                                ignoredMethods,
6427
                                auxiliaryTypes);
6428
                    }
6429

6430
                    @Override
6431
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6432
                                                      Transformer<FieldDescription> transformer,
6433
                                                      @MaybeNull Object defaultValue) {
6434
                        return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
1✔
6435
                    }
6436
                }
6437

6438
                /**
6439
                 * An adapter for defining a new method.
6440
                 */
6441
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6442
                protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
6443

6444
                    /**
6445
                     * A token representing the currently defined method.
6446
                     */
6447
                    private final MethodDescription.Token token;
6448

6449
                    /**
6450
                     * Creates a new method definition adapter.
6451
                     *
6452
                     * @param token A token representing the currently defined method.
6453
                     */
6454
                    protected MethodDefinitionAdapter(MethodDescription.Token token) {
1✔
6455
                        this.token = token;
1✔
6456
                    }
1✔
6457

6458
                    /**
6459
                     * {@inheritDoc}
6460
                     */
6461
                    public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
6462
                        return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
1✔
6463
                    }
6464

6465
                    /**
6466
                     * {@inheritDoc}
6467
                     */
6468
                    public Simple.Annotatable<U> withParameter(TypeDefinition type) {
6469
                        return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
1✔
6470
                    }
6471

6472
                    /**
6473
                     * {@inheritDoc}
6474
                     */
6475
                    public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
6476
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6477
                                token.getModifiers(),
1✔
6478
                                token.getTypeVariableTokens(),
1✔
6479
                                token.getReturnType(),
1✔
6480
                                token.getParameterTokens(),
1✔
6481
                                CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
1✔
6482
                                token.getAnnotations(),
1✔
6483
                                token.getDefaultValue(),
1✔
6484
                                token.getReceiverType()));
1✔
6485
                    }
6486

6487
                    /**
6488
                     * {@inheritDoc}
6489
                     */
6490
                    public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
6491
                        return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
6492
                    }
6493

6494
                    /**
6495
                     * {@inheritDoc}
6496
                     */
6497
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
6498
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
6499
                    }
6500

6501
                    /**
6502
                     * {@inheritDoc}
6503
                     */
6504
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
6505
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6506
                                (token.getModifiers() & Opcodes.ACC_NATIVE) == 0
1✔
6507
                                        ? ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers())
1✔
6508
                                        : token.getModifiers(),
1✔
6509
                                token.getTypeVariableTokens(),
1✔
6510
                                token.getReturnType(),
1✔
6511
                                token.getParameterTokens(),
1✔
6512
                                token.getExceptionTypes(),
1✔
6513
                                token.getAnnotations(),
1✔
6514
                                token.getDefaultValue(),
1✔
6515
                                token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
6516
                    }
6517

6518
                    /**
6519
                     * {@inheritDoc}
6520
                     */
6521
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
6522
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6523
                                ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
1✔
6524
                                token.getTypeVariableTokens(),
1✔
6525
                                token.getReturnType(),
1✔
6526
                                token.getParameterTokens(),
1✔
6527
                                token.getExceptionTypes(),
1✔
6528
                                token.getAnnotations(),
1✔
6529
                                annotationValue,
6530
                                token.getReceiverType())).materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
6531
                    }
6532

6533
                    /**
6534
                     * Materializes the given handler as the implementation.
6535
                     *
6536
                     * @param handler The handler for implementing the method.
6537
                     * @return A method definition for the given handler.
6538
                     */
6539
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
6540
                        return new AnnotationAdapter(handler);
1✔
6541
                    }
6542

6543
                    /**
6544
                     * An adapter for defining a new type variable for the currently defined method.
6545
                     */
6546
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6547
                    protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
6548

6549
                        /**
6550
                         * The currently defined type variable.
6551
                         */
6552
                        private final TypeVariableToken token;
6553

6554
                        /**
6555
                         * Creates a new type variable annotation adapter.
6556
                         *
6557
                         * @param token The currently defined type variable.
6558
                         */
6559
                        protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
1✔
6560
                            this.token = token;
1✔
6561
                        }
1✔
6562

6563
                        @Override
6564
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
6565
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6566
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6567
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getTypeVariableTokens(), token),
1✔
6568
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6569
                                    MethodDefinitionAdapter.this.token.getParameterTokens(),
1✔
6570
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6571
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6572
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6573
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6574
                        }
6575

6576
                        /**
6577
                         * {@inheritDoc}
6578
                         */
6579
                        public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
6580
                            return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
1✔
6581
                                    token.getBounds(),
1✔
6582
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6583
                        }
6584
                    }
6585

6586
                    /**
6587
                     * An annotation adapter for a parameter definition.
6588
                     */
6589
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6590
                    protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
6591

6592
                        /**
6593
                         * The token of the currently defined parameter.
6594
                         */
6595
                        private final ParameterDescription.Token token;
6596

6597
                        /**
6598
                         * Creates a new parameter annotation adapter.
6599
                         *
6600
                         * @param token The token of the currently defined parameter.
6601
                         */
6602
                        protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
6603
                            this.token = token;
1✔
6604
                        }
1✔
6605

6606
                        /**
6607
                         * {@inheritDoc}
6608
                         */
6609
                        public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
UNCOV
6610
                            return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
×
UNCOV
6611
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
UNCOV
6612
                                    token.getName(),
×
UNCOV
6613
                                    token.getModifiers()));
×
6614
                        }
6615

6616
                        @Override
6617
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
6618
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6619
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6620
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
6621
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6622
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
6623
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6624
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6625
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6626
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6627
                        }
6628
                    }
6629

6630
                    /**
6631
                     * An annotation adapter for a simple parameter definition.
6632
                     */
6633
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6634
                    protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
6635

6636
                        /**
6637
                         * The token of the currently defined parameter.
6638
                         */
6639
                        private final ParameterDescription.Token token;
6640

6641
                        /**
6642
                         * Creates a new simple parameter annotation adapter.
6643
                         *
6644
                         * @param token The token of the currently defined parameter.
6645
                         */
6646
                        protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
6647
                            this.token = token;
1✔
6648
                        }
1✔
6649

6650
                        /**
6651
                         * {@inheritDoc}
6652
                         */
6653
                        public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
6654
                            return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
1✔
6655
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
6656
                                    token.getName(),
1✔
6657
                                    token.getModifiers()));
1✔
6658
                        }
6659

6660
                        @Override
6661
                        protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
6662
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6663
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6664
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
6665
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6666
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
6667
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6668
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6669
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6670
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6671
                        }
6672
                    }
6673

6674
                    /**
6675
                     * An annotation adapter for a method definition.
6676
                     */
6677
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6678
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
6679

6680
                        /**
6681
                         * Creates a new annotation adapter.
6682
                         *
6683
                         * @param handler The handler that determines how a method is implemented.
6684
                         */
6685
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
6686
                            this(handler,
1✔
6687
                                    MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER,
6688
                                    Transformer.NoOp.<MethodDescription>make());
1✔
6689
                        }
1✔
6690

6691
                        /**
6692
                         * Creates a new annotation adapter.
6693
                         *
6694
                         * @param handler                        The handler that determines how a method is implemented.
6695
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
6696
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
6697
                         */
6698
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
6699
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6700
                                                    Transformer<MethodDescription> transformer) {
1✔
6701
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
6702
                        }
1✔
6703

6704
                        /**
6705
                         * {@inheritDoc}
6706
                         */
6707
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
6708
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6709
                                    token.getModifiers(),
1✔
6710
                                    token.getTypeVariableTokens(),
1✔
6711
                                    token.getReturnType(),
1✔
6712
                                    token.getParameterTokens(),
1✔
6713
                                    token.getExceptionTypes(),
1✔
6714
                                    token.getAnnotations(),
1✔
6715
                                    token.getDefaultValue(),
1✔
6716
                                    receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
6717
                        }
6718

6719
                        /**
6720
                         * {@inheritDoc}
6721
                         */
6722
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
6723
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6724
                                    token.getModifiers(),
1✔
6725
                                    token.getTypeVariableTokens(),
1✔
6726
                                    token.getReturnType(),
1✔
6727
                                    token.getParameterTokens(),
1✔
6728
                                    token.getExceptionTypes(),
1✔
6729
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
6730
                                    token.getDefaultValue(),
1✔
6731
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
6732
                        }
6733

6734
                        /**
6735
                         * {@inheritDoc}
6736
                         */
6737
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
UNCOV
6738
                            List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
×
UNCOV
6739
                            parameterTokens.set(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
×
UNCOV
6740
                                    CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
UNCOV
6741
                                    token.getParameterTokens().get(index).getName(),
×
UNCOV
6742
                                    token.getParameterTokens().get(index).getModifiers()));
×
UNCOV
6743
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
×
UNCOV
6744
                                    token.getModifiers(),
×
UNCOV
6745
                                    token.getTypeVariableTokens(),
×
UNCOV
6746
                                    token.getReturnType(),
×
6747
                                    parameterTokens,
UNCOV
6748
                                    token.getExceptionTypes(),
×
UNCOV
6749
                                    token.getAnnotations(),
×
UNCOV
6750
                                    token.getDefaultValue(),
×
UNCOV
6751
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
6752
                        }
6753

6754
                        @Override
6755
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
6756
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6757
                                                                  Transformer<MethodDescription> transformer) {
UNCOV
6758
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
6759
                        }
6760

6761
                        @Override
6762
                        protected Builder<U> materialize() {
6763
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
1✔
6764
                                    fieldRegistry,
6765
                                    methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
1✔
6766
                                            handler,
6767
                                            methodAttributeAppenderFactory,
6768
                                            transformer),
6769
                                    recordComponentRegistry,
6770
                                    typeAttributeAppender,
6771
                                    asmVisitorWrapper,
6772
                                    classFileVersion,
6773
                                    auxiliaryTypeNamingStrategy,
6774
                                    annotationValueFilterFactory,
6775
                                    annotationRetention,
6776
                                    implementationContextFactory,
6777
                                    methodGraphCompiler,
6778
                                    typeValidation,
6779
                                    visibilityBridgeStrategy,
6780
                                    classReaderFactory,
6781
                                    classWriterFactory,
6782
                                    ignoredMethods,
6783
                                    auxiliaryTypes);
6784
                        }
6785
                    }
6786
                }
6787

6788
                /**
6789
                 * An adapter for matching an existing method.
6790
                 */
6791
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6792
                protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
6793

6794
                    /**
6795
                     * The method matcher of this adapter.
6796
                     */
6797
                    private final LatentMatcher<? super MethodDescription> matcher;
6798

6799
                    /**
6800
                     * Creates a new method match adapter.
6801
                     *
6802
                     * @param matcher The method matcher of this adapter.
6803
                     */
6804
                    protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
1✔
6805
                        this.matcher = matcher;
1✔
6806
                    }
1✔
6807

6808
                    /**
6809
                     * {@inheritDoc}
6810
                     */
6811
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
6812
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
6813
                    }
6814

6815
                    /**
6816
                     * {@inheritDoc}
6817
                     */
6818
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
6819
                        return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
6820
                    }
6821

6822
                    /**
6823
                     * {@inheritDoc}
6824
                     */
6825
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
6826
                        return materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
6827
                    }
6828

6829
                    /**
6830
                     * Materializes the method definition with the supplied handler.
6831
                     *
6832
                     * @param handler The handler that implements any method matched by this instances matcher.
6833
                     * @return A method definition where any matched method is implemented by the supplied handler.
6834
                     */
6835
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
6836
                        return new AnnotationAdapter(handler);
1✔
6837
                    }
6838

6839
                    /**
6840
                     * An annotation adapter for implementing annotations during a method definition.
6841
                     */
6842
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6843
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
6844

6845
                        /**
6846
                         * Creates a new annotation adapter.
6847
                         *
6848
                         * @param handler The handler that determines how a method is implemented.
6849
                         */
6850
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
6851
                            this(handler, MethodAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<MethodDescription>make());
1✔
6852
                        }
1✔
6853

6854
                        /**
6855
                         * Creates a new annotation adapter.
6856
                         *
6857
                         * @param handler                        The handler that determines how a method is implemented.
6858
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
6859
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
6860
                         */
6861
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
6862
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6863
                                                    Transformer<MethodDescription> transformer) {
1✔
6864
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
6865
                        }
1✔
6866

6867
                        /**
6868
                         * {@inheritDoc}
6869
                         */
6870
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
6871
                            return new AnnotationAdapter(handler,
1✔
6872
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
6873
                                    transformer);
6874
                        }
6875

6876
                        /**
6877
                         * {@inheritDoc}
6878
                         */
6879
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
6880
                            return new AnnotationAdapter(handler,
1✔
6881
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
6882
                                    transformer);
6883
                        }
6884

6885
                        /**
6886
                         * {@inheritDoc}
6887
                         */
6888
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
UNCOV
6889
                            return new AnnotationAdapter(handler,
×
6890
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
6891
                                    transformer);
6892
                        }
6893

6894
                        @Override
6895
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
6896
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6897
                                                                  Transformer<MethodDescription> transformer) {
6898
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
6899
                        }
6900

6901
                        @Override
6902
                        protected Builder<U> materialize() {
6903
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
6904
                                    fieldRegistry,
6905
                                    methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, transformer),
1✔
6906
                                    recordComponentRegistry,
6907
                                    typeAttributeAppender,
6908
                                    asmVisitorWrapper,
6909
                                    classFileVersion,
6910
                                    auxiliaryTypeNamingStrategy,
6911
                                    annotationValueFilterFactory,
6912
                                    annotationRetention,
6913
                                    implementationContextFactory,
6914
                                    methodGraphCompiler,
6915
                                    typeValidation,
6916
                                    visibilityBridgeStrategy,
6917
                                    classReaderFactory,
6918
                                    classWriterFactory,
6919
                                    ignoredMethods,
6920
                                    auxiliaryTypes);
6921
                        }
6922
                    }
6923
                }
6924

6925
                /**
6926
                 * An adapter for optionally matching methods defined by declared interfaces.
6927
                 */
6928
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6929
                protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
6930

6931
                    /**
6932
                     * The interfaces whose methods are optionally matched.
6933
                     */
6934
                    private final TypeList.Generic interfaces;
6935

6936
                    /**
6937
                     * Creates a new optional method match adapter.
6938
                     *
6939
                     * @param interfaces The interfaces whose methods are optionally matched.
6940
                     */
6941
                    protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
1✔
6942
                        this.interfaces = interfaces;
1✔
6943
                    }
1✔
6944

6945
                    @Override
6946
                    protected Builder<U> materialize() {
6947
                        return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
1✔
6948
                                fieldRegistry,
6949
                                methodRegistry,
6950
                                recordComponentRegistry,
6951
                                typeAttributeAppender,
6952
                                asmVisitorWrapper,
6953
                                classFileVersion,
6954
                                auxiliaryTypeNamingStrategy,
6955
                                annotationValueFilterFactory,
6956
                                annotationRetention,
6957
                                implementationContextFactory,
6958
                                methodGraphCompiler,
6959
                                typeValidation,
6960
                                visibilityBridgeStrategy,
6961
                                classReaderFactory,
6962
                                classWriterFactory,
6963
                                ignoredMethods,
6964
                                auxiliaryTypes);
6965
                    }
6966

6967
                    /**
6968
                     * {@inheritDoc}
6969
                     */
6970
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
6971
                        return interfaceType().intercept(implementation);
1✔
6972
                    }
6973

6974
                    /**
6975
                     * {@inheritDoc}
6976
                     */
6977
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
UNCOV
6978
                        return interfaceType().withoutCode();
×
6979
                    }
6980

6981
                    /**
6982
                     * {@inheritDoc}
6983
                     */
6984
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
UNCOV
6985
                        return interfaceType().defaultValue(annotationValue);
×
6986
                    }
6987

6988
                    /**
6989
                     * {@inheritDoc}
6990
                     */
6991
                    public <V> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(V value, Class<? extends V> type) {
UNCOV
6992
                        return interfaceType().defaultValue(value, type);
×
6993
                    }
6994

6995
                    /**
6996
                     * Returns a matcher for the interfaces' methods.
6997
                     *
6998
                     * @return A matcher for the interfaces' methods.
6999
                     */
7000
                    private MethodDefinition.ImplementationDefinition<U> interfaceType() {
7001
                        ElementMatcher.Junction<TypeDescription> elementMatcher = none();
1✔
7002
                        for (TypeDescription typeDescription : interfaces.asErasures()) {
1✔
7003
                            elementMatcher = elementMatcher.or(isSuperTypeOf(typeDescription));
1✔
7004
                        }
1✔
7005
                        return materialize().invokable(isDeclaredBy(isInterface().and(elementMatcher)));
1✔
7006
                    }
7007
                }
7008

7009
                /**
7010
                 * An adapter for defining a record component.
7011
                 */
7012
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
7013
                protected class RecordComponentDefinitionAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
7014

7015
                    /**
7016
                     * The record component attribute appender factory to apply.
7017
                     */
7018
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
7019

7020
                    /**
7021
                     * A token representing the defined record component.
7022
                     */
7023
                    private final RecordComponentDescription.Token token;
7024

7025
                    /**
7026
                     * A transformer to apply on matched record component descriptions.
7027
                     */
7028
                    private final Transformer<RecordComponentDescription> transformer;
7029

7030
                    /**
7031
                     * Creates a new record component definition adapter.
7032
                     *
7033
                     * @param token A token representing the defined record component.
7034
                     */
7035
                    protected RecordComponentDefinitionAdapter(RecordComponentDescription.Token token) {
UNCOV
7036
                        this(RecordComponentAttributeAppender.ForInstrumentedRecordComponent.INSTANCE,
×
UNCOV
7037
                                Transformer.NoOp.<RecordComponentDescription>make(),
×
7038
                                token);
UNCOV
7039
                    }
×
7040

7041
                    /**
7042
                     * Creates a new record component definition adapter.
7043
                     *
7044
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
7045
                     * @param transformer                             A transformer to apply on matched record component descriptions.
7046
                     * @param token                                   A token representing the defined record component.
7047
                     */
7048
                    protected RecordComponentDefinitionAdapter(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
7049
                                                               Transformer<RecordComponentDescription> transformer,
UNCOV
7050
                                                               RecordComponentDescription.Token token) {
×
UNCOV
7051
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
UNCOV
7052
                        this.transformer = transformer;
×
UNCOV
7053
                        this.token = token;
×
UNCOV
7054
                    }
×
7055

7056
                    /**
7057
                     * {@inheritDoc}
7058
                     */
7059
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
UNCOV
7060
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory, transformer, new RecordComponentDescription.Token(token.getName(),
×
UNCOV
7061
                                token.getType(),
×
UNCOV
7062
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
×
7063
                    }
7064

7065
                    /**
7066
                     * {@inheritDoc}
7067
                     */
7068
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
UNCOV
7069
                        return new RecordComponentDefinitionAdapter(new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
7070
                                recordComponentAttributeAppenderFactory), transformer, token);
7071
                    }
7072

7073
                    /**
7074
                     * {@inheritDoc}
7075
                     */
7076
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
7077
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
UNCOV
7078
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory,
×
7079
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer),
7080
                                token);
7081
                    }
7082

7083
                    @Override
7084
                    protected Builder<U> materialize() {
UNCOV
7085
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withRecordComponent(token),
×
7086
                                fieldRegistry,
7087
                                methodRegistry,
UNCOV
7088
                                recordComponentRegistry.prepend(new LatentMatcher.ForRecordComponentToken(token),
×
7089
                                        recordComponentAttributeAppenderFactory,
7090
                                        transformer),
7091
                                typeAttributeAppender,
7092
                                asmVisitorWrapper,
7093
                                classFileVersion,
7094
                                auxiliaryTypeNamingStrategy,
7095
                                annotationValueFilterFactory,
7096
                                annotationRetention,
7097
                                implementationContextFactory,
7098
                                methodGraphCompiler,
7099
                                typeValidation,
7100
                                visibilityBridgeStrategy,
7101
                                classReaderFactory,
7102
                                classWriterFactory,
7103
                                ignoredMethods,
7104
                                auxiliaryTypes);
7105
                    }
7106
                }
7107

7108
                /**
7109
                 * An adapter for matching record components.
7110
                 */
7111
                protected class RecordComponentMatchAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
7112

7113
                    /**
7114
                     * The matcher for identifying record components to match.
7115
                     */
7116
                    private final LatentMatcher<? super RecordComponentDescription> matcher;
7117

7118
                    /**
7119
                     * The record component attribute appender factory to apply.
7120
                     */
7121
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
7122

7123
                    /**
7124
                     * A transformer to apply on matched record component descriptions.
7125
                     */
7126
                    private final Transformer<RecordComponentDescription> transformer;
7127

7128
                    /**
7129
                     * Creates a new record component match adapter.
7130
                     *
7131
                     * @param matcher The matcher for identifying record components to match.
7132
                     */
7133
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher) {
UNCOV
7134
                        this(matcher, RecordComponentAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<RecordComponentDescription>make());
×
UNCOV
7135
                    }
×
7136

7137
                    /**
7138
                     * Creates a new record component match adapter.
7139
                     *
7140
                     * @param matcher                                 The matcher for identifying record components to match.
7141
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
7142
                     * @param transformer                             A transformer to apply on matched record component descriptions.
7143
                     */
7144
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher,
7145
                                                          RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
UNCOV
7146
                                                          Transformer<RecordComponentDescription> transformer) {
×
UNCOV
7147
                        this.matcher = matcher;
×
UNCOV
7148
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
UNCOV
7149
                        this.transformer = transformer;
×
UNCOV
7150
                    }
×
7151

7152
                    /**
7153
                     * {@inheritDoc}
7154
                     */
7155
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
UNCOV
7156
                        return attribute(new RecordComponentAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
×
7157
                    }
7158

7159
                    /**
7160
                     * {@inheritDoc}
7161
                     */
7162
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
UNCOV
7163
                        return new RecordComponentMatchAdapter(matcher, new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
7164
                                recordComponentAttributeAppenderFactory), transformer);
7165
                    }
7166

7167
                    /**
7168
                     * {@inheritDoc}
7169
                     */
7170
                    @SuppressWarnings("unchecked")  // In absence of @SafeVarargs
7171
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
UNCOV
7172
                        return new RecordComponentMatchAdapter(matcher,
×
7173
                                recordComponentAttributeAppenderFactory,
7174
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer));
7175
                    }
7176

7177
                    @Override
7178
                    protected Builder<U> materialize() {
UNCOV
7179
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
×
7180
                                fieldRegistry,
7181
                                methodRegistry,
UNCOV
7182
                                recordComponentRegistry.prepend(matcher, recordComponentAttributeAppenderFactory, transformer),
×
7183
                                typeAttributeAppender,
7184
                                asmVisitorWrapper,
7185
                                classFileVersion,
7186
                                auxiliaryTypeNamingStrategy,
7187
                                annotationValueFilterFactory,
7188
                                annotationRetention,
7189
                                implementationContextFactory,
7190
                                methodGraphCompiler,
7191
                                typeValidation,
7192
                                visibilityBridgeStrategy,
7193
                                classReaderFactory,
7194
                                classWriterFactory,
7195
                                ignoredMethods,
7196
                                auxiliaryTypes);
7197
                    }
7198
                }
7199
            }
7200
        }
7201
    }
7202

7203
    /**
7204
     * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
7205
     *
7206
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7207
     *            type itself, an interface or the direct super class.
7208
     */
7209
    interface Unloaded<T> extends DynamicType {
7210

7211
        /**
7212
         * <p>
7213
         * Attempts to load this dynamic type including all of its auxiliary types, if any. If the class loader is an
7214
         * unsealed instance of {@link InjectionClassLoader}, the classes are injected directy into the class loader, otherwise,
7215
         * a new class loader is created where the supplied class loader is set as parent.
7216
         * </p>
7217
         * <p>
7218
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
7219
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
7220
         * </p>
7221
         *
7222
         * @param classLoader The class loader to use for this class loading or {@code null} for using the boot loader.
7223
         * @return This dynamic type in its loaded state.
7224
         */
7225
        Loaded<T> load(@MaybeNull ClassLoader classLoader);
7226

7227
        /**
7228
         * <p>
7229
         * Attempts to load this dynamic type including all of its auxiliary types, if any.
7230
         * </p>
7231
         * <p>
7232
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
7233
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
7234
         * </p>
7235
         *
7236
         * @param classLoader          The class loader to use for this class loading.
7237
         * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
7238
         * @param <S>                  The least specific type of class loader this strategy can apply to.
7239
         * @return This dynamic type in its loaded state.
7240
         * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
7241
         */
7242
        <S extends ClassLoader> Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
7243

7244
        /**
7245
         * Includes the provided dynamic types as auxiliary types of this instance.
7246
         *
7247
         * @param dynamicType The dynamic types to include.
7248
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
7249
         */
7250
        Unloaded<T> include(DynamicType... dynamicType);
7251

7252
        /**
7253
         * Includes the provided dynamic types as auxiliary types of this instance.
7254
         *
7255
         * @param dynamicTypes The dynamic types to include.
7256
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
7257
         */
7258
        Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
7259
    }
7260

7261
    /**
7262
     * A dynamic type that has been loaded into the running instance of the Java virtual machine.
7263
     *
7264
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7265
     *            type itself, an interface or the direct super class.
7266
     */
7267
    interface Loaded<T> extends DynamicType {
7268

7269
        /**
7270
         * Returns the loaded main class.
7271
         *
7272
         * @return A loaded class representation of this dynamic type.
7273
         */
7274
        Class<? extends T> getLoaded();
7275

7276
        /**
7277
         * <p>
7278
         * Returns a map of all loaded auxiliary types to this dynamic type.
7279
         * </p>
7280
         * <p>
7281
         * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
7282
         * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
7283
         * </p>
7284
         *
7285
         * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
7286
         */
7287
        Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
7288

7289
        /**
7290
         * Returns all loaded types that are implied by this dynamic type.
7291
         *
7292
         * @return All loaded types that are implied by this dynamic type.
7293
         */
7294
        Map<TypeDescription, Class<?>> getAllLoaded();
7295
    }
7296

7297
    @HashCodeAndEqualsPlugin.Enhance
7298
    abstract class AbstractBase implements DynamicType {
1✔
7299

7300
        /**
7301
         * The file name extension for Java class files.
7302
         */
7303
        private static final String CLASS_FILE_EXTENSION = ".class";
7304

7305
        /**
7306
         * The default version of a jar file manifest.
7307
         */
7308
        private static final String MANIFEST_VERSION = "1.0";
7309

7310
        /**
7311
         * A suffix for temporary files.
7312
         */
7313
        private static final String TEMP_SUFFIX = "tmp";
7314

7315
        /**
7316
         * {@inheritDoc}
7317
         */
7318
        public Resolution locate(String name) throws IOException {
7319
            if (getTypeDescription().getName().equals(name)) {
1✔
7320
                return new Resolution.Explicit(getBytes());
1✔
7321
            }
7322
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7323
                Resolution resolution = auxiliaryType.locate(name);
1✔
7324
                if (resolution.isResolved()) {
1✔
7325
                    return resolution;
1✔
7326
                }
7327
            }
1✔
7328
            return new Resolution.Illegal(name);
1✔
7329
        }
7330

7331
        /**
7332
         * {@inheritDoc}
7333
         */
7334
        public void close() {
7335
            /* do nothing */
UNCOV
7336
        }
×
7337

7338
        /**
7339
         * {@inheritDoc}
7340
         */
7341
        public Set<TypeDescription> getAuxiliaryTypeDescriptions() {
7342
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
7343
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7344
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
7345
            }
1✔
7346
            return types;
1✔
7347
        }
7348

7349
        /**
7350
         * {@inheritDoc}
7351
         */
7352
        public Set<TypeDescription> getAllTypeDescriptions() {
7353
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
7354
            types.add(getTypeDescription());
1✔
7355
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7356
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
7357
            }
1✔
7358
            return types;
1✔
7359
        }
7360

7361
        /**
7362
         * {@inheritDoc}
7363
         */
7364
        public Map<TypeDescription, byte[]> getAllTypes() {
7365
            Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
1✔
7366
            allTypes.put(getTypeDescription(), getBytes());
1✔
7367
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7368
                allTypes.putAll(auxiliaryType.getAllTypes());
1✔
7369
            }
1✔
7370
            return allTypes;
1✔
7371
        }
7372

7373
        /**
7374
         * {@inheritDoc}
7375
         */
7376
        public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
7377
            Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
1✔
7378
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7379
                classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
1✔
7380
            }
1✔
7381
            classLoadingCallbacks.put(getTypeDescription(), getLoadedTypeInitializer());
1✔
7382
            return classLoadingCallbacks;
1✔
7383
        }
7384

7385
        /**
7386
         * {@inheritDoc}
7387
         */
7388
        public boolean hasAliveLoadedTypeInitializers() {
7389
            if (getLoadedTypeInitializer().isAlive()) {
1✔
7390
                return true;
1✔
7391
            }
7392
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7393
                if (auxiliaryType.hasAliveLoadedTypeInitializers()) {
1✔
7394
                    return true;
1✔
7395
                }
7396
            }
1✔
7397
            return false;
1✔
7398
        }
7399

7400
        /**
7401
         * {@inheritDoc}
7402
         */
7403
        public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
7404
            Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
1✔
7405
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7406
                auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
1✔
7407
                auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
1✔
7408
            }
1✔
7409
            return auxiliaryTypes;
1✔
7410
        }
7411

7412
        /**
7413
         * {@inheritDoc}
7414
         */
7415
        public Map<TypeDescription, File> saveIn(File folder) throws IOException {
7416
            Map<TypeDescription, File> files = new HashMap<TypeDescription, File>();
1✔
7417
            File target = new File(folder, getTypeDescription().getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
1✔
7418
            if (target.getParentFile() != null && !target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
1✔
UNCOV
7419
                throw new IllegalArgumentException("Could not create directory: " + target.getParentFile());
×
7420
            }
7421
            OutputStream outputStream = new FileOutputStream(target);
1✔
7422
            try {
7423
                outputStream.write(getBytes());
1✔
7424
            } finally {
7425
                outputStream.close();
1✔
7426
            }
7427
            files.put(getTypeDescription(), target);
1✔
7428
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7429
                files.putAll(auxiliaryType.saveIn(folder));
1✔
7430
            }
1✔
7431
            return files;
1✔
7432
        }
7433

7434
        /**
7435
         * {@inheritDoc}
7436
         */
7437
        public File inject(File sourceJar, File targetJar) throws IOException {
7438
            return sourceJar.equals(targetJar)
1✔
7439
                    ? inject(sourceJar)
1✔
7440
                    : doInject(sourceJar, targetJar);
1✔
7441
        }
7442

7443
        /**
7444
         * {@inheritDoc}
7445
         */
7446
        public File inject(File jar) throws IOException {
7447
            FileSystem.getInstance().move(doInject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX)), jar);
1✔
7448
            return jar;
1✔
7449
        }
7450

7451
        /**
7452
         * Injects this dynamic type into a source jar and writes the result to the target jar.
7453
         *
7454
         * @param sourceJar The source jar.
7455
         * @param targetJar The target jar.
7456
         * @return The jar file that was written to.
7457
         * @throws IOException If an I/O error occurs.
7458
         */
7459
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
7460
        private File doInject(File sourceJar, File targetJar) throws IOException {
7461
            InputStream inputStream = new FileInputStream(sourceJar);
1✔
7462
            try {
7463
                JarInputStream jarInputStream = new JarInputStream(inputStream);
1✔
7464
                if (!targetJar.isFile() && !targetJar.createNewFile()) {
1✔
UNCOV
7465
                    throw new IllegalArgumentException("Could not create file: " + targetJar);
×
7466
                }
7467
                Manifest manifest = jarInputStream.getManifest();
1✔
7468
                OutputStream outputStream = new FileOutputStream(targetJar);
1✔
7469
                try {
7470
                    JarOutputStream jarOutputStream = manifest == null
1✔
7471
                            ? new JarOutputStream(outputStream)
7472
                            : new JarOutputStream(outputStream, manifest);
7473
                    Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
1✔
7474
                    Map<String, byte[]> files = new HashMap<String, byte[]>();
1✔
7475
                    for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
1✔
7476
                        files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
1✔
7477
                    }
1✔
7478
                    files.put(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION, getBytes());
1✔
7479
                    JarEntry jarEntry;
7480
                    while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
1✔
7481
                        byte[] replacement = files.remove(jarEntry.getName());
1✔
7482
                        if (replacement == null) {
1✔
7483
                            jarOutputStream.putNextEntry(jarEntry);
1✔
7484
                            byte[] buffer = new byte[1024];
1✔
7485
                            int index;
7486
                            while ((index = jarInputStream.read(buffer)) != -1) {
1✔
7487
                                jarOutputStream.write(buffer, 0, index);
1✔
7488
                            }
7489
                        } else {
1✔
7490
                            jarOutputStream.putNextEntry(new JarEntry(jarEntry.getName()));
1✔
7491
                            jarOutputStream.write(replacement);
1✔
7492
                        }
7493
                        jarInputStream.closeEntry();
1✔
7494
                        jarOutputStream.closeEntry();
1✔
7495
                    }
1✔
7496
                    for (Map.Entry<String, byte[]> entry : files.entrySet()) {
1✔
7497
                        jarOutputStream.putNextEntry(new JarEntry(entry.getKey()));
1✔
7498
                        jarOutputStream.write(entry.getValue());
1✔
7499
                        jarOutputStream.closeEntry();
1✔
7500
                    }
1✔
7501
                    jarOutputStream.close();
1✔
7502
                } finally {
7503
                    outputStream.close();
1✔
7504
                }
7505
                jarInputStream.close();
1✔
7506
            } finally {
7507
                inputStream.close();
1✔
7508
            }
7509
            return targetJar;
1✔
7510
        }
7511

7512
        /**
7513
         * {@inheritDoc}
7514
         */
7515
        public File toJar(File file) throws IOException {
7516
            Manifest manifest = new Manifest();
1✔
7517
            manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
1✔
7518
            return toJar(file, manifest);
1✔
7519
        }
7520

7521
        /**
7522
         * {@inheritDoc}
7523
         */
7524
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
7525
        public File toJar(File file, Manifest manifest) throws IOException {
7526
            if (!file.isFile() && !file.createNewFile()) {
1✔
UNCOV
7527
                throw new IllegalArgumentException("Could not create file: " + file);
×
7528
            }
7529
            OutputStream outputStream = new FileOutputStream(file);
1✔
7530
            try {
7531
                JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest);
1✔
7532
                for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
1✔
7533
                    jarOutputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
1✔
7534
                    jarOutputStream.write(entry.getValue());
1✔
7535
                    jarOutputStream.closeEntry();
1✔
7536
                }
1✔
7537
                jarOutputStream.putNextEntry(new JarEntry(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION));
1✔
7538
                jarOutputStream.write(getBytes());
1✔
7539
                jarOutputStream.closeEntry();
1✔
7540
                jarOutputStream.close();
1✔
7541
            } finally {
7542
                outputStream.close();
1✔
7543
            }
7544
            return file;
1✔
7545
        }
7546
    }
7547

7548
    /**
7549
     * A default implementation of a dynamic type.
7550
     */
7551
    @HashCodeAndEqualsPlugin.Enhance
7552
    class Default extends AbstractBase {
7553

7554
        /**
7555
         * A type description of this dynamic type.
7556
         */
7557
        protected final TypeDescription typeDescription;
7558

7559
        /**
7560
         * The byte array representing this dynamic type.
7561
         */
7562
        protected final byte[] binaryRepresentation;
7563

7564
        /**
7565
         * The loaded type initializer for this dynamic type.
7566
         */
7567
        protected final LoadedTypeInitializer loadedTypeInitializer;
7568

7569
        /**
7570
         * A list of auxiliary types for this dynamic type.
7571
         */
7572
        protected final List<? extends DynamicType> auxiliaryTypes;
7573

7574
        /**
7575
         * Creates a new dynamic type.
7576
         *
7577
         * @param typeDescription       A description of this dynamic type.
7578
         * @param binaryRepresentation  A byte array containing the binary representation of this dynamic type. The array must not be modified.
7579
         * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
7580
         * @param auxiliaryTypes        The auxiliary type required for this dynamic type.
7581
         */
7582
        @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not modified by class contract.")
7583
        public Default(TypeDescription typeDescription,
7584
                       byte[] binaryRepresentation,
7585
                       LoadedTypeInitializer loadedTypeInitializer,
7586
                       List<? extends DynamicType> auxiliaryTypes) {
1✔
7587
            this.typeDescription = typeDescription;
1✔
7588
            this.binaryRepresentation = binaryRepresentation;
1✔
7589
            this.loadedTypeInitializer = loadedTypeInitializer;
1✔
7590
            this.auxiliaryTypes = auxiliaryTypes;
1✔
7591
        }
1✔
7592

7593
        /**
7594
         * {@inheritDoc}
7595
         */
7596
        public TypeDescription getTypeDescription() {
7597
            return typeDescription;
1✔
7598
        }
7599

7600
        /**
7601
         * {@inheritDoc}
7602
         */
7603
        @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not modified by class contract.")
7604
        public byte[] getBytes() {
7605
            return binaryRepresentation;
1✔
7606
        }
7607

7608
        /**
7609
         * {@inheritDoc}
7610
         */
7611
        public LoadedTypeInitializer getLoadedTypeInitializer() {
7612
            return loadedTypeInitializer;
1✔
7613
        }
7614

7615
        /**
7616
         * {@inheritDoc}
7617
         */
7618
        public List<? extends DynamicType> getAuxiliaries() {
7619
            return auxiliaryTypes;
1✔
7620
        }
7621

7622
        /**
7623
         * A default implementation of an unloaded dynamic type.
7624
         *
7625
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7626
         *            type itself, an interface or the direct super class.
7627
         */
7628
        @HashCodeAndEqualsPlugin.Enhance
7629
        public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
7630

7631
            /**
7632
             * The type resolution strategy to use for initializing the dynamic type.
7633
             */
7634
            private final TypeResolutionStrategy.Resolved typeResolutionStrategy;
7635

7636
            /**
7637
             * Creates a new unloaded representation of a dynamic type.
7638
             *
7639
             * @param typeDescription        A description of this dynamic type.
7640
             * @param binaryRepresentation   An array of byte of the binary representation of this dynamic type.
7641
             * @param loadedTypeInitializer  The type initializer of this dynamic type.
7642
             * @param auxiliaryTypes         The auxiliary types that are required for this dynamic type.
7643
             * @param typeResolutionStrategy The type resolution strategy to use for initializing the dynamic type.
7644
             */
7645
            public Unloaded(TypeDescription typeDescription,
7646
                            byte[] binaryRepresentation,
7647
                            LoadedTypeInitializer loadedTypeInitializer,
7648
                            List<? extends DynamicType> auxiliaryTypes,
7649
                            TypeResolutionStrategy.Resolved typeResolutionStrategy) {
7650
                super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
1✔
7651
                this.typeResolutionStrategy = typeResolutionStrategy;
1✔
7652
            }
1✔
7653

7654
            /**
7655
             * {@inheritDoc}
7656
             */
7657
            public DynamicType.Loaded<T> load(@MaybeNull ClassLoader classLoader) {
7658
                if (classLoader instanceof InjectionClassLoader && !((InjectionClassLoader) classLoader).isSealed()) {
1✔
7659
                    return load((InjectionClassLoader) classLoader, InjectionClassLoader.Strategy.INSTANCE);
1✔
7660
                } else {
7661
                    return load(classLoader, ClassLoadingStrategy.Default.WRAPPER);
1✔
7662
                }
7663
            }
7664

7665
            /**
7666
             * {@inheritDoc}
7667
             */
7668
            public <S extends ClassLoader> DynamicType.Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
7669
                return new Default.Loaded<T>(typeDescription,
1✔
7670
                        binaryRepresentation,
7671
                        loadedTypeInitializer,
7672
                        auxiliaryTypes,
7673
                        typeResolutionStrategy.initialize(this, classLoader, classLoadingStrategy));
1✔
7674
            }
7675

7676
            /**
7677
             * {@inheritDoc}
7678
             */
7679
            public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
7680
                return include(Arrays.asList(dynamicType));
1✔
7681
            }
7682

7683
            /**
7684
             * {@inheritDoc}
7685
             */
7686
            public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
7687
                return new Default.Unloaded<T>(typeDescription,
1✔
7688
                        binaryRepresentation,
7689
                        loadedTypeInitializer,
7690
                        CompoundList.of(auxiliaryTypes, dynamicType),
1✔
7691
                        typeResolutionStrategy);
7692
            }
7693
        }
7694

7695
        /**
7696
         * A default implementation of a loaded dynamic type.
7697
         *
7698
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7699
         *            type itself, an interface or the direct super class.
7700
         */
7701
        @HashCodeAndEqualsPlugin.Enhance
7702
        protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
7703

7704
            /**
7705
             * The loaded types for the given loaded dynamic type.
7706
             */
7707
            private final Map<TypeDescription, Class<?>> loadedTypes;
7708

7709
            /**
7710
             * Creates a new representation of a loaded dynamic type.
7711
             *
7712
             * @param typeDescription       A description of this dynamic type.
7713
             * @param typeByte              An array of byte of the binary representation of this dynamic type.
7714
             * @param loadedTypeInitializer The type initializer of this dynamic type.
7715
             * @param auxiliaryTypes        The auxiliary types that are required for this dynamic type.
7716
             * @param loadedTypes           A map of loaded types for this dynamic type and all its auxiliary types.
7717
             */
7718
            protected Loaded(TypeDescription typeDescription,
7719
                             byte[] typeByte,
7720
                             LoadedTypeInitializer loadedTypeInitializer,
7721
                             List<? extends DynamicType> auxiliaryTypes,
7722
                             Map<TypeDescription, Class<?>> loadedTypes) {
7723
                super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
1✔
7724
                this.loadedTypes = loadedTypes;
1✔
7725
            }
1✔
7726

7727
            /**
7728
             * {@inheritDoc}
7729
             */
7730
            public Class<? extends T> getLoaded() {
7731
                @SuppressWarnings("unchecked")
7732
                Class<? extends T> type = (Class<? extends T>) loadedTypes.get(typeDescription);
1✔
7733
                if (type == null) {
1✔
UNCOV
7734
                    throw new IllegalStateException(typeDescription + " cannot be loaded explicitly");
×
7735
                }
7736
                return type;
1✔
7737
            }
7738

7739
            /**
7740
             * {@inheritDoc}
7741
             */
7742
            public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
7743
                Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
7744
                loadedAuxiliaryTypes.remove(typeDescription);
1✔
7745
                return loadedAuxiliaryTypes;
1✔
7746
            }
7747

7748
            /**
7749
             * {@inheritDoc}
7750
             */
7751
            public Map<TypeDescription, Class<?>> getAllLoaded() {
7752
                return new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
7753
            }
7754
        }
7755
    }
7756
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc