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

raphw / byte-buddy / #811

03 Nov 2025 10:41AM UTC coverage: 83.677% (-0.3%) from 84.023%
#811

push

raphw
Fix null handling.

0 of 1 new or added line in 1 file covered. (0.0%)

791 existing lines in 12 files now uncovered.

29814 of 35630 relevant lines covered (83.68%)

0.84 hits per line

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

62.21
/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
         * Adjusts a previous module definition in this class file. This is normally only meaningful for classes named {@code module-info}.
393
         *
394
         * @return A new builder that is equal to this builder but which adjusts the current module information.
395
         */
396
        ModuleDefinition<T> adjustModule();
397

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

742
        /**
743
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
744
         * this type was not previously sealed, only the supplied subclasses are permitted.
745
         *
746
         * @param types The permitted subclasses.
747
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
748
         */
749
        Builder<T> permittedSubclass(Collection<? extends TypeDescription> types);
750

751
        /**
752
         * Unseales this type.
753
         *
754
         * @return A new builder that is equal to this builder but where the built type does not restrain its permitted subclasses.
755
         */
756
        Builder<T> unsealed();
757

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

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

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

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

791
        /**
792
         * Annotates the instrumented type with the supplied annotations.
793
         *
794
         * @param annotations The annotations to add to the instrumented type.
795
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
796
         */
797
        Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
798

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

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

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

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

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

881
        /**
882
         * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
883
         * type initializers are supplied, each loaded type initializer is executed in its registration order.
884
         *
885
         * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
886
         * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
887
         * loading the instrumented type.
888
         */
889
        Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
890

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

900
        /**
901
         * Explicitly requires another dynamic type for the creation of this type.
902
         *
903
         * @param type                 The type to require.
904
         * @param binaryRepresentation The type's binary representation.
905
         * @param typeInitializer      The type's loaded type initializer.
906
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
907
         */
908
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
909

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

918
        /**
919
         * Explicitly requires other dynamic types for the creation of this type.
920
         *
921
         * @param auxiliaryTypes The required dynamic types.
922
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
923
         */
924
        Builder<T> require(Collection<DynamicType> auxiliaryTypes);
925

926
        /**
927
         * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
928
         *
929
         * @param symbol The type variable's symbol.
930
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
931
         */
932
        TypeVariableDefinition<T> typeVariable(String symbol);
933

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

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

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

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

974
        /**
975
         * Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
976
         *
977
         * @param matcher     The matcher to decide what type variables to transform.
978
         * @param transformer The transformer to apply to the matched type variables.
979
         * @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
980
         */
981
        Builder<T> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer);
982

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1279
        /**
1280
         * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
1281
         * the method/constructor or method/constructor parameters.
1282
         *
1283
         * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
1284
         * @return A builder that allows for defining an implementation for the method or constructor.
1285
         */
1286
        MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
1287

1288
        /**
1289
         * Defines a Java bean property with the specified name.
1290
         *
1291
         * @param name The name of the property.
1292
         * @param type The property type.
1293
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1294
         */
1295
        FieldDefinition.Optional<T> defineProperty(String name, Type type);
1296

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

1307
        /**
1308
         * Defines a Java bean property with the specified name.
1309
         *
1310
         * @param name The name of the property.
1311
         * @param type The property type.
1312
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1313
         */
1314
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type);
1315

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1639
        /**
1640
         * Returns a {@link TypeDescription} for the currently built type.
1641
         *
1642
         * @return A {@link TypeDescription} for the currently built type.
1643
         */
1644
        TypeDescription toTypeDescription();
1645

1646
        /**
1647
         * A specification of a Java module.
1648
         *
1649
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1650
         */
1651
        interface ModuleDefinition<S> extends Builder<S> {
1652

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

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

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

1677
            /**
1678
             * Specifies the main class of the module being defined.
1679
             *
1680
             * @param name The name of the main class of the module or {@code null} if no main class is to be specified.
1681
             * @return A new builder that is equal to this builder but with the given main class specification.
1682
             */
1683
            ModuleDefinition<S> mainClass(@MaybeNull String name);
1684

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

1693
            /**
1694
             * Specifies the packages that are contained within the module being defined.
1695
             *
1696
             * @param packages The names of the packages contained within the module.
1697
             * @return A new builder that is equal to this builder but with the given package specifications.
1698
             */
1699
            ModuleDefinition<S> packages(Collection<String> packages);
1700

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

1709
            /**
1710
             * Specifies the modules that are required by the module being defined.
1711
             *
1712
             * @param modules The names of the modules that are required.
1713
             * @return A new builder that is equal to this builder but with the given module requirements.
1714
             */
1715
            ModuleDefinition<S> requires(Collection<String> modules);
1716

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

1726
            /**
1727
             * Specifies a module requirement with additional modifiers.
1728
             *
1729
             * @param module The name of the module that is required.
1730
             * @param modifierContributors The modifiers to apply to the module requirement.
1731
             * @return A builder for defining the module requirement.
1732
             */
1733
            RequiresDefinition<S> require(String module, Collection<? extends ModifierContributor.ForModule.OfRequire> modifierContributors);
1734

1735
            /**
1736
             * Specifies a module requirement with explicit modifiers.
1737
             *
1738
             * @param module The name of the module that is required.
1739
             * @param modifiers The modifiers to apply to the module requirement.
1740
             * @return A builder for defining the module requirement.
1741
             */
1742
            RequiresDefinition<S> require(String module, int modifiers);
1743

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

1752
            /**
1753
             * Specifies packages that are exported by the module being defined.
1754
             *
1755
             * @param packages The names of the packages to export.
1756
             * @return A new builder that is equal to this builder but with the given package exports.
1757
             */
1758
            ModuleDefinition<S> exports(Collection<String> packages);
1759

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

1769
            /**
1770
             * Specifies a package export with additional modifiers.
1771
             *
1772
             * @param aPackage The name of the package to export.
1773
             * @param modifierContributors The modifiers to apply to the package export.
1774
             * @return A new builder that is equal to this builder but with the given package export.
1775
             */
1776
            ModuleDefinition<S> export(String aPackage, Collection<? extends ModifierContributor.ForModule.OfExport> modifierContributors);
1777

1778
            /**
1779
             * Specifies a package export with explicit modifiers.
1780
             *
1781
             * @param aPackage The name of the package to export.
1782
             * @param modifiers The modifiers to apply to the package export.
1783
             * @return A new builder that is equal to this builder but with the given package export.
1784
             */
1785
            ModuleDefinition<S> export(String aPackage, int modifiers);
1786

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

1795
            /**
1796
             * Specifies packages that are opened by the module being defined.
1797
             *
1798
             * @param packages The names of the packages to open.
1799
             * @return A new builder that is equal to this builder but with the given package openings.
1800
             */
1801
            ModuleDefinition<S> opens(Collection<String> packages);
1802

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

1812
            /**
1813
             * Specifies a package opening with additional modifiers.
1814
             *
1815
             * @param aPackage The name of the package to open.
1816
             * @param modifierContributors The modifiers to apply to the package opening.
1817
             * @return A new builder that is equal to this builder but with the given package opening.
1818
             */
1819
            ModuleDefinition<S> open(String aPackage, Collection<? extends ModifierContributor.ForModule.OfOpen> modifierContributors);
1820

1821
            /**
1822
             * Specifies a package opening with explicit modifiers.
1823
             *
1824
             * @param aPackage The name of the package to open.
1825
             * @param modifiers The modifiers to apply to the package opening.
1826
             * @return A new builder that is equal to this builder but with the given package opening.
1827
             */
1828
            ModuleDefinition<S> open(String aPackage, int modifiers);
1829

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

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

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

1854
            /**
1855
             * Specifies services that are used by the module being defined.
1856
             *
1857
             * @param services The names of the types of the services to use.
1858
             * @return A new builder that is equal to this builder but with the given service uses.
1859
             */
1860
            ModuleDefinition<S> uses(Collection<String> services);
1861

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

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

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

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

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

1907
            /**
1908
             * Specifies service implementations that are provided by the module being defined.
1909
             *
1910
             * @param service The name of the type of the service for which implementations are provided.
1911
             * @param implementations The names of the types of the implementations that are provided.
1912
             * @return A new builder that is equal to this builder but with the given service provision.
1913
             */
1914
            ModuleDefinition<S> provides(String service, Collection<String> implementations);
1915

1916
            /**
1917
             * A specification of a module requirement.
1918
             *
1919
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1920
             */
1921
            interface RequiresDefinition<U> extends ModuleDefinition<U> {
1922

1923
                /**
1924
                 * Specifies the version of the required module.
1925
                 *
1926
                 * @param version The version of the required module or {@code null} if no version is to be specified.
1927
                 * @return A new builder that is equal to this builder but with the given version specification.
1928
                 */
1929
                RequiresDefinition<U> requiredVersion(@MaybeNull String version);
1930

1931
                /**
1932
                 * An abstract base implementation of a {@link RequiresDefinition}.
1933
                 *
1934
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1935
                 */
UNCOV
1936
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements RequiresDefinition<V> {
×
1937
                    /* empty */
1938
                }
1939
            }
1940

1941
            /**
1942
             * A specification of a module export.
1943
             *
1944
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1945
             */
1946
            interface ExportsDefinition<U> extends ModuleDefinition<U> {
1947

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

1956
                /**
1957
                 * Specifies the modules to which the previously defined package is exported.
1958
                 *
1959
                 * @param modules The names of the modules to which the package is exported.
1960
                 * @return A new builder that is equal to this builder but with the given modules specified.
1961
                 */
1962
                ExportsDefinition<U> to(Collection<String> modules);
1963

1964
                /**
1965
                 * An abstract base implementation of a {@link OpensDefinition}.
1966
                 *
1967
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1968
                 */
UNCOV
1969
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements ExportsDefinition<V> {
×
1970

1971
                    /**
1972
                     * {@inheritDoc}ModuleDefinition
1973
                     */
1974
                    public ExportsDefinition<V> to(String... module) {
UNCOV
1975
                        return to(Arrays.asList(module));
×
1976
                    }
1977
                }
1978
            }
1979

1980
            /**
1981
             * A specification of a module opening.
1982
             *
1983
             * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1984
             */
1985
            interface OpensDefinition<S> extends ModuleDefinition<S> {
1986

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

1995
                /**
1996
                 * Specifies the modules to which the previously defined package is opened.
1997
                 *
1998
                 * @param modules The names of the modules to which the package is opened.
1999
                 * @return A new builder that is equal to this builder but with the given modules specified.
2000
                 */
2001
                OpensDefinition<S> to(Collection<String> modules);
2002

2003
                /**
2004
                 * An abstract base implementation of a {@link OpensDefinition}.
2005
                 *
2006
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2007
                 */
UNCOV
2008
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements OpensDefinition<V> {
×
2009

2010
                    /**
2011
                     * {@inheritDoc}
2012
                     */
2013
                    public OpensDefinition<V> to(String... module) {
UNCOV
2014
                        return to(Arrays.asList(module));
×
2015
                    }
2016
                }
2017
            }
2018

2019
            /**
2020
             * An abstract base implementation of a {@link ModuleDefinition}.
2021
             *
2022
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2023
             */
UNCOV
2024
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements ModuleDefinition<U> {
×
2025

2026
                /**
2027
                 * {@inheritDoc}
2028
                 */
2029
                public ModuleDefinition<U> mainClass(@MaybeNull Class<?> type) {
UNCOV
2030
                    return mainClass(type == null
×
2031
                            ? null
2032
                            : TypeDescription.ForLoadedType.of(type));
×
2033
                }
2034

2035
                /**
2036
                 * {@inheritDoc}
2037
                 */
2038
                public ModuleDefinition<U> mainClass(@MaybeNull TypeDescription typeDescription) {
UNCOV
2039
                    if (typeDescription != null && (typeDescription.isArray() || typeDescription.isPrimitive())) {
×
UNCOV
2040
                        throw new IllegalArgumentException("Cannot use primitive types for main class: " + typeDescription);
×
2041
                    }
UNCOV
2042
                    return mainClass(typeDescription == null
×
2043
                            ? null
2044
                            : typeDescription.getName());
×
2045
                }
2046

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

2054
                /**
2055
                 * {@inheritDoc}
2056
                 */
2057
                public ModuleDefinition<U> requires(String... module) {
2058
                    return requires(Arrays.asList(module));
×
2059
                }
2060

2061
                /**
2062
                 * {@inheritDoc}
2063
                 */
2064
                public ModuleDefinition<U> requires(Collection<String> modules) {
UNCOV
2065
                    ModuleDefinition<U> definition = this;
×
UNCOV
2066
                    for (String module : modules) {
×
UNCOV
2067
                        definition = definition.requires(module);
×
UNCOV
2068
                    }
×
2069
                    return definition;
×
2070
                }
2071

2072
                /**
2073
                 * {@inheritDoc}
2074
                 */
2075
                public RequiresDefinition<U> require(String module, ModifierContributor.ForModule.OfRequire... modifierContributor) {
2076
                    return require(module, Arrays.asList(modifierContributor));
×
2077
                }
2078

2079
                /**
2080
                 * {@inheritDoc}
2081
                 */
2082
                public RequiresDefinition<U> require(String module, Collection<? extends ModifierContributor.ForModule.OfRequire> modifierContributors) {
2083
                    return require(module, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2084
                }
2085

2086
                /**
2087
                 * {@inheritDoc}
2088
                 */
2089
                public ModuleDefinition<U> exports(String... aPackage) {
2090
                    return exports(Arrays.asList(aPackage));
×
2091
                }
2092

2093
                /**
2094
                 * {@inheritDoc}
2095
                 */
2096
                public ModuleDefinition<U> exports(Collection<String> packages) {
UNCOV
2097
                    ModuleDefinition<U> definition = this;
×
UNCOV
2098
                    for (String aPackage : packages) {
×
UNCOV
2099
                        definition = definition.export(aPackage);
×
UNCOV
2100
                    }
×
2101
                    return definition;
×
2102
                }
2103

2104
                /**
2105
                 * {@inheritDoc}
2106
                 */
2107
                public ModuleDefinition<U> export(String aPackage, ModifierContributor.ForModule.OfExport... modifierContributor) {
2108
                    return export(aPackage, Arrays.asList(modifierContributor));
×
2109
                }
2110

2111
                /**
2112
                 * {@inheritDoc}
2113
                 */
2114
                public ModuleDefinition<U> export(String aPackage, Collection<? extends ModifierContributor.ForModule.OfExport> modifierContributors) {
2115
                    return export(aPackage, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2116
                }
2117

2118
                /**
2119
                 * {@inheritDoc}
2120
                 */
2121
                public ModuleDefinition<U> opens(String... aPackage) {
2122
                    return opens(Arrays.asList(aPackage));
×
2123
                }
2124

2125
                /**
2126
                 * {@inheritDoc}
2127
                 */
2128
                public ModuleDefinition<U> opens(Collection<String> packages) {
UNCOV
2129
                    ModuleDefinition<U> definition = this;
×
UNCOV
2130
                    for (String aPackage : packages) {
×
UNCOV
2131
                        definition = definition.open(aPackage);
×
UNCOV
2132
                    }
×
2133
                    return definition;
×
2134
                }
2135

2136
                /**
2137
                 * {@inheritDoc}
2138
                 */
2139
                public ModuleDefinition<U> open(String aPackage, ModifierContributor.ForModule.OfOpen... modifierContributor) {
2140
                    return open(aPackage, Arrays.asList(modifierContributor));
×
2141
                }
2142

2143
                /**
2144
                 * {@inheritDoc}
2145
                 */
2146
                public ModuleDefinition<U> open(String aPackage, Collection<? extends ModifierContributor.ForModule.OfOpen> modifierContributors) {
2147
                    return open(aPackage, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2148
                }
2149

2150
                /**
2151
                 * {@inheritDoc}
2152
                 */
2153
                public ModuleDefinition<U> uses(Class<?>... service) {
2154
                    return uses(new TypeList.ForLoadedTypes(service));
×
2155
                }
2156

2157
                /**
2158
                 * {@inheritDoc}
2159
                 */
2160
                public ModuleDefinition<U> uses(TypeDescription... service) {
UNCOV
2161
                    return uses(Arrays.asList(service));
×
2162
                }
2163

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

2181
                /**
2182
                 * {@inheritDoc}
2183
                 */
2184
                public ModuleDefinition<U> uses(String... service) {
2185
                    return uses(Arrays.asList(service));
×
2186
                }
2187

2188
                /**
2189
                 * {@inheritDoc}
2190
                 */
2191
                public ModuleDefinition<U> provides(Class<?> service, Class<?>... implementations) {
2192
                    return provides(service, Arrays.asList(implementations));
×
2193
                }
2194

2195
                /**
2196
                 * {@inheritDoc}
2197
                 */
2198
                public ModuleDefinition<U> provides(Class<?> service, Collection<Class<?>> implementations) {
2199
                    return provides(TypeDescription.ForLoadedType.of(service), new TypeList.ForLoadedTypes(new ArrayList<Class<?>>(implementations)));
×
2200
                }
2201

2202
                /**
2203
                 * {@inheritDoc}
2204
                 */
2205
                public ModuleDefinition<U> provides(TypeDescription service, TypeDescription... implementation) {
2206
                    return provides(service, Arrays.asList(implementation));
×
2207
                }
2208

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

2226
                /**
2227
                 * {@inheritDoc}
2228
                 */
2229
                public ModuleDefinition<U> provides(String service, String... implementations) {
UNCOV
2230
                    return provides(service, Arrays.asList(implementations));
×
2231
                }
2232

2233
                /**
2234
                 * An adapter for a {@link ModuleDefinition}.
2235
                 *
2236
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2237
                 */
UNCOV
2238
                public abstract static class Delegator<V> extends ModuleDefinition.AbstractBase<V> {
×
2239

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

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

2254
                    /**
2255
                     * {@inheritDoc}
2256
                     */
2257
                    public ModuleDefinition<V> packages(Collection<String> packages) {
2258
                        return materialize().packages(packages);
×
2259
                    }
2260

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

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

2275
                    /**
2276
                     * {@inheritDoc}
2277
                     */
2278
                    public ModuleDefinition<V> open(String aPackage, int modifiers) {
2279
                        return materialize().open(aPackage, modifiers);
×
2280
                    }
2281

2282
                    /**
2283
                     * {@inheritDoc}
2284
                     */
2285
                    public ModuleDefinition<V> uses(Collection<String> services) {
2286
                        return materialize().uses(services);
×
2287
                    }
2288

2289
                    /**
2290
                     * {@inheritDoc}
2291
                     */
2292
                    public ModuleDefinition<V> provides(String service, Collection<String> implementations) {
UNCOV
2293
                        return materialize().provides(service, implementations);
×
2294
                    }
2295

2296
                    @Override
2297
                    protected abstract ModuleDefinition<V> materialize();
2298
                }
2299
            }
2300
        }
2301

2302
        /**
2303
         * An inner type definition for defining a type that is contained within another type, method or constructor.
2304
         *
2305
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2306
         */
2307
        interface InnerTypeDefinition<S> extends Builder<S> {
2308

2309
            /**
2310
             * Defines this inner type declaration as an anonymous type.
2311
             *
2312
             * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
2313
             */
2314
            Builder<S> asAnonymousType();
2315

2316
            /**
2317
             * An inner type definition for defining a type that is contained within another type.
2318
             *
2319
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2320
             */
2321
            interface ForType<U> extends InnerTypeDefinition<U> {
2322

2323
                /**
2324
                 * Defines this inner type declaration as a member type.
2325
                 *
2326
                 * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
2327
                 */
2328
                Builder<U> asMemberType();
2329
            }
2330
        }
2331

2332
        /**
2333
         * A builder for a type variable definition.
2334
         *
2335
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2336
         */
2337
        interface TypeVariableDefinition<S> extends Builder<S> {
2338

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

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

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

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

2375
            /**
2376
             * An abstract base implementation of a type variable definition.
2377
             *
2378
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2379
             */
2380
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
1✔
2381

2382
                /**
2383
                 * {@inheritDoc}
2384
                 */
2385
                public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
2386
                    return annotateTypeVariable(Arrays.asList(annotation));
×
2387
                }
2388

2389
                /**
2390
                 * {@inheritDoc}
2391
                 */
2392
                public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
UNCOV
2393
                    return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
2394
                }
2395

2396
                /**
2397
                 * {@inheritDoc}
2398
                 */
2399
                public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
2400
                    return annotateTypeVariable(Arrays.asList(annotation));
1✔
2401
                }
2402
            }
2403
        }
2404

2405
        /**
2406
         * A builder for a field definition.
2407
         *
2408
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2409
         */
2410
        interface FieldDefinition<S> {
2411

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

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

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

2439
            /**
2440
             * Annotates the previously defined or matched field with the supplied annotations.
2441
             *
2442
             * @param annotations The annotations to declare on the previously defined or matched field.
2443
             * @return A new builder that is equal to this builder but with the given annotations declared
2444
             * on the previously defined or matched field.
2445
             */
2446
            FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
2447

2448
            /**
2449
             * Applies the supplied attribute appender factory onto the previously defined or matched field.
2450
             *
2451
             * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
2452
             *                                      previously defined or matched field.
2453
             * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
2454
             * applied to the previously defined or matched field.
2455
             */
2456
            FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
2457

2458
            /**
2459
             * Applies the supplied transformer onto the previously defined or matched field. The transformed
2460
             * field is written <i>as it is</i> and is not subject to any validations.
2461
             *
2462
             * @param transformer The transformer to apply to the previously defined or matched field.
2463
             * @return A new builder that is equal to this builder but with the supplied field transformer
2464
             * applied to the previously defined or matched field.
2465
             */
2466
            FieldDefinition.Optional<S> transform(Transformer<FieldDescription> transformer);
2467

2468
            /**
2469
             * A builder for a field definition that allows for defining a value.
2470
             *
2471
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2472
             */
2473
            interface Valuable<U> extends FieldDefinition<U> {
2474

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

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

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

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

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

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

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

2584
                /**
2585
                 * A builder for an optional field definition that allows for defining a value.
2586
                 *
2587
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2588
                 */
2589
                interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
2590

2591
                    /**
2592
                     * An abstract base implementation of an optional field definition that allows for defining a value.
2593
                     *
2594
                     * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2595
                     */
2596
                    abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1✔
2597

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

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

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

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

2626
                        /**
2627
                         * {@inheritDoc}
2628
                         */
2629
                        public FieldDefinition.Optional<U> value(double value) {
2630
                            return defaultValue(value);
1✔
2631
                        }
2632

2633
                        /**
2634
                         * {@inheritDoc}
2635
                         */
2636
                        public FieldDefinition.Optional<U> value(String value) {
2637
                            if (value == null) {
1✔
2638
                                throw new IllegalArgumentException("Cannot define 'null' as constant value");
1✔
2639
                            }
2640
                            return defaultValue(value);
1✔
2641
                        }
2642

2643
                        /**
2644
                         * Defines the supplied value as a default value of the previously defined or matched field.
2645
                         *
2646
                         * @param defaultValue The value to define as a default value of the defined field.
2647
                         * @return A new builder that is equal to this builder but with the given default value declared for the
2648
                         * previously defined or matched field.
2649
                         */
2650
                        protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
2651

2652
                        /**
2653
                         * An adapter for an optional field definition that allows for defining a value.
2654
                         *
2655
                         * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2656
                         */
2657
                        @HashCodeAndEqualsPlugin.Enhance
2658
                        private abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
2659

2660
                            /**
2661
                             * The field attribute appender factory to apply.
2662
                             */
2663
                            protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
2664

2665
                            /**
2666
                             * The field transformer to apply.
2667
                             */
2668
                            protected final Transformer<FieldDescription> transformer;
2669

2670
                            /**
2671
                             * The field's default value or {@code null} if no value is to be defined.
2672
                             */
2673
                            @MaybeNull
2674
                            @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
2675
                            protected final Object defaultValue;
2676

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

2692
                            /**
2693
                             * {@inheritDoc}
2694
                             */
2695
                            public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
2696
                                return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
1✔
2697
                            }
2698

2699
                            /**
2700
                             * {@inheritDoc}
2701
                             */
2702
                            @SuppressWarnings("unchecked") // In absence of @SafeVarargs
2703
                            public FieldDefinition.Optional<V> transform(Transformer<FieldDescription> transformer) {
2704
                                return materialize(fieldAttributeAppenderFactory, new Transformer.Compound<FieldDescription>(this.transformer, transformer), defaultValue);
1✔
2705
                            }
2706

2707
                            @Override
2708
                            protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
2709
                                return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
2710
                            }
2711

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

2727
                /**
2728
                 * An abstract base implementation for an optional field definition.
2729
                 *
2730
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2731
                 */
2732
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1✔
2733

2734
                    /**
2735
                     * {@inheritDoc}
2736
                     */
2737
                    public FieldDefinition.Optional<U> annotateField(Annotation... annotation) {
2738
                        return annotateField(Arrays.asList(annotation));
1✔
2739
                    }
2740

2741
                    /**
2742
                     * {@inheritDoc}
2743
                     */
2744
                    public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
2745
                        return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
2746
                    }
2747

2748
                    /**
2749
                     * {@inheritDoc}
2750
                     */
2751
                    public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
2752
                        return annotateField(Arrays.asList(annotation));
1✔
2753
                    }
2754
                }
2755
            }
2756
        }
2757

2758
        /**
2759
         * A builder for a method definition.
2760
         *
2761
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2762
         */
2763
        interface MethodDefinition<S> extends Builder<S> {
2764

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

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

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

2792
            /**
2793
             * Annotates the previously defined or matched method with the supplied annotations.
2794
             *
2795
             * @param annotations The annotations to declare on the previously defined or matched method.
2796
             * @return A new builder that is equal to this builder but with the given annotations declared
2797
             * on the previously defined or matched method.
2798
             */
2799
            MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
2800

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

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

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

2831
            /**
2832
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2833
             *
2834
             * @param index       The parameter's index.
2835
             * @param annotations The annotations to declare on the previously defined or matched method.
2836
             * @return A new builder that is equal to this builder but with the given annotations declared
2837
             * on the previously defined or matched method's parameter of the given index.
2838
             */
2839
            MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
2840

2841
            /**
2842
             * Applies the supplied method attribute appender factory onto the previously defined or matched method.
2843
             *
2844
             * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
2845
             *                                       previously defined or matched method.
2846
             * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
2847
             * applied to the previously defined or matched method.
2848
             */
2849
            MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
2850

2851
            /**
2852
             * Applies the supplied transformer onto the previously defined or matched method. The transformed
2853
             * method is written <i>as it is</i> and it not subject to any validations.
2854
             *
2855
             * @param transformer The transformer to apply to the previously defined or matched method.
2856
             * @return A new builder that is equal to this builder but with the supplied transformer
2857
             * applied to the previously defined or matched method.
2858
             */
2859
            MethodDefinition<S> transform(Transformer<MethodDescription> transformer);
2860

2861
            /**
2862
             * A builder for a method definition with a receiver type.
2863
             *
2864
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2865
             */
2866
            interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
2867

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

2877
                /**
2878
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2879
                 *
2880
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2881
                 * @return A new builder that is equal to this builder but with the given type defined as the
2882
                 * receiver on the previously defined or matched method.
2883
                 */
2884
                MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
2885

2886
                /**
2887
                 * An abstract base implementation of a method definition that can accept a receiver type.
2888
                 *
2889
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2890
                 */
2891
                abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
1✔
2892

2893
                    /**
2894
                     * {@inheritDoc}
2895
                     */
2896
                    public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
UNCOV
2897
                        return receiverType(TypeDefinition.Sort.describeAnnotated(receiverType));
×
2898
                    }
2899
                }
2900
            }
2901

2902
            /**
2903
             * A builder for defining an implementation of a method.
2904
             *
2905
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2906
             */
2907
            interface ImplementationDefinition<U> {
2908

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

2930
                /**
2931
                 * Defines the previously defined or matched method not to declare a method body. This implies the
2932
                 * method to be {@code abstract} unless it was already declared to be {@code native}.
2933
                 *
2934
                 * @return A new builder where the previously defined or matched method is implemented to be abstract.
2935
                 */
2936
                MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
2937

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

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

2960
                /**
2961
                 * A builder for optionally defining an implementation of a method.
2962
                 *
2963
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2964
                 */
2965
                interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
2966
                    /* union type */
2967
                }
2968

2969
                /**
2970
                 * An abstract base implementation for a builder optionally defining an implementation of a method.
2971
                 *
2972
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2973
                 */
2974
                abstract class AbstractBase<V> implements ImplementationDefinition<V> {
1✔
2975

2976
                    /**
2977
                     * {@inheritDoc}
2978
                     */
2979
                    public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) {
2980
                        return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
1✔
2981
                    }
2982
                }
2983
            }
2984

2985
            /**
2986
             * A builder for defining an implementation of a method and optionally defining a type variable.
2987
             *
2988
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2989
             */
2990
            interface TypeVariableDefinition<U> extends ImplementationDefinition<U> {
2991

2992
                /**
2993
                 * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
2994
                 *
2995
                 * @param symbol The symbol of the type variable.
2996
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2997
                 */
2998
                Annotatable<U> typeVariable(String symbol);
2999

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

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

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

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

3040
                /**
3041
                 * A builder for optionally defining an annotation for a type variable.
3042
                 *
3043
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3044
                 */
3045
                interface Annotatable<V> extends TypeVariableDefinition<V> {
3046

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

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

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

3074
                    /**
3075
                     * Annotates the previously defined type variable with the supplied annotations.
3076
                     *
3077
                     * @param annotations The annotations to declare on the previously defined type variable.
3078
                     * @return A new builder that is equal to this builder but with the given annotations declared
3079
                     * on the previously defined type variable.
3080
                     */
3081
                    Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
3082

3083
                    /**
3084
                     * An abstract base implementation for defining an annotation on a parameter.
3085
                     *
3086
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3087
                     */
3088
                    abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
3089

3090
                        /**
3091
                         * {@inheritDoc}
3092
                         */
3093
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
3094
                            return annotateTypeVariable(Arrays.asList(annotation));
×
3095
                        }
3096

3097
                        /**
3098
                         * {@inheritDoc}
3099
                         */
3100
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
UNCOV
3101
                            return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
3102
                        }
3103

3104
                        /**
3105
                         * {@inheritDoc}
3106
                         */
3107
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
3108
                            return annotateTypeVariable(Arrays.asList(annotation));
1✔
3109
                        }
3110

3111
                        /**
3112
                         * An adapter implementation for an annotatable type variable definition.
3113
                         *
3114
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3115
                         */
3116
                        protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
1✔
3117

3118
                            /**
3119
                             * {@inheritDoc}
3120
                             */
3121
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3122
                                return materialize().typeVariable(symbol, bounds);
1✔
3123
                            }
3124

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

3132
                            /**
3133
                             * {@inheritDoc}
3134
                             */
3135
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3136
                                return materialize().withoutCode();
1✔
3137
                            }
3138

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

3146
                            /**
3147
                             * {@inheritDoc}
3148
                             */
3149
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
UNCOV
3150
                                return materialize().defaultValue(value, type);
×
3151
                            }
3152

3153
                            /**
3154
                             * Materializes this instance as a parameter definition with the currently defined properties.
3155
                             *
3156
                             * @return A parameter definition with the currently defined properties.
3157
                             */
3158
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
3159
                        }
3160
                    }
3161
                }
3162

3163
                /**
3164
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
3165
                 *
3166
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3167
                 */
3168
                abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
1✔
3169

3170
                    /**
3171
                     * {@inheritDoc}
3172
                     */
3173
                    public Annotatable<V> typeVariable(String symbol) {
3174
                        return typeVariable(symbol, Collections.singletonList(Object.class));
1✔
3175
                    }
3176

3177
                    /**
3178
                     * {@inheritDoc}
3179
                     */
3180
                    public Annotatable<V> typeVariable(String symbol, Type... bound) {
3181
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
3182
                    }
3183

3184
                    /**
3185
                     * {@inheritDoc}
3186
                     */
3187
                    public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
3188
                        return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
3189
                    }
3190

3191
                    /**
3192
                     * {@inheritDoc}
3193
                     */
3194
                    public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
3195
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
3196
                    }
3197
                }
3198
            }
3199

3200
            /**
3201
             * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
3202
             *
3203
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3204
             */
3205
            interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
3206

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

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

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

3231
                /**
3232
                 * Defines a method variable to be declared by the currently defined method.
3233
                 *
3234
                 * @param types The type of the exception being declared by the currently defined method.
3235
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
3236
                 */
3237
                ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
3238

3239
                /**
3240
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
3241
                 *
3242
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3243
                 */
3244
                abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
1✔
3245

3246
                    /**
3247
                     * {@inheritDoc}
3248
                     */
3249
                    public ExceptionDefinition<V> throwing(Type... type) {
3250
                        return throwing(Arrays.asList(type));
1✔
3251
                    }
3252

3253
                    /**
3254
                     * {@inheritDoc}
3255
                     */
3256
                    public ExceptionDefinition<V> throwing(List<? extends Type> types) {
3257
                        return throwing(new TypeList.Generic.ForLoadedTypes(types));
1✔
3258
                    }
3259

3260
                    /**
3261
                     * {@inheritDoc}
3262
                     */
3263
                    public ExceptionDefinition<V> throwing(TypeDefinition... type) {
3264
                        return throwing(Arrays.asList(type));
1✔
3265
                    }
3266
                }
3267
            }
3268

3269
            /**
3270
             * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
3271
             *
3272
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3273
             */
3274
            interface ParameterDefinition<U> extends ExceptionDefinition<U> {
3275

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

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

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

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

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

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

3342
                /**
3343
                 * A builder for optionally defining an annotation on a parameter.
3344
                 *
3345
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3346
                 */
3347
                interface Annotatable<V> extends ParameterDefinition<V> {
3348

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

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

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

3376
                    /**
3377
                     * Annotates the previously defined parameter with the specified annotations.
3378
                     *
3379
                     * @param annotations The annotations to declare on the previously defined parameter.
3380
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3381
                     * the specified annotations.
3382
                     */
3383
                    Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
3384

3385
                    /**
3386
                     * An abstract base implementation for defining an annotation on a parameter.
3387
                     *
3388
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3389
                     */
3390
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
3391

3392
                        /**
3393
                         * {@inheritDoc}
3394
                         */
3395
                        public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
3396
                            return annotateParameter(Arrays.asList(annotation));
×
3397
                        }
3398

3399
                        /**
3400
                         * {@inheritDoc}
3401
                         */
3402
                        public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
3403
                            return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
3404
                        }
3405

3406
                        /**
3407
                         * {@inheritDoc}
3408
                         */
3409
                        public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
UNCOV
3410
                            return annotateParameter(Arrays.asList(annotation));
×
3411
                        }
3412

3413
                        /**
3414
                         * An adapter implementation for defining an annotation on a parameter.
3415
                         *
3416
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3417
                         */
3418
                        protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
1✔
3419

3420
                            /**
3421
                             * {@inheritDoc}
3422
                             */
3423
                            public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
UNCOV
3424
                                return materialize().withParameter(type, name, modifiers);
×
3425
                            }
3426

3427
                            /**
3428
                             * {@inheritDoc}
3429
                             */
3430
                            public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
3431
                                return materialize().throwing(types);
1✔
3432
                            }
3433

3434
                            /**
3435
                             * {@inheritDoc}
3436
                             */
3437
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3438
                                return materialize().typeVariable(symbol, bounds);
×
3439
                            }
3440

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

3448
                            /**
3449
                             * {@inheritDoc}
3450
                             */
3451
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3452
                                return materialize().withoutCode();
×
3453
                            }
3454

3455
                            /**
3456
                             * {@inheritDoc}
3457
                             */
3458
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
3459
                                return materialize().defaultValue(annotationValue);
×
3460
                            }
3461

3462
                            /**
3463
                             * {@inheritDoc}
3464
                             */
3465
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
UNCOV
3466
                                return materialize().defaultValue(value, type);
×
3467
                            }
3468

3469
                            /**
3470
                             * Materializes this instance as a parameter definition with the currently defined properties.
3471
                             *
3472
                             * @return A parameter definition with the currently defined properties.
3473
                             */
3474
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
3475
                        }
3476
                    }
3477
                }
3478

3479
                /**
3480
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
3481
                 *
3482
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3483
                 */
3484
                interface Simple<V> extends ExceptionDefinition<V> {
3485

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

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

3504
                    /**
3505
                     * A builder for optionally defining an annotation on a parameter.
3506
                     *
3507
                     * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3508
                     */
3509
                    interface Annotatable<V> extends Simple<V> {
3510

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

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

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

3538
                        /**
3539
                         * Annotates the previously defined parameter with the specified annotations.
3540
                         *
3541
                         * @param annotations The annotations to declare on the previously defined parameter.
3542
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3543
                         * the specified annotations.
3544
                         */
3545
                        Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
3546

3547
                        /**
3548
                         * An abstract base implementation of a simple parameter definition.
3549
                         *
3550
                         * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3551
                         */
3552
                        abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
1✔
3553

3554
                            /**
3555
                             * {@inheritDoc}
3556
                             */
3557
                            public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
3558
                                return annotateParameter(Arrays.asList(annotation));
×
3559
                            }
3560

3561
                            /**
3562
                             * {@inheritDoc}
3563
                             */
3564
                            public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
UNCOV
3565
                                return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
3566
                            }
3567

3568
                            /**
3569
                             * {@inheritDoc}
3570
                             */
3571
                            public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
3572
                                return annotateParameter(Arrays.asList(annotation));
1✔
3573
                            }
3574

3575
                            /**
3576
                             * An adapter implementation of a simple parameter definition.
3577
                             *
3578
                             * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3579
                             */
3580
                            protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
1✔
3581

3582
                                /**
3583
                                 * {@inheritDoc}
3584
                                 */
3585
                                public Simple.Annotatable<X> withParameter(TypeDefinition type) {
3586
                                    return materialize().withParameter(type);
1✔
3587
                                }
3588

3589
                                /**
3590
                                 * {@inheritDoc}
3591
                                 */
3592
                                public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
3593
                                    return materialize().throwing(types);
1✔
3594
                                }
3595

3596
                                /**
3597
                                 * {@inheritDoc}
3598
                                 */
3599
                                public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
UNCOV
3600
                                    return materialize().typeVariable(symbol, bounds);
×
3601
                                }
3602

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

3610
                                /**
3611
                                 * {@inheritDoc}
3612
                                 */
3613
                                public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3614
                                    return materialize().withoutCode();
1✔
3615
                                }
3616

3617
                                /**
3618
                                 * {@inheritDoc}
3619
                                 */
3620
                                public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
3621
                                    return materialize().defaultValue(annotationValue);
×
3622
                                }
3623

3624
                                /**
3625
                                 * {@inheritDoc}
3626
                                 */
3627
                                public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
UNCOV
3628
                                    return materialize().defaultValue(value, type);
×
3629
                                }
3630

3631
                                /**
3632
                                 * Materializes this instance as a simple parameter definition with the currently defined properties.
3633
                                 *
3634
                                 * @return A simple parameter definition with the currently defined properties.
3635
                                 */
3636
                                protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
3637
                            }
3638
                        }
3639
                    }
3640

3641
                    /**
3642
                     * An abstract base implementation of an exception definition.
3643
                     *
3644
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3645
                     */
3646
                    abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
1✔
3647

3648
                        /**
3649
                         * {@inheritDoc}
3650
                         */
3651
                        public Simple.Annotatable<W> withParameter(Type type) {
3652
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
3653
                        }
3654
                    }
3655
                }
3656

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

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

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

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

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

3703
                    /**
3704
                     * An abstract base implementation for an initial parameter definition.
3705
                     *
3706
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3707
                     */
3708
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
1✔
3709

3710
                        /**
3711
                         * {@inheritDoc}
3712
                         */
3713
                        public Simple.Annotatable<W> withParameter(Type type) {
3714
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
3715
                        }
3716

3717
                        /**
3718
                         * {@inheritDoc}
3719
                         */
3720
                        public ExceptionDefinition<W> withParameters(Type... type) {
3721
                            return withParameters(Arrays.asList(type));
1✔
3722
                        }
3723

3724
                        /**
3725
                         * {@inheritDoc}
3726
                         */
3727
                        public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
3728
                            return withParameters(new TypeList.Generic.ForLoadedTypes(types));
1✔
3729
                        }
3730

3731
                        /**
3732
                         * {@inheritDoc}
3733
                         */
3734
                        public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
3735
                            return withParameters(Arrays.asList(type));
1✔
3736
                        }
3737

3738
                        /**
3739
                         * {@inheritDoc}
3740
                         */
3741
                        public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
3742
                            ParameterDefinition.Simple<W> parameterDefinition = this;
1✔
3743
                            for (TypeDefinition type : types) {
1✔
3744
                                parameterDefinition = parameterDefinition.withParameter(type);
1✔
3745
                            }
1✔
3746
                            return parameterDefinition;
1✔
3747
                        }
3748
                    }
3749
                }
3750

3751
                /**
3752
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable, thrown exception or parameter type.
3753
                 *
3754
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3755
                 */
3756
                abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
1✔
3757

3758
                    /**
3759
                     * {@inheritDoc}
3760
                     */
3761
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
3762
                        return withParameter(type, name, Arrays.asList(modifierContributor));
1✔
3763
                    }
3764

3765
                    /**
3766
                     * {@inheritDoc}
3767
                     */
3768
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
3769
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3770
                    }
3771

3772
                    /**
3773
                     * {@inheritDoc}
3774
                     */
3775
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
3776
                        return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
1✔
3777
                    }
3778

3779
                    /**
3780
                     * {@inheritDoc}
3781
                     */
3782
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
3783
                        return withParameter(type, name, Arrays.asList(modifierContributor));
×
3784
                    }
3785

3786
                    /**
3787
                     * {@inheritDoc}
3788
                     */
3789
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
UNCOV
3790
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
3791
                    }
3792
                }
3793
            }
3794

3795
            /**
3796
             * An abstract base implementation of a method definition.
3797
             *
3798
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3799
             */
3800
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
1✔
3801

3802
                /**
3803
                 * {@inheritDoc}
3804
                 */
3805
                public MethodDefinition<U> annotateMethod(Annotation... annotation) {
3806
                    return annotateMethod(Arrays.asList(annotation));
1✔
3807
                }
3808

3809
                /**
3810
                 * {@inheritDoc}
3811
                 */
3812
                public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
3813
                    return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
3814
                }
3815

3816
                /**
3817
                 * {@inheritDoc}
3818
                 */
3819
                public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
3820
                    return annotateMethod(Arrays.asList(annotation));
1✔
3821
                }
3822

3823
                /**
3824
                 * {@inheritDoc}
3825
                 */
3826
                public MethodDefinition<U> annotateParameter(int index, Annotation... annotation) {
3827
                    return annotateParameter(index, Arrays.asList(annotation));
×
3828
                }
3829

3830
                /**
3831
                 * {@inheritDoc}
3832
                 */
3833
                public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
3834
                    return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
×
3835
                }
3836

3837
                /**
3838
                 * {@inheritDoc}
3839
                 */
3840
                public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
UNCOV
3841
                    return annotateParameter(index, Arrays.asList(annotation));
×
3842
                }
3843

3844
                /**
3845
                 * An adapter implementation of a method definition.
3846
                 *
3847
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3848
                 */
3849
                @HashCodeAndEqualsPlugin.Enhance
3850
                protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
3851

3852
                    /**
3853
                     * The handler that determines how a method is implemented.
3854
                     */
3855
                    protected final MethodRegistry.Handler handler;
3856

3857
                    /**
3858
                     * The method attribute appender factory to apply onto the method that is currently being implemented.
3859
                     */
3860
                    protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
3861

3862
                    /**
3863
                     * The transformer to apply onto the method that is currently being implemented.
3864
                     */
3865
                    protected final Transformer<MethodDescription> transformer;
3866

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

3882
                    /**
3883
                     * {@inheritDoc}
3884
                     */
3885
                    public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
3886
                        return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), transformer);
1✔
3887
                    }
3888

3889
                    /**
3890
                     * {@inheritDoc}
3891
                     */
3892
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
3893
                    public MethodDefinition<V> transform(Transformer<MethodDescription> transformer) {
3894
                        return materialize(handler, methodAttributeAppenderFactory, new Transformer.Compound<MethodDescription>(this.transformer, transformer));
1✔
3895
                    }
3896

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

3912
        /**
3913
         * A builder for a record component definition.
3914
         *
3915
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3916
         */
3917
        interface RecordComponentDefinition<S> {
3918

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

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

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

3943
            /**
3944
             * Annotates the record component with the supplied annotations.
3945
             *
3946
             * @param annotations The annotations to declare.
3947
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3948
             */
3949
            Optional<S> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations);
3950

3951
            /**
3952
             * Applies the supplied record component attribute appender factory onto the previously defined record component.
3953
             *
3954
             * @param recordComponentAttributeAppenderFactory The record component attribute appender factory that should be applied on the
3955
             *                                                previously defined or matched method.
3956
             * @return A new builder that is equal to this builder but with the supplied record component attribute appender factory
3957
             * applied to the previously defined record component.
3958
             */
3959
            Optional<S> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory);
3960

3961
            /**
3962
             * Transforms a record component description before writing.
3963
             *
3964
             * @param transformer The transformer to apply.
3965
             * @return new builder that is equal to this builder but with the supplied transformer being applied.
3966
             */
3967
            Optional<S> transform(Transformer<RecordComponentDescription> transformer);
3968

3969
            /**
3970
             * A {@link RecordComponentDefinition} as an optional build step.
3971
             *
3972
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3973
             */
3974
            interface Optional<U> extends RecordComponentDefinition<U>, Builder<U> {
3975

3976
                /**
3977
                 * An abstract base implementation of a record definition.
3978
                 *
3979
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3980
                 */
UNCOV
3981
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements RecordComponentDefinition.Optional<U> {
×
3982

3983
                    /**
3984
                     * {@inheritDoc}
3985
                     */
3986
                    public Optional<U> annotateRecordComponent(Annotation... annotation) {
3987
                        return annotateRecordComponent(Arrays.asList(annotation));
×
3988
                    }
3989

3990
                    /**
3991
                     * {@inheritDoc}
3992
                     */
3993
                    public Optional<U> annotateRecordComponent(List<? extends Annotation> annotations) {
3994
                        return annotateRecordComponent(new AnnotationList.ForLoadedAnnotations(annotations));
×
3995
                    }
3996

3997
                    /**
3998
                     * {@inheritDoc}
3999
                     */
4000
                    public Optional<U> annotateRecordComponent(AnnotationDescription... annotation) {
UNCOV
4001
                        return annotateRecordComponent(Arrays.asList(annotation));
×
4002
                    }
4003
                }
4004
            }
4005
        }
4006

4007
        /**
4008
         * An abstract base implementation of a dynamic type builder.
4009
         *
4010
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
4011
         */
4012
        abstract class AbstractBase<S> implements Builder<S> {
1✔
4013

4014
            /**
4015
             * {@inheritDoc}
4016
             */
4017
            public ModuleDefinition<S> module(String name, ModifierContributor.ForModule... modifierContributors) {
4018
                return module(name, Arrays.asList(modifierContributors));
×
4019
            }
4020

4021
            /**
4022
             * {@inheritDoc}
4023
             */
4024
            public ModuleDefinition<S> module(String name, Collection<? extends ModifierContributor.ForModule> modifierContributors) {
UNCOV
4025
                return module(name, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
4026
            }
4027

4028
            /**
4029
             * {@inheritDoc}
4030
             */
4031
            public InnerTypeDefinition.ForType<S> innerTypeOf(Class<?> type) {
4032
                return innerTypeOf(TypeDescription.ForLoadedType.of(type));
1✔
4033
            }
4034

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

4042
            /**
4043
             * {@inheritDoc}
4044
             */
4045
            public InnerTypeDefinition<S> innerTypeOf(Constructor<?> constructor) {
4046
                return innerTypeOf(new MethodDescription.ForLoadedConstructor(constructor));
1✔
4047
            }
4048

4049
            /**
4050
             * {@inheritDoc}
4051
             */
4052
            public Builder<S> declaredTypes(Class<?>... type) {
UNCOV
4053
                return declaredTypes(Arrays.asList(type));
×
4054
            }
4055

4056
            /**
4057
             * {@inheritDoc}
4058
             */
4059
            public Builder<S> declaredTypes(TypeDescription... type) {
4060
                return declaredTypes(Arrays.asList(type));
1✔
4061
            }
4062

4063
            /**
4064
             * {@inheritDoc}
4065
             */
4066
            public Builder<S> declaredTypes(List<? extends Class<?>> type) {
4067
                return declaredTypes(new TypeList.ForLoadedTypes(type));
×
4068
            }
4069

4070
            /**
4071
             * {@inheritDoc}
4072
             */
4073
            public Builder<S> noNestMate() {
4074
                return nestHost(TargetType.DESCRIPTION);
×
4075
            }
4076

4077
            /**
4078
             * {@inheritDoc}
4079
             */
4080
            public Builder<S> nestHost(Class<?> type) {
UNCOV
4081
                return nestHost(TypeDescription.ForLoadedType.of(type));
×
4082
            }
4083

4084
            /**
4085
             * {@inheritDoc}
4086
             */
4087
            public Builder<S> nestMembers(Class<?>... type) {
4088
                return nestMembers(Arrays.asList(type));
1✔
4089
            }
4090

4091
            /**
4092
             * {@inheritDoc}
4093
             */
4094
            public Builder<S> nestMembers(TypeDescription... type) {
UNCOV
4095
                return nestMembers(Arrays.asList(type));
×
4096
            }
4097

4098
            /**
4099
             * {@inheritDoc}
4100
             */
4101
            public Builder<S> nestMembers(List<? extends Class<?>> types) {
4102
                return nestMembers(new TypeList.ForLoadedTypes(types));
1✔
4103
            }
4104

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

4112
            /**
4113
             * {@inheritDoc}
4114
             */
4115
            public Builder<S> permittedSubclass(TypeDescription... type) {
4116
                return permittedSubclass(Arrays.asList(type));
×
4117
            }
4118

4119
            /**
4120
             * {@inheritDoc}
4121
             */
4122
            public Builder<S> permittedSubclass(List<? extends Class<?>> types) {
UNCOV
4123
                return permittedSubclass(new TypeList.ForLoadedTypes(types));
×
4124
            }
4125

4126
            /**
4127
             * {@inheritDoc}
4128
             */
4129
            public Builder<S> annotateType(Annotation... annotation) {
4130
                return annotateType(Arrays.asList(annotation));
1✔
4131
            }
4132

4133
            /**
4134
             * {@inheritDoc}
4135
             */
4136
            public Builder<S> annotateType(List<? extends Annotation> annotations) {
4137
                return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
4138
            }
4139

4140
            /**
4141
             * {@inheritDoc}
4142
             */
4143
            public Builder<S> annotateType(AnnotationDescription... annotation) {
4144
                return annotateType(Arrays.asList(annotation));
1✔
4145
            }
4146

4147
            /**
4148
             * {@inheritDoc}
4149
             */
4150
            public Builder<S> modifiers(ModifierContributor.ForType... modifierContributor) {
4151
                return modifiers(Arrays.asList(modifierContributor));
1✔
4152
            }
4153

4154
            /**
4155
             * {@inheritDoc}
4156
             */
4157
            public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4158
                return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4159
            }
4160

4161
            /**
4162
             * {@inheritDoc}
4163
             */
4164
            public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
4165
                return merge(Arrays.asList(modifierContributor));
1✔
4166
            }
4167

4168
            /**
4169
             * {@inheritDoc}
4170
             */
4171
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(Type... interfaceType) {
4172
                return implement(Arrays.asList(interfaceType));
1✔
4173
            }
4174

4175
            /**
4176
             * {@inheritDoc}
4177
             */
4178
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
4179
                return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
1✔
4180
            }
4181

4182
            /**
4183
             * {@inheritDoc}
4184
             */
4185
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
4186
                return implement(Arrays.asList(interfaceType));
1✔
4187
            }
4188

4189
            /**
4190
             * {@inheritDoc}
4191
             */
4192
            public TypeVariableDefinition<S> typeVariable(String symbol) {
4193
                return typeVariable(symbol, TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class));
1✔
4194
            }
4195

4196
            /**
4197
             * {@inheritDoc}
4198
             */
4199
            public TypeVariableDefinition<S> typeVariable(String symbol, Type... bound) {
4200
                return typeVariable(symbol, Arrays.asList(bound));
1✔
4201
            }
4202

4203
            /**
4204
             * {@inheritDoc}
4205
             */
4206
            public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
4207
                return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
4208
            }
4209

4210
            /**
4211
             * {@inheritDoc}
4212
             */
4213
            public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
4214
                return typeVariable(symbol, Arrays.asList(bound));
1✔
4215
            }
4216

4217
            /**
4218
             * {@inheritDoc}
4219
             */
4220
            public RecordComponentDefinition.Optional<S> defineRecordComponent(String name, Type type) {
4221
                return defineRecordComponent(name, TypeDefinition.Sort.describe(type));
×
4222
            }
4223

4224
            /**
4225
             * {@inheritDoc}
4226
             */
4227
            public RecordComponentDefinition.Optional<S> define(RecordComponentDescription recordComponentDescription) {
4228
                return defineRecordComponent(recordComponentDescription.getActualName(), recordComponentDescription.getType());
×
4229
            }
4230

4231
            /**
4232
             * {@inheritDoc}
4233
             */
4234
            public RecordComponentDefinition<S> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
UNCOV
4235
                return recordComponent(new LatentMatcher.Resolved<RecordComponentDescription>(matcher));
×
4236
            }
4237

4238
            /**
4239
             * {@inheritDoc}
4240
             */
4241
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor) {
4242
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
4243
            }
4244

4245
            /**
4246
             * {@inheritDoc}
4247
             */
4248
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
4249
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4250
            }
4251

4252
            /**
4253
             * {@inheritDoc}
4254
             */
4255
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
4256
                return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
1✔
4257
            }
4258

4259
            /**
4260
             * {@inheritDoc}
4261
             */
4262
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
4263
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
4264
            }
4265

4266
            /**
4267
             * {@inheritDoc}
4268
             */
4269
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
4270
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4271
            }
4272

4273
            /**
4274
             * {@inheritDoc}
4275
             */
4276
            public FieldDefinition.Optional.Valuable<S> define(Field field) {
4277
                return define(new FieldDescription.ForLoadedField(field));
×
4278
            }
4279

4280
            /**
4281
             * {@inheritDoc}
4282
             */
4283
            public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
UNCOV
4284
                return defineField(field.getName(), field.getType(), field.getModifiers());
×
4285
            }
4286

4287
            /**
4288
             * {@inheritDoc}
4289
             */
4290
            public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
4291
                return defineField("serialVersionUID", long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
1✔
4292
            }
4293

4294
            /**
4295
             * {@inheritDoc}
4296
             */
4297
            public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
4298
                return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
1✔
4299
            }
4300

4301
            /**
4302
             * {@inheritDoc}
4303
             */
4304
            public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
4305
                return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
1✔
4306
            }
4307

4308
            /**
4309
             * {@inheritDoc}
4310
             */
4311
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor) {
4312
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
4313
            }
4314

4315
            /**
4316
             * {@inheritDoc}
4317
             */
4318
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4319
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4320
            }
4321

4322
            /**
4323
             * {@inheritDoc}
4324
             */
4325
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
4326
                return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
1✔
4327
            }
4328

4329
            /**
4330
             * {@inheritDoc}
4331
             */
4332
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
4333
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
4334
            }
4335

4336
            /**
4337
             * {@inheritDoc}
4338
             */
4339
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4340
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4341
            }
4342

4343
            /**
4344
             * {@inheritDoc}
4345
             */
4346
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
4347
                return defineConstructor(Arrays.asList(modifierContributor));
1✔
4348
            }
4349

4350
            /**
4351
             * {@inheritDoc}
4352
             */
4353
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4354
                return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4355
            }
4356

4357
            /**
4358
             * {@inheritDoc}
4359
             */
4360
            public MethodDefinition.ImplementationDefinition<S> define(Method method) {
4361
                return define(new MethodDescription.ForLoadedMethod(method));
×
4362
            }
4363

4364
            /**
4365
             * {@inheritDoc}
4366
             */
4367
            public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
4368
                return define(new MethodDescription.ForLoadedConstructor(constructor));
×
4369
            }
4370

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

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

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

4410
            /**
4411
             * {@inheritDoc}
4412
             */
4413
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type) {
4414
                return defineProperty(name, type, false);
1✔
4415
            }
4416

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

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

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

4459
            /**
4460
             * {@inheritDoc}
4461
             */
4462
            public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
4463
                return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
1✔
4464
            }
4465

4466
            /**
4467
             * {@inheritDoc}
4468
             */
4469
            public Builder<S> withHashCodeEquals() {
4470
                return method(isHashCode())
1✔
4471
                        .intercept(HashCodeMethod.usingDefaultOffset().withIgnoredFields(isSynthetic()))
1✔
4472
                        .method(isEquals())
1✔
4473
                        .intercept(EqualsMethod.isolated().withIgnoredFields(isSynthetic()));
1✔
4474
            }
4475

4476
            /**
4477
             * {@inheritDoc}
4478
             */
4479
            public Builder<S> withToString() {
4480
                return method(isToString()).intercept(ToStringMethod.prefixedBySimpleClassName());
1✔
4481
            }
4482

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

4490
            /**
4491
             * {@inheritDoc}
4492
             */
4493
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer) {
4494
                return require(new Default(type, binaryRepresentation, typeInitializer, Collections.<DynamicType>emptyList()));
1✔
4495
            }
4496

4497
            /**
4498
             * {@inheritDoc}
4499
             */
4500
            public Builder<S> require(DynamicType... auxiliaryType) {
4501
                return require(Arrays.asList(auxiliaryType));
1✔
4502
            }
4503

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

4511
            /**
4512
             * {@inheritDoc}
4513
             */
4514
            public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool) {
UNCOV
4515
                return wrap(classVisitor, typePool, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
×
4516
            }
4517

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

4525
            /**
4526
             * {@inheritDoc}
4527
             */
4528
            public Unloaded<S> make() {
4529
                return make(TypeResolutionStrategy.Passive.INSTANCE);
1✔
4530
            }
4531

4532
            /**
4533
             * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
4534
             *
4535
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4536
             */
4537
            public abstract static class Delegator<U> extends AbstractBase<U> {
1✔
4538

4539
                /**
4540
                 * {@inheritDoc}
4541
                 */
4542
                public ModuleDefinition<U> module(String name, int modifiers) {
UNCOV
4543
                    return materialize().module(name, modifiers);
×
4544
                }
4545

4546
                /**
4547
                 * {@inheritDoc}
4548
                 */
4549
                public ModuleDefinition<U> adjustModule() {
UNCOV
4550
                    return materialize().adjustModule();
×
4551
                }
4552

4553
                /**
4554
                 * {@inheritDoc}
4555
                 */
4556
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
4557
                    return materialize().visit(asmVisitorWrapper);
1✔
4558
                }
4559

4560
                /**
4561
                 * {@inheritDoc}
4562
                 */
4563
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
4564
                    return materialize().initializer(loadedTypeInitializer);
1✔
4565
                }
4566

4567
                /**
4568
                 * {@inheritDoc}
4569
                 */
4570
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
UNCOV
4571
                    return materialize().annotateType(annotations);
×
4572
                }
4573

4574
                /**
4575
                 * {@inheritDoc}
4576
                 */
4577
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
4578
                    return materialize().attribute(typeAttributeAppender);
×
4579
                }
4580

4581
                /**
4582
                 * {@inheritDoc}
4583
                 */
4584
                public Builder<U> modifiers(int modifiers) {
4585
                    return materialize().modifiers(modifiers);
1✔
4586
                }
4587

4588
                /**
4589
                 * {@inheritDoc}
4590
                 */
4591
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
UNCOV
4592
                    return materialize().merge(modifierContributors);
×
4593
                }
4594

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

4602
                /**
4603
                 * {@inheritDoc}
4604
                 */
4605
                public Builder<U> name(String name) {
4606
                    return materialize().name(name);
1✔
4607
                }
4608

4609
                /**
4610
                 * {@inheritDoc}
4611
                 */
4612
                public Builder<U> topLevelType() {
4613
                    return materialize().topLevelType();
×
4614
                }
4615

4616
                /**
4617
                 * {@inheritDoc}
4618
                 */
4619
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
UNCOV
4620
                    return materialize().innerTypeOf(type);
×
4621
                }
4622

4623
                /**
4624
                 * {@inheritDoc}
4625
                 */
4626
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
4627
                    return materialize().innerTypeOf(methodDescription);
×
4628
                }
4629

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

4637
                /**
4638
                 * {@inheritDoc}
4639
                 */
4640
                public Builder<U> nestHost(TypeDescription type) {
4641
                    return materialize().nestHost(type);
×
4642
                }
4643

4644
                /**
4645
                 * {@inheritDoc}
4646
                 */
4647
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
4648
                    return materialize().nestMembers(types);
×
4649
                }
4650

4651
                /**
4652
                 * {@inheritDoc}
4653
                 */
4654
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
UNCOV
4655
                    return materialize().permittedSubclass(types);
×
4656
                }
4657

4658
                /**
4659
                 * {@inheritDoc}
4660
                 */
4661
                public Builder<U> unsealed() {
UNCOV
4662
                    return materialize().unsealed();
×
4663
                }
4664

4665
                /**
4666
                 * {@inheritDoc}
4667
                 */
4668
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
4669
                    return materialize().implement(interfaceTypes);
1✔
4670
                }
4671

4672
                /**
4673
                 * {@inheritDoc}
4674
                 */
4675
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
4676
                    return materialize().initializer(byteCodeAppender);
1✔
4677
                }
4678

4679
                /**
4680
                 * {@inheritDoc}
4681
                 */
4682
                public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
4683
                    return materialize().ignoreAlso(ignoredMethods);
1✔
4684
                }
4685

4686
                /**
4687
                 * {@inheritDoc}
4688
                 */
4689
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
UNCOV
4690
                    return materialize().ignoreAlso(ignoredMethods);
×
4691
                }
4692

4693
                /**
4694
                 * {@inheritDoc}
4695
                 */
4696
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
4697
                    return materialize().typeVariable(symbol, bounds);
1✔
4698
                }
4699

4700
                /**
4701
                 * {@inheritDoc}
4702
                 */
4703
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
4704
                    return materialize().transform(matcher, transformer);
1✔
4705
                }
4706

4707
                /**
4708
                 * {@inheritDoc}
4709
                 */
4710
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
4711
                    return materialize().defineField(name, type, modifiers);
1✔
4712
                }
4713

4714
                /**
4715
                 * {@inheritDoc}
4716
                 */
4717
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
4718
                    return materialize().field(matcher);
1✔
4719
                }
4720

4721
                /**
4722
                 * {@inheritDoc}
4723
                 */
4724
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4725
                    return materialize().defineMethod(name, returnType, modifiers);
1✔
4726
                }
4727

4728
                /**
4729
                 * {@inheritDoc}
4730
                 */
4731
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4732
                    return materialize().defineConstructor(modifiers);
1✔
4733
                }
4734

4735
                /**
4736
                 * {@inheritDoc}
4737
                 */
4738
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4739
                    return materialize().invokable(matcher);
1✔
4740
                }
4741

4742
                /**
4743
                 * {@inheritDoc}
4744
                 */
4745
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
4746
                    return materialize().require(auxiliaryTypes);
×
4747
                }
4748

4749
                /**
4750
                 * {@inheritDoc}
4751
                 */
4752
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
4753
                    return materialize().defineRecordComponent(name, type);
×
4754
                }
4755

4756
                /**
4757
                 * {@inheritDoc}
4758
                 */
4759
                public RecordComponentDefinition.Optional<U> define(RecordComponentDescription recordComponentDescription) {
4760
                    return materialize().define(recordComponentDescription);
×
4761
                }
4762

4763
                /**
4764
                 * {@inheritDoc}
4765
                 */
4766
                public RecordComponentDefinition<U> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
UNCOV
4767
                    return materialize().recordComponent(matcher);
×
4768
                }
4769

4770
                /**
4771
                 * {@inheritDoc}
4772
                 */
4773
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
4774
                    return materialize().recordComponent(matcher);
×
4775
                }
4776

4777
                /**
4778
                 * {@inheritDoc}
4779
                 */
4780
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4781
                    return materialize().wrap(classVisitor, writerFlags, readerFlags);
1✔
4782
                }
4783

4784
                /**
4785
                 * {@inheritDoc}
4786
                 */
4787
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
UNCOV
4788
                    return materialize().wrap(classVisitor, typePool, writerFlags, readerFlags);
×
4789
                }
4790

4791
                /**
4792
                 * {@inheritDoc}
4793
                 */
4794
                public DynamicType.Unloaded<U> make() {
4795
                    return materialize().make();
1✔
4796
                }
4797

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

4805
                /**
4806
                 * {@inheritDoc}
4807
                 */
4808
                public Unloaded<U> make(TypePool typePool) {
UNCOV
4809
                    return materialize().make(typePool);
×
4810
                }
4811

4812
                /**
4813
                 * {@inheritDoc}
4814
                 */
4815
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4816
                    return materialize().make(typeResolutionStrategy, typePool);
1✔
4817
                }
4818

4819
                /**
4820
                 * {@inheritDoc}
4821
                 */
4822
                public TypeDescription toTypeDescription() {
4823
                    return materialize().toTypeDescription();
1✔
4824
                }
4825

4826
                /**
4827
                 * Creates a new builder that realizes the current state of the builder.
4828
                 *
4829
                 * @return A new builder that realizes the current state of the builder.
4830
                 */
4831
                protected abstract Builder<U> materialize();
4832
            }
4833

4834
            /**
4835
             * A dynamic type writer that uses a {@link TypeWriter} to create a dynamic type.
4836
             *
4837
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4838
             */
4839
            public abstract static class UsingTypeWriter<U> extends AbstractBase<U> {
1✔
4840

4841
                /**
4842
                 * {@inheritDoc}
4843
                 */
4844
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4845
                    return toTypeWriter().wrap(classVisitor, writerFlags, readerFlags);
1✔
4846
                }
4847

4848
                /**
4849
                 * {@inheritDoc}
4850
                 */
4851
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
UNCOV
4852
                    return toTypeWriter(typePool).wrap(classVisitor, writerFlags, readerFlags);
×
4853
                }
4854

4855
                /**
4856
                 * {@inheritDoc}
4857
                 */
4858
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4859
                    return toTypeWriter().make(typeResolutionStrategy.resolve());
1✔
4860
                }
4861

4862
                /**
4863
                 * {@inheritDoc}
4864
                 */
4865
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4866
                    return toTypeWriter(typePool).make(typeResolutionStrategy.resolve());
1✔
4867
                }
4868

4869
                /**
4870
                 * Creates a {@link TypeWriter} without an explicitly specified {@link TypePool}.
4871
                 *
4872
                 * @return An appropriate {@link TypeWriter}.
4873
                 */
4874
                protected abstract TypeWriter<U> toTypeWriter();
4875

4876
                /**
4877
                 * Creates a {@link TypeWriter} given the specified {@link TypePool}.
4878
                 *
4879
                 * @param typePool The {@link TypePool} to use.
4880
                 * @return An appropriate {@link TypeWriter}.
4881
                 */
4882
                protected abstract TypeWriter<U> toTypeWriter(TypePool typePool);
4883
            }
4884

4885
            /**
4886
             * An adapter implementation of a dynamic type builder.
4887
             *
4888
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4889
             */
4890
            @HashCodeAndEqualsPlugin.Enhance
4891
            public abstract static class Adapter<U> extends UsingTypeWriter<U> {
4892

4893
                /**
4894
                 * The instrumented type to be created.
4895
                 */
4896
                protected final InstrumentedType.WithFlexibleName instrumentedType;
4897

4898
                /**
4899
                 * The current field registry.
4900
                 */
4901
                protected final FieldRegistry fieldRegistry;
4902

4903
                /**
4904
                 * The current method registry.
4905
                 */
4906
                protected final MethodRegistry methodRegistry;
4907

4908
                /**
4909
                 * The current record component registry.
4910
                 */
4911
                protected final RecordComponentRegistry recordComponentRegistry;
4912

4913
                /**
4914
                 * The type attribute appender to apply onto the instrumented type.
4915
                 */
4916
                protected final TypeAttributeAppender typeAttributeAppender;
4917

4918
                /**
4919
                 * The ASM visitor wrapper to apply onto the class writer.
4920
                 */
4921
                protected final AsmVisitorWrapper asmVisitorWrapper;
4922

4923
                /**
4924
                 * The class file version to define auxiliary types in.
4925
                 */
4926
                protected final ClassFileVersion classFileVersion;
4927

4928
                /**
4929
                 * The naming strategy for auxiliary types to apply.
4930
                 */
4931
                protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
4932

4933
                /**
4934
                 * The annotation value filter factory to apply.
4935
                 */
4936
                protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
4937

4938
                /**
4939
                 * The annotation retention to apply.
4940
                 */
4941
                protected final AnnotationRetention annotationRetention;
4942

4943
                /**
4944
                 * The implementation context factory to apply.
4945
                 */
4946
                protected final Implementation.Context.Factory implementationContextFactory;
4947

4948
                /**
4949
                 * The method graph compiler to use.
4950
                 */
4951
                protected final MethodGraph.Compiler methodGraphCompiler;
4952

4953
                /**
4954
                 * Determines if a type should be explicitly validated.
4955
                 */
4956
                protected final TypeValidation typeValidation;
4957

4958
                /**
4959
                 * The visibility bridge strategy to apply.
4960
                 */
4961
                protected final VisibilityBridgeStrategy visibilityBridgeStrategy;
4962

4963
                /**
4964
                 * The class reader factory to use.
4965
                 */
4966
                protected final AsmClassReader.Factory classReaderFactory;
4967

4968
                /**
4969
                 * The class writer factory to use.
4970
                 */
4971
                protected final AsmClassWriter.Factory classWriterFactory;
4972

4973
                /**
4974
                 * A matcher for identifying methods that should be excluded from instrumentation.
4975
                 */
4976
                protected final LatentMatcher<? super MethodDescription> ignoredMethods;
4977

4978
                /**
4979
                 * A list of explicitly defined auxiliary types.
4980
                 */
4981
                protected final List<? extends DynamicType> auxiliaryTypes;
4982

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

5043
                /**
5044
                 * {@inheritDoc}
5045
                 */
5046
                public ModuleDefinition<U> module(String name, int modifiers) {
UNCOV
5047
                    return new ModuleDefinitionAdapter(name, modifiers);
×
5048
                }
5049

5050
                /**
5051
                 * {@inheritDoc}
5052
                 */
5053
                public ModuleDefinition<U> adjustModule() {
UNCOV
5054
                    ModuleDescription moduleDescription = instrumentedType.toModuleDescription();
×
UNCOV
5055
                    if (moduleDescription == null) {
×
UNCOV
5056
                        throw new IllegalStateException("Expected previous module description for " + instrumentedType);
×
5057
                    }
UNCOV
5058
                    return new ModuleDefinitionAdapter(moduleDescription.getActualName(),
×
UNCOV
5059
                            moduleDescription.getModifiers(),
×
UNCOV
5060
                            moduleDescription.getVersion(),
×
UNCOV
5061
                            moduleDescription.getMainClass(),
×
UNCOV
5062
                            moduleDescription.getPackages(),
×
UNCOV
5063
                            moduleDescription.getRequires(),
×
UNCOV
5064
                            moduleDescription.getExports(),
×
UNCOV
5065
                            moduleDescription.getOpens(),
×
UNCOV
5066
                            moduleDescription.getUses(),
×
UNCOV
5067
                            moduleDescription.getProvides());
×
5068
                }
5069

5070
                /**
5071
                 * {@inheritDoc}
5072
                 */
5073
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
5074
                    return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
1✔
5075
                }
5076

5077
                /**
5078
                 * {@inheritDoc}
5079
                 */
5080
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
5081
                    return new FieldMatchAdapter(matcher);
1✔
5082
                }
5083

5084
                /**
5085
                 * {@inheritDoc}
5086
                 */
5087
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
5088
                    return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
1✔
5089
                }
5090

5091
                /**
5092
                 * {@inheritDoc}
5093
                 */
5094
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
5095
                    return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
1✔
5096
                }
5097

5098
                /**
5099
                 * {@inheritDoc}
5100
                 */
5101
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
5102
                    return new MethodMatchAdapter(matcher);
1✔
5103
                }
5104

5105
                /**
5106
                 * {@inheritDoc}
5107
                 */
5108
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
5109
                    return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
1✔
5110
                }
5111

5112
                /**
5113
                 * {@inheritDoc}
5114
                 */
5115
                @SuppressWarnings("unchecked") // In absence of @SafeVarargs
5116
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
5117
                    return materialize(instrumentedType,
1✔
5118
                            fieldRegistry,
5119
                            methodRegistry,
5120
                            recordComponentRegistry,
5121
                            typeAttributeAppender,
5122
                            asmVisitorWrapper,
5123
                            classFileVersion,
5124
                            auxiliaryTypeNamingStrategy,
5125
                            annotationValueFilterFactory,
5126
                            annotationRetention,
5127
                            implementationContextFactory,
5128
                            methodGraphCompiler,
5129
                            typeValidation,
5130
                            visibilityBridgeStrategy,
5131
                            classReaderFactory,
5132
                            classWriterFactory,
5133
                            new LatentMatcher.Disjunction<MethodDescription>(this.ignoredMethods, ignoredMethods),
5134
                            auxiliaryTypes);
5135
                }
5136

5137
                /**
5138
                 * {@inheritDoc}
5139
                 */
5140
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
UNCOV
5141
                    return new RecordComponentDefinitionAdapter(new RecordComponentDescription.Token(name, type.asGenericType()));
×
5142
                }
5143

5144
                /**
5145
                 * {@inheritDoc}
5146
                 */
5147
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
UNCOV
5148
                    return new RecordComponentMatchAdapter(matcher);
×
5149
                }
5150

5151
                /**
5152
                 * {@inheritDoc}
5153
                 */
5154
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
5155
                    return materialize(instrumentedType.withInitializer(byteCodeAppender),
1✔
5156
                            fieldRegistry,
5157
                            methodRegistry,
5158
                            recordComponentRegistry,
5159
                            typeAttributeAppender,
5160
                            asmVisitorWrapper,
5161
                            classFileVersion,
5162
                            auxiliaryTypeNamingStrategy,
5163
                            annotationValueFilterFactory,
5164
                            annotationRetention,
5165
                            implementationContextFactory,
5166
                            methodGraphCompiler,
5167
                            typeValidation,
5168
                            visibilityBridgeStrategy,
5169
                            classReaderFactory,
5170
                            classWriterFactory,
5171
                            ignoredMethods,
5172
                            auxiliaryTypes);
5173
                }
5174

5175
                /**
5176
                 * {@inheritDoc}
5177
                 */
5178
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
5179
                    return materialize(instrumentedType.withInitializer(loadedTypeInitializer),
1✔
5180
                            fieldRegistry,
5181
                            methodRegistry,
5182
                            recordComponentRegistry,
5183
                            typeAttributeAppender,
5184
                            asmVisitorWrapper,
5185
                            classFileVersion,
5186
                            auxiliaryTypeNamingStrategy,
5187
                            annotationValueFilterFactory,
5188
                            annotationRetention,
5189
                            implementationContextFactory,
5190
                            methodGraphCompiler,
5191
                            typeValidation,
5192
                            visibilityBridgeStrategy,
5193
                            classReaderFactory,
5194
                            classWriterFactory,
5195
                            ignoredMethods,
5196
                            auxiliaryTypes);
5197
                }
5198

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

5223
                /**
5224
                 * {@inheritDoc}
5225
                 */
5226
                public Builder<U> suffix(String suffix) {
UNCOV
5227
                    return name(instrumentedType.getName() + "$" + suffix);
×
5228
                }
5229

5230
                /**
5231
                 * {@inheritDoc}
5232
                 */
5233
                public Builder<U> modifiers(int modifiers) {
5234
                    return materialize(instrumentedType.withModifiers(modifiers),
1✔
5235
                            fieldRegistry,
5236
                            methodRegistry,
5237
                            recordComponentRegistry,
5238
                            typeAttributeAppender,
5239
                            asmVisitorWrapper,
5240
                            classFileVersion,
5241
                            auxiliaryTypeNamingStrategy,
5242
                            annotationValueFilterFactory,
5243
                            annotationRetention,
5244
                            implementationContextFactory,
5245
                            methodGraphCompiler,
5246
                            typeValidation,
5247
                            visibilityBridgeStrategy,
5248
                            classReaderFactory,
5249
                            classWriterFactory,
5250
                            ignoredMethods,
5251
                            auxiliaryTypes);
5252
                }
5253

5254
                /**
5255
                 * {@inheritDoc}
5256
                 */
5257
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
5258
                    return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
1✔
5259
                            fieldRegistry,
5260
                            methodRegistry,
5261
                            recordComponentRegistry,
5262
                            typeAttributeAppender,
5263
                            asmVisitorWrapper,
5264
                            classFileVersion,
5265
                            auxiliaryTypeNamingStrategy,
5266
                            annotationValueFilterFactory,
5267
                            annotationRetention,
5268
                            implementationContextFactory,
5269
                            methodGraphCompiler,
5270
                            typeValidation,
5271
                            visibilityBridgeStrategy,
5272
                            classReaderFactory,
5273
                            classWriterFactory,
5274
                            ignoredMethods,
5275
                            auxiliaryTypes);
5276
                }
5277

5278
                /**
5279
                 * {@inheritDoc}
5280
                 */
5281
                public Builder<U> topLevelType() {
5282
                    return Adapter.this.materialize(instrumentedType
1✔
5283
                                    .withDeclaringType(TypeDescription.UNDEFINED)
1✔
5284
                                    .withEnclosingType(TypeDescription.UNDEFINED)
1✔
5285
                                    .withLocalClass(false),
1✔
5286
                            fieldRegistry,
5287
                            methodRegistry,
5288
                            recordComponentRegistry,
5289
                            typeAttributeAppender,
5290
                            asmVisitorWrapper,
5291
                            classFileVersion,
5292
                            auxiliaryTypeNamingStrategy,
5293
                            annotationValueFilterFactory,
5294
                            annotationRetention,
5295
                            implementationContextFactory,
5296
                            methodGraphCompiler,
5297
                            typeValidation,
5298
                            visibilityBridgeStrategy,
5299
                            classReaderFactory,
5300
                            classWriterFactory,
5301
                            ignoredMethods,
5302
                            auxiliaryTypes);
5303
                }
5304

5305
                /**
5306
                 * {@inheritDoc}
5307
                 */
5308
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
5309
                    return new InnerTypeDefinitionForTypeAdapter(type);
1✔
5310
                }
5311

5312
                /**
5313
                 * {@inheritDoc}
5314
                 */
5315
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
5316
                    return methodDescription.isTypeInitializer()
1✔
5317
                            ? new InnerTypeDefinitionForTypeAdapter(methodDescription.getDeclaringType())
1✔
5318
                            : new InnerTypeDefinitionForMethodAdapter(methodDescription);
5319
                }
5320

5321
                /**
5322
                 * {@inheritDoc}
5323
                 */
5324
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
5325
                    return materialize(instrumentedType.withDeclaredTypes(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
5326
                            fieldRegistry,
5327
                            methodRegistry,
5328
                            recordComponentRegistry,
5329
                            typeAttributeAppender,
5330
                            asmVisitorWrapper,
5331
                            classFileVersion,
5332
                            auxiliaryTypeNamingStrategy,
5333
                            annotationValueFilterFactory,
5334
                            annotationRetention,
5335
                            implementationContextFactory,
5336
                            methodGraphCompiler,
5337
                            typeValidation,
5338
                            visibilityBridgeStrategy,
5339
                            classReaderFactory,
5340
                            classWriterFactory,
5341
                            ignoredMethods,
5342
                            auxiliaryTypes);
5343
                }
5344

5345
                /**
5346
                 * {@inheritDoc}
5347
                 */
5348
                public Builder<U> nestHost(TypeDescription type) {
UNCOV
5349
                    return materialize(instrumentedType.withNestHost(type),
×
5350
                            fieldRegistry,
5351
                            methodRegistry,
5352
                            recordComponentRegistry,
5353
                            typeAttributeAppender,
5354
                            asmVisitorWrapper,
5355
                            classFileVersion,
5356
                            auxiliaryTypeNamingStrategy,
5357
                            annotationValueFilterFactory,
5358
                            annotationRetention,
5359
                            implementationContextFactory,
5360
                            methodGraphCompiler,
5361
                            typeValidation,
5362
                            visibilityBridgeStrategy,
5363
                            classReaderFactory,
5364
                            classWriterFactory,
5365
                            ignoredMethods,
5366
                            auxiliaryTypes);
5367
                }
5368

5369
                /**
5370
                 * {@inheritDoc}
5371
                 */
5372
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
5373
                    return materialize(instrumentedType.withNestMembers(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
5374
                            fieldRegistry,
5375
                            methodRegistry,
5376
                            recordComponentRegistry,
5377
                            typeAttributeAppender,
5378
                            asmVisitorWrapper,
5379
                            classFileVersion,
5380
                            auxiliaryTypeNamingStrategy,
5381
                            annotationValueFilterFactory,
5382
                            annotationRetention,
5383
                            implementationContextFactory,
5384
                            methodGraphCompiler,
5385
                            typeValidation,
5386
                            visibilityBridgeStrategy,
5387
                            classReaderFactory,
5388
                            classWriterFactory,
5389
                            ignoredMethods,
5390
                            auxiliaryTypes);
5391
                }
5392

5393
                /**
5394
                 * {@inheritDoc}
5395
                 */
5396
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
UNCOV
5397
                    return materialize(instrumentedType.withPermittedSubclasses(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
×
5398
                            fieldRegistry,
5399
                            methodRegistry,
5400
                            recordComponentRegistry,
5401
                            typeAttributeAppender,
5402
                            asmVisitorWrapper,
5403
                            classFileVersion,
5404
                            auxiliaryTypeNamingStrategy,
5405
                            annotationValueFilterFactory,
5406
                            annotationRetention,
5407
                            implementationContextFactory,
5408
                            methodGraphCompiler,
5409
                            typeValidation,
5410
                            visibilityBridgeStrategy,
5411
                            classReaderFactory,
5412
                            classWriterFactory,
5413
                            ignoredMethods,
5414
                            auxiliaryTypes);
5415
                }
5416

5417
                /**
5418
                 * {@inheritDoc}
5419
                 */
5420
                public Builder<U> unsealed() {
UNCOV
5421
                    return materialize(instrumentedType.withPermittedSubclasses(TypeList.UNDEFINED),
×
5422
                            fieldRegistry,
5423
                            methodRegistry,
5424
                            recordComponentRegistry,
5425
                            typeAttributeAppender,
5426
                            asmVisitorWrapper,
5427
                            classFileVersion,
5428
                            auxiliaryTypeNamingStrategy,
5429
                            annotationValueFilterFactory,
5430
                            annotationRetention,
5431
                            implementationContextFactory,
5432
                            methodGraphCompiler,
5433
                            typeValidation,
5434
                            visibilityBridgeStrategy,
5435
                            classReaderFactory,
5436
                            classWriterFactory,
5437
                            ignoredMethods,
5438
                            auxiliaryTypes);
5439
                }
5440

5441
                /**
5442
                 * {@inheritDoc}
5443
                 */
5444
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
5445
                    return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
5446
                }
5447

5448
                /**
5449
                 * {@inheritDoc}
5450
                 */
5451
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
5452
                    return materialize(instrumentedType.withTypeVariables(matcher, transformer),
1✔
5453
                            fieldRegistry,
5454
                            methodRegistry,
5455
                            recordComponentRegistry,
5456
                            typeAttributeAppender,
5457
                            asmVisitorWrapper,
5458
                            classFileVersion,
5459
                            auxiliaryTypeNamingStrategy,
5460
                            annotationValueFilterFactory,
5461
                            annotationRetention,
5462
                            implementationContextFactory,
5463
                            methodGraphCompiler,
5464
                            typeValidation,
5465
                            visibilityBridgeStrategy,
5466
                            classReaderFactory,
5467
                            classWriterFactory,
5468
                            ignoredMethods,
5469
                            auxiliaryTypes);
5470
                }
5471

5472
                /**
5473
                 * {@inheritDoc}
5474
                 */
5475
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
5476
                    return materialize(instrumentedType,
1✔
5477
                            fieldRegistry,
5478
                            methodRegistry,
5479
                            recordComponentRegistry,
5480
                            new TypeAttributeAppender.Compound(this.typeAttributeAppender, typeAttributeAppender),
5481
                            asmVisitorWrapper,
5482
                            classFileVersion,
5483
                            auxiliaryTypeNamingStrategy,
5484
                            annotationValueFilterFactory,
5485
                            annotationRetention,
5486
                            implementationContextFactory,
5487
                            methodGraphCompiler,
5488
                            typeValidation,
5489
                            visibilityBridgeStrategy,
5490
                            classReaderFactory,
5491
                            classWriterFactory,
5492
                            ignoredMethods,
5493
                            auxiliaryTypes);
5494
                }
5495

5496
                /**
5497
                 * {@inheritDoc}
5498
                 */
5499
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
5500
                    ModuleDescription moduleDescription = instrumentedType.toModuleDescription();
1✔
5501
                    return materialize(instrumentedType
1✔
5502
                                    .withAnnotations(new ArrayList<AnnotationDescription>(annotations))
1✔
5503
                                    .withModuleDescription(moduleDescription == null ? ModuleDescription.UNDEFINED : new ModuleDescription.Latent(moduleDescription.getActualName(),
1✔
UNCOV
5504
                                            moduleDescription.getModifiers(),
×
UNCOV
5505
                                            moduleDescription.getVersion(),
×
UNCOV
5506
                                            moduleDescription.getMainClass(),
×
UNCOV
5507
                                            moduleDescription.getPackages(),
×
UNCOV
5508
                                            moduleDescription.getRequires(),
×
UNCOV
5509
                                            moduleDescription.getExports(),
×
UNCOV
5510
                                            moduleDescription.getOpens(),
×
UNCOV
5511
                                            moduleDescription.getUses(),
×
UNCOV
5512
                                            moduleDescription.getProvides(),
×
UNCOV
5513
                                            CompoundList.of(instrumentedType.getDeclaredAnnotations(), new ArrayList<AnnotationDescription>(annotations)))),
×
5514
                            fieldRegistry,
5515
                            methodRegistry,
5516
                            recordComponentRegistry,
5517
                            typeAttributeAppender,
5518
                            asmVisitorWrapper,
5519
                            classFileVersion,
5520
                            auxiliaryTypeNamingStrategy,
5521
                            annotationValueFilterFactory,
5522
                            annotationRetention,
5523
                            implementationContextFactory,
5524
                            methodGraphCompiler,
5525
                            typeValidation,
5526
                            visibilityBridgeStrategy,
5527
                            classReaderFactory,
5528
                            classWriterFactory,
5529
                            ignoredMethods,
5530
                            auxiliaryTypes);
5531
                }
5532

5533
                /**
5534
                 * {@inheritDoc}
5535
                 */
5536
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
5537
                    return materialize(instrumentedType,
1✔
5538
                            fieldRegistry,
5539
                            methodRegistry,
5540
                            recordComponentRegistry,
5541
                            typeAttributeAppender,
5542
                            new AsmVisitorWrapper.Compound(this.asmVisitorWrapper, asmVisitorWrapper),
5543
                            classFileVersion,
5544
                            auxiliaryTypeNamingStrategy,
5545
                            annotationValueFilterFactory,
5546
                            annotationRetention,
5547
                            implementationContextFactory,
5548
                            methodGraphCompiler,
5549
                            typeValidation,
5550
                            visibilityBridgeStrategy,
5551
                            classReaderFactory,
5552
                            classWriterFactory,
5553
                            ignoredMethods,
5554
                            auxiliaryTypes);
5555
                }
5556

5557
                /**
5558
                 * {@inheritDoc}
5559
                 */
5560
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
5561
                    return materialize(instrumentedType,
1✔
5562
                            fieldRegistry,
5563
                            methodRegistry,
5564
                            recordComponentRegistry,
5565
                            typeAttributeAppender,
5566
                            asmVisitorWrapper,
5567
                            classFileVersion,
5568
                            auxiliaryTypeNamingStrategy,
5569
                            annotationValueFilterFactory,
5570
                            annotationRetention,
5571
                            implementationContextFactory,
5572
                            methodGraphCompiler,
5573
                            typeValidation,
5574
                            visibilityBridgeStrategy,
5575
                            classReaderFactory,
5576
                            classWriterFactory,
5577
                            ignoredMethods,
5578
                            CompoundList.of(this.auxiliaryTypes, new ArrayList<DynamicType>(auxiliaryTypes)));
1✔
5579
                }
5580

5581
                /**
5582
                 * {@inheritDoc}
5583
                 */
5584
                public TypeDescription toTypeDescription() {
5585
                    return instrumentedType;
1✔
5586
                }
5587

5588
                /**
5589
                 * Materializes the supplied state of a dynamic type builder.
5590
                 *
5591
                 * @param instrumentedType             The instrumented type.
5592
                 * @param fieldRegistry                The current field registry.
5593
                 * @param methodRegistry               The current method registry.
5594
                 * @param recordComponentRegistry      The record component pool to use.
5595
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
5596
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
5597
                 * @param classFileVersion             The class file version to define auxiliary types in.
5598
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
5599
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
5600
                 * @param annotationRetention          The annotation retention to apply.
5601
                 * @param implementationContextFactory The implementation context factory to apply.
5602
                 * @param methodGraphCompiler          The method graph compiler to use.
5603
                 * @param typeValidation               The type validation state.
5604
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
5605
                 * @param classReaderFactory           The class reader factory to use.
5606
                 * @param classWriterFactory           The class writer factory to use.
5607
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
5608
                 * @param auxiliaryTypes               A list of explicitly required auxiliary types.
5609
                 * @return A type builder that represents the supplied arguments.
5610
                 */
5611
                protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
5612
                                                          FieldRegistry fieldRegistry,
5613
                                                          MethodRegistry methodRegistry,
5614
                                                          RecordComponentRegistry recordComponentRegistry,
5615
                                                          TypeAttributeAppender typeAttributeAppender,
5616
                                                          AsmVisitorWrapper asmVisitorWrapper,
5617
                                                          ClassFileVersion classFileVersion,
5618
                                                          AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
5619
                                                          AnnotationValueFilter.Factory annotationValueFilterFactory,
5620
                                                          AnnotationRetention annotationRetention,
5621
                                                          Implementation.Context.Factory implementationContextFactory,
5622
                                                          MethodGraph.Compiler methodGraphCompiler,
5623
                                                          TypeValidation typeValidation,
5624
                                                          VisibilityBridgeStrategy visibilityBridgeStrategy,
5625
                                                          AsmClassReader.Factory classReaderFactory,
5626
                                                          AsmClassWriter.Factory classWriterFactory,
5627
                                                          LatentMatcher<? super MethodDescription> ignoredMethods,
5628
                                                          List<? extends DynamicType> auxiliaryTypes);
5629

5630
                /**
5631
                 * An adapter for defining a module.
5632
                 */
5633
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5634
                protected class ModuleDefinitionAdapter extends ModuleDefinition.AbstractBase<U> {
5635

5636
                    /**
5637
                     * The name of the module.
5638
                     */
5639
                    private final String name;
5640

5641
                    /**
5642
                     * The modifiers of the module.
5643
                     */
5644
                    private final int modifiers;
5645

5646
                    /**
5647
                     * The module version or {@code null} if no version was specified.
5648
                     */
5649
                    @MaybeNull
5650
                    @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5651
                    private final String version;
5652

5653
                    /**
5654
                     * The module's main class or {@code null} if no main class was specified.
5655
                     */
5656
                    @MaybeNull
5657
                    @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5658
                    private final String mainClass;
5659

5660
                    /**
5661
                     * The module's packages.
5662
                     */
5663
                    private final Set<String> packages;
5664

5665
                    /**
5666
                     * The modules that this module requires.
5667
                     */
5668
                    private final Map<String, ModuleDescription.Requires> requires;
5669

5670
                    /**
5671
                     * The packages that this module exports.
5672
                     */
5673
                    private final Map<String, ModuleDescription.Exports> exports;
5674

5675
                    /**
5676
                     * The packages that this module opens.
5677
                     */
5678
                    private final Map<String, ModuleDescription.Opens> opens;
5679

5680
                    /**
5681
                     * The services that this module uses.
5682
                     */
5683
                    private final Set<String> uses;
5684

5685
                    /**
5686
                     * The services that this module provides.
5687
                     */
5688
                    private final Map<String, ModuleDescription.Provides> provides;
5689

5690
                    protected ModuleDefinitionAdapter(String name, int modifiers) {
UNCOV
5691
                        this(name,
×
5692
                                modifiers,
5693
                                null,
5694
                                null,
5695
                                Collections.<String>emptySet(),
×
5696
                                "java.base".equals(name)
×
5697
                                        ? Collections.<String, ModuleDescription.Requires>emptyMap()
×
5698
                                        : Collections.<String, ModuleDescription.Requires>singletonMap("java.base", new ModuleDescription.Requires.Simple(null, Opcodes.ACC_MANDATED)),
×
5699
                                Collections.<String, ModuleDescription.Exports>emptyMap(),
×
5700
                                Collections.<String, ModuleDescription.Opens>emptyMap(),
×
5701
                                Collections.<String>emptySet(),
×
5702
                                Collections.<String, ModuleDescription.Provides>emptyMap());
×
5703
                    }
×
5704

5705
                    /**
5706
                     * Creates a new module definition adapter.
5707
                     *
5708
                     * @param name      The name of the module.
5709
                     * @param modifiers The modifiers of the module.
5710
                     * @param version   The module version or {@code null} if no version was specified.
5711
                     * @param mainClass The module's main class or {@code null} if no main class was specified.
5712
                     * @param packages  The module's packages.
5713
                     * @param requires  The modules that this module requires.
5714
                     * @param exports   The packages that this module exports.
5715
                     * @param opens     The packages that this module opens.
5716
                     * @param uses      The services that this module uses.
5717
                     * @param provides  The services that this module provides.
5718
                     */
5719
                    protected ModuleDefinitionAdapter(String name,
5720
                                                      int modifiers,
5721
                                                      @MaybeNull String version,
5722
                                                      @MaybeNull String mainClass,
5723
                                                      Set<String> packages,
5724
                                                      Map<String, ModuleDescription.Requires> requires,
5725
                                                      Map<String, ModuleDescription.Exports> exports,
5726
                                                      Map<String, ModuleDescription.Opens> opens,
5727
                                                      Set<String> uses,
UNCOV
5728
                                                      Map<String, ModuleDescription.Provides> provides) {
×
UNCOV
5729
                        this.name = name;
×
UNCOV
5730
                        this.modifiers = modifiers;
×
UNCOV
5731
                        this.version = version;
×
UNCOV
5732
                        this.mainClass = mainClass;
×
UNCOV
5733
                        this.packages = packages;
×
UNCOV
5734
                        this.requires = requires;
×
UNCOV
5735
                        this.exports = exports;
×
UNCOV
5736
                        this.opens = opens;
×
UNCOV
5737
                        this.uses = uses;
×
UNCOV
5738
                        this.provides = provides;
×
UNCOV
5739
                    }
×
5740

5741
                    /**
5742
                     * {@inheritDoc}
5743
                     */
5744
                    public ModuleDefinition<U> version(@MaybeNull String version) {
5745
                        return new ModuleDefinitionAdapter(name,
×
5746
                                modifiers,
5747
                                version,
5748
                                mainClass,
5749
                                packages,
5750
                                requires,
5751
                                exports,
5752
                                opens,
5753
                                uses,
5754
                                provides);
5755
                    }
5756

5757
                    /**
5758
                     * {@inheritDoc}
5759
                     */
5760
                    public ModuleDefinition<U> mainClass(@MaybeNull String name) {
5761
                        return new ModuleDefinitionAdapter(this.name,
×
5762
                                modifiers,
5763
                                version,
5764
                                name,
5765
                                packages,
5766
                                requires,
5767
                                exports,
5768
                                opens,
5769
                                uses,
5770
                                provides);
5771
                    }
5772

5773
                    /**
5774
                     * {@inheritDoc}
5775
                     */
5776
                    public ModuleDefinition<U> packages(Collection<String> packages) {
UNCOV
5777
                        Set<String> merged = new LinkedHashSet<String>(this.packages);
×
UNCOV
5778
                        merged.addAll(packages);
×
UNCOV
5779
                        return new ModuleDefinitionAdapter(name,
×
5780
                                modifiers,
5781
                                version,
5782
                                mainClass,
5783
                                merged,
5784
                                requires,
5785
                                exports,
5786
                                opens,
5787
                                uses,
5788
                                provides);
5789
                    }
5790

5791
                    /**
5792
                     * {@inheritDoc}
5793
                     */
5794
                    public RequiresDefinition<U> require(String module, int modifiers) {
UNCOV
5795
                        return new RequiresDefinitionAdapter(module, modifiers);
×
5796
                    }
5797

5798
                    /**
5799
                     * {@inheritDoc}
5800
                     */
5801
                    public ExportsDefinition<U> export(String aPackage, int modifiers) {
5802
                        return new ExportsDefinitionAdapter(aPackage, modifiers);
×
5803
                    }
5804

5805
                    /**
5806
                     * {@inheritDoc}
5807
                     */
5808
                    public OpensDefinition<U> open(String aPackage, int modifiers) {
UNCOV
5809
                        return new OpensDefinitionAdapter(aPackage, modifiers);
×
5810
                    }
5811

5812
                    /**
5813
                     * {@inheritDoc}
5814
                     */
5815
                    public ModuleDefinition<U> uses(Collection<String> services) {
5816
                        Set<String> uses = new LinkedHashSet<String>(this.uses);
×
UNCOV
5817
                        uses.addAll(services);
×
UNCOV
5818
                        return new ModuleDefinitionAdapter(name,
×
5819
                                modifiers,
5820
                                version,
5821
                                mainClass,
5822
                                packages,
5823
                                requires,
5824
                                exports,
5825
                                opens,
5826
                                uses,
5827
                                provides);
5828
                    }
5829

5830
                    /**
5831
                     * {@inheritDoc}
5832
                     */
5833
                    public ModuleDefinition<U> provides(String service, Collection<String> implementations) {
UNCOV
5834
                        Map<String, ModuleDescription.Provides> provides = new LinkedHashMap<String, ModuleDescription.Provides>(this.provides);
×
UNCOV
5835
                        provides.put(service, new ModuleDescription.Provides.Simple(new LinkedHashSet<String>(implementations)));
×
UNCOV
5836
                        return new ModuleDefinitionAdapter(name,
×
5837
                                modifiers,
5838
                                version,
5839
                                mainClass,
5840
                                packages,
5841
                                requires,
5842
                                exports,
5843
                                opens,
5844
                                uses,
5845
                                provides);
5846
                    }
5847

5848
                    @Override
5849
                    protected Builder<U> materialize() {
UNCOV
5850
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withModuleDescription(new ModuleDescription.Latent(name,
×
5851
                                        modifiers,
5852
                                        version,
5853
                                        mainClass,
5854
                                        packages,
5855
                                        requires,
5856
                                        exports,
5857
                                        opens,
5858
                                        uses,
5859
                                        provides,
UNCOV
5860
                                        instrumentedType.getDeclaredAnnotations())).withModifiers(modifiers),
×
5861
                                fieldRegistry,
5862
                                methodRegistry,
5863
                                recordComponentRegistry,
5864
                                typeAttributeAppender,
5865
                                asmVisitorWrapper,
5866
                                classFileVersion,
5867
                                auxiliaryTypeNamingStrategy,
5868
                                annotationValueFilterFactory,
5869
                                annotationRetention,
5870
                                implementationContextFactory,
5871
                                methodGraphCompiler,
5872
                                typeValidation,
5873
                                visibilityBridgeStrategy,
5874
                                classReaderFactory,
5875
                                classWriterFactory,
5876
                                ignoredMethods,
5877
                                auxiliaryTypes);
5878
                    }
5879

5880
                    /**
5881
                     * An adapter for definining a module requirement.
5882
                     */
5883
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5884
                    protected class RequiresDefinitionAdapter extends RequiresDefinition.Delegator<U> {
5885

5886
                        /**
5887
                         * The module that is being required.
5888
                         */
5889
                        private final String module;
5890

5891
                        /**
5892
                         * The modifiers of the required module.
5893
                         */
5894
                        private final int modifiers;
5895

5896
                        /**
5897
                         * The version of the required module or {@code null} if no particular version is required.
5898
                         */
5899
                        @MaybeNull
5900
                        @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5901
                        private final String version;
5902

5903
                        /**
5904
                         * Creates a new module requirement definition.
5905
                         *
5906
                         * @param module    The module that is being required.
5907
                         * @param modifiers The modifiers of the required module.
5908
                         */
5909
                        protected RequiresDefinitionAdapter(String module, int modifiers) {
5910
                            this(module, modifiers, null);
×
5911
                        }
×
5912

5913
                        /**
5914
                         * Creates a new module requirement definition.
5915
                         *
5916
                         * @param module    The module that is being required.
5917
                         * @param modifiers The modifiers of the required module.
5918
                         * @param version   The version of the required module or {@code null} if no particular version is required.
5919
                         */
UNCOV
5920
                        protected RequiresDefinitionAdapter(String module, int modifiers, @MaybeNull String version) {
×
UNCOV
5921
                            this.module = module;
×
UNCOV
5922
                            this.modifiers = modifiers;
×
UNCOV
5923
                            this.version = version;
×
UNCOV
5924
                        }
×
5925

5926
                        /**
5927
                         * {@inheritDoc}
5928
                         */
5929
                        public RequiresDefinition<U> requiredVersion(@MaybeNull String version) {
UNCOV
5930
                            return new RequiresDefinitionAdapter(module, modifiers, version);
×
5931
                        }
5932

5933
                        @Override
5934
                        protected ModuleDefinition<U> materialize() {
UNCOV
5935
                            Map<String, ModuleDescription.Requires> requires = new LinkedHashMap<String, ModuleDescription.Requires>(ModuleDefinitionAdapter.this.requires);
×
UNCOV
5936
                            requires.put(name, new ModuleDescription.Requires.Simple(version, modifiers));
×
UNCOV
5937
                            return new ModuleDefinitionAdapter(ModuleDefinitionAdapter.this.name,
×
UNCOV
5938
                                    ModuleDefinitionAdapter.this.modifiers,
×
UNCOV
5939
                                    ModuleDefinitionAdapter.this.version,
×
UNCOV
5940
                                    mainClass,
×
UNCOV
5941
                                    packages,
×
5942
                                    requires,
UNCOV
5943
                                    exports,
×
5944
                                    opens,
×
5945
                                    uses,
×
UNCOV
5946
                                    provides);
×
5947
                        }
5948
                    }
5949

5950
                    /**
5951
                     * An adapter for defining a module export.
5952
                     */
5953
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5954
                    protected class ExportsDefinitionAdapter extends ExportsDefinition.Delegator<U> {
5955

5956
                        /**
5957
                         * The package that is being exported.
5958
                         */
5959
                        private final String aPackage;
5960

5961
                        /**
5962
                         * The modifiers for the exporting declaration.
5963
                         */
5964
                        private final int modifiers;
5965

5966
                        /**
5967
                         * The modules to which the package is exported, or no modules if exported to all modules.
5968
                         */
5969
                        private final Set<String> targets;
5970

5971
                        /**
5972
                         * Creates a new exporting definition adapter.
5973
                         *
5974
                         * @param aPackage  The package that is being exported.
5975
                         * @param modifiers The modifiers for the exporting declaration.
5976
                         */
5977
                        protected ExportsDefinitionAdapter(String aPackage, int modifiers) {
5978
                            this(aPackage, modifiers, Collections.<String>emptySet());
×
UNCOV
5979
                        }
×
5980

5981
                        /**
5982
                         * Creates a new exporting definition adapter.
5983
                         *
5984
                         * @param aPackage  The package that is being exported.
5985
                         * @param modifiers The modifiers for the exporting declaration.
5986
                         * @param targets   The modules to which the package is exported, or no modules if exported to all modules.
5987
                         */
UNCOV
5988
                        protected ExportsDefinitionAdapter(String aPackage, int modifiers, Set<String> targets) {
×
UNCOV
5989
                            this.aPackage = aPackage;
×
UNCOV
5990
                            this.modifiers = modifiers;
×
UNCOV
5991
                            this.targets = targets;
×
UNCOV
5992
                        }
×
5993

5994
                        /**
5995
                         * {@inheritDoc}
5996
                         */
5997
                        public ExportsDefinition<U> to(Collection<String> modules) {
UNCOV
5998
                            Set<String> targets = new LinkedHashSet<String>(this.targets);
×
UNCOV
5999
                            targets.addAll(modules);
×
UNCOV
6000
                            return new ExportsDefinitionAdapter(aPackage, modifiers, targets);
×
6001
                        }
6002

6003
                        @Override
6004
                        protected ModuleDefinition<U> materialize() {
UNCOV
6005
                            Map<String, ModuleDescription.Exports> exports = new LinkedHashMap<String, ModuleDescription.Exports>(ModuleDefinitionAdapter.this.exports);
×
UNCOV
6006
                            exports.put(aPackage, new ModuleDescription.Exports.Simple(targets, modifiers));
×
UNCOV
6007
                            return new ModuleDefinitionAdapter(name,
×
UNCOV
6008
                                    ModuleDefinitionAdapter.this.modifiers,
×
UNCOV
6009
                                    version,
×
UNCOV
6010
                                    mainClass,
×
UNCOV
6011
                                    packages,
×
UNCOV
6012
                                    requires,
×
6013
                                    exports,
6014
                                    opens,
×
6015
                                    uses,
×
UNCOV
6016
                                    provides);
×
6017
                        }
6018
                    }
6019

6020
                    /**
6021
                     * An adapter for defining a module opening.
6022
                     */
6023
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6024
                    protected class OpensDefinitionAdapter extends OpensDefinition.Delegator<U> {
6025

6026
                        /**
6027
                         * The package that is being opened.
6028
                         */
6029
                        private final String aPackage;
6030

6031
                        /**
6032
                         * The modifiers for the opening declaration.
6033
                         */
6034
                        private final int modifiers;
6035

6036
                        /**
6037
                         * The modules to which the package is opened, or no modules if opened to all modules.
6038
                         */
6039
                        private final Set<String> targets;
6040

6041
                        /**
6042
                         * Creates a new opens definition adapter.
6043
                         *
6044
                         * @param aPackage  The package that is being opened.
6045
                         * @param modifiers The modifiers for the opening declaration.
6046
                         */
6047
                        protected OpensDefinitionAdapter(String aPackage, int modifiers) {
6048
                            this(aPackage, modifiers, Collections.<String>emptySet());
×
6049
                        }
×
6050

6051
                        /**
6052
                         * Creates a new opens definition adapter.
6053
                         *
6054
                         * @param aPackage  The package that is being opened.
6055
                         * @param modifiers The modifiers for the opening declaration.
6056
                         * @param targets   The modules to which the package is opened, or no modules if opened to all modules.
6057
                         */
UNCOV
6058
                        protected OpensDefinitionAdapter(String aPackage, int modifiers, Set<String> targets) {
×
UNCOV
6059
                            this.aPackage = aPackage;
×
UNCOV
6060
                            this.modifiers = modifiers;
×
UNCOV
6061
                            this.targets = targets;
×
UNCOV
6062
                        }
×
6063

6064
                        /**
6065
                         * {@inheritDoc}
6066
                         */
6067
                        public OpensDefinition<U> to(Collection<String> modules) {
UNCOV
6068
                            Set<String> targets = new LinkedHashSet<String>(this.targets);
×
UNCOV
6069
                            targets.addAll(modules);
×
UNCOV
6070
                            return new OpensDefinitionAdapter(aPackage, modifiers, targets);
×
6071
                        }
6072

6073
                        @Override
6074
                        protected ModuleDefinition<U> materialize() {
UNCOV
6075
                            Map<String, ModuleDescription.Opens> opens = new LinkedHashMap<String, ModuleDescription.Opens>(ModuleDefinitionAdapter.this.opens);
×
UNCOV
6076
                            opens.put(aPackage, new ModuleDescription.Opens.Simple(targets, modifiers));
×
UNCOV
6077
                            return new ModuleDefinitionAdapter(name,
×
UNCOV
6078
                                    ModuleDefinitionAdapter.this.modifiers,
×
UNCOV
6079
                                    version,
×
UNCOV
6080
                                    mainClass,
×
UNCOV
6081
                                    packages,
×
UNCOV
6082
                                    requires,
×
UNCOV
6083
                                    exports,
×
6084
                                    opens,
UNCOV
6085
                                    uses,
×
UNCOV
6086
                                    provides);
×
6087
                        }
6088
                    }
6089
                }
6090

6091
                /**
6092
                 * An adapter for applying an inner type definition for an outer type.
6093
                 */
6094
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6095
                protected class InnerTypeDefinitionForTypeAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition.ForType<U> {
6096

6097
                    /**
6098
                     * A description of the type that is the defined outer type.
6099
                     */
6100
                    private final TypeDescription typeDescription;
6101

6102
                    /**
6103
                     * Creates a new adapter for an inner type definition for an outer type.
6104
                     *
6105
                     * @param typeDescription A description of the type that is the defined outer type.
6106
                     */
6107
                    protected InnerTypeDefinitionForTypeAdapter(TypeDescription typeDescription) {
1✔
6108
                        this.typeDescription = typeDescription;
1✔
6109
                    }
1✔
6110

6111
                    /**
6112
                     * {@inheritDoc}
6113
                     */
6114
                    public Builder<U> asAnonymousType() {
6115
                        return Adapter.this.materialize(instrumentedType
1✔
6116
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6117
                                        .withEnclosingType(typeDescription)
1✔
6118
                                        .withAnonymousClass(true),
1✔
6119
                                fieldRegistry,
6120
                                methodRegistry,
6121
                                recordComponentRegistry,
6122
                                typeAttributeAppender,
6123
                                asmVisitorWrapper,
6124
                                classFileVersion,
6125
                                auxiliaryTypeNamingStrategy,
6126
                                annotationValueFilterFactory,
6127
                                annotationRetention,
6128
                                implementationContextFactory,
6129
                                methodGraphCompiler,
6130
                                typeValidation,
6131
                                visibilityBridgeStrategy,
6132
                                classReaderFactory,
6133
                                classWriterFactory,
6134
                                ignoredMethods,
6135
                                auxiliaryTypes);
6136
                    }
6137

6138
                    /**
6139
                     * {@inheritDoc}
6140
                     */
6141
                    public Builder<U> asMemberType() {
6142
                        return Adapter.this.materialize(instrumentedType
1✔
6143
                                        .withDeclaringType(typeDescription)
1✔
6144
                                        .withEnclosingType(typeDescription)
1✔
6145
                                        .withAnonymousClass(false)
1✔
6146
                                        .withLocalClass(false),
1✔
6147
                                fieldRegistry,
6148
                                methodRegistry,
6149
                                recordComponentRegistry,
6150
                                typeAttributeAppender,
6151
                                asmVisitorWrapper,
6152
                                classFileVersion,
6153
                                auxiliaryTypeNamingStrategy,
6154
                                annotationValueFilterFactory,
6155
                                annotationRetention,
6156
                                implementationContextFactory,
6157
                                methodGraphCompiler,
6158
                                typeValidation,
6159
                                visibilityBridgeStrategy,
6160
                                classReaderFactory,
6161
                                classWriterFactory,
6162
                                ignoredMethods,
6163
                                auxiliaryTypes);
6164
                    }
6165

6166
                    @Override
6167
                    protected Builder<U> materialize() {
6168
                        return Adapter.this.materialize(instrumentedType
1✔
6169
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6170
                                        .withEnclosingType(typeDescription)
1✔
6171
                                        .withLocalClass(true),
1✔
6172
                                fieldRegistry,
6173
                                methodRegistry,
6174
                                recordComponentRegistry,
6175
                                typeAttributeAppender,
6176
                                asmVisitorWrapper,
6177
                                classFileVersion,
6178
                                auxiliaryTypeNamingStrategy,
6179
                                annotationValueFilterFactory,
6180
                                annotationRetention,
6181
                                implementationContextFactory,
6182
                                methodGraphCompiler,
6183
                                typeValidation,
6184
                                visibilityBridgeStrategy,
6185
                                classReaderFactory,
6186
                                classWriterFactory,
6187
                                ignoredMethods,
6188
                                auxiliaryTypes);
6189
                    }
6190
                }
6191

6192
                /**
6193
                 * An adapter for applying an inner type definition for an outer method or constructor.
6194
                 */
6195
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6196
                protected class InnerTypeDefinitionForMethodAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition<U> {
6197

6198
                    /**
6199
                     * A description of the declaring method or constructor.
6200
                     */
6201
                    private final MethodDescription.InDefinedShape methodDescription;
6202

6203
                    /**
6204
                     * Creates a new adapter for defining a type that is declared within a method or constructor.
6205
                     *
6206
                     * @param methodDescription A description of the declaring method or constructor.
6207
                     */
6208
                    protected InnerTypeDefinitionForMethodAdapter(MethodDescription.InDefinedShape methodDescription) {
1✔
6209
                        this.methodDescription = methodDescription;
1✔
6210
                    }
1✔
6211

6212
                    /**
6213
                     * {@inheritDoc}
6214
                     */
6215
                    public Builder<U> asAnonymousType() {
6216
                        return Adapter.this.materialize(instrumentedType
1✔
6217
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6218
                                        .withEnclosingMethod(methodDescription)
1✔
6219
                                        .withAnonymousClass(true),
1✔
6220
                                fieldRegistry,
6221
                                methodRegistry,
6222
                                recordComponentRegistry,
6223
                                typeAttributeAppender,
6224
                                asmVisitorWrapper,
6225
                                classFileVersion,
6226
                                auxiliaryTypeNamingStrategy,
6227
                                annotationValueFilterFactory,
6228
                                annotationRetention,
6229
                                implementationContextFactory,
6230
                                methodGraphCompiler,
6231
                                typeValidation,
6232
                                visibilityBridgeStrategy,
6233
                                classReaderFactory,
6234
                                classWriterFactory,
6235
                                ignoredMethods,
6236
                                auxiliaryTypes);
6237
                    }
6238

6239
                    @Override
6240
                    protected Builder<U> materialize() {
6241
                        return Adapter.this.materialize(instrumentedType
1✔
6242
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6243
                                        .withEnclosingMethod(methodDescription)
1✔
6244
                                        .withLocalClass(true),
1✔
6245
                                fieldRegistry,
6246
                                methodRegistry,
6247
                                recordComponentRegistry,
6248
                                typeAttributeAppender,
6249
                                asmVisitorWrapper,
6250
                                classFileVersion,
6251
                                auxiliaryTypeNamingStrategy,
6252
                                annotationValueFilterFactory,
6253
                                annotationRetention,
6254
                                implementationContextFactory,
6255
                                methodGraphCompiler,
6256
                                typeValidation,
6257
                                visibilityBridgeStrategy,
6258
                                classReaderFactory,
6259
                                classWriterFactory,
6260
                                ignoredMethods,
6261
                                auxiliaryTypes);
6262
                    }
6263
                }
6264

6265
                /**
6266
                 * An adapter for defining a new type variable for the instrumented type.
6267
                 */
6268
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6269
                protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
6270

6271
                    /**
6272
                     * The current definition of the type variable.
6273
                     */
6274
                    private final TypeVariableToken token;
6275

6276
                    /**
6277
                     * Creates a new type variable definition adapter.
6278
                     *
6279
                     * @param token The current definition of the type variable.
6280
                     */
6281
                    protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
1✔
6282
                        this.token = token;
1✔
6283
                    }
1✔
6284

6285
                    /**
6286
                     * {@inheritDoc}
6287
                     */
6288
                    public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
6289
                        return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
1✔
6290
                                token.getBounds(),
1✔
6291
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6292
                    }
6293

6294
                    @Override
6295
                    protected Builder<U> materialize() {
6296
                        return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
1✔
6297
                                fieldRegistry,
6298
                                methodRegistry,
6299
                                recordComponentRegistry,
6300
                                typeAttributeAppender,
6301
                                asmVisitorWrapper,
6302
                                classFileVersion,
6303
                                auxiliaryTypeNamingStrategy,
6304
                                annotationValueFilterFactory,
6305
                                annotationRetention,
6306
                                implementationContextFactory,
6307
                                methodGraphCompiler,
6308
                                typeValidation,
6309
                                visibilityBridgeStrategy,
6310
                                classReaderFactory,
6311
                                classWriterFactory,
6312
                                ignoredMethods,
6313
                                auxiliaryTypes);
6314
                    }
6315
                }
6316

6317
                /**
6318
                 * An adapter for defining a new field.
6319
                 */
6320
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6321
                protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
6322

6323
                    /**
6324
                     * The token representing the current field definition.
6325
                     */
6326
                    private final FieldDescription.Token token;
6327

6328
                    /**
6329
                     * Creates a new field definition adapter.
6330
                     *
6331
                     * @param token The token representing the current field definition.
6332
                     */
6333
                    protected FieldDefinitionAdapter(FieldDescription.Token token) {
6334
                        this(FieldAttributeAppender.ForInstrumentedField.INSTANCE,
1✔
6335
                                Transformer.NoOp.<FieldDescription>make(),
1✔
6336
                                FieldDescription.NO_DEFAULT_VALUE,
6337
                                token);
6338
                    }
1✔
6339

6340
                    /**
6341
                     * Creates a new field definition adapter.
6342
                     *
6343
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
6344
                     * @param transformer                   The field transformer to apply.
6345
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
6346
                     * @param token                         The token representing the current field definition.
6347
                     */
6348
                    protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6349
                                                     Transformer<FieldDescription> transformer,
6350
                                                     @MaybeNull Object defaultValue,
6351
                                                     FieldDescription.Token token) {
1✔
6352
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
6353
                        this.token = token;
1✔
6354
                    }
1✔
6355

6356
                    /**
6357
                     * {@inheritDoc}
6358
                     */
6359
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
6360
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, new FieldDescription.Token(token.getName(),
1✔
6361
                                token.getModifiers(),
1✔
6362
                                token.getType(),
1✔
6363
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6364
                    }
6365

6366
                    @Override
6367
                    protected Builder<U> materialize() {
6368
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
1✔
6369
                                fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
6370
                                methodRegistry,
6371
                                recordComponentRegistry,
6372
                                typeAttributeAppender,
6373
                                asmVisitorWrapper,
6374
                                classFileVersion,
6375
                                auxiliaryTypeNamingStrategy,
6376
                                annotationValueFilterFactory,
6377
                                annotationRetention,
6378
                                implementationContextFactory,
6379
                                methodGraphCompiler,
6380
                                typeValidation,
6381
                                visibilityBridgeStrategy,
6382
                                classReaderFactory,
6383
                                classWriterFactory,
6384
                                ignoredMethods,
6385
                                auxiliaryTypes);
6386
                    }
6387

6388
                    @Override
6389
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6390
                                                      Transformer<FieldDescription> transformer,
6391
                                                      @MaybeNull Object defaultValue) {
6392
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
1✔
6393
                    }
6394
                }
6395

6396
                /**
6397
                 * An adapter for matching an existing field.
6398
                 */
6399
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6400
                protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
6401

6402
                    /**
6403
                     * The matcher for any fields to apply this matcher to.
6404
                     */
6405
                    private final LatentMatcher<? super FieldDescription> matcher;
6406

6407
                    /**
6408
                     * Creates a new field match adapter.
6409
                     *
6410
                     * @param matcher The matcher for any fields to apply this matcher to.
6411
                     */
6412
                    protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
6413
                        this(FieldAttributeAppender.NoOp.INSTANCE,
1✔
6414
                                Transformer.NoOp.<FieldDescription>make(),
1✔
6415
                                FieldDescription.NO_DEFAULT_VALUE,
6416
                                matcher);
6417
                    }
1✔
6418

6419
                    /**
6420
                     * Creates a new field match adapter.
6421
                     *
6422
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
6423
                     * @param transformer                   The field transformer to apply.
6424
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
6425
                     * @param matcher                       The matcher for any fields to apply this matcher to.
6426
                     */
6427
                    protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6428
                                                Transformer<FieldDescription> transformer,
6429
                                                @MaybeNull Object defaultValue,
6430
                                                LatentMatcher<? super FieldDescription> matcher) {
1✔
6431
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
6432
                        this.matcher = matcher;
1✔
6433
                    }
1✔
6434

6435
                    /**
6436
                     * {@inheritDoc}
6437
                     */
6438
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
6439
                        return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
1✔
6440
                    }
6441

6442
                    @Override
6443
                    protected Builder<U> materialize() {
6444
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
6445
                                fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
6446
                                methodRegistry,
6447
                                recordComponentRegistry,
6448
                                typeAttributeAppender,
6449
                                asmVisitorWrapper,
6450
                                classFileVersion,
6451
                                auxiliaryTypeNamingStrategy,
6452
                                annotationValueFilterFactory,
6453
                                annotationRetention,
6454
                                implementationContextFactory,
6455
                                methodGraphCompiler,
6456
                                typeValidation,
6457
                                visibilityBridgeStrategy,
6458
                                classReaderFactory,
6459
                                classWriterFactory,
6460
                                ignoredMethods,
6461
                                auxiliaryTypes);
6462
                    }
6463

6464
                    @Override
6465
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6466
                                                      Transformer<FieldDescription> transformer,
6467
                                                      @MaybeNull Object defaultValue) {
6468
                        return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
1✔
6469
                    }
6470
                }
6471

6472
                /**
6473
                 * An adapter for defining a new method.
6474
                 */
6475
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6476
                protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
6477

6478
                    /**
6479
                     * A token representing the currently defined method.
6480
                     */
6481
                    private final MethodDescription.Token token;
6482

6483
                    /**
6484
                     * Creates a new method definition adapter.
6485
                     *
6486
                     * @param token A token representing the currently defined method.
6487
                     */
6488
                    protected MethodDefinitionAdapter(MethodDescription.Token token) {
1✔
6489
                        this.token = token;
1✔
6490
                    }
1✔
6491

6492
                    /**
6493
                     * {@inheritDoc}
6494
                     */
6495
                    public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
6496
                        return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
1✔
6497
                    }
6498

6499
                    /**
6500
                     * {@inheritDoc}
6501
                     */
6502
                    public Simple.Annotatable<U> withParameter(TypeDefinition type) {
6503
                        return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
1✔
6504
                    }
6505

6506
                    /**
6507
                     * {@inheritDoc}
6508
                     */
6509
                    public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
6510
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6511
                                token.getModifiers(),
1✔
6512
                                token.getTypeVariableTokens(),
1✔
6513
                                token.getReturnType(),
1✔
6514
                                token.getParameterTokens(),
1✔
6515
                                CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
1✔
6516
                                token.getAnnotations(),
1✔
6517
                                token.getDefaultValue(),
1✔
6518
                                token.getReceiverType()));
1✔
6519
                    }
6520

6521
                    /**
6522
                     * {@inheritDoc}
6523
                     */
6524
                    public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
6525
                        return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
6526
                    }
6527

6528
                    /**
6529
                     * {@inheritDoc}
6530
                     */
6531
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
6532
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
6533
                    }
6534

6535
                    /**
6536
                     * {@inheritDoc}
6537
                     */
6538
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
6539
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6540
                                (token.getModifiers() & Opcodes.ACC_NATIVE) == 0
1✔
6541
                                        ? ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers())
1✔
6542
                                        : token.getModifiers(),
1✔
6543
                                token.getTypeVariableTokens(),
1✔
6544
                                token.getReturnType(),
1✔
6545
                                token.getParameterTokens(),
1✔
6546
                                token.getExceptionTypes(),
1✔
6547
                                token.getAnnotations(),
1✔
6548
                                token.getDefaultValue(),
1✔
6549
                                token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
6550
                    }
6551

6552
                    /**
6553
                     * {@inheritDoc}
6554
                     */
6555
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
6556
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6557
                                ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
1✔
6558
                                token.getTypeVariableTokens(),
1✔
6559
                                token.getReturnType(),
1✔
6560
                                token.getParameterTokens(),
1✔
6561
                                token.getExceptionTypes(),
1✔
6562
                                token.getAnnotations(),
1✔
6563
                                annotationValue,
6564
                                token.getReceiverType())).materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
6565
                    }
6566

6567
                    /**
6568
                     * Materializes the given handler as the implementation.
6569
                     *
6570
                     * @param handler The handler for implementing the method.
6571
                     * @return A method definition for the given handler.
6572
                     */
6573
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
6574
                        return new AnnotationAdapter(handler);
1✔
6575
                    }
6576

6577
                    /**
6578
                     * An adapter for defining a new type variable for the currently defined method.
6579
                     */
6580
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6581
                    protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
6582

6583
                        /**
6584
                         * The currently defined type variable.
6585
                         */
6586
                        private final TypeVariableToken token;
6587

6588
                        /**
6589
                         * Creates a new type variable annotation adapter.
6590
                         *
6591
                         * @param token The currently defined type variable.
6592
                         */
6593
                        protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
1✔
6594
                            this.token = token;
1✔
6595
                        }
1✔
6596

6597
                        @Override
6598
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
6599
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6600
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6601
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getTypeVariableTokens(), token),
1✔
6602
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6603
                                    MethodDefinitionAdapter.this.token.getParameterTokens(),
1✔
6604
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6605
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6606
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6607
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6608
                        }
6609

6610
                        /**
6611
                         * {@inheritDoc}
6612
                         */
6613
                        public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
6614
                            return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
1✔
6615
                                    token.getBounds(),
1✔
6616
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6617
                        }
6618
                    }
6619

6620
                    /**
6621
                     * An annotation adapter for a parameter definition.
6622
                     */
6623
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6624
                    protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
6625

6626
                        /**
6627
                         * The token of the currently defined parameter.
6628
                         */
6629
                        private final ParameterDescription.Token token;
6630

6631
                        /**
6632
                         * Creates a new parameter annotation adapter.
6633
                         *
6634
                         * @param token The token of the currently defined parameter.
6635
                         */
6636
                        protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
6637
                            this.token = token;
1✔
6638
                        }
1✔
6639

6640
                        /**
6641
                         * {@inheritDoc}
6642
                         */
6643
                        public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
UNCOV
6644
                            return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
×
UNCOV
6645
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
UNCOV
6646
                                    token.getName(),
×
UNCOV
6647
                                    token.getModifiers()));
×
6648
                        }
6649

6650
                        @Override
6651
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
6652
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6653
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6654
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
6655
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6656
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
6657
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6658
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6659
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6660
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6661
                        }
6662
                    }
6663

6664
                    /**
6665
                     * An annotation adapter for a simple parameter definition.
6666
                     */
6667
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6668
                    protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
6669

6670
                        /**
6671
                         * The token of the currently defined parameter.
6672
                         */
6673
                        private final ParameterDescription.Token token;
6674

6675
                        /**
6676
                         * Creates a new simple parameter annotation adapter.
6677
                         *
6678
                         * @param token The token of the currently defined parameter.
6679
                         */
6680
                        protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
6681
                            this.token = token;
1✔
6682
                        }
1✔
6683

6684
                        /**
6685
                         * {@inheritDoc}
6686
                         */
6687
                        public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
6688
                            return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
1✔
6689
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
6690
                                    token.getName(),
1✔
6691
                                    token.getModifiers()));
1✔
6692
                        }
6693

6694
                        @Override
6695
                        protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
6696
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6697
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6698
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
6699
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6700
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
6701
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6702
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6703
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6704
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6705
                        }
6706
                    }
6707

6708
                    /**
6709
                     * An annotation adapter for a method definition.
6710
                     */
6711
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6712
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
6713

6714
                        /**
6715
                         * Creates a new annotation adapter.
6716
                         *
6717
                         * @param handler The handler that determines how a method is implemented.
6718
                         */
6719
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
6720
                            this(handler,
1✔
6721
                                    MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER,
6722
                                    Transformer.NoOp.<MethodDescription>make());
1✔
6723
                        }
1✔
6724

6725
                        /**
6726
                         * Creates a new annotation adapter.
6727
                         *
6728
                         * @param handler                        The handler that determines how a method is implemented.
6729
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
6730
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
6731
                         */
6732
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
6733
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6734
                                                    Transformer<MethodDescription> transformer) {
1✔
6735
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
6736
                        }
1✔
6737

6738
                        /**
6739
                         * {@inheritDoc}
6740
                         */
6741
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
6742
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6743
                                    token.getModifiers(),
1✔
6744
                                    token.getTypeVariableTokens(),
1✔
6745
                                    token.getReturnType(),
1✔
6746
                                    token.getParameterTokens(),
1✔
6747
                                    token.getExceptionTypes(),
1✔
6748
                                    token.getAnnotations(),
1✔
6749
                                    token.getDefaultValue(),
1✔
6750
                                    receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
6751
                        }
6752

6753
                        /**
6754
                         * {@inheritDoc}
6755
                         */
6756
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
6757
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6758
                                    token.getModifiers(),
1✔
6759
                                    token.getTypeVariableTokens(),
1✔
6760
                                    token.getReturnType(),
1✔
6761
                                    token.getParameterTokens(),
1✔
6762
                                    token.getExceptionTypes(),
1✔
6763
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
6764
                                    token.getDefaultValue(),
1✔
6765
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
6766
                        }
6767

6768
                        /**
6769
                         * {@inheritDoc}
6770
                         */
6771
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
UNCOV
6772
                            List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
×
UNCOV
6773
                            parameterTokens.set(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
×
UNCOV
6774
                                    CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
UNCOV
6775
                                    token.getParameterTokens().get(index).getName(),
×
UNCOV
6776
                                    token.getParameterTokens().get(index).getModifiers()));
×
UNCOV
6777
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
×
UNCOV
6778
                                    token.getModifiers(),
×
UNCOV
6779
                                    token.getTypeVariableTokens(),
×
UNCOV
6780
                                    token.getReturnType(),
×
6781
                                    parameterTokens,
UNCOV
6782
                                    token.getExceptionTypes(),
×
UNCOV
6783
                                    token.getAnnotations(),
×
UNCOV
6784
                                    token.getDefaultValue(),
×
UNCOV
6785
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
6786
                        }
6787

6788
                        @Override
6789
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
6790
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6791
                                                                  Transformer<MethodDescription> transformer) {
UNCOV
6792
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
6793
                        }
6794

6795
                        @Override
6796
                        protected Builder<U> materialize() {
6797
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
1✔
6798
                                    fieldRegistry,
6799
                                    methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
1✔
6800
                                            handler,
6801
                                            methodAttributeAppenderFactory,
6802
                                            transformer),
6803
                                    recordComponentRegistry,
6804
                                    typeAttributeAppender,
6805
                                    asmVisitorWrapper,
6806
                                    classFileVersion,
6807
                                    auxiliaryTypeNamingStrategy,
6808
                                    annotationValueFilterFactory,
6809
                                    annotationRetention,
6810
                                    implementationContextFactory,
6811
                                    methodGraphCompiler,
6812
                                    typeValidation,
6813
                                    visibilityBridgeStrategy,
6814
                                    classReaderFactory,
6815
                                    classWriterFactory,
6816
                                    ignoredMethods,
6817
                                    auxiliaryTypes);
6818
                        }
6819
                    }
6820
                }
6821

6822
                /**
6823
                 * An adapter for matching an existing method.
6824
                 */
6825
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6826
                protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
6827

6828
                    /**
6829
                     * The method matcher of this adapter.
6830
                     */
6831
                    private final LatentMatcher<? super MethodDescription> matcher;
6832

6833
                    /**
6834
                     * Creates a new method match adapter.
6835
                     *
6836
                     * @param matcher The method matcher of this adapter.
6837
                     */
6838
                    protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
1✔
6839
                        this.matcher = matcher;
1✔
6840
                    }
1✔
6841

6842
                    /**
6843
                     * {@inheritDoc}
6844
                     */
6845
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
6846
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
6847
                    }
6848

6849
                    /**
6850
                     * {@inheritDoc}
6851
                     */
6852
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
6853
                        return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
6854
                    }
6855

6856
                    /**
6857
                     * {@inheritDoc}
6858
                     */
6859
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
6860
                        return materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
6861
                    }
6862

6863
                    /**
6864
                     * Materializes the method definition with the supplied handler.
6865
                     *
6866
                     * @param handler The handler that implements any method matched by this instances matcher.
6867
                     * @return A method definition where any matched method is implemented by the supplied handler.
6868
                     */
6869
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
6870
                        return new AnnotationAdapter(handler);
1✔
6871
                    }
6872

6873
                    /**
6874
                     * An annotation adapter for implementing annotations during a method definition.
6875
                     */
6876
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6877
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
6878

6879
                        /**
6880
                         * Creates a new annotation adapter.
6881
                         *
6882
                         * @param handler The handler that determines how a method is implemented.
6883
                         */
6884
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
6885
                            this(handler, MethodAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<MethodDescription>make());
1✔
6886
                        }
1✔
6887

6888
                        /**
6889
                         * Creates a new annotation adapter.
6890
                         *
6891
                         * @param handler                        The handler that determines how a method is implemented.
6892
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
6893
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
6894
                         */
6895
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
6896
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6897
                                                    Transformer<MethodDescription> transformer) {
1✔
6898
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
6899
                        }
1✔
6900

6901
                        /**
6902
                         * {@inheritDoc}
6903
                         */
6904
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
6905
                            return new AnnotationAdapter(handler,
1✔
6906
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
6907
                                    transformer);
6908
                        }
6909

6910
                        /**
6911
                         * {@inheritDoc}
6912
                         */
6913
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
6914
                            return new AnnotationAdapter(handler,
1✔
6915
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
6916
                                    transformer);
6917
                        }
6918

6919
                        /**
6920
                         * {@inheritDoc}
6921
                         */
6922
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
UNCOV
6923
                            return new AnnotationAdapter(handler,
×
6924
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
6925
                                    transformer);
6926
                        }
6927

6928
                        @Override
6929
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
6930
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6931
                                                                  Transformer<MethodDescription> transformer) {
6932
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
6933
                        }
6934

6935
                        @Override
6936
                        protected Builder<U> materialize() {
6937
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
6938
                                    fieldRegistry,
6939
                                    methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, transformer),
1✔
6940
                                    recordComponentRegistry,
6941
                                    typeAttributeAppender,
6942
                                    asmVisitorWrapper,
6943
                                    classFileVersion,
6944
                                    auxiliaryTypeNamingStrategy,
6945
                                    annotationValueFilterFactory,
6946
                                    annotationRetention,
6947
                                    implementationContextFactory,
6948
                                    methodGraphCompiler,
6949
                                    typeValidation,
6950
                                    visibilityBridgeStrategy,
6951
                                    classReaderFactory,
6952
                                    classWriterFactory,
6953
                                    ignoredMethods,
6954
                                    auxiliaryTypes);
6955
                        }
6956
                    }
6957
                }
6958

6959
                /**
6960
                 * An adapter for optionally matching methods defined by declared interfaces.
6961
                 */
6962
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6963
                protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
6964

6965
                    /**
6966
                     * The interfaces whose methods are optionally matched.
6967
                     */
6968
                    private final TypeList.Generic interfaces;
6969

6970
                    /**
6971
                     * Creates a new optional method match adapter.
6972
                     *
6973
                     * @param interfaces The interfaces whose methods are optionally matched.
6974
                     */
6975
                    protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
1✔
6976
                        this.interfaces = interfaces;
1✔
6977
                    }
1✔
6978

6979
                    @Override
6980
                    protected Builder<U> materialize() {
6981
                        return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
1✔
6982
                                fieldRegistry,
6983
                                methodRegistry,
6984
                                recordComponentRegistry,
6985
                                typeAttributeAppender,
6986
                                asmVisitorWrapper,
6987
                                classFileVersion,
6988
                                auxiliaryTypeNamingStrategy,
6989
                                annotationValueFilterFactory,
6990
                                annotationRetention,
6991
                                implementationContextFactory,
6992
                                methodGraphCompiler,
6993
                                typeValidation,
6994
                                visibilityBridgeStrategy,
6995
                                classReaderFactory,
6996
                                classWriterFactory,
6997
                                ignoredMethods,
6998
                                auxiliaryTypes);
6999
                    }
7000

7001
                    /**
7002
                     * {@inheritDoc}
7003
                     */
7004
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
7005
                        return interfaceType().intercept(implementation);
1✔
7006
                    }
7007

7008
                    /**
7009
                     * {@inheritDoc}
7010
                     */
7011
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
UNCOV
7012
                        return interfaceType().withoutCode();
×
7013
                    }
7014

7015
                    /**
7016
                     * {@inheritDoc}
7017
                     */
7018
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
UNCOV
7019
                        return interfaceType().defaultValue(annotationValue);
×
7020
                    }
7021

7022
                    /**
7023
                     * {@inheritDoc}
7024
                     */
7025
                    public <V> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(V value, Class<? extends V> type) {
UNCOV
7026
                        return interfaceType().defaultValue(value, type);
×
7027
                    }
7028

7029
                    /**
7030
                     * Returns a matcher for the interfaces' methods.
7031
                     *
7032
                     * @return A matcher for the interfaces' methods.
7033
                     */
7034
                    private MethodDefinition.ImplementationDefinition<U> interfaceType() {
7035
                        ElementMatcher.Junction<TypeDescription> elementMatcher = none();
1✔
7036
                        for (TypeDescription typeDescription : interfaces.asErasures()) {
1✔
7037
                            elementMatcher = elementMatcher.or(isSuperTypeOf(typeDescription));
1✔
7038
                        }
1✔
7039
                        return materialize().invokable(isDeclaredBy(isInterface().and(elementMatcher)));
1✔
7040
                    }
7041
                }
7042

7043
                /**
7044
                 * An adapter for defining a record component.
7045
                 */
7046
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
7047
                protected class RecordComponentDefinitionAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
7048

7049
                    /**
7050
                     * The record component attribute appender factory to apply.
7051
                     */
7052
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
7053

7054
                    /**
7055
                     * A token representing the defined record component.
7056
                     */
7057
                    private final RecordComponentDescription.Token token;
7058

7059
                    /**
7060
                     * A transformer to apply on matched record component descriptions.
7061
                     */
7062
                    private final Transformer<RecordComponentDescription> transformer;
7063

7064
                    /**
7065
                     * Creates a new record component definition adapter.
7066
                     *
7067
                     * @param token A token representing the defined record component.
7068
                     */
7069
                    protected RecordComponentDefinitionAdapter(RecordComponentDescription.Token token) {
UNCOV
7070
                        this(RecordComponentAttributeAppender.ForInstrumentedRecordComponent.INSTANCE,
×
UNCOV
7071
                                Transformer.NoOp.<RecordComponentDescription>make(),
×
7072
                                token);
UNCOV
7073
                    }
×
7074

7075
                    /**
7076
                     * Creates a new record component definition adapter.
7077
                     *
7078
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
7079
                     * @param transformer                             A transformer to apply on matched record component descriptions.
7080
                     * @param token                                   A token representing the defined record component.
7081
                     */
7082
                    protected RecordComponentDefinitionAdapter(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
7083
                                                               Transformer<RecordComponentDescription> transformer,
UNCOV
7084
                                                               RecordComponentDescription.Token token) {
×
7085
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
UNCOV
7086
                        this.transformer = transformer;
×
UNCOV
7087
                        this.token = token;
×
7088
                    }
×
7089

7090
                    /**
7091
                     * {@inheritDoc}
7092
                     */
7093
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
UNCOV
7094
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory, transformer, new RecordComponentDescription.Token(token.getName(),
×
UNCOV
7095
                                token.getType(),
×
UNCOV
7096
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
×
7097
                    }
7098

7099
                    /**
7100
                     * {@inheritDoc}
7101
                     */
7102
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
UNCOV
7103
                        return new RecordComponentDefinitionAdapter(new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
7104
                                recordComponentAttributeAppenderFactory), transformer, token);
7105
                    }
7106

7107
                    /**
7108
                     * {@inheritDoc}
7109
                     */
7110
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
7111
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
UNCOV
7112
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory,
×
7113
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer),
7114
                                token);
7115
                    }
7116

7117
                    @Override
7118
                    protected Builder<U> materialize() {
UNCOV
7119
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withRecordComponent(token),
×
7120
                                fieldRegistry,
7121
                                methodRegistry,
UNCOV
7122
                                recordComponentRegistry.prepend(new LatentMatcher.ForRecordComponentToken(token),
×
7123
                                        recordComponentAttributeAppenderFactory,
7124
                                        transformer),
7125
                                typeAttributeAppender,
7126
                                asmVisitorWrapper,
7127
                                classFileVersion,
7128
                                auxiliaryTypeNamingStrategy,
7129
                                annotationValueFilterFactory,
7130
                                annotationRetention,
7131
                                implementationContextFactory,
7132
                                methodGraphCompiler,
7133
                                typeValidation,
7134
                                visibilityBridgeStrategy,
7135
                                classReaderFactory,
7136
                                classWriterFactory,
7137
                                ignoredMethods,
7138
                                auxiliaryTypes);
7139
                    }
7140
                }
7141

7142
                /**
7143
                 * An adapter for matching record components.
7144
                 */
7145
                protected class RecordComponentMatchAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
7146

7147
                    /**
7148
                     * The matcher for identifying record components to match.
7149
                     */
7150
                    private final LatentMatcher<? super RecordComponentDescription> matcher;
7151

7152
                    /**
7153
                     * The record component attribute appender factory to apply.
7154
                     */
7155
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
7156

7157
                    /**
7158
                     * A transformer to apply on matched record component descriptions.
7159
                     */
7160
                    private final Transformer<RecordComponentDescription> transformer;
7161

7162
                    /**
7163
                     * Creates a new record component match adapter.
7164
                     *
7165
                     * @param matcher The matcher for identifying record components to match.
7166
                     */
7167
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher) {
UNCOV
7168
                        this(matcher, RecordComponentAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<RecordComponentDescription>make());
×
UNCOV
7169
                    }
×
7170

7171
                    /**
7172
                     * Creates a new record component match adapter.
7173
                     *
7174
                     * @param matcher                                 The matcher for identifying record components to match.
7175
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
7176
                     * @param transformer                             A transformer to apply on matched record component descriptions.
7177
                     */
7178
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher,
7179
                                                          RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
UNCOV
7180
                                                          Transformer<RecordComponentDescription> transformer) {
×
UNCOV
7181
                        this.matcher = matcher;
×
7182
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
UNCOV
7183
                        this.transformer = transformer;
×
UNCOV
7184
                    }
×
7185

7186
                    /**
7187
                     * {@inheritDoc}
7188
                     */
7189
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
UNCOV
7190
                        return attribute(new RecordComponentAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
×
7191
                    }
7192

7193
                    /**
7194
                     * {@inheritDoc}
7195
                     */
7196
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
UNCOV
7197
                        return new RecordComponentMatchAdapter(matcher, new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
7198
                                recordComponentAttributeAppenderFactory), transformer);
7199
                    }
7200

7201
                    /**
7202
                     * {@inheritDoc}
7203
                     */
7204
                    @SuppressWarnings("unchecked")  // In absence of @SafeVarargs
7205
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
UNCOV
7206
                        return new RecordComponentMatchAdapter(matcher,
×
7207
                                recordComponentAttributeAppenderFactory,
7208
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer));
7209
                    }
7210

7211
                    @Override
7212
                    protected Builder<U> materialize() {
UNCOV
7213
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
×
7214
                                fieldRegistry,
7215
                                methodRegistry,
UNCOV
7216
                                recordComponentRegistry.prepend(matcher, recordComponentAttributeAppenderFactory, transformer),
×
7217
                                typeAttributeAppender,
7218
                                asmVisitorWrapper,
7219
                                classFileVersion,
7220
                                auxiliaryTypeNamingStrategy,
7221
                                annotationValueFilterFactory,
7222
                                annotationRetention,
7223
                                implementationContextFactory,
7224
                                methodGraphCompiler,
7225
                                typeValidation,
7226
                                visibilityBridgeStrategy,
7227
                                classReaderFactory,
7228
                                classWriterFactory,
7229
                                ignoredMethods,
7230
                                auxiliaryTypes);
7231
                    }
7232
                }
7233
            }
7234
        }
7235
    }
7236

7237
    /**
7238
     * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
7239
     *
7240
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7241
     *            type itself, an interface or the direct super class.
7242
     */
7243
    interface Unloaded<T> extends DynamicType {
7244

7245
        /**
7246
         * <p>
7247
         * Attempts to load this dynamic type including all of its auxiliary types, if any. If the class loader is an
7248
         * unsealed instance of {@link InjectionClassLoader}, the classes are injected directy into the class loader, otherwise,
7249
         * a new class loader is created where the supplied class loader is set as parent.
7250
         * </p>
7251
         * <p>
7252
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
7253
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
7254
         * </p>
7255
         *
7256
         * @param classLoader The class loader to use for this class loading or {@code null} for using the boot loader.
7257
         * @return This dynamic type in its loaded state.
7258
         */
7259
        Loaded<T> load(@MaybeNull ClassLoader classLoader);
7260

7261
        /**
7262
         * <p>
7263
         * Attempts to load this dynamic type including all of its auxiliary types, if any.
7264
         * </p>
7265
         * <p>
7266
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
7267
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
7268
         * </p>
7269
         *
7270
         * @param classLoader          The class loader to use for this class loading.
7271
         * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
7272
         * @param <S>                  The least specific type of class loader this strategy can apply to.
7273
         * @return This dynamic type in its loaded state.
7274
         * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
7275
         */
7276
        <S extends ClassLoader> Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
7277

7278
        /**
7279
         * Includes the provided dynamic types as auxiliary types of this instance.
7280
         *
7281
         * @param dynamicType The dynamic types to include.
7282
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
7283
         */
7284
        Unloaded<T> include(DynamicType... dynamicType);
7285

7286
        /**
7287
         * Includes the provided dynamic types as auxiliary types of this instance.
7288
         *
7289
         * @param dynamicTypes The dynamic types to include.
7290
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
7291
         */
7292
        Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
7293
    }
7294

7295
    /**
7296
     * A dynamic type that has been loaded into the running instance of the Java virtual machine.
7297
     *
7298
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7299
     *            type itself, an interface or the direct super class.
7300
     */
7301
    interface Loaded<T> extends DynamicType {
7302

7303
        /**
7304
         * Returns the loaded main class.
7305
         *
7306
         * @return A loaded class representation of this dynamic type.
7307
         */
7308
        Class<? extends T> getLoaded();
7309

7310
        /**
7311
         * <p>
7312
         * Returns a map of all loaded auxiliary types to this dynamic type.
7313
         * </p>
7314
         * <p>
7315
         * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
7316
         * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
7317
         * </p>
7318
         *
7319
         * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
7320
         */
7321
        Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
7322

7323
        /**
7324
         * Returns all loaded types that are implied by this dynamic type.
7325
         *
7326
         * @return All loaded types that are implied by this dynamic type.
7327
         */
7328
        Map<TypeDescription, Class<?>> getAllLoaded();
7329
    }
7330

7331
    @HashCodeAndEqualsPlugin.Enhance
7332
    abstract class AbstractBase implements DynamicType {
1✔
7333

7334
        /**
7335
         * The default version of a jar file manifest.
7336
         */
7337
        private static final String MANIFEST_VERSION = "1.0";
7338

7339
        /**
7340
         * A suffix for temporary files.
7341
         */
7342
        private static final String TEMP_SUFFIX = "tmp";
7343

7344
        /**
7345
         * {@inheritDoc}
7346
         */
7347
        public Resolution locate(String name) throws IOException {
7348
            if (getTypeDescription().getName().equals(name)) {
1✔
7349
                return new Resolution.Explicit(getBytes());
1✔
7350
            }
7351
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7352
                Resolution resolution = auxiliaryType.locate(name);
1✔
7353
                if (resolution.isResolved()) {
1✔
7354
                    return resolution;
1✔
7355
                }
7356
            }
1✔
7357
            return new Resolution.Illegal(name);
1✔
7358
        }
7359

7360
        /**
7361
         * {@inheritDoc}
7362
         */
7363
        public void close() {
7364
            /* do nothing */
UNCOV
7365
        }
×
7366

7367
        /**
7368
         * {@inheritDoc}
7369
         */
7370
        public Set<TypeDescription> getAuxiliaryTypeDescriptions() {
7371
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
7372
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7373
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
7374
            }
1✔
7375
            return types;
1✔
7376
        }
7377

7378
        /**
7379
         * {@inheritDoc}
7380
         */
7381
        public Set<TypeDescription> getAllTypeDescriptions() {
7382
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
7383
            types.add(getTypeDescription());
1✔
7384
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7385
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
7386
            }
1✔
7387
            return types;
1✔
7388
        }
7389

7390
        /**
7391
         * {@inheritDoc}
7392
         */
7393
        public Map<TypeDescription, byte[]> getAllTypes() {
7394
            Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
1✔
7395
            allTypes.put(getTypeDescription(), getBytes());
1✔
7396
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7397
                allTypes.putAll(auxiliaryType.getAllTypes());
1✔
7398
            }
1✔
7399
            return allTypes;
1✔
7400
        }
7401

7402
        /**
7403
         * {@inheritDoc}
7404
         */
7405
        public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
7406
            Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
1✔
7407
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7408
                classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
1✔
7409
            }
1✔
7410
            classLoadingCallbacks.put(getTypeDescription(), getLoadedTypeInitializer());
1✔
7411
            return classLoadingCallbacks;
1✔
7412
        }
7413

7414
        /**
7415
         * {@inheritDoc}
7416
         */
7417
        public boolean hasAliveLoadedTypeInitializers() {
7418
            if (getLoadedTypeInitializer().isAlive()) {
1✔
7419
                return true;
1✔
7420
            }
7421
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7422
                if (auxiliaryType.hasAliveLoadedTypeInitializers()) {
1✔
7423
                    return true;
1✔
7424
                }
7425
            }
1✔
7426
            return false;
1✔
7427
        }
7428

7429
        /**
7430
         * {@inheritDoc}
7431
         */
7432
        public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
7433
            Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
1✔
7434
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7435
                auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
1✔
7436
                auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
1✔
7437
            }
1✔
7438
            return auxiliaryTypes;
1✔
7439
        }
7440

7441
        /**
7442
         * {@inheritDoc}
7443
         */
7444
        public Map<TypeDescription, File> saveIn(File folder) throws IOException {
7445
            Map<TypeDescription, File> files = new HashMap<TypeDescription, File>();
1✔
7446
            File target = new File(folder, getTypeDescription().getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
1✔
7447
            if (target.getParentFile() != null && !target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
1✔
UNCOV
7448
                throw new IllegalArgumentException("Could not create directory: " + target.getParentFile());
×
7449
            }
7450
            OutputStream outputStream = new FileOutputStream(target);
1✔
7451
            try {
7452
                outputStream.write(getBytes());
1✔
7453
            } finally {
7454
                outputStream.close();
1✔
7455
            }
7456
            files.put(getTypeDescription(), target);
1✔
7457
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7458
                files.putAll(auxiliaryType.saveIn(folder));
1✔
7459
            }
1✔
7460
            return files;
1✔
7461
        }
7462

7463
        /**
7464
         * {@inheritDoc}
7465
         */
7466
        public File inject(File sourceJar, File targetJar) throws IOException {
7467
            return sourceJar.equals(targetJar)
1✔
7468
                    ? inject(sourceJar)
1✔
7469
                    : doInject(sourceJar, targetJar);
1✔
7470
        }
7471

7472
        /**
7473
         * {@inheritDoc}
7474
         */
7475
        public File inject(File jar) throws IOException {
7476
            FileSystem.getInstance().move(doInject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX)), jar);
1✔
7477
            return jar;
1✔
7478
        }
7479

7480
        /**
7481
         * Injects this dynamic type into a source jar and writes the result to the target jar.
7482
         *
7483
         * @param sourceJar The source jar.
7484
         * @param targetJar The target jar.
7485
         * @return The jar file that was written to.
7486
         * @throws IOException If an I/O error occurs.
7487
         */
7488
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
7489
        private File doInject(File sourceJar, File targetJar) throws IOException {
7490
            InputStream inputStream = new FileInputStream(sourceJar);
1✔
7491
            try {
7492
                JarInputStream jarInputStream = new JarInputStream(inputStream);
1✔
7493
                if (!targetJar.isFile() && !targetJar.createNewFile()) {
1✔
UNCOV
7494
                    throw new IllegalArgumentException("Could not create file: " + targetJar);
×
7495
                }
7496
                Manifest manifest = jarInputStream.getManifest();
1✔
7497
                OutputStream outputStream = new FileOutputStream(targetJar);
1✔
7498
                try {
7499
                    JarOutputStream jarOutputStream = manifest == null
1✔
7500
                            ? new JarOutputStream(outputStream)
7501
                            : new JarOutputStream(outputStream, manifest);
7502
                    Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
1✔
7503
                    Map<String, byte[]> files = new HashMap<String, byte[]>();
1✔
7504
                    for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
1✔
7505
                        files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
1✔
7506
                    }
1✔
7507
                    files.put(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION, getBytes());
1✔
7508
                    JarEntry jarEntry;
7509
                    while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
1✔
7510
                        byte[] replacement = files.remove(jarEntry.getName());
1✔
7511
                        if (replacement == null) {
1✔
7512
                            jarOutputStream.putNextEntry(jarEntry);
1✔
7513
                            byte[] buffer = new byte[1024];
1✔
7514
                            int index;
7515
                            while ((index = jarInputStream.read(buffer)) != -1) {
1✔
7516
                                jarOutputStream.write(buffer, 0, index);
1✔
7517
                            }
7518
                        } else {
1✔
7519
                            jarOutputStream.putNextEntry(new JarEntry(jarEntry.getName()));
1✔
7520
                            jarOutputStream.write(replacement);
1✔
7521
                        }
7522
                        jarInputStream.closeEntry();
1✔
7523
                        jarOutputStream.closeEntry();
1✔
7524
                    }
1✔
7525
                    for (Map.Entry<String, byte[]> entry : files.entrySet()) {
1✔
7526
                        jarOutputStream.putNextEntry(new JarEntry(entry.getKey()));
1✔
7527
                        jarOutputStream.write(entry.getValue());
1✔
7528
                        jarOutputStream.closeEntry();
1✔
7529
                    }
1✔
7530
                    jarOutputStream.close();
1✔
7531
                } finally {
7532
                    outputStream.close();
1✔
7533
                }
7534
                jarInputStream.close();
1✔
7535
            } finally {
7536
                inputStream.close();
1✔
7537
            }
7538
            return targetJar;
1✔
7539
        }
7540

7541
        /**
7542
         * {@inheritDoc}
7543
         */
7544
        public File toJar(File file) throws IOException {
7545
            Manifest manifest = new Manifest();
1✔
7546
            manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
1✔
7547
            return toJar(file, manifest);
1✔
7548
        }
7549

7550
        /**
7551
         * {@inheritDoc}
7552
         */
7553
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
7554
        public File toJar(File file, Manifest manifest) throws IOException {
7555
            if (!file.isFile() && !file.createNewFile()) {
1✔
UNCOV
7556
                throw new IllegalArgumentException("Could not create file: " + file);
×
7557
            }
7558
            OutputStream outputStream = new FileOutputStream(file);
1✔
7559
            try {
7560
                JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest);
1✔
7561
                for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
1✔
7562
                    jarOutputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
1✔
7563
                    jarOutputStream.write(entry.getValue());
1✔
7564
                    jarOutputStream.closeEntry();
1✔
7565
                }
1✔
7566
                jarOutputStream.putNextEntry(new JarEntry(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION));
1✔
7567
                jarOutputStream.write(getBytes());
1✔
7568
                jarOutputStream.closeEntry();
1✔
7569
                jarOutputStream.close();
1✔
7570
            } finally {
7571
                outputStream.close();
1✔
7572
            }
7573
            return file;
1✔
7574
        }
7575
    }
7576

7577
    /**
7578
     * A default implementation of a dynamic type.
7579
     */
7580
    @HashCodeAndEqualsPlugin.Enhance
7581
    class Default extends AbstractBase {
7582

7583
        /**
7584
         * A type description of this dynamic type.
7585
         */
7586
        protected final TypeDescription typeDescription;
7587

7588
        /**
7589
         * The byte array representing this dynamic type.
7590
         */
7591
        protected final byte[] binaryRepresentation;
7592

7593
        /**
7594
         * The loaded type initializer for this dynamic type.
7595
         */
7596
        protected final LoadedTypeInitializer loadedTypeInitializer;
7597

7598
        /**
7599
         * A list of auxiliary types for this dynamic type.
7600
         */
7601
        protected final List<? extends DynamicType> auxiliaryTypes;
7602

7603
        /**
7604
         * Creates a new dynamic type.
7605
         *
7606
         * @param typeDescription       A description of this dynamic type.
7607
         * @param binaryRepresentation  A byte array containing the binary representation of this dynamic type. The array must not be modified.
7608
         * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
7609
         * @param auxiliaryTypes        The auxiliary type required for this dynamic type.
7610
         */
7611
        @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not modified by class contract.")
7612
        public Default(TypeDescription typeDescription,
7613
                       byte[] binaryRepresentation,
7614
                       LoadedTypeInitializer loadedTypeInitializer,
7615
                       List<? extends DynamicType> auxiliaryTypes) {
1✔
7616
            this.typeDescription = typeDescription;
1✔
7617
            this.binaryRepresentation = binaryRepresentation;
1✔
7618
            this.loadedTypeInitializer = loadedTypeInitializer;
1✔
7619
            this.auxiliaryTypes = auxiliaryTypes;
1✔
7620
        }
1✔
7621

7622
        /**
7623
         * {@inheritDoc}
7624
         */
7625
        public TypeDescription getTypeDescription() {
7626
            return typeDescription;
1✔
7627
        }
7628

7629
        /**
7630
         * {@inheritDoc}
7631
         */
7632
        @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not modified by class contract.")
7633
        public byte[] getBytes() {
7634
            return binaryRepresentation;
1✔
7635
        }
7636

7637
        /**
7638
         * {@inheritDoc}
7639
         */
7640
        public LoadedTypeInitializer getLoadedTypeInitializer() {
7641
            return loadedTypeInitializer;
1✔
7642
        }
7643

7644
        /**
7645
         * {@inheritDoc}
7646
         */
7647
        public List<? extends DynamicType> getAuxiliaries() {
7648
            return auxiliaryTypes;
1✔
7649
        }
7650

7651
        /**
7652
         * A default implementation of an unloaded dynamic type.
7653
         *
7654
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7655
         *            type itself, an interface or the direct super class.
7656
         */
7657
        @HashCodeAndEqualsPlugin.Enhance
7658
        public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
7659

7660
            /**
7661
             * The type resolution strategy to use for initializing the dynamic type.
7662
             */
7663
            private final TypeResolutionStrategy.Resolved typeResolutionStrategy;
7664

7665
            /**
7666
             * Creates a new unloaded representation of a dynamic type.
7667
             *
7668
             * @param typeDescription        A description of this dynamic type.
7669
             * @param binaryRepresentation   An array of byte of the binary representation of this dynamic type.
7670
             * @param loadedTypeInitializer  The type initializer of this dynamic type.
7671
             * @param auxiliaryTypes         The auxiliary types that are required for this dynamic type.
7672
             * @param typeResolutionStrategy The type resolution strategy to use for initializing the dynamic type.
7673
             */
7674
            public Unloaded(TypeDescription typeDescription,
7675
                            byte[] binaryRepresentation,
7676
                            LoadedTypeInitializer loadedTypeInitializer,
7677
                            List<? extends DynamicType> auxiliaryTypes,
7678
                            TypeResolutionStrategy.Resolved typeResolutionStrategy) {
7679
                super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
1✔
7680
                this.typeResolutionStrategy = typeResolutionStrategy;
1✔
7681
            }
1✔
7682

7683
            /**
7684
             * {@inheritDoc}
7685
             */
7686
            public DynamicType.Loaded<T> load(@MaybeNull ClassLoader classLoader) {
7687
                if (classLoader instanceof InjectionClassLoader && !((InjectionClassLoader) classLoader).isSealed()) {
1✔
7688
                    return load((InjectionClassLoader) classLoader, InjectionClassLoader.Strategy.INSTANCE);
1✔
7689
                } else {
7690
                    return load(classLoader, ClassLoadingStrategy.Default.WRAPPER);
1✔
7691
                }
7692
            }
7693

7694
            /**
7695
             * {@inheritDoc}
7696
             */
7697
            public <S extends ClassLoader> DynamicType.Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
7698
                return new Default.Loaded<T>(typeDescription,
1✔
7699
                        binaryRepresentation,
7700
                        loadedTypeInitializer,
7701
                        auxiliaryTypes,
7702
                        typeResolutionStrategy.initialize(this, classLoader, classLoadingStrategy));
1✔
7703
            }
7704

7705
            /**
7706
             * {@inheritDoc}
7707
             */
7708
            public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
7709
                return include(Arrays.asList(dynamicType));
1✔
7710
            }
7711

7712
            /**
7713
             * {@inheritDoc}
7714
             */
7715
            public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
7716
                return new Default.Unloaded<T>(typeDescription,
1✔
7717
                        binaryRepresentation,
7718
                        loadedTypeInitializer,
7719
                        CompoundList.of(auxiliaryTypes, dynamicType),
1✔
7720
                        typeResolutionStrategy);
7721
            }
7722
        }
7723

7724
        /**
7725
         * A default implementation of a loaded dynamic type.
7726
         *
7727
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7728
         *            type itself, an interface or the direct super class.
7729
         */
7730
        @HashCodeAndEqualsPlugin.Enhance
7731
        protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
7732

7733
            /**
7734
             * The loaded types for the given loaded dynamic type.
7735
             */
7736
            private final Map<TypeDescription, Class<?>> loadedTypes;
7737

7738
            /**
7739
             * Creates a new representation of a loaded dynamic type.
7740
             *
7741
             * @param typeDescription       A description of this dynamic type.
7742
             * @param typeByte              An array of byte of the binary representation of this dynamic type.
7743
             * @param loadedTypeInitializer The type initializer of this dynamic type.
7744
             * @param auxiliaryTypes        The auxiliary types that are required for this dynamic type.
7745
             * @param loadedTypes           A map of loaded types for this dynamic type and all its auxiliary types.
7746
             */
7747
            protected Loaded(TypeDescription typeDescription,
7748
                             byte[] typeByte,
7749
                             LoadedTypeInitializer loadedTypeInitializer,
7750
                             List<? extends DynamicType> auxiliaryTypes,
7751
                             Map<TypeDescription, Class<?>> loadedTypes) {
7752
                super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
1✔
7753
                this.loadedTypes = loadedTypes;
1✔
7754
            }
1✔
7755

7756
            /**
7757
             * {@inheritDoc}
7758
             */
7759
            public Class<? extends T> getLoaded() {
7760
                @SuppressWarnings("unchecked")
7761
                Class<? extends T> type = (Class<? extends T>) loadedTypes.get(typeDescription);
1✔
7762
                if (type == null) {
1✔
UNCOV
7763
                    throw new IllegalStateException(typeDescription + " cannot be loaded explicitly");
×
7764
                }
7765
                return type;
1✔
7766
            }
7767

7768
            /**
7769
             * {@inheritDoc}
7770
             */
7771
            public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
7772
                Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
7773
                loadedAuxiliaryTypes.remove(typeDescription);
1✔
7774
                return loadedAuxiliaryTypes;
1✔
7775
            }
7776

7777
            /**
7778
             * {@inheritDoc}
7779
             */
7780
            public Map<TypeDescription, Class<?>> getAllLoaded() {
7781
                return new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
7782
            }
7783
        }
7784
    }
7785
}
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