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

raphw / byte-buddy / #818

07 Nov 2025 11:24AM UTC coverage: 83.01% (+0.05%) from 82.964%
#818

push

raphw
[release] Release new version.

29613 of 35674 relevant lines covered (83.01%)

0.83 hits per line

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

66.63
/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
         * @param modifierContributor The modifier contributors to merge into the module.
395
         * @return A new builder that is equal to this builder but which adjusts the current module information.
396
         */
397
        ModuleDefinition<T> adjustModule(ModifierContributor.ForModule... modifierContributor);
398

399
        /**
400
         * Adjusts a previous module definition in this class file. This is normally only meaningful for classes named {@code module-info}.
401
         *
402
         * @param modifierContributors The modifier contributors to merge into the module.
403
         * @return A new builder that is equal to this builder but which adjusts the current module information.
404
         */
405
        ModuleDefinition<T> adjustModule(Collection<? extends ModifierContributor.ForModule> modifierContributors);
406

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

706
        /**
707
         * <p>
708
         * Defines this type as a nest host for the supplied types.
709
         * </p>
710
         * <p>
711
         * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
712
         * </p>
713
         * <p>
714
         * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
715
         * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
716
         * consistent among the definitions of connected types.
717
         * </p>
718
         *
719
         * @param types The nest members.
720
         * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
721
         */
722
        Builder<T> nestMembers(Collection<? extends TypeDescription> types);
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(Class<?>... 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 type 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(TypeDescription... type);
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(List<? extends Class<?>> types);
750

751
        /**
752
         * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
753
         * this type was not previously sealed, only the supplied subclasses are permitted.
754
         *
755
         * @param types The permitted subclasses.
756
         * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
757
         */
758
        Builder<T> permittedSubclass(Collection<? extends TypeDescription> types);
759

760
        /**
761
         * Unseales this type.
762
         *
763
         * @return A new builder that is equal to this builder but where the built type does not restrain its permitted subclasses.
764
         */
765
        Builder<T> unsealed();
766

767
        /**
768
         * Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
769
         * any type of meta data to a type, not only Java {@link Annotation}s.
770
         *
771
         * @param typeAttributeAppender The type attribute appender to apply.
772
         * @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
773
         */
774
        Builder<T> attribute(TypeAttributeAppender typeAttributeAppender);
775

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

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

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

800
        /**
801
         * Annotates the instrumented type with the supplied annotations.
802
         *
803
         * @param annotations The annotations to add to the instrumented type.
804
         * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
805
         */
806
        Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
807

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

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

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

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

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

890
        /**
891
         * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
892
         * type initializers are supplied, each loaded type initializer is executed in its registration order.
893
         *
894
         * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
895
         * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
896
         * loading the instrumented type.
897
         */
898
        Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
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
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
906
         */
907
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation);
908

909
        /**
910
         * Explicitly requires another dynamic type for the creation of this type.
911
         *
912
         * @param type                 The type to require.
913
         * @param binaryRepresentation The type's binary representation.
914
         * @param typeInitializer      The type's loaded type initializer.
915
         * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
916
         */
917
        Builder<T> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
918

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

927
        /**
928
         * Explicitly requires other dynamic types for the creation of this type.
929
         *
930
         * @param auxiliaryTypes The required dynamic types.
931
         * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
932
         */
933
        Builder<T> require(Collection<DynamicType> auxiliaryTypes);
934

935
        /**
936
         * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
937
         *
938
         * @param symbol The type variable's symbol.
939
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
940
         */
941
        TypeVariableDefinition<T> typeVariable(String symbol);
942

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

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

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

973
        /**
974
         * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
975
         *
976
         * @param symbol The type variable's symbol.
977
         * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
978
         *               should be equal to the currently instrumented type.
979
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
980
         */
981
        TypeVariableDefinition<T> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
982

983
        /**
984
         * Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
985
         *
986
         * @param matcher     The matcher to decide what type variables to transform.
987
         * @param transformer The transformer to apply to the matched type variables.
988
         * @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
989
         */
990
        Builder<T> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer);
991

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

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

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

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

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

1052
        /**
1053
         * Defines the specified field as a field of the built dynamic type.
1054
         *
1055
         * @param name      The name of the field.
1056
         * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
1057
         *                  should be equal to the currently instrumented type.
1058
         * @param modifiers The modifiers of the field.
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> defineField(String name, TypeDefinition type, int modifiers);
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(Field field);
1072

1073
        /**
1074
         * Defines a field that is similar to the supplied field but without copying any annotations on the field.
1075
         *
1076
         * @param field The field to imitate as a field of the instrumented type.
1077
         * @return A new builder that is equal to this builder but with the given field 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.Valuable<T> define(FieldDescription field);
1081

1082
        /**
1083
         * Defines a private, static, final field for a serial version UID of the given value.
1084
         *
1085
         * @param serialVersionUid The serial version UID to define as a value.
1086
         * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
1087
         * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
1088
         */
1089
        FieldDefinition.Optional<T> serialVersionUid(long serialVersionUid);
1090

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

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

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

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

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

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

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

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

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

1232
        /**
1233
         * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1234
         * type variables can be defined in subsequent steps.
1235
         *
1236
         * @param name       The name of the method.
1237
         * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1238
         *                   should be equal to the currently instrumented type.
1239
         * @param modifiers  The method's modifiers.
1240
         * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1241
         */
1242
        MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, int modifiers);
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 modifierContributor 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(ModifierContributor.ForMethod... modifierContributor);
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 modifierContributors 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(Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1261

1262
        /**
1263
         * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1264
         * type variables can be defined in subsequent steps.
1265
         *
1266
         * @param modifiers The constructor's modifiers.
1267
         * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1268
         */
1269
        MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(int modifiers);
1270

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

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

1288
        /**
1289
         * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
1290
         * the method/constructor or method/constructor parameters.
1291
         *
1292
         * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
1293
         * @return A builder that allows for defining an implementation for the method or constructor.
1294
         */
1295
        MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
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
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1303
         */
1304
        FieldDefinition.Optional<T> defineProperty(String name, Type type);
1305

1306
        /**
1307
         * Defines a Java bean property with the specified name.
1308
         *
1309
         * @param name     The name of the property.
1310
         * @param type     The property type.
1311
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
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, Type type, boolean readOnly);
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
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1322
         */
1323
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type);
1324

1325
        /**
1326
         * Defines a Java bean property with the specified name.
1327
         *
1328
         * @param name     The name of the property.
1329
         * @param type     The property type.
1330
         * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1331
         * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1332
         */
1333
        FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type, boolean readOnly);
1334

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

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

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

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

1449
        /**
1450
         * Implements {@link Object#hashCode()} and {@link Object#equals(Object)} methods for the instrumented type if those
1451
         * methods are not declared as {@code final} by a super class. The implementations do not consider any implementations
1452
         * of a super class and compare a class field by field without considering synthetic fields.
1453
         *
1454
         * @return A new type builder that defines {@link Object#hashCode()} and {@link Object#equals(Object)} methods accordingly.
1455
         */
1456
        Builder<T> withHashCodeEquals();
1457

1458
        /**
1459
         * Implements a {@link Object#toString()} method for the instrumented type if such a method is not declared as {@code final}
1460
         * by a super class. The implementation prefixes the string with the simple class name and prints each non-synthetic field's
1461
         * value after the field's name.
1462
         *
1463
         * @return A new type builder that defines {@link Object#toString()} method accordingly.
1464
         */
1465
        Builder<T> withToString();
1466

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

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

1487
        /**
1488
         * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1489
         * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1490
         *
1491
         * @param recordComponentDescription A description of the record component to immitate.
1492
         * @return A new builder that is equal to this builder but also defines the supplied record component.
1493
         */
1494
        RecordComponentDefinition.Optional<T> define(RecordComponentDescription recordComponentDescription);
1495

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

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

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

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

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

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

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

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

1624
        /**
1625
         * <p>
1626
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1627
         * </p>
1628
         * <p>
1629
         * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1630
         * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1631
         * executing the initializer must rely on such an initializer.
1632
         * </p>
1633
         *
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(TypePool typePool);
1638

1639
        /**
1640
         * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1641
         *
1642
         * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1643
         * @param typePool               A type pool that is used for computing stack map frames by the underlying class writer, if required.
1644
         * @return An unloaded dynamic type representing the type specified by this builder.
1645
         */
1646
        DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool);
1647

1648
        /**
1649
         * Returns a {@link TypeDescription} for the currently built type.
1650
         *
1651
         * @return A {@link TypeDescription} for the currently built type.
1652
         */
1653
        TypeDescription toTypeDescription();
1654

1655
        /**
1656
         * A specification of a Java module.
1657
         *
1658
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1659
         */
1660
        interface ModuleDefinition<S> extends Builder<S> {
1661

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

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

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

1686
            /**
1687
             * Specifies the main class of the module being defined.
1688
             *
1689
             * @param name The name of the main class of the module or {@code null} if no main class is to be specified.
1690
             * @return A new builder that is equal to this builder but with the given main class specification.
1691
             */
1692
            ModuleDefinition<S> mainClass(@MaybeNull String name);
1693

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

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

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

1718
            /**
1719
             * Specifies the modules that are required by the module being defined.
1720
             *
1721
             * @param modules The names of the modules that are required.
1722
             * @return A new builder that is equal to this builder but with the given module requirements.
1723
             */
1724
            ModuleDefinition<S> requires(Collection<String> modules);
1725

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

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

1744
            /**
1745
             * Specifies a module requirement with explicit modifiers.
1746
             *
1747
             * @param module    The name of the module that is required.
1748
             * @param modifiers The modifiers to apply to the module requirement.
1749
             * @return A builder for defining the module requirement.
1750
             */
1751
            RequiresDefinition<S> require(String module, int modifiers);
1752

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

1761
            /**
1762
             * Specifies packages that are exported by the module being defined.
1763
             *
1764
             * @param packages The names of the packages to export.
1765
             * @return A new builder that is equal to this builder but with the given package exports.
1766
             */
1767
            ModuleDefinition<S> exports(Collection<String> packages);
1768

1769
            /**
1770
             * Specifies a package export with additional modifiers.
1771
             *
1772
             * @param aPackage            The name of the package to export.
1773
             * @param modifierContributor 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, ModifierContributor.ForModule.OfExport... modifierContributor);
1777

1778
            /**
1779
             * Specifies a package export with additional modifiers.
1780
             *
1781
             * @param aPackage             The name of the package to export.
1782
             * @param modifierContributors 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, Collection<? extends ModifierContributor.ForModule.OfExport> modifierContributors);
1786

1787
            /**
1788
             * Specifies a package export with explicit modifiers.
1789
             *
1790
             * @param aPackage  The name of the package to export.
1791
             * @param modifiers The modifiers to apply to the package export.
1792
             * @return A new builder that is equal to this builder but with the given package export.
1793
             */
1794
            ModuleDefinition<S> export(String aPackage, int modifiers);
1795

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

1804
            /**
1805
             * Specifies packages that are opened by the module being defined.
1806
             *
1807
             * @param packages The names of the packages to open.
1808
             * @return A new builder that is equal to this builder but with the given package openings.
1809
             */
1810
            ModuleDefinition<S> opens(Collection<String> packages);
1811

1812
            /**
1813
             * Specifies a package opening with additional modifiers.
1814
             *
1815
             * @param aPackage            The name of the package to open.
1816
             * @param modifierContributor 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, ModifierContributor.ForModule.OfOpen... modifierContributor);
1820

1821
            /**
1822
             * Specifies a package opening with additional modifiers.
1823
             *
1824
             * @param aPackage             The name of the package to open.
1825
             * @param modifierContributors 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, Collection<? extends ModifierContributor.ForModule.OfOpen> modifierContributors);
1829

1830
            /**
1831
             * Specifies a package opening with explicit modifiers.
1832
             *
1833
             * @param aPackage  The name of the package to open.
1834
             * @param modifiers The modifiers to apply to the package opening.
1835
             * @return A new builder that is equal to this builder but with the given package opening.
1836
             */
1837
            ModuleDefinition<S> open(String aPackage, int modifiers);
1838

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

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

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

1863
            /**
1864
             * Specifies services that are used by the module being defined.
1865
             *
1866
             * @param services The names of the types of the services to use.
1867
             * @return A new builder that is equal to this builder but with the given service uses.
1868
             */
1869
            ModuleDefinition<S> uses(Collection<String> services);
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 implementation 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, Class<?>... implementation);
1879

1880
            /**
1881
             * Specifies service implementations that are provided by the module being defined.
1882
             *
1883
             * @param service         The type of the service for which implementations are provided.
1884
             * @param implementations 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(Class<?> service, Collection<Class<?>> implementations);
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 implementation 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, TypeDescription... implementation);
1897

1898
            /**
1899
             * Specifies service implementations that are provided by the module being defined.
1900
             *
1901
             * @param service         The description of the type of the service for which implementations are provided.
1902
             * @param implementations The descriptions 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(TypeDescription service, Collection<TypeDescription> implementations);
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 implementation 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, String... implementation);
1915

1916
            /**
1917
             * Specifies service implementations that are provided by the module being defined.
1918
             *
1919
             * @param service         The name of the type of the service for which implementations are provided.
1920
             * @param implementations The names of the types of the implementations that are provided.
1921
             * @return A new builder that is equal to this builder but with the given service provision.
1922
             */
1923
            ModuleDefinition<S> provides(String service, Collection<String> implementations);
1924

1925
            /**
1926
             * A specification of a module requirement.
1927
             *
1928
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1929
             */
1930
            interface RequiresDefinition<U> extends ModuleDefinition<U> {
1931

1932
                /**
1933
                 * Specifies the version of the required module.
1934
                 *
1935
                 * @param version The version of the required module or {@code null} if no version is to be specified.
1936
                 * @return A new builder that is equal to this builder but with the given version specification.
1937
                 */
1938
                RequiresDefinition<U> requiredVersion(@MaybeNull String version);
1939

1940
                /**
1941
                 * An abstract base implementation of a {@link RequiresDefinition}.
1942
                 *
1943
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1944
                 */
1945
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements RequiresDefinition<V> {
×
1946
                    /* empty */
1947
                }
1948
            }
1949

1950
            /**
1951
             * A specification of a module export.
1952
             *
1953
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1954
             */
1955
            interface ExportsDefinition<U> extends ModuleDefinition<U> {
1956

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

1965
                /**
1966
                 * Specifies the modules to which the previously defined package is exported.
1967
                 *
1968
                 * @param modules The names of the modules to which the package is exported.
1969
                 * @return A new builder that is equal to this builder but with the given modules specified.
1970
                 */
1971
                ExportsDefinition<U> to(Collection<String> modules);
1972

1973
                /**
1974
                 * An abstract base implementation of a {@link OpensDefinition}.
1975
                 *
1976
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1977
                 */
1978
                abstract class Delegator<V> extends ModuleDefinition.AbstractBase.Delegator<V> implements ExportsDefinition<V> {
×
1979

1980
                    /**
1981
                     * {@inheritDoc}ModuleDefinition
1982
                     */
1983
                    public ExportsDefinition<V> to(String... module) {
1984
                        return to(Arrays.asList(module));
×
1985
                    }
1986
                }
1987
            }
1988

1989
            /**
1990
             * A specification of a module opening.
1991
             *
1992
             * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1993
             */
1994
            interface OpensDefinition<S> extends ModuleDefinition<S> {
1995

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

2004
                /**
2005
                 * Specifies the modules to which the previously defined package is opened.
2006
                 *
2007
                 * @param modules The names of the modules to which the package is opened.
2008
                 * @return A new builder that is equal to this builder but with the given modules specified.
2009
                 */
2010
                OpensDefinition<S> to(Collection<String> modules);
2011

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

2019
                    /**
2020
                     * {@inheritDoc}
2021
                     */
2022
                    public OpensDefinition<V> to(String... module) {
2023
                        return to(Arrays.asList(module));
×
2024
                    }
2025
                }
2026
            }
2027

2028
            /**
2029
             * An abstract base implementation of a {@link ModuleDefinition}.
2030
             *
2031
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2032
             */
2033
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements ModuleDefinition<U> {
1✔
2034

2035
                /**
2036
                 * {@inheritDoc}
2037
                 */
2038
                public ModuleDefinition<U> mainClass(@MaybeNull Class<?> type) {
2039
                    return mainClass(type == null
×
2040
                            ? null
2041
                            : TypeDescription.ForLoadedType.of(type));
×
2042
                }
2043

2044
                /**
2045
                 * {@inheritDoc}
2046
                 */
2047
                public ModuleDefinition<U> mainClass(@MaybeNull TypeDescription typeDescription) {
2048
                    if (typeDescription != null && (typeDescription.isArray() || typeDescription.isPrimitive())) {
×
2049
                        throw new IllegalArgumentException("Cannot use primitive types for main class: " + typeDescription);
×
2050
                    }
2051
                    return mainClass(typeDescription == null
×
2052
                            ? null
2053
                            : typeDescription.getName());
×
2054
                }
2055

2056
                /**
2057
                 * {@inheritDoc}
2058
                 */
2059
                public ModuleDefinition<U> packages(String... aPackage) {
2060
                    return packages(Arrays.asList(aPackage));
×
2061
                }
2062

2063
                /**
2064
                 * {@inheritDoc}
2065
                 */
2066
                public ModuleDefinition<U> requires(String... module) {
2067
                    return requires(Arrays.asList(module));
×
2068
                }
2069

2070
                /**
2071
                 * {@inheritDoc}
2072
                 */
2073
                public ModuleDefinition<U> requires(Collection<String> modules) {
2074
                    ModuleDefinition<U> definition = this;
×
2075
                    for (String module : modules) {
×
2076
                        definition = definition.requires(module);
×
2077
                    }
×
2078
                    return definition;
×
2079
                }
2080

2081
                /**
2082
                 * {@inheritDoc}
2083
                 */
2084
                public RequiresDefinition<U> require(String module, ModifierContributor.ForModule.OfRequire... modifierContributor) {
2085
                    return require(module, Arrays.asList(modifierContributor));
×
2086
                }
2087

2088
                /**
2089
                 * {@inheritDoc}
2090
                 */
2091
                public RequiresDefinition<U> require(String module, Collection<? extends ModifierContributor.ForModule.OfRequire> modifierContributors) {
2092
                    return require(module, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2093
                }
2094

2095
                /**
2096
                 * {@inheritDoc}
2097
                 */
2098
                public ModuleDefinition<U> exports(String... aPackage) {
2099
                    return exports(Arrays.asList(aPackage));
×
2100
                }
2101

2102
                /**
2103
                 * {@inheritDoc}
2104
                 */
2105
                public ModuleDefinition<U> exports(Collection<String> packages) {
2106
                    ModuleDefinition<U> definition = this;
×
2107
                    for (String aPackage : packages) {
×
2108
                        definition = definition.export(aPackage);
×
2109
                    }
×
2110
                    return definition;
×
2111
                }
2112

2113
                /**
2114
                 * {@inheritDoc}
2115
                 */
2116
                public ModuleDefinition<U> export(String aPackage, ModifierContributor.ForModule.OfExport... modifierContributor) {
2117
                    return export(aPackage, Arrays.asList(modifierContributor));
×
2118
                }
2119

2120
                /**
2121
                 * {@inheritDoc}
2122
                 */
2123
                public ModuleDefinition<U> export(String aPackage, Collection<? extends ModifierContributor.ForModule.OfExport> modifierContributors) {
2124
                    return export(aPackage, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2125
                }
2126

2127
                /**
2128
                 * {@inheritDoc}
2129
                 */
2130
                public ModuleDefinition<U> opens(String... aPackage) {
2131
                    return opens(Arrays.asList(aPackage));
×
2132
                }
2133

2134
                /**
2135
                 * {@inheritDoc}
2136
                 */
2137
                public ModuleDefinition<U> opens(Collection<String> packages) {
2138
                    ModuleDefinition<U> definition = this;
×
2139
                    for (String aPackage : packages) {
×
2140
                        definition = definition.open(aPackage);
×
2141
                    }
×
2142
                    return definition;
×
2143
                }
2144

2145
                /**
2146
                 * {@inheritDoc}
2147
                 */
2148
                public ModuleDefinition<U> open(String aPackage, ModifierContributor.ForModule.OfOpen... modifierContributor) {
2149
                    return open(aPackage, Arrays.asList(modifierContributor));
×
2150
                }
2151

2152
                /**
2153
                 * {@inheritDoc}
2154
                 */
2155
                public ModuleDefinition<U> open(String aPackage, Collection<? extends ModifierContributor.ForModule.OfOpen> modifierContributors) {
2156
                    return open(aPackage, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
2157
                }
2158

2159
                /**
2160
                 * {@inheritDoc}
2161
                 */
2162
                public ModuleDefinition<U> uses(Class<?>... service) {
2163
                    return uses(new TypeList.ForLoadedTypes(service));
×
2164
                }
2165

2166
                /**
2167
                 * {@inheritDoc}
2168
                 */
2169
                public ModuleDefinition<U> uses(TypeDescription... service) {
2170
                    return uses(Arrays.asList(service));
×
2171
                }
2172

2173
                /**
2174
                 * Includes the provided type in the usage of the module description.
2175
                 *
2176
                 * @param services The services to use.
2177
                 * @return A module description where these services are included.
2178
                 */
2179
                private ModuleDefinition<U> uses(List<TypeDescription> services) {
2180
                    List<String> names = new ArrayList<String>(services.size());
×
2181
                    for (TypeDescription service : services) {
×
2182
                        if (service.isArray() || service.isPrimitive()) {
×
2183
                            throw new IllegalArgumentException("A service can only be provided by a regular class: " + service);
×
2184
                        }
2185
                        names.add(service.getName());
×
2186
                    }
×
2187
                    return uses(names);
×
2188
                }
2189

2190
                /**
2191
                 * {@inheritDoc}
2192
                 */
2193
                public ModuleDefinition<U> uses(String... service) {
2194
                    return uses(Arrays.asList(service));
×
2195
                }
2196

2197
                /**
2198
                 * {@inheritDoc}
2199
                 */
2200
                public ModuleDefinition<U> provides(Class<?> service, Class<?>... implementations) {
2201
                    return provides(service, Arrays.asList(implementations));
×
2202
                }
2203

2204
                /**
2205
                 * {@inheritDoc}
2206
                 */
2207
                public ModuleDefinition<U> provides(Class<?> service, Collection<Class<?>> implementations) {
2208
                    return provides(TypeDescription.ForLoadedType.of(service), new TypeList.ForLoadedTypes(new ArrayList<Class<?>>(implementations)));
×
2209
                }
2210

2211
                /**
2212
                 * {@inheritDoc}
2213
                 */
2214
                public ModuleDefinition<U> provides(TypeDescription service, TypeDescription... implementation) {
2215
                    return provides(service, Arrays.asList(implementation));
×
2216
                }
2217

2218
                /**
2219
                 * {@inheritDoc}
2220
                 */
2221
                public ModuleDefinition<U> provides(TypeDescription service, Collection<TypeDescription> implementations) {
2222
                    if (service.isArray() || service.isPrimitive()) {
×
2223
                        throw new IllegalArgumentException("Service must be a regular class: " + service);
×
2224
                    }
2225
                    List<String> names = new ArrayList<String>(implementations.size());
×
2226
                    for (TypeDescription implementation : implementations) {
×
2227
                        if (implementation.isArray() || implementation.isPrimitive() || implementation.isAbstract()) {
×
2228
                            throw new IllegalArgumentException("Service implementation must be a regular, non-abstract class: " + implementation);
×
2229
                        }
2230
                        names.add(implementation.getName());
×
2231
                    }
×
2232
                    return provides(service.getName(), names);
×
2233
                }
2234

2235
                /**
2236
                 * {@inheritDoc}
2237
                 */
2238
                public ModuleDefinition<U> provides(String service, String... implementations) {
2239
                    return provides(service, Arrays.asList(implementations));
×
2240
                }
2241

2242
                /**
2243
                 * An adapter for a {@link ModuleDefinition}.
2244
                 *
2245
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2246
                 */
2247
                public abstract static class Delegator<V> extends ModuleDefinition.AbstractBase<V> {
×
2248

2249
                    /**
2250
                     * {@inheritDoc}
2251
                     */
2252
                    public ModuleDefinition<V> version(@MaybeNull String version) {
2253
                        return materialize().version(version);
×
2254
                    }
2255

2256
                    /**
2257
                     * {@inheritDoc}
2258
                     */
2259
                    public ModuleDefinition<V> mainClass(@MaybeNull String name) {
2260
                        return materialize().mainClass(name);
×
2261
                    }
2262

2263
                    /**
2264
                     * {@inheritDoc}
2265
                     */
2266
                    public ModuleDefinition<V> packages(Collection<String> packages) {
2267
                        return materialize().packages(packages);
×
2268
                    }
2269

2270
                    /**
2271
                     * {@inheritDoc}
2272
                     */
2273
                    public RequiresDefinition<V> require(String module, int modifiers) {
2274
                        return materialize().require(module, modifiers);
×
2275
                    }
2276

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

2284
                    /**
2285
                     * {@inheritDoc}
2286
                     */
2287
                    public ModuleDefinition<V> open(String aPackage, int modifiers) {
2288
                        return materialize().open(aPackage, modifiers);
×
2289
                    }
2290

2291
                    /**
2292
                     * {@inheritDoc}
2293
                     */
2294
                    public ModuleDefinition<V> uses(Collection<String> services) {
2295
                        return materialize().uses(services);
×
2296
                    }
2297

2298
                    /**
2299
                     * {@inheritDoc}
2300
                     */
2301
                    public ModuleDefinition<V> provides(String service, Collection<String> implementations) {
2302
                        return materialize().provides(service, implementations);
×
2303
                    }
2304

2305
                    @Override
2306
                    protected abstract ModuleDefinition<V> materialize();
2307
                }
2308
            }
2309
        }
2310

2311
        /**
2312
         * An inner type definition for defining a type that is contained within another type, method or constructor.
2313
         *
2314
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2315
         */
2316
        interface InnerTypeDefinition<S> extends Builder<S> {
2317

2318
            /**
2319
             * Defines this inner type declaration as an anonymous type.
2320
             *
2321
             * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
2322
             */
2323
            Builder<S> asAnonymousType();
2324

2325
            /**
2326
             * An inner type definition for defining a type that is contained within another type.
2327
             *
2328
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2329
             */
2330
            interface ForType<U> extends InnerTypeDefinition<U> {
2331

2332
                /**
2333
                 * Defines this inner type declaration as a member type.
2334
                 *
2335
                 * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
2336
                 */
2337
                Builder<U> asMemberType();
2338
            }
2339
        }
2340

2341
        /**
2342
         * A builder for a type variable definition.
2343
         *
2344
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2345
         */
2346
        interface TypeVariableDefinition<S> extends Builder<S> {
2347

2348
            /**
2349
             * Annotates the previously defined type variable with the supplied annotations.
2350
             *
2351
             * @param annotation 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(Annotation... annotation);
2356

2357
            /**
2358
             * Annotates the previously defined type variable with the supplied annotations.
2359
             *
2360
             * @param annotations 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(List<? extends Annotation> annotations);
2365

2366
            /**
2367
             * Annotates the previously defined type variable with the supplied annotations.
2368
             *
2369
             * @param annotation 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(AnnotationDescription... annotation);
2374

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

2384
            /**
2385
             * An abstract base implementation of a type variable definition.
2386
             *
2387
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2388
             */
2389
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
1✔
2390

2391
                /**
2392
                 * {@inheritDoc}
2393
                 */
2394
                public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
2395
                    return annotateTypeVariable(Arrays.asList(annotation));
×
2396
                }
2397

2398
                /**
2399
                 * {@inheritDoc}
2400
                 */
2401
                public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
2402
                    return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
2403
                }
2404

2405
                /**
2406
                 * {@inheritDoc}
2407
                 */
2408
                public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
2409
                    return annotateTypeVariable(Arrays.asList(annotation));
1✔
2410
                }
2411
            }
2412
        }
2413

2414
        /**
2415
         * A builder for a field definition.
2416
         *
2417
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2418
         */
2419
        interface FieldDefinition<S> {
2420

2421
            /**
2422
             * Annotates the previously defined or matched field with the supplied annotations.
2423
             *
2424
             * @param annotation 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(Annotation... annotation);
2429

2430
            /**
2431
             * Annotates the previously defined or matched field with the supplied annotations.
2432
             *
2433
             * @param annotations 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(List<? extends Annotation> annotations);
2438

2439
            /**
2440
             * Annotates the previously defined or matched field with the supplied annotations.
2441
             *
2442
             * @param annotation 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(AnnotationDescription... annotation);
2447

2448
            /**
2449
             * Annotates the previously defined or matched field with the supplied annotations.
2450
             *
2451
             * @param annotations The annotations to declare on the previously defined or matched field.
2452
             * @return A new builder that is equal to this builder but with the given annotations declared
2453
             * on the previously defined or matched field.
2454
             */
2455
            FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
2456

2457
            /**
2458
             * Applies the supplied attribute appender factory onto the previously defined or matched field.
2459
             *
2460
             * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
2461
             *                                      previously defined or matched field.
2462
             * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
2463
             * applied to the previously defined or matched field.
2464
             */
2465
            FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
2466

2467
            /**
2468
             * Applies the supplied transformer onto the previously defined or matched field. The transformed
2469
             * field is written <i>as it is</i> and is not subject to any validations.
2470
             *
2471
             * @param transformer The transformer to apply to the previously defined or matched field.
2472
             * @return A new builder that is equal to this builder but with the supplied field transformer
2473
             * applied to the previously defined or matched field.
2474
             */
2475
            FieldDefinition.Optional<S> transform(Transformer<FieldDescription> transformer);
2476

2477
            /**
2478
             * A builder for a field definition that allows for defining a value.
2479
             *
2480
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2481
             */
2482
            interface Valuable<U> extends FieldDefinition<U> {
2483

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

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

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

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

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

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

2586
            /**
2587
             * A builder for an optional field definition.
2588
             *
2589
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2590
             */
2591
            interface Optional<U> extends FieldDefinition<U>, Builder<U> {
2592

2593
                /**
2594
                 * A builder for an optional field definition that allows for defining a value.
2595
                 *
2596
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2597
                 */
2598
                interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
2599

2600
                    /**
2601
                     * An abstract base implementation of an optional field definition that allows for defining a value.
2602
                     *
2603
                     * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2604
                     */
2605
                    abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1✔
2606

2607
                        /**
2608
                         * {@inheritDoc}
2609
                         */
2610
                        public FieldDefinition.Optional<U> value(boolean value) {
2611
                            return defaultValue(value ? 1 : 0);
1✔
2612
                        }
2613

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

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

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

2635
                        /**
2636
                         * {@inheritDoc}
2637
                         */
2638
                        public FieldDefinition.Optional<U> value(double value) {
2639
                            return defaultValue(value);
1✔
2640
                        }
2641

2642
                        /**
2643
                         * {@inheritDoc}
2644
                         */
2645
                        public FieldDefinition.Optional<U> value(String value) {
2646
                            if (value == null) {
1✔
2647
                                throw new IllegalArgumentException("Cannot define 'null' as constant value");
1✔
2648
                            }
2649
                            return defaultValue(value);
1✔
2650
                        }
2651

2652
                        /**
2653
                         * Defines the supplied value as a default value of the previously defined or matched field.
2654
                         *
2655
                         * @param defaultValue The value to define as a default value of the defined field.
2656
                         * @return A new builder that is equal to this builder but with the given default value declared for the
2657
                         * previously defined or matched field.
2658
                         */
2659
                        protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
2660

2661
                        /**
2662
                         * An adapter for an optional field definition that allows for defining a value.
2663
                         *
2664
                         * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2665
                         */
2666
                        @HashCodeAndEqualsPlugin.Enhance
2667
                        private abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
2668

2669
                            /**
2670
                             * The field attribute appender factory to apply.
2671
                             */
2672
                            protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
2673

2674
                            /**
2675
                             * The field transformer to apply.
2676
                             */
2677
                            protected final Transformer<FieldDescription> transformer;
2678

2679
                            /**
2680
                             * The field's default value or {@code null} if no value is to be defined.
2681
                             */
2682
                            @MaybeNull
2683
                            @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
2684
                            protected final Object defaultValue;
2685

2686
                            /**
2687
                             * Creates a new field adapter.
2688
                             *
2689
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
2690
                             * @param transformer                   The field transformer to apply.
2691
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
2692
                             */
2693
                            protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
2694
                                              Transformer<FieldDescription> transformer,
2695
                                              @MaybeNull Object defaultValue) {
1✔
2696
                                this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
1✔
2697
                                this.transformer = transformer;
1✔
2698
                                this.defaultValue = defaultValue;
1✔
2699
                            }
1✔
2700

2701
                            /**
2702
                             * {@inheritDoc}
2703
                             */
2704
                            public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
2705
                                return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
1✔
2706
                            }
2707

2708
                            /**
2709
                             * {@inheritDoc}
2710
                             */
2711
                            @SuppressWarnings("unchecked") // In absence of @SafeVarargs
2712
                            public FieldDefinition.Optional<V> transform(Transformer<FieldDescription> transformer) {
2713
                                return materialize(fieldAttributeAppenderFactory, new Transformer.Compound<FieldDescription>(this.transformer, transformer), defaultValue);
1✔
2714
                            }
2715

2716
                            @Override
2717
                            protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
2718
                                return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
2719
                            }
2720

2721
                            /**
2722
                             * Creates a new optional field definition for which all of the supplied values are represented.
2723
                             *
2724
                             * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
2725
                             * @param transformer                   The field transformer to apply.
2726
                             * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
2727
                             * @return A new field definition that represents the supplied values.
2728
                             */
2729
                            protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
2730
                                                                                       Transformer<FieldDescription> transformer,
2731
                                                                                       @MaybeNull Object defaultValue);
2732
                        }
2733
                    }
2734
                }
2735

2736
                /**
2737
                 * An abstract base implementation for an optional field definition.
2738
                 *
2739
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2740
                 */
2741
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1✔
2742

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

2750
                    /**
2751
                     * {@inheritDoc}
2752
                     */
2753
                    public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
2754
                        return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
2755
                    }
2756

2757
                    /**
2758
                     * {@inheritDoc}
2759
                     */
2760
                    public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
2761
                        return annotateField(Arrays.asList(annotation));
1✔
2762
                    }
2763
                }
2764
            }
2765
        }
2766

2767
        /**
2768
         * A builder for a method definition.
2769
         *
2770
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2771
         */
2772
        interface MethodDefinition<S> extends Builder<S> {
2773

2774
            /**
2775
             * Annotates the previously defined or matched method with the supplied annotations.
2776
             *
2777
             * @param annotation 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(Annotation... annotation);
2782

2783
            /**
2784
             * Annotates the previously defined or matched method with the supplied annotations.
2785
             *
2786
             * @param annotations 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(List<? extends Annotation> annotations);
2791

2792
            /**
2793
             * Annotates the previously defined or matched method with the supplied annotations.
2794
             *
2795
             * @param annotation 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(AnnotationDescription... annotation);
2800

2801
            /**
2802
             * Annotates the previously defined or matched method with the supplied annotations.
2803
             *
2804
             * @param annotations The annotations to declare on the previously defined or matched method.
2805
             * @return A new builder that is equal to this builder but with the given annotations declared
2806
             * on the previously defined or matched method.
2807
             */
2808
            MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
2809

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

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

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

2840
            /**
2841
             * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
2842
             *
2843
             * @param index       The parameter's index.
2844
             * @param annotations The annotations to declare on the previously defined or matched method.
2845
             * @return A new builder that is equal to this builder but with the given annotations declared
2846
             * on the previously defined or matched method's parameter of the given index.
2847
             */
2848
            MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
2849

2850
            /**
2851
             * Applies the supplied method attribute appender factory onto the previously defined or matched method.
2852
             *
2853
             * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
2854
             *                                       previously defined or matched method.
2855
             * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
2856
             * applied to the previously defined or matched method.
2857
             */
2858
            MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
2859

2860
            /**
2861
             * Applies the supplied transformer onto the previously defined or matched method. The transformed
2862
             * method is written <i>as it is</i> and it not subject to any validations.
2863
             *
2864
             * @param transformer The transformer to apply to the previously defined or matched method.
2865
             * @return A new builder that is equal to this builder but with the supplied transformer
2866
             * applied to the previously defined or matched method.
2867
             */
2868
            MethodDefinition<S> transform(Transformer<MethodDescription> transformer);
2869

2870
            /**
2871
             * A builder for a method definition with a receiver type.
2872
             *
2873
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2874
             */
2875
            interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
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(AnnotatedElement receiverType);
2885

2886
                /**
2887
                 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2888
                 *
2889
                 * @param receiverType The receiver type to define on the previously defined or matched method.
2890
                 * @return A new builder that is equal to this builder but with the given type defined as the
2891
                 * receiver on the previously defined or matched method.
2892
                 */
2893
                MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
2894

2895
                /**
2896
                 * An abstract base implementation of a method definition that can accept a receiver type.
2897
                 *
2898
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2899
                 */
2900
                abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
1✔
2901

2902
                    /**
2903
                     * {@inheritDoc}
2904
                     */
2905
                    public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
2906
                        return receiverType(TypeDefinition.Sort.describeAnnotated(receiverType));
×
2907
                    }
2908
                }
2909
            }
2910

2911
            /**
2912
             * A builder for defining an implementation of a method.
2913
             *
2914
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2915
             */
2916
            interface ImplementationDefinition<U> {
2917

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

2939
                /**
2940
                 * Defines the previously defined or matched method not to declare a method body. This implies the
2941
                 * method to be {@code abstract} unless it was already declared to be {@code native}.
2942
                 *
2943
                 * @return A new builder where the previously defined or matched method is implemented to be abstract.
2944
                 */
2945
                MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
2946

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

2958
                /**
2959
                 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2960
                 * value must be supplied in its loaded state paired with the property type of the value.
2961
                 *
2962
                 * @param value The value to be defined as a default value.
2963
                 * @param type  The type of the annotation property.
2964
                 * @param <W>   The type of the annotation property.
2965
                 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2966
                 */
2967
                <W> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(W value, Class<? extends W> type);
2968

2969
                /**
2970
                 * A builder for 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
                interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
2975
                    /* union type */
2976
                }
2977

2978
                /**
2979
                 * An abstract base implementation for a builder optionally defining an implementation of a method.
2980
                 *
2981
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2982
                 */
2983
                abstract class AbstractBase<V> implements ImplementationDefinition<V> {
1✔
2984

2985
                    /**
2986
                     * {@inheritDoc}
2987
                     */
2988
                    public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) {
2989
                        return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
1✔
2990
                    }
2991
                }
2992
            }
2993

2994
            /**
2995
             * A builder for defining an implementation of a method and optionally defining a type variable.
2996
             *
2997
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2998
             */
2999
            interface TypeVariableDefinition<U> extends ImplementationDefinition<U> {
3000

3001
                /**
3002
                 * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
3003
                 *
3004
                 * @param symbol The symbol of the type variable.
3005
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
3006
                 */
3007
                Annotatable<U> typeVariable(String symbol);
3008

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

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

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

3039
                /**
3040
                 * Defines a method variable to be declared by the currently defined method.
3041
                 *
3042
                 * @param symbol The symbol of the type variable.
3043
                 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
3044
                 *               if a bound type should be equal to the currently instrumented type.
3045
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
3046
                 */
3047
                Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
3048

3049
                /**
3050
                 * A builder for optionally defining an annotation for a type variable.
3051
                 *
3052
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3053
                 */
3054
                interface Annotatable<V> extends TypeVariableDefinition<V> {
3055

3056
                    /**
3057
                     * Annotates the previously defined type variable with the supplied annotations.
3058
                     *
3059
                     * @param annotation 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(Annotation... annotation);
3064

3065
                    /**
3066
                     * Annotates the previously defined type variable with the supplied annotations.
3067
                     *
3068
                     * @param annotations 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(List<? extends Annotation> annotations);
3073

3074
                    /**
3075
                     * Annotates the previously defined type variable with the supplied annotations.
3076
                     *
3077
                     * @param annotation 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(AnnotationDescription... annotation);
3082

3083
                    /**
3084
                     * Annotates the previously defined type variable with the supplied annotations.
3085
                     *
3086
                     * @param annotations The annotations to declare on the previously defined type variable.
3087
                     * @return A new builder that is equal to this builder but with the given annotations declared
3088
                     * on the previously defined type variable.
3089
                     */
3090
                    Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
3091

3092
                    /**
3093
                     * An abstract base implementation for defining an annotation on a parameter.
3094
                     *
3095
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3096
                     */
3097
                    abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
3098

3099
                        /**
3100
                         * {@inheritDoc}
3101
                         */
3102
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
3103
                            return annotateTypeVariable(Arrays.asList(annotation));
×
3104
                        }
3105

3106
                        /**
3107
                         * {@inheritDoc}
3108
                         */
3109
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
3110
                            return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
×
3111
                        }
3112

3113
                        /**
3114
                         * {@inheritDoc}
3115
                         */
3116
                        public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
3117
                            return annotateTypeVariable(Arrays.asList(annotation));
1✔
3118
                        }
3119

3120
                        /**
3121
                         * An adapter implementation for an annotatable type variable definition.
3122
                         *
3123
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3124
                         */
3125
                        protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
1✔
3126

3127
                            /**
3128
                             * {@inheritDoc}
3129
                             */
3130
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3131
                                return materialize().typeVariable(symbol, bounds);
1✔
3132
                            }
3133

3134
                            /**
3135
                             * {@inheritDoc}
3136
                             */
3137
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
3138
                                return materialize().intercept(implementation);
1✔
3139
                            }
3140

3141
                            /**
3142
                             * {@inheritDoc}
3143
                             */
3144
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3145
                                return materialize().withoutCode();
1✔
3146
                            }
3147

3148
                            /**
3149
                             * {@inheritDoc}
3150
                             */
3151
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
3152
                                return materialize().defaultValue(annotationValue);
×
3153
                            }
3154

3155
                            /**
3156
                             * {@inheritDoc}
3157
                             */
3158
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
3159
                                return materialize().defaultValue(value, type);
×
3160
                            }
3161

3162
                            /**
3163
                             * Materializes this instance as a parameter definition with the currently defined properties.
3164
                             *
3165
                             * @return A parameter definition with the currently defined properties.
3166
                             */
3167
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
3168
                        }
3169
                    }
3170
                }
3171

3172
                /**
3173
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
3174
                 *
3175
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3176
                 */
3177
                abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
1✔
3178

3179
                    /**
3180
                     * {@inheritDoc}
3181
                     */
3182
                    public Annotatable<V> typeVariable(String symbol) {
3183
                        return typeVariable(symbol, Collections.singletonList(Object.class));
1✔
3184
                    }
3185

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

3193
                    /**
3194
                     * {@inheritDoc}
3195
                     */
3196
                    public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
3197
                        return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
3198
                    }
3199

3200
                    /**
3201
                     * {@inheritDoc}
3202
                     */
3203
                    public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
3204
                        return typeVariable(symbol, Arrays.asList(bound));
1✔
3205
                    }
3206
                }
3207
            }
3208

3209
            /**
3210
             * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
3211
             *
3212
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3213
             */
3214
            interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
3215

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

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

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

3240
                /**
3241
                 * Defines a method variable to be declared by the currently defined method.
3242
                 *
3243
                 * @param types The type of the exception being declared by the currently defined method.
3244
                 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
3245
                 */
3246
                ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
3247

3248
                /**
3249
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
3250
                 *
3251
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3252
                 */
3253
                abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
1✔
3254

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

3262
                    /**
3263
                     * {@inheritDoc}
3264
                     */
3265
                    public ExceptionDefinition<V> throwing(List<? extends Type> types) {
3266
                        return throwing(new TypeList.Generic.ForLoadedTypes(types));
1✔
3267
                    }
3268

3269
                    /**
3270
                     * {@inheritDoc}
3271
                     */
3272
                    public ExceptionDefinition<V> throwing(TypeDefinition... type) {
3273
                        return throwing(Arrays.asList(type));
1✔
3274
                    }
3275
                }
3276
            }
3277

3278
            /**
3279
             * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
3280
             *
3281
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3282
             */
3283
            interface ParameterDefinition<U> extends ExceptionDefinition<U> {
3284

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

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

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

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

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

3340
                /**
3341
                 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3342
                 *
3343
                 * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3344
                 *                  should be equal to the currently instrumented type.
3345
                 * @param name      The parameter's name.
3346
                 * @param modifiers The parameter's modifiers.
3347
                 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3348
                 */
3349
                Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers);
3350

3351
                /**
3352
                 * A builder for optionally defining an annotation on a parameter.
3353
                 *
3354
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3355
                 */
3356
                interface Annotatable<V> extends ParameterDefinition<V> {
3357

3358
                    /**
3359
                     * Annotates the previously defined parameter with the specified annotations.
3360
                     *
3361
                     * @param annotation 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(Annotation... annotation);
3366

3367
                    /**
3368
                     * Annotates the previously defined parameter with the specified annotations.
3369
                     *
3370
                     * @param annotations 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(List<? extends Annotation> annotations);
3375

3376
                    /**
3377
                     * Annotates the previously defined parameter with the specified annotations.
3378
                     *
3379
                     * @param annotation 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(AnnotationDescription... annotation);
3384

3385
                    /**
3386
                     * Annotates the previously defined parameter with the specified annotations.
3387
                     *
3388
                     * @param annotations The annotations to declare on the previously defined parameter.
3389
                     * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3390
                     * the specified annotations.
3391
                     */
3392
                    Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
3393

3394
                    /**
3395
                     * An abstract base implementation for defining an annotation on a parameter.
3396
                     *
3397
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3398
                     */
3399
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
1✔
3400

3401
                        /**
3402
                         * {@inheritDoc}
3403
                         */
3404
                        public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
3405
                            return annotateParameter(Arrays.asList(annotation));
×
3406
                        }
3407

3408
                        /**
3409
                         * {@inheritDoc}
3410
                         */
3411
                        public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
3412
                            return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
3413
                        }
3414

3415
                        /**
3416
                         * {@inheritDoc}
3417
                         */
3418
                        public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
3419
                            return annotateParameter(Arrays.asList(annotation));
×
3420
                        }
3421

3422
                        /**
3423
                         * An adapter implementation for defining an annotation on a parameter.
3424
                         *
3425
                         * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3426
                         */
3427
                        protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
1✔
3428

3429
                            /**
3430
                             * {@inheritDoc}
3431
                             */
3432
                            public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
3433
                                return materialize().withParameter(type, name, modifiers);
×
3434
                            }
3435

3436
                            /**
3437
                             * {@inheritDoc}
3438
                             */
3439
                            public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
3440
                                return materialize().throwing(types);
1✔
3441
                            }
3442

3443
                            /**
3444
                             * {@inheritDoc}
3445
                             */
3446
                            public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3447
                                return materialize().typeVariable(symbol, bounds);
×
3448
                            }
3449

3450
                            /**
3451
                             * {@inheritDoc}
3452
                             */
3453
                            public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
3454
                                return materialize().intercept(implementation);
×
3455
                            }
3456

3457
                            /**
3458
                             * {@inheritDoc}
3459
                             */
3460
                            public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3461
                                return materialize().withoutCode();
×
3462
                            }
3463

3464
                            /**
3465
                             * {@inheritDoc}
3466
                             */
3467
                            public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
3468
                                return materialize().defaultValue(annotationValue);
×
3469
                            }
3470

3471
                            /**
3472
                             * {@inheritDoc}
3473
                             */
3474
                            public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
3475
                                return materialize().defaultValue(value, type);
×
3476
                            }
3477

3478
                            /**
3479
                             * Materializes this instance as a parameter definition with the currently defined properties.
3480
                             *
3481
                             * @return A parameter definition with the currently defined properties.
3482
                             */
3483
                            protected abstract MethodDefinition.ParameterDefinition<X> materialize();
3484
                        }
3485
                    }
3486
                }
3487

3488
                /**
3489
                 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
3490
                 *
3491
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3492
                 */
3493
                interface Simple<V> extends ExceptionDefinition<V> {
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(Type type);
3503

3504
                    /**
3505
                     * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
3506
                     *
3507
                     * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3508
                     *             should be equal to the currently instrumented type.
3509
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
3510
                     */
3511
                    Annotatable<V> withParameter(TypeDefinition type);
3512

3513
                    /**
3514
                     * A builder for optionally defining an annotation on a parameter.
3515
                     *
3516
                     * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3517
                     */
3518
                    interface Annotatable<V> extends Simple<V> {
3519

3520
                        /**
3521
                         * Annotates the previously defined parameter with the specified annotations.
3522
                         *
3523
                         * @param annotation 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(Annotation... annotation);
3528

3529
                        /**
3530
                         * Annotates the previously defined parameter with the specified annotations.
3531
                         *
3532
                         * @param annotations 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(List<? extends Annotation> annotations);
3537

3538
                        /**
3539
                         * Annotates the previously defined parameter with the specified annotations.
3540
                         *
3541
                         * @param annotation 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(AnnotationDescription... annotation);
3546

3547
                        /**
3548
                         * Annotates the previously defined parameter with the specified annotations.
3549
                         *
3550
                         * @param annotations The annotations to declare on the previously defined parameter.
3551
                         * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
3552
                         * the specified annotations.
3553
                         */
3554
                        Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
3555

3556
                        /**
3557
                         * An abstract base implementation of a simple parameter definition.
3558
                         *
3559
                         * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3560
                         */
3561
                        abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
1✔
3562

3563
                            /**
3564
                             * {@inheritDoc}
3565
                             */
3566
                            public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
3567
                                return annotateParameter(Arrays.asList(annotation));
×
3568
                            }
3569

3570
                            /**
3571
                             * {@inheritDoc}
3572
                             */
3573
                            public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
3574
                                return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
×
3575
                            }
3576

3577
                            /**
3578
                             * {@inheritDoc}
3579
                             */
3580
                            public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
3581
                                return annotateParameter(Arrays.asList(annotation));
1✔
3582
                            }
3583

3584
                            /**
3585
                             * An adapter implementation of a simple parameter definition.
3586
                             *
3587
                             * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
3588
                             */
3589
                            protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
1✔
3590

3591
                                /**
3592
                                 * {@inheritDoc}
3593
                                 */
3594
                                public Simple.Annotatable<X> withParameter(TypeDefinition type) {
3595
                                    return materialize().withParameter(type);
1✔
3596
                                }
3597

3598
                                /**
3599
                                 * {@inheritDoc}
3600
                                 */
3601
                                public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
3602
                                    return materialize().throwing(types);
1✔
3603
                                }
3604

3605
                                /**
3606
                                 * {@inheritDoc}
3607
                                 */
3608
                                public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3609
                                    return materialize().typeVariable(symbol, bounds);
×
3610
                                }
3611

3612
                                /**
3613
                                 * {@inheritDoc}
3614
                                 */
3615
                                public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
3616
                                    return materialize().intercept(implementation);
1✔
3617
                                }
3618

3619
                                /**
3620
                                 * {@inheritDoc}
3621
                                 */
3622
                                public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
3623
                                    return materialize().withoutCode();
1✔
3624
                                }
3625

3626
                                /**
3627
                                 * {@inheritDoc}
3628
                                 */
3629
                                public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
3630
                                    return materialize().defaultValue(annotationValue);
×
3631
                                }
3632

3633
                                /**
3634
                                 * {@inheritDoc}
3635
                                 */
3636
                                public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
3637
                                    return materialize().defaultValue(value, type);
×
3638
                                }
3639

3640
                                /**
3641
                                 * Materializes this instance as a simple parameter definition with the currently defined properties.
3642
                                 *
3643
                                 * @return A simple parameter definition with the currently defined properties.
3644
                                 */
3645
                                protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
3646
                            }
3647
                        }
3648
                    }
3649

3650
                    /**
3651
                     * An abstract base implementation of an exception definition.
3652
                     *
3653
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3654
                     */
3655
                    abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
1✔
3656

3657
                        /**
3658
                         * {@inheritDoc}
3659
                         */
3660
                        public Simple.Annotatable<W> withParameter(Type type) {
3661
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
3662
                        }
3663
                    }
3664
                }
3665

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

3676
                    /**
3677
                     * Defines the specified parameters for the currently defined method.
3678
                     *
3679
                     * @param type 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(Type... type);
3684

3685
                    /**
3686
                     * Defines the specified parameters for the currently defined method.
3687
                     *
3688
                     * @param types 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(List<? extends Type> types);
3693

3694
                    /**
3695
                     * Defines the specified parameters for the currently defined method.
3696
                     *
3697
                     * @param type 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(TypeDefinition... type);
3702

3703
                    /**
3704
                     * Defines the specified parameters for the currently defined method.
3705
                     *
3706
                     * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
3707
                     *              should be equal to the currently instrumented type.
3708
                     * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
3709
                     */
3710
                    ExceptionDefinition<V> withParameters(Collection<? extends TypeDefinition> types);
3711

3712
                    /**
3713
                     * An abstract base implementation for an initial parameter definition.
3714
                     *
3715
                     * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
3716
                     */
3717
                    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
1✔
3718

3719
                        /**
3720
                         * {@inheritDoc}
3721
                         */
3722
                        public Simple.Annotatable<W> withParameter(Type type) {
3723
                            return withParameter(TypeDefinition.Sort.describe(type));
1✔
3724
                        }
3725

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

3733
                        /**
3734
                         * {@inheritDoc}
3735
                         */
3736
                        public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
3737
                            return withParameters(new TypeList.Generic.ForLoadedTypes(types));
1✔
3738
                        }
3739

3740
                        /**
3741
                         * {@inheritDoc}
3742
                         */
3743
                        public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
3744
                            return withParameters(Arrays.asList(type));
1✔
3745
                        }
3746

3747
                        /**
3748
                         * {@inheritDoc}
3749
                         */
3750
                        public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
3751
                            ParameterDefinition.Simple<W> parameterDefinition = this;
1✔
3752
                            for (TypeDefinition type : types) {
1✔
3753
                                parameterDefinition = parameterDefinition.withParameter(type);
1✔
3754
                            }
1✔
3755
                            return parameterDefinition;
1✔
3756
                        }
3757
                    }
3758
                }
3759

3760
                /**
3761
                 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable, thrown exception or parameter type.
3762
                 *
3763
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3764
                 */
3765
                abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
1✔
3766

3767
                    /**
3768
                     * {@inheritDoc}
3769
                     */
3770
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
3771
                        return withParameter(type, name, Arrays.asList(modifierContributor));
1✔
3772
                    }
3773

3774
                    /**
3775
                     * {@inheritDoc}
3776
                     */
3777
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
3778
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
3779
                    }
3780

3781
                    /**
3782
                     * {@inheritDoc}
3783
                     */
3784
                    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
3785
                        return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
1✔
3786
                    }
3787

3788
                    /**
3789
                     * {@inheritDoc}
3790
                     */
3791
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
3792
                        return withParameter(type, name, Arrays.asList(modifierContributor));
×
3793
                    }
3794

3795
                    /**
3796
                     * {@inheritDoc}
3797
                     */
3798
                    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
3799
                        return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
×
3800
                    }
3801
                }
3802
            }
3803

3804
            /**
3805
             * An abstract base implementation of a method definition.
3806
             *
3807
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3808
             */
3809
            abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
1✔
3810

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

3818
                /**
3819
                 * {@inheritDoc}
3820
                 */
3821
                public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
3822
                    return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
3823
                }
3824

3825
                /**
3826
                 * {@inheritDoc}
3827
                 */
3828
                public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
3829
                    return annotateMethod(Arrays.asList(annotation));
1✔
3830
                }
3831

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

3839
                /**
3840
                 * {@inheritDoc}
3841
                 */
3842
                public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
3843
                    return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
×
3844
                }
3845

3846
                /**
3847
                 * {@inheritDoc}
3848
                 */
3849
                public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
3850
                    return annotateParameter(index, Arrays.asList(annotation));
×
3851
                }
3852

3853
                /**
3854
                 * An adapter implementation of a method definition.
3855
                 *
3856
                 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3857
                 */
3858
                @HashCodeAndEqualsPlugin.Enhance
3859
                protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
3860

3861
                    /**
3862
                     * The handler that determines how a method is implemented.
3863
                     */
3864
                    protected final MethodRegistry.Handler handler;
3865

3866
                    /**
3867
                     * The method attribute appender factory to apply onto the method that is currently being implemented.
3868
                     */
3869
                    protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
3870

3871
                    /**
3872
                     * The transformer to apply onto the method that is currently being implemented.
3873
                     */
3874
                    protected final Transformer<MethodDescription> transformer;
3875

3876
                    /**
3877
                     * Creates a new adapter for a method definition.
3878
                     *
3879
                     * @param handler                        The handler that determines how a method is implemented.
3880
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3881
                     * @param transformer                    The transformer to apply onto the method that is currently being implemented.
3882
                     */
3883
                    protected Adapter(MethodRegistry.Handler handler,
3884
                                      MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3885
                                      Transformer<MethodDescription> transformer) {
1✔
3886
                        this.handler = handler;
1✔
3887
                        this.methodAttributeAppenderFactory = methodAttributeAppenderFactory;
1✔
3888
                        this.transformer = transformer;
1✔
3889
                    }
1✔
3890

3891
                    /**
3892
                     * {@inheritDoc}
3893
                     */
3894
                    public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
3895
                        return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), transformer);
1✔
3896
                    }
3897

3898
                    /**
3899
                     * {@inheritDoc}
3900
                     */
3901
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
3902
                    public MethodDefinition<V> transform(Transformer<MethodDescription> transformer) {
3903
                        return materialize(handler, methodAttributeAppenderFactory, new Transformer.Compound<MethodDescription>(this.transformer, transformer));
1✔
3904
                    }
3905

3906
                    /**
3907
                     * Materializes the current builder as a method definition.
3908
                     *
3909
                     * @param handler                        The handler that determines how a method is implemented.
3910
                     * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3911
                     * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
3912
                     * @return Returns a method definition for the supplied properties.
3913
                     */
3914
                    protected abstract MethodDefinition<V> materialize(MethodRegistry.Handler handler,
3915
                                                                       MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3916
                                                                       Transformer<MethodDescription> transformer);
3917
                }
3918
            }
3919
        }
3920

3921
        /**
3922
         * A builder for a record component definition.
3923
         *
3924
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3925
         */
3926
        interface RecordComponentDefinition<S> {
3927

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

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

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

3952
            /**
3953
             * Annotates the record component with the supplied annotations.
3954
             *
3955
             * @param annotations The annotations to declare.
3956
             * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3957
             */
3958
            Optional<S> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations);
3959

3960
            /**
3961
             * Applies the supplied record component attribute appender factory onto the previously defined record component.
3962
             *
3963
             * @param recordComponentAttributeAppenderFactory The record component attribute appender factory that should be applied on the
3964
             *                                                previously defined or matched method.
3965
             * @return A new builder that is equal to this builder but with the supplied record component attribute appender factory
3966
             * applied to the previously defined record component.
3967
             */
3968
            Optional<S> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory);
3969

3970
            /**
3971
             * Transforms a record component description before writing.
3972
             *
3973
             * @param transformer The transformer to apply.
3974
             * @return new builder that is equal to this builder but with the supplied transformer being applied.
3975
             */
3976
            Optional<S> transform(Transformer<RecordComponentDescription> transformer);
3977

3978
            /**
3979
             * A {@link RecordComponentDefinition} as an optional build step.
3980
             *
3981
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3982
             */
3983
            interface Optional<U> extends RecordComponentDefinition<U>, Builder<U> {
3984

3985
                /**
3986
                 * An abstract base implementation of a record definition.
3987
                 *
3988
                 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3989
                 */
3990
                abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements RecordComponentDefinition.Optional<U> {
×
3991

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

3999
                    /**
4000
                     * {@inheritDoc}
4001
                     */
4002
                    public Optional<U> annotateRecordComponent(List<? extends Annotation> annotations) {
4003
                        return annotateRecordComponent(new AnnotationList.ForLoadedAnnotations(annotations));
×
4004
                    }
4005

4006
                    /**
4007
                     * {@inheritDoc}
4008
                     */
4009
                    public Optional<U> annotateRecordComponent(AnnotationDescription... annotation) {
4010
                        return annotateRecordComponent(Arrays.asList(annotation));
×
4011
                    }
4012
                }
4013
            }
4014
        }
4015

4016
        /**
4017
         * An abstract base implementation of a dynamic type builder.
4018
         *
4019
         * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
4020
         */
4021
        abstract class AbstractBase<S> implements Builder<S> {
1✔
4022

4023
            /**
4024
             * {@inheritDoc}
4025
             */
4026
            public ModuleDefinition<S> module(String name, ModifierContributor.ForModule... modifierContributors) {
4027
                return module(name, Arrays.asList(modifierContributors));
×
4028
            }
4029

4030
            /**
4031
             * {@inheritDoc}
4032
             */
4033
            public ModuleDefinition<S> module(String name, Collection<? extends ModifierContributor.ForModule> modifierContributors) {
4034
                return module(name, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4035
            }
4036

4037
            /**
4038
             * {@inheritDoc}
4039
             */
4040
            public ModuleDefinition<S> adjustModule(ModifierContributor.ForModule... modifierContributor) {
4041
                return adjustModule(Arrays.asList(modifierContributor));
1✔
4042
            }
4043

4044
            /**
4045
             * {@inheritDoc}
4046
             */
4047
            public InnerTypeDefinition.ForType<S> innerTypeOf(Class<?> type) {
4048
                return innerTypeOf(TypeDescription.ForLoadedType.of(type));
1✔
4049
            }
4050

4051
            /**
4052
             * {@inheritDoc}
4053
             */
4054
            public InnerTypeDefinition<S> innerTypeOf(Method method) {
4055
                return innerTypeOf(new MethodDescription.ForLoadedMethod(method));
1✔
4056
            }
4057

4058
            /**
4059
             * {@inheritDoc}
4060
             */
4061
            public InnerTypeDefinition<S> innerTypeOf(Constructor<?> constructor) {
4062
                return innerTypeOf(new MethodDescription.ForLoadedConstructor(constructor));
1✔
4063
            }
4064

4065
            /**
4066
             * {@inheritDoc}
4067
             */
4068
            public Builder<S> declaredTypes(Class<?>... type) {
4069
                return declaredTypes(Arrays.asList(type));
×
4070
            }
4071

4072
            /**
4073
             * {@inheritDoc}
4074
             */
4075
            public Builder<S> declaredTypes(TypeDescription... type) {
4076
                return declaredTypes(Arrays.asList(type));
1✔
4077
            }
4078

4079
            /**
4080
             * {@inheritDoc}
4081
             */
4082
            public Builder<S> declaredTypes(List<? extends Class<?>> type) {
4083
                return declaredTypes(new TypeList.ForLoadedTypes(type));
×
4084
            }
4085

4086
            /**
4087
             * {@inheritDoc}
4088
             */
4089
            public Builder<S> noNestMate() {
4090
                return nestHost(TargetType.DESCRIPTION);
×
4091
            }
4092

4093
            /**
4094
             * {@inheritDoc}
4095
             */
4096
            public Builder<S> nestHost(Class<?> type) {
4097
                return nestHost(TypeDescription.ForLoadedType.of(type));
×
4098
            }
4099

4100
            /**
4101
             * {@inheritDoc}
4102
             */
4103
            public Builder<S> nestMembers(Class<?>... type) {
4104
                return nestMembers(Arrays.asList(type));
1✔
4105
            }
4106

4107
            /**
4108
             * {@inheritDoc}
4109
             */
4110
            public Builder<S> nestMembers(TypeDescription... type) {
4111
                return nestMembers(Arrays.asList(type));
×
4112
            }
4113

4114
            /**
4115
             * {@inheritDoc}
4116
             */
4117
            public Builder<S> nestMembers(List<? extends Class<?>> types) {
4118
                return nestMembers(new TypeList.ForLoadedTypes(types));
1✔
4119
            }
4120

4121
            /**
4122
             * {@inheritDoc}
4123
             */
4124
            public Builder<S> permittedSubclass(Class<?>... type) {
4125
                return permittedSubclass(Arrays.asList(type));
×
4126
            }
4127

4128
            /**
4129
             * {@inheritDoc}
4130
             */
4131
            public Builder<S> permittedSubclass(TypeDescription... type) {
4132
                return permittedSubclass(Arrays.asList(type));
×
4133
            }
4134

4135
            /**
4136
             * {@inheritDoc}
4137
             */
4138
            public Builder<S> permittedSubclass(List<? extends Class<?>> types) {
4139
                return permittedSubclass(new TypeList.ForLoadedTypes(types));
×
4140
            }
4141

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

4149
            /**
4150
             * {@inheritDoc}
4151
             */
4152
            public Builder<S> annotateType(List<? extends Annotation> annotations) {
4153
                return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
1✔
4154
            }
4155

4156
            /**
4157
             * {@inheritDoc}
4158
             */
4159
            public Builder<S> annotateType(AnnotationDescription... annotation) {
4160
                return annotateType(Arrays.asList(annotation));
1✔
4161
            }
4162

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

4170
            /**
4171
             * {@inheritDoc}
4172
             */
4173
            public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4174
                return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4175
            }
4176

4177
            /**
4178
             * {@inheritDoc}
4179
             */
4180
            public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
4181
                return merge(Arrays.asList(modifierContributor));
1✔
4182
            }
4183

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

4191
            /**
4192
             * {@inheritDoc}
4193
             */
4194
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
4195
                return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
1✔
4196
            }
4197

4198
            /**
4199
             * {@inheritDoc}
4200
             */
4201
            public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
4202
                return implement(Arrays.asList(interfaceType));
1✔
4203
            }
4204

4205
            /**
4206
             * {@inheritDoc}
4207
             */
4208
            public TypeVariableDefinition<S> typeVariable(String symbol) {
4209
                return typeVariable(symbol, TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class));
1✔
4210
            }
4211

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

4219
            /**
4220
             * {@inheritDoc}
4221
             */
4222
            public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
4223
                return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1✔
4224
            }
4225

4226
            /**
4227
             * {@inheritDoc}
4228
             */
4229
            public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
4230
                return typeVariable(symbol, Arrays.asList(bound));
1✔
4231
            }
4232

4233
            /**
4234
             * {@inheritDoc}
4235
             */
4236
            public RecordComponentDefinition.Optional<S> defineRecordComponent(String name, Type type) {
4237
                return defineRecordComponent(name, TypeDefinition.Sort.describe(type));
×
4238
            }
4239

4240
            /**
4241
             * {@inheritDoc}
4242
             */
4243
            public RecordComponentDefinition.Optional<S> define(RecordComponentDescription recordComponentDescription) {
4244
                return defineRecordComponent(recordComponentDescription.getActualName(), recordComponentDescription.getType());
×
4245
            }
4246

4247
            /**
4248
             * {@inheritDoc}
4249
             */
4250
            public RecordComponentDefinition<S> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
4251
                return recordComponent(new LatentMatcher.Resolved<RecordComponentDescription>(matcher));
×
4252
            }
4253

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

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

4268
            /**
4269
             * {@inheritDoc}
4270
             */
4271
            public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
4272
                return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
1✔
4273
            }
4274

4275
            /**
4276
             * {@inheritDoc}
4277
             */
4278
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
4279
                return defineField(name, type, Arrays.asList(modifierContributor));
1✔
4280
            }
4281

4282
            /**
4283
             * {@inheritDoc}
4284
             */
4285
            public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
4286
                return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4287
            }
4288

4289
            /**
4290
             * {@inheritDoc}
4291
             */
4292
            public FieldDefinition.Optional.Valuable<S> define(Field field) {
4293
                return define(new FieldDescription.ForLoadedField(field));
×
4294
            }
4295

4296
            /**
4297
             * {@inheritDoc}
4298
             */
4299
            public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
4300
                return defineField(field.getName(), field.getType(), field.getModifiers());
×
4301
            }
4302

4303
            /**
4304
             * {@inheritDoc}
4305
             */
4306
            public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
4307
                return defineField("serialVersionUID", long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
1✔
4308
            }
4309

4310
            /**
4311
             * {@inheritDoc}
4312
             */
4313
            public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
4314
                return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
1✔
4315
            }
4316

4317
            /**
4318
             * {@inheritDoc}
4319
             */
4320
            public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
4321
                return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
1✔
4322
            }
4323

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

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

4338
            /**
4339
             * {@inheritDoc}
4340
             */
4341
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
4342
                return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
1✔
4343
            }
4344

4345
            /**
4346
             * {@inheritDoc}
4347
             */
4348
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
4349
                return defineMethod(name, returnType, Arrays.asList(modifierContributor));
1✔
4350
            }
4351

4352
            /**
4353
             * {@inheritDoc}
4354
             */
4355
            public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4356
                return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4357
            }
4358

4359
            /**
4360
             * {@inheritDoc}
4361
             */
4362
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
4363
                return defineConstructor(Arrays.asList(modifierContributor));
1✔
4364
            }
4365

4366
            /**
4367
             * {@inheritDoc}
4368
             */
4369
            public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
4370
                return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
1✔
4371
            }
4372

4373
            /**
4374
             * {@inheritDoc}
4375
             */
4376
            public MethodDefinition.ImplementationDefinition<S> define(Method method) {
4377
                return define(new MethodDescription.ForLoadedMethod(method));
×
4378
            }
4379

4380
            /**
4381
             * {@inheritDoc}
4382
             */
4383
            public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
4384
                return define(new MethodDescription.ForLoadedConstructor(constructor));
×
4385
            }
4386

4387
            /**
4388
             * {@inheritDoc}
4389
             */
4390
            public MethodDefinition.ImplementationDefinition<S> define(MethodDescription methodDescription) {
4391
                MethodDefinition.ParameterDefinition.Initial<S> initialParameterDefinition = methodDescription.isConstructor()
×
4392
                        ? defineConstructor(methodDescription.getModifiers())
×
4393
                        : defineMethod(methodDescription.getInternalName(), methodDescription.getReturnType(), methodDescription.getModifiers());
×
4394
                ParameterList<?> parameterList = methodDescription.getParameters();
×
4395
                MethodDefinition.ExceptionDefinition<S> exceptionDefinition;
4396
                if (parameterList.hasExplicitMetaData()) {
×
4397
                    MethodDefinition.ParameterDefinition<S> parameterDefinition = initialParameterDefinition;
×
4398
                    for (ParameterDescription parameter : parameterList) {
×
4399
                        parameterDefinition = parameterDefinition.withParameter(parameter.getType(), parameter.getName(), parameter.getModifiers());
×
4400
                    }
×
4401
                    exceptionDefinition = parameterDefinition;
×
4402
                } else {
×
4403
                    exceptionDefinition = initialParameterDefinition.withParameters(parameterList.asTypeList());
×
4404
                }
4405
                MethodDefinition.TypeVariableDefinition<S> typeVariableDefinition = exceptionDefinition.throwing(methodDescription.getExceptionTypes());
×
4406
                for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
×
4407
                    typeVariableDefinition = typeVariableDefinition.typeVariable(typeVariable.getSymbol(), typeVariable.getUpperBounds());
×
4408
                }
×
4409
                return typeVariableDefinition;
×
4410
            }
4411

4412
            /**
4413
             * {@inheritDoc}
4414
             */
4415
            public FieldDefinition.Optional<S> defineProperty(String name, Type type) {
4416
                return defineProperty(name, TypeDefinition.Sort.describe(type));
1✔
4417
            }
4418

4419
            /**
4420
             * {@inheritDoc}
4421
             */
4422
            public FieldDefinition.Optional<S> defineProperty(String name, Type type, boolean readOnly) {
4423
                return defineProperty(name, TypeDefinition.Sort.describe(type), readOnly);
1✔
4424
            }
4425

4426
            /**
4427
             * {@inheritDoc}
4428
             */
4429
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type) {
4430
                return defineProperty(name, type, false);
1✔
4431
            }
4432

4433
            /**
4434
             * {@inheritDoc}
4435
             */
4436
            public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type, boolean readOnly) {
4437
                if (name.length() == 0) {
1✔
4438
                    throw new IllegalArgumentException("A bean property cannot have an empty name");
1✔
4439
                } else if (type.represents(void.class)) {
1✔
4440
                    throw new IllegalArgumentException("A bean property cannot have a void type");
1✔
4441
                }
4442
                DynamicType.Builder<S> builder = this;
1✔
4443
                FieldManifestation fieldManifestation;
4444
                if (!readOnly) {
1✔
4445
                    builder = builder
1✔
4446
                            .defineMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), void.class, Visibility.PUBLIC)
1✔
4447
                            .withParameters(type)
1✔
4448
                            .intercept(FieldAccessor.ofField(name));
1✔
4449
                    fieldManifestation = FieldManifestation.PLAIN;
1✔
4450
                } else {
4451
                    fieldManifestation = FieldManifestation.FINAL;
1✔
4452
                }
4453
                return builder
1✔
4454
                        .defineMethod((type.represents(boolean.class)
1✔
4455
                                ? "is"
4456
                                : "get") + Character.toUpperCase(name.charAt(0)) + name.substring(1), type, Visibility.PUBLIC)
1✔
4457
                        .intercept(FieldAccessor.ofField(name))
1✔
4458
                        .defineField(name, type, Visibility.PRIVATE, fieldManifestation);
1✔
4459
            }
4460

4461
            /**
4462
             * {@inheritDoc}
4463
             */
4464
            public MethodDefinition.ImplementationDefinition<S> method(ElementMatcher<? super MethodDescription> matcher) {
4465
                return invokable(isMethod().and(matcher));
1✔
4466
            }
4467

4468
            /**
4469
             * {@inheritDoc}
4470
             */
4471
            public MethodDefinition.ImplementationDefinition<S> constructor(ElementMatcher<? super MethodDescription> matcher) {
4472
                return invokable(isConstructor().and(matcher));
1✔
4473
            }
4474

4475
            /**
4476
             * {@inheritDoc}
4477
             */
4478
            public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
4479
                return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
1✔
4480
            }
4481

4482
            /**
4483
             * {@inheritDoc}
4484
             */
4485
            public Builder<S> withHashCodeEquals() {
4486
                return method(isHashCode())
1✔
4487
                        .intercept(HashCodeMethod.usingDefaultOffset().withIgnoredFields(isSynthetic()))
1✔
4488
                        .method(isEquals())
1✔
4489
                        .intercept(EqualsMethod.isolated().withIgnoredFields(isSynthetic()));
1✔
4490
            }
4491

4492
            /**
4493
             * {@inheritDoc}
4494
             */
4495
            public Builder<S> withToString() {
4496
                return method(isToString()).intercept(ToStringMethod.prefixedBySimpleClassName());
1✔
4497
            }
4498

4499
            /**
4500
             * {@inheritDoc}
4501
             */
4502
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation) {
4503
                return require(type, binaryRepresentation, LoadedTypeInitializer.NoOp.INSTANCE);
1✔
4504
            }
4505

4506
            /**
4507
             * {@inheritDoc}
4508
             */
4509
            public Builder<S> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer) {
4510
                return require(new Default(type, binaryRepresentation, typeInitializer, Collections.<DynamicType>emptyList()));
1✔
4511
            }
4512

4513
            /**
4514
             * {@inheritDoc}
4515
             */
4516
            public Builder<S> require(DynamicType... auxiliaryType) {
4517
                return require(Arrays.asList(auxiliaryType));
1✔
4518
            }
4519

4520
            /**
4521
             * {@inheritDoc}
4522
             */
4523
            public ContextClassVisitor wrap(ClassVisitor classVisitor) {
4524
                return wrap(classVisitor, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
1✔
4525
            }
4526

4527
            /**
4528
             * {@inheritDoc}
4529
             */
4530
            public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool) {
4531
                return wrap(classVisitor, typePool, AsmVisitorWrapper.NO_FLAGS, AsmVisitorWrapper.NO_FLAGS);
×
4532
            }
4533

4534
            /**
4535
             * {@inheritDoc}
4536
             */
4537
            public Unloaded<S> make(TypePool typePool) {
4538
                return make(TypeResolutionStrategy.Passive.INSTANCE, typePool);
1✔
4539
            }
4540

4541
            /**
4542
             * {@inheritDoc}
4543
             */
4544
            public Unloaded<S> make() {
4545
                return make(TypeResolutionStrategy.Passive.INSTANCE);
1✔
4546
            }
4547

4548
            /**
4549
             * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
4550
             *
4551
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4552
             */
4553
            public abstract static class Delegator<U> extends AbstractBase<U> {
1✔
4554

4555
                /**
4556
                 * {@inheritDoc}
4557
                 */
4558
                public ModuleDefinition<U> module(String name, int modifiers) {
4559
                    return materialize().module(name, modifiers);
×
4560
                }
4561

4562
                /**
4563
                 * {@inheritDoc}
4564
                 */
4565
                public ModuleDefinition<U> adjustModule(ModifierContributor.ForModule... modifierContributor) {
4566
                    return materialize().adjustModule(modifierContributor);
×
4567
                }
4568

4569
                /**
4570
                 * {@inheritDoc}
4571
                 */
4572
                public ModuleDefinition<U> adjustModule(Collection<? extends ModifierContributor.ForModule> modifierContributors) {
4573
                    return materialize().adjustModule(modifierContributors);
×
4574
                }
4575

4576
                /**
4577
                 * {@inheritDoc}
4578
                 */
4579
                public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
4580
                    return materialize().visit(asmVisitorWrapper);
1✔
4581
                }
4582

4583
                /**
4584
                 * {@inheritDoc}
4585
                 */
4586
                public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
4587
                    return materialize().initializer(loadedTypeInitializer);
1✔
4588
                }
4589

4590
                /**
4591
                 * {@inheritDoc}
4592
                 */
4593
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
4594
                    return materialize().annotateType(annotations);
×
4595
                }
4596

4597
                /**
4598
                 * {@inheritDoc}
4599
                 */
4600
                public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
4601
                    return materialize().attribute(typeAttributeAppender);
×
4602
                }
4603

4604
                /**
4605
                 * {@inheritDoc}
4606
                 */
4607
                public Builder<U> modifiers(int modifiers) {
4608
                    return materialize().modifiers(modifiers);
1✔
4609
                }
4610

4611
                /**
4612
                 * {@inheritDoc}
4613
                 */
4614
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4615
                    return materialize().merge(modifierContributors);
×
4616
                }
4617

4618
                /**
4619
                 * {@inheritDoc}
4620
                 */
4621
                public Builder<U> suffix(String suffix) {
4622
                    return materialize().suffix(suffix);
×
4623
                }
4624

4625
                /**
4626
                 * {@inheritDoc}
4627
                 */
4628
                public Builder<U> name(String name) {
4629
                    return materialize().name(name);
1✔
4630
                }
4631

4632
                /**
4633
                 * {@inheritDoc}
4634
                 */
4635
                public Builder<U> topLevelType() {
4636
                    return materialize().topLevelType();
×
4637
                }
4638

4639
                /**
4640
                 * {@inheritDoc}
4641
                 */
4642
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
4643
                    return materialize().innerTypeOf(type);
×
4644
                }
4645

4646
                /**
4647
                 * {@inheritDoc}
4648
                 */
4649
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
4650
                    return materialize().innerTypeOf(methodDescription);
×
4651
                }
4652

4653
                /**
4654
                 * {@inheritDoc}
4655
                 */
4656
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
4657
                    return materialize().declaredTypes(types);
1✔
4658
                }
4659

4660
                /**
4661
                 * {@inheritDoc}
4662
                 */
4663
                public Builder<U> nestHost(TypeDescription type) {
4664
                    return materialize().nestHost(type);
×
4665
                }
4666

4667
                /**
4668
                 * {@inheritDoc}
4669
                 */
4670
                public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
4671
                    return materialize().nestMembers(types);
×
4672
                }
4673

4674
                /**
4675
                 * {@inheritDoc}
4676
                 */
4677
                public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
4678
                    return materialize().permittedSubclass(types);
×
4679
                }
4680

4681
                /**
4682
                 * {@inheritDoc}
4683
                 */
4684
                public Builder<U> unsealed() {
4685
                    return materialize().unsealed();
×
4686
                }
4687

4688
                /**
4689
                 * {@inheritDoc}
4690
                 */
4691
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
4692
                    return materialize().implement(interfaceTypes);
1✔
4693
                }
4694

4695
                /**
4696
                 * {@inheritDoc}
4697
                 */
4698
                public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
4699
                    return materialize().initializer(byteCodeAppender);
1✔
4700
                }
4701

4702
                /**
4703
                 * {@inheritDoc}
4704
                 */
4705
                public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
4706
                    return materialize().ignoreAlso(ignoredMethods);
1✔
4707
                }
4708

4709
                /**
4710
                 * {@inheritDoc}
4711
                 */
4712
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
4713
                    return materialize().ignoreAlso(ignoredMethods);
×
4714
                }
4715

4716
                /**
4717
                 * {@inheritDoc}
4718
                 */
4719
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
4720
                    return materialize().typeVariable(symbol, bounds);
1✔
4721
                }
4722

4723
                /**
4724
                 * {@inheritDoc}
4725
                 */
4726
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
4727
                    return materialize().transform(matcher, transformer);
1✔
4728
                }
4729

4730
                /**
4731
                 * {@inheritDoc}
4732
                 */
4733
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
4734
                    return materialize().defineField(name, type, modifiers);
1✔
4735
                }
4736

4737
                /**
4738
                 * {@inheritDoc}
4739
                 */
4740
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
4741
                    return materialize().field(matcher);
1✔
4742
                }
4743

4744
                /**
4745
                 * {@inheritDoc}
4746
                 */
4747
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4748
                    return materialize().defineMethod(name, returnType, modifiers);
1✔
4749
                }
4750

4751
                /**
4752
                 * {@inheritDoc}
4753
                 */
4754
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4755
                    return materialize().defineConstructor(modifiers);
1✔
4756
                }
4757

4758
                /**
4759
                 * {@inheritDoc}
4760
                 */
4761
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4762
                    return materialize().invokable(matcher);
1✔
4763
                }
4764

4765
                /**
4766
                 * {@inheritDoc}
4767
                 */
4768
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
4769
                    return materialize().require(auxiliaryTypes);
×
4770
                }
4771

4772
                /**
4773
                 * {@inheritDoc}
4774
                 */
4775
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
4776
                    return materialize().defineRecordComponent(name, type);
×
4777
                }
4778

4779
                /**
4780
                 * {@inheritDoc}
4781
                 */
4782
                public RecordComponentDefinition.Optional<U> define(RecordComponentDescription recordComponentDescription) {
4783
                    return materialize().define(recordComponentDescription);
×
4784
                }
4785

4786
                /**
4787
                 * {@inheritDoc}
4788
                 */
4789
                public RecordComponentDefinition<U> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
4790
                    return materialize().recordComponent(matcher);
×
4791
                }
4792

4793
                /**
4794
                 * {@inheritDoc}
4795
                 */
4796
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
4797
                    return materialize().recordComponent(matcher);
×
4798
                }
4799

4800
                /**
4801
                 * {@inheritDoc}
4802
                 */
4803
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4804
                    return materialize().wrap(classVisitor, writerFlags, readerFlags);
1✔
4805
                }
4806

4807
                /**
4808
                 * {@inheritDoc}
4809
                 */
4810
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
4811
                    return materialize().wrap(classVisitor, typePool, writerFlags, readerFlags);
×
4812
                }
4813

4814
                /**
4815
                 * {@inheritDoc}
4816
                 */
4817
                public DynamicType.Unloaded<U> make() {
4818
                    return materialize().make();
1✔
4819
                }
4820

4821
                /**
4822
                 * {@inheritDoc}
4823
                 */
4824
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4825
                    return materialize().make(typeResolutionStrategy);
1✔
4826
                }
4827

4828
                /**
4829
                 * {@inheritDoc}
4830
                 */
4831
                public Unloaded<U> make(TypePool typePool) {
4832
                    return materialize().make(typePool);
×
4833
                }
4834

4835
                /**
4836
                 * {@inheritDoc}
4837
                 */
4838
                public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4839
                    return materialize().make(typeResolutionStrategy, typePool);
1✔
4840
                }
4841

4842
                /**
4843
                 * {@inheritDoc}
4844
                 */
4845
                public TypeDescription toTypeDescription() {
4846
                    return materialize().toTypeDescription();
1✔
4847
                }
4848

4849
                /**
4850
                 * Creates a new builder that realizes the current state of the builder.
4851
                 *
4852
                 * @return A new builder that realizes the current state of the builder.
4853
                 */
4854
                protected abstract Builder<U> materialize();
4855
            }
4856

4857
            /**
4858
             * A dynamic type writer that uses a {@link TypeWriter} to create a dynamic type.
4859
             *
4860
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4861
             */
4862
            public abstract static class UsingTypeWriter<U> extends AbstractBase<U> {
1✔
4863

4864
                /**
4865
                 * {@inheritDoc}
4866
                 */
4867
                public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int readerFlags) {
4868
                    return toTypeWriter().wrap(classVisitor, writerFlags, readerFlags);
1✔
4869
                }
4870

4871
                /**
4872
                 * {@inheritDoc}
4873
                 */
4874
                public ContextClassVisitor wrap(ClassVisitor classVisitor, TypePool typePool, int writerFlags, int readerFlags) {
4875
                    return toTypeWriter(typePool).wrap(classVisitor, writerFlags, readerFlags);
×
4876
                }
4877

4878
                /**
4879
                 * {@inheritDoc}
4880
                 */
4881
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
4882
                    return toTypeWriter().make(typeResolutionStrategy.resolve());
1✔
4883
                }
4884

4885
                /**
4886
                 * {@inheritDoc}
4887
                 */
4888
                public DynamicType.Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
4889
                    return toTypeWriter(typePool).make(typeResolutionStrategy.resolve());
1✔
4890
                }
4891

4892
                /**
4893
                 * Creates a {@link TypeWriter} without an explicitly specified {@link TypePool}.
4894
                 *
4895
                 * @return An appropriate {@link TypeWriter}.
4896
                 */
4897
                protected abstract TypeWriter<U> toTypeWriter();
4898

4899
                /**
4900
                 * Creates a {@link TypeWriter} given the specified {@link TypePool}.
4901
                 *
4902
                 * @param typePool The {@link TypePool} to use.
4903
                 * @return An appropriate {@link TypeWriter}.
4904
                 */
4905
                protected abstract TypeWriter<U> toTypeWriter(TypePool typePool);
4906
            }
4907

4908
            /**
4909
             * An adapter implementation of a dynamic type builder.
4910
             *
4911
             * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
4912
             */
4913
            @HashCodeAndEqualsPlugin.Enhance
4914
            public abstract static class Adapter<U> extends UsingTypeWriter<U> {
4915

4916
                /**
4917
                 * The instrumented type to be created.
4918
                 */
4919
                protected final InstrumentedType.WithFlexibleName instrumentedType;
4920

4921
                /**
4922
                 * The current field registry.
4923
                 */
4924
                protected final FieldRegistry fieldRegistry;
4925

4926
                /**
4927
                 * The current method registry.
4928
                 */
4929
                protected final MethodRegistry methodRegistry;
4930

4931
                /**
4932
                 * The current record component registry.
4933
                 */
4934
                protected final RecordComponentRegistry recordComponentRegistry;
4935

4936
                /**
4937
                 * The type attribute appender to apply onto the instrumented type.
4938
                 */
4939
                protected final TypeAttributeAppender typeAttributeAppender;
4940

4941
                /**
4942
                 * The ASM visitor wrapper to apply onto the class writer.
4943
                 */
4944
                protected final AsmVisitorWrapper asmVisitorWrapper;
4945

4946
                /**
4947
                 * The class file version to define auxiliary types in.
4948
                 */
4949
                protected final ClassFileVersion classFileVersion;
4950

4951
                /**
4952
                 * The naming strategy for auxiliary types to apply.
4953
                 */
4954
                protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
4955

4956
                /**
4957
                 * The annotation value filter factory to apply.
4958
                 */
4959
                protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
4960

4961
                /**
4962
                 * The annotation retention to apply.
4963
                 */
4964
                protected final AnnotationRetention annotationRetention;
4965

4966
                /**
4967
                 * The implementation context factory to apply.
4968
                 */
4969
                protected final Implementation.Context.Factory implementationContextFactory;
4970

4971
                /**
4972
                 * The method graph compiler to use.
4973
                 */
4974
                protected final MethodGraph.Compiler methodGraphCompiler;
4975

4976
                /**
4977
                 * Determines if a type should be explicitly validated.
4978
                 */
4979
                protected final TypeValidation typeValidation;
4980

4981
                /**
4982
                 * The visibility bridge strategy to apply.
4983
                 */
4984
                protected final VisibilityBridgeStrategy visibilityBridgeStrategy;
4985

4986
                /**
4987
                 * The class reader factory to use.
4988
                 */
4989
                protected final AsmClassReader.Factory classReaderFactory;
4990

4991
                /**
4992
                 * The class writer factory to use.
4993
                 */
4994
                protected final AsmClassWriter.Factory classWriterFactory;
4995

4996
                /**
4997
                 * A matcher for identifying methods that should be excluded from instrumentation.
4998
                 */
4999
                protected final LatentMatcher<? super MethodDescription> ignoredMethods;
5000

5001
                /**
5002
                 * A list of explicitly defined auxiliary types.
5003
                 */
5004
                protected final List<? extends DynamicType> auxiliaryTypes;
5005

5006
                /**
5007
                 * Creates a new default type writer for creating a new type that is not based on an existing class file.
5008
                 *
5009
                 * @param instrumentedType             The instrumented type to be created.
5010
                 * @param fieldRegistry                The current field registry.
5011
                 * @param methodRegistry               The current method registry.
5012
                 * @param recordComponentRegistry      The record component pool to use.
5013
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
5014
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
5015
                 * @param classFileVersion             The class file version to define auxiliary types in.
5016
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
5017
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
5018
                 * @param annotationRetention          The annotation retention to apply.
5019
                 * @param implementationContextFactory The implementation context factory to apply.
5020
                 * @param methodGraphCompiler          The method graph compiler to use.
5021
                 * @param typeValidation               Determines if a type should be explicitly validated.
5022
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
5023
                 * @param classReaderFactory           The class reader factory to use.
5024
                 * @param classWriterFactory           The class writer factory to use.
5025
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
5026
                 * @param auxiliaryTypes               A list of explicitly defined auxiliary types.
5027
                 */
5028
                protected Adapter(InstrumentedType.WithFlexibleName instrumentedType,
5029
                                  FieldRegistry fieldRegistry,
5030
                                  MethodRegistry methodRegistry,
5031
                                  RecordComponentRegistry recordComponentRegistry,
5032
                                  TypeAttributeAppender typeAttributeAppender,
5033
                                  AsmVisitorWrapper asmVisitorWrapper,
5034
                                  ClassFileVersion classFileVersion,
5035
                                  AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
5036
                                  AnnotationValueFilter.Factory annotationValueFilterFactory,
5037
                                  AnnotationRetention annotationRetention,
5038
                                  Implementation.Context.Factory implementationContextFactory,
5039
                                  MethodGraph.Compiler methodGraphCompiler,
5040
                                  TypeValidation typeValidation,
5041
                                  VisibilityBridgeStrategy visibilityBridgeStrategy,
5042
                                  AsmClassReader.Factory classReaderFactory,
5043
                                  AsmClassWriter.Factory classWriterFactory,
5044
                                  LatentMatcher<? super MethodDescription> ignoredMethods,
5045
                                  List<? extends DynamicType> auxiliaryTypes) {
1✔
5046
                    this.instrumentedType = instrumentedType;
1✔
5047
                    this.fieldRegistry = fieldRegistry;
1✔
5048
                    this.methodRegistry = methodRegistry;
1✔
5049
                    this.recordComponentRegistry = recordComponentRegistry;
1✔
5050
                    this.typeAttributeAppender = typeAttributeAppender;
1✔
5051
                    this.asmVisitorWrapper = asmVisitorWrapper;
1✔
5052
                    this.classFileVersion = classFileVersion;
1✔
5053
                    this.auxiliaryTypeNamingStrategy = auxiliaryTypeNamingStrategy;
1✔
5054
                    this.annotationValueFilterFactory = annotationValueFilterFactory;
1✔
5055
                    this.annotationRetention = annotationRetention;
1✔
5056
                    this.implementationContextFactory = implementationContextFactory;
1✔
5057
                    this.methodGraphCompiler = methodGraphCompiler;
1✔
5058
                    this.typeValidation = typeValidation;
1✔
5059
                    this.visibilityBridgeStrategy = visibilityBridgeStrategy;
1✔
5060
                    this.classReaderFactory = classReaderFactory;
1✔
5061
                    this.classWriterFactory = classWriterFactory;
1✔
5062
                    this.ignoredMethods = ignoredMethods;
1✔
5063
                    this.auxiliaryTypes = auxiliaryTypes;
1✔
5064
                }
1✔
5065

5066
                /**
5067
                 * {@inheritDoc}
5068
                 */
5069
                public ModuleDefinition<U> module(String name, int modifiers) {
5070
                    return new ModuleDefinitionAdapter(name, modifiers);
1✔
5071
                }
5072

5073
                /**
5074
                 * {@inheritDoc}
5075
                 */
5076
                public ModuleDefinition<U> adjustModule(Collection<? extends ModifierContributor.ForModule> modifierContributors) {
5077
                    ModuleDescription moduleDescription = instrumentedType.toModuleDescription();
1✔
5078
                    if (moduleDescription == null) {
1✔
5079
                        throw new IllegalStateException("Expected previous module description for " + instrumentedType);
×
5080
                    }
5081
                    return new ModuleDefinitionAdapter(moduleDescription.getActualName(),
1✔
5082
                            ModifierContributor.Resolver.of(modifierContributors).resolve(moduleDescription.getModifiers()),
1✔
5083
                            moduleDescription.getVersion(),
1✔
5084
                            moduleDescription.getMainClass(),
1✔
5085
                            moduleDescription.getPackages(),
1✔
5086
                            moduleDescription.getRequires(),
1✔
5087
                            moduleDescription.getExports(),
1✔
5088
                            moduleDescription.getOpens(),
1✔
5089
                            moduleDescription.getUses(),
1✔
5090
                            moduleDescription.getProvides());
1✔
5091
                }
5092

5093
                /**
5094
                 * {@inheritDoc}
5095
                 */
5096
                public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
5097
                    return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
1✔
5098
                }
5099

5100
                /**
5101
                 * {@inheritDoc}
5102
                 */
5103
                public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
5104
                    return new FieldMatchAdapter(matcher);
1✔
5105
                }
5106

5107
                /**
5108
                 * {@inheritDoc}
5109
                 */
5110
                public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
5111
                    return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
1✔
5112
                }
5113

5114
                /**
5115
                 * {@inheritDoc}
5116
                 */
5117
                public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
5118
                    return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
1✔
5119
                }
5120

5121
                /**
5122
                 * {@inheritDoc}
5123
                 */
5124
                public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
5125
                    return new MethodMatchAdapter(matcher);
1✔
5126
                }
5127

5128
                /**
5129
                 * {@inheritDoc}
5130
                 */
5131
                public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
5132
                    return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
1✔
5133
                }
5134

5135
                /**
5136
                 * {@inheritDoc}
5137
                 */
5138
                @SuppressWarnings("unchecked") // In absence of @SafeVarargs
5139
                public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
5140
                    return materialize(instrumentedType,
1✔
5141
                            fieldRegistry,
5142
                            methodRegistry,
5143
                            recordComponentRegistry,
5144
                            typeAttributeAppender,
5145
                            asmVisitorWrapper,
5146
                            classFileVersion,
5147
                            auxiliaryTypeNamingStrategy,
5148
                            annotationValueFilterFactory,
5149
                            annotationRetention,
5150
                            implementationContextFactory,
5151
                            methodGraphCompiler,
5152
                            typeValidation,
5153
                            visibilityBridgeStrategy,
5154
                            classReaderFactory,
5155
                            classWriterFactory,
5156
                            new LatentMatcher.Disjunction<MethodDescription>(this.ignoredMethods, ignoredMethods),
5157
                            auxiliaryTypes);
5158
                }
5159

5160
                /**
5161
                 * {@inheritDoc}
5162
                 */
5163
                public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
5164
                    return new RecordComponentDefinitionAdapter(new RecordComponentDescription.Token(name, type.asGenericType()));
×
5165
                }
5166

5167
                /**
5168
                 * {@inheritDoc}
5169
                 */
5170
                public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
5171
                    return new RecordComponentMatchAdapter(matcher);
×
5172
                }
5173

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

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

5222
                /**
5223
                 * {@inheritDoc}
5224
                 */
5225
                public Builder<U> name(String name) {
5226
                    return materialize(instrumentedType.withName(name),
1✔
5227
                            fieldRegistry,
5228
                            methodRegistry,
5229
                            recordComponentRegistry,
5230
                            typeAttributeAppender,
5231
                            asmVisitorWrapper,
5232
                            classFileVersion,
5233
                            auxiliaryTypeNamingStrategy,
5234
                            annotationValueFilterFactory,
5235
                            annotationRetention,
5236
                            implementationContextFactory,
5237
                            methodGraphCompiler,
5238
                            typeValidation,
5239
                            visibilityBridgeStrategy,
5240
                            classReaderFactory,
5241
                            classWriterFactory,
5242
                            ignoredMethods,
5243
                            auxiliaryTypes);
5244
                }
5245

5246
                /**
5247
                 * {@inheritDoc}
5248
                 */
5249
                public Builder<U> suffix(String suffix) {
5250
                    return name(instrumentedType.getName() + "$" + suffix);
×
5251
                }
5252

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

5277
                /**
5278
                 * {@inheritDoc}
5279
                 */
5280
                public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
5281
                    return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
1✔
5282
                            fieldRegistry,
5283
                            methodRegistry,
5284
                            recordComponentRegistry,
5285
                            typeAttributeAppender,
5286
                            asmVisitorWrapper,
5287
                            classFileVersion,
5288
                            auxiliaryTypeNamingStrategy,
5289
                            annotationValueFilterFactory,
5290
                            annotationRetention,
5291
                            implementationContextFactory,
5292
                            methodGraphCompiler,
5293
                            typeValidation,
5294
                            visibilityBridgeStrategy,
5295
                            classReaderFactory,
5296
                            classWriterFactory,
5297
                            ignoredMethods,
5298
                            auxiliaryTypes);
5299
                }
5300

5301
                /**
5302
                 * {@inheritDoc}
5303
                 */
5304
                public Builder<U> topLevelType() {
5305
                    return Adapter.this.materialize(instrumentedType
1✔
5306
                                    .withDeclaringType(TypeDescription.UNDEFINED)
1✔
5307
                                    .withEnclosingType(TypeDescription.UNDEFINED)
1✔
5308
                                    .withLocalClass(false),
1✔
5309
                            fieldRegistry,
5310
                            methodRegistry,
5311
                            recordComponentRegistry,
5312
                            typeAttributeAppender,
5313
                            asmVisitorWrapper,
5314
                            classFileVersion,
5315
                            auxiliaryTypeNamingStrategy,
5316
                            annotationValueFilterFactory,
5317
                            annotationRetention,
5318
                            implementationContextFactory,
5319
                            methodGraphCompiler,
5320
                            typeValidation,
5321
                            visibilityBridgeStrategy,
5322
                            classReaderFactory,
5323
                            classWriterFactory,
5324
                            ignoredMethods,
5325
                            auxiliaryTypes);
5326
                }
5327

5328
                /**
5329
                 * {@inheritDoc}
5330
                 */
5331
                public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
5332
                    return new InnerTypeDefinitionForTypeAdapter(type);
1✔
5333
                }
5334

5335
                /**
5336
                 * {@inheritDoc}
5337
                 */
5338
                public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
5339
                    return methodDescription.isTypeInitializer()
1✔
5340
                            ? new InnerTypeDefinitionForTypeAdapter(methodDescription.getDeclaringType())
1✔
5341
                            : new InnerTypeDefinitionForMethodAdapter(methodDescription);
5342
                }
5343

5344
                /**
5345
                 * {@inheritDoc}
5346
                 */
5347
                public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
5348
                    return materialize(instrumentedType.withDeclaredTypes(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
1✔
5349
                            fieldRegistry,
5350
                            methodRegistry,
5351
                            recordComponentRegistry,
5352
                            typeAttributeAppender,
5353
                            asmVisitorWrapper,
5354
                            classFileVersion,
5355
                            auxiliaryTypeNamingStrategy,
5356
                            annotationValueFilterFactory,
5357
                            annotationRetention,
5358
                            implementationContextFactory,
5359
                            methodGraphCompiler,
5360
                            typeValidation,
5361
                            visibilityBridgeStrategy,
5362
                            classReaderFactory,
5363
                            classWriterFactory,
5364
                            ignoredMethods,
5365
                            auxiliaryTypes);
5366
                }
5367

5368
                /**
5369
                 * {@inheritDoc}
5370
                 */
5371
                public Builder<U> nestHost(TypeDescription type) {
5372
                    return materialize(instrumentedType.withNestHost(type),
×
5373
                            fieldRegistry,
5374
                            methodRegistry,
5375
                            recordComponentRegistry,
5376
                            typeAttributeAppender,
5377
                            asmVisitorWrapper,
5378
                            classFileVersion,
5379
                            auxiliaryTypeNamingStrategy,
5380
                            annotationValueFilterFactory,
5381
                            annotationRetention,
5382
                            implementationContextFactory,
5383
                            methodGraphCompiler,
5384
                            typeValidation,
5385
                            visibilityBridgeStrategy,
5386
                            classReaderFactory,
5387
                            classWriterFactory,
5388
                            ignoredMethods,
5389
                            auxiliaryTypes);
5390
                }
5391

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

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

5440
                /**
5441
                 * {@inheritDoc}
5442
                 */
5443
                public Builder<U> unsealed() {
5444
                    return materialize(instrumentedType.withPermittedSubclasses(TypeList.UNDEFINED),
×
5445
                            fieldRegistry,
5446
                            methodRegistry,
5447
                            recordComponentRegistry,
5448
                            typeAttributeAppender,
5449
                            asmVisitorWrapper,
5450
                            classFileVersion,
5451
                            auxiliaryTypeNamingStrategy,
5452
                            annotationValueFilterFactory,
5453
                            annotationRetention,
5454
                            implementationContextFactory,
5455
                            methodGraphCompiler,
5456
                            typeValidation,
5457
                            visibilityBridgeStrategy,
5458
                            classReaderFactory,
5459
                            classWriterFactory,
5460
                            ignoredMethods,
5461
                            auxiliaryTypes);
5462
                }
5463

5464
                /**
5465
                 * {@inheritDoc}
5466
                 */
5467
                public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
5468
                    return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
5469
                }
5470

5471
                /**
5472
                 * {@inheritDoc}
5473
                 */
5474
                public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
5475
                    return materialize(instrumentedType.withTypeVariables(matcher, transformer),
1✔
5476
                            fieldRegistry,
5477
                            methodRegistry,
5478
                            recordComponentRegistry,
5479
                            typeAttributeAppender,
5480
                            asmVisitorWrapper,
5481
                            classFileVersion,
5482
                            auxiliaryTypeNamingStrategy,
5483
                            annotationValueFilterFactory,
5484
                            annotationRetention,
5485
                            implementationContextFactory,
5486
                            methodGraphCompiler,
5487
                            typeValidation,
5488
                            visibilityBridgeStrategy,
5489
                            classReaderFactory,
5490
                            classWriterFactory,
5491
                            ignoredMethods,
5492
                            auxiliaryTypes);
5493
                }
5494

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

5519
                /**
5520
                 * {@inheritDoc}
5521
                 */
5522
                public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
5523
                    ModuleDescription moduleDescription = instrumentedType.toModuleDescription();
1✔
5524
                    return materialize(instrumentedType
1✔
5525
                                    .withAnnotations(new ArrayList<AnnotationDescription>(annotations))
1✔
5526
                                    .withModuleDescription(moduleDescription == null ? ModuleDescription.UNDEFINED : new ModuleDescription.Latent(moduleDescription.getActualName(),
1✔
5527
                                            moduleDescription.getModifiers(),
×
5528
                                            moduleDescription.getVersion(),
×
5529
                                            moduleDescription.getMainClass(),
×
5530
                                            moduleDescription.getPackages(),
×
5531
                                            moduleDescription.getRequires(),
×
5532
                                            moduleDescription.getExports(),
×
5533
                                            moduleDescription.getOpens(),
×
5534
                                            moduleDescription.getUses(),
×
5535
                                            moduleDescription.getProvides(),
×
5536
                                            CompoundList.of(instrumentedType.getDeclaredAnnotations(), new ArrayList<AnnotationDescription>(annotations)))),
×
5537
                            fieldRegistry,
5538
                            methodRegistry,
5539
                            recordComponentRegistry,
5540
                            typeAttributeAppender,
5541
                            asmVisitorWrapper,
5542
                            classFileVersion,
5543
                            auxiliaryTypeNamingStrategy,
5544
                            annotationValueFilterFactory,
5545
                            annotationRetention,
5546
                            implementationContextFactory,
5547
                            methodGraphCompiler,
5548
                            typeValidation,
5549
                            visibilityBridgeStrategy,
5550
                            classReaderFactory,
5551
                            classWriterFactory,
5552
                            ignoredMethods,
5553
                            auxiliaryTypes);
5554
                }
5555

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

5580
                /**
5581
                 * {@inheritDoc}
5582
                 */
5583
                public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
5584
                    return materialize(instrumentedType,
1✔
5585
                            fieldRegistry,
5586
                            methodRegistry,
5587
                            recordComponentRegistry,
5588
                            typeAttributeAppender,
5589
                            asmVisitorWrapper,
5590
                            classFileVersion,
5591
                            auxiliaryTypeNamingStrategy,
5592
                            annotationValueFilterFactory,
5593
                            annotationRetention,
5594
                            implementationContextFactory,
5595
                            methodGraphCompiler,
5596
                            typeValidation,
5597
                            visibilityBridgeStrategy,
5598
                            classReaderFactory,
5599
                            classWriterFactory,
5600
                            ignoredMethods,
5601
                            CompoundList.of(this.auxiliaryTypes, new ArrayList<DynamicType>(auxiliaryTypes)));
1✔
5602
                }
5603

5604
                /**
5605
                 * {@inheritDoc}
5606
                 */
5607
                public TypeDescription toTypeDescription() {
5608
                    return instrumentedType;
1✔
5609
                }
5610

5611
                /**
5612
                 * Materializes the supplied state of a dynamic type builder.
5613
                 *
5614
                 * @param instrumentedType             The instrumented type.
5615
                 * @param fieldRegistry                The current field registry.
5616
                 * @param methodRegistry               The current method registry.
5617
                 * @param recordComponentRegistry      The record component pool to use.
5618
                 * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
5619
                 * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
5620
                 * @param classFileVersion             The class file version to define auxiliary types in.
5621
                 * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
5622
                 * @param annotationValueFilterFactory The annotation value filter factory to apply.
5623
                 * @param annotationRetention          The annotation retention to apply.
5624
                 * @param implementationContextFactory The implementation context factory to apply.
5625
                 * @param methodGraphCompiler          The method graph compiler to use.
5626
                 * @param typeValidation               The type validation state.
5627
                 * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
5628
                 * @param classReaderFactory           The class reader factory to use.
5629
                 * @param classWriterFactory           The class writer factory to use.
5630
                 * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
5631
                 * @param auxiliaryTypes               A list of explicitly required auxiliary types.
5632
                 * @return A type builder that represents the supplied arguments.
5633
                 */
5634
                protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
5635
                                                          FieldRegistry fieldRegistry,
5636
                                                          MethodRegistry methodRegistry,
5637
                                                          RecordComponentRegistry recordComponentRegistry,
5638
                                                          TypeAttributeAppender typeAttributeAppender,
5639
                                                          AsmVisitorWrapper asmVisitorWrapper,
5640
                                                          ClassFileVersion classFileVersion,
5641
                                                          AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
5642
                                                          AnnotationValueFilter.Factory annotationValueFilterFactory,
5643
                                                          AnnotationRetention annotationRetention,
5644
                                                          Implementation.Context.Factory implementationContextFactory,
5645
                                                          MethodGraph.Compiler methodGraphCompiler,
5646
                                                          TypeValidation typeValidation,
5647
                                                          VisibilityBridgeStrategy visibilityBridgeStrategy,
5648
                                                          AsmClassReader.Factory classReaderFactory,
5649
                                                          AsmClassWriter.Factory classWriterFactory,
5650
                                                          LatentMatcher<? super MethodDescription> ignoredMethods,
5651
                                                          List<? extends DynamicType> auxiliaryTypes);
5652

5653
                /**
5654
                 * An adapter for defining a module.
5655
                 */
5656
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5657
                protected class ModuleDefinitionAdapter extends ModuleDefinition.AbstractBase<U> {
5658

5659
                    /**
5660
                     * The name of the module.
5661
                     */
5662
                    private final String name;
5663

5664
                    /**
5665
                     * The modifiers of the module.
5666
                     */
5667
                    private final int modifiers;
5668

5669
                    /**
5670
                     * The module version or {@code null} if no version was specified.
5671
                     */
5672
                    @MaybeNull
5673
                    @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5674
                    private final String version;
5675

5676
                    /**
5677
                     * The module's main class or {@code null} if no main class was specified.
5678
                     */
5679
                    @MaybeNull
5680
                    @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5681
                    private final String mainClass;
5682

5683
                    /**
5684
                     * The module's packages.
5685
                     */
5686
                    private final Set<String> packages;
5687

5688
                    /**
5689
                     * The modules that this module requires.
5690
                     */
5691
                    private final Map<String, ModuleDescription.Requires> requires;
5692

5693
                    /**
5694
                     * The packages that this module exports.
5695
                     */
5696
                    private final Map<String, ModuleDescription.Exports> exports;
5697

5698
                    /**
5699
                     * The packages that this module opens.
5700
                     */
5701
                    private final Map<String, ModuleDescription.Opens> opens;
5702

5703
                    /**
5704
                     * The services that this module uses.
5705
                     */
5706
                    private final Set<String> uses;
5707

5708
                    /**
5709
                     * The services that this module provides.
5710
                     */
5711
                    private final Map<String, ModuleDescription.Provides> provides;
5712

5713
                    protected ModuleDefinitionAdapter(String name, int modifiers) {
5714
                        this(name,
1✔
5715
                                modifiers,
5716
                                null,
5717
                                null,
5718
                                Collections.<String>emptySet(),
1✔
5719
                                "java.base".equals(name)
1✔
5720
                                        ? Collections.<String, ModuleDescription.Requires>emptyMap()
1✔
5721
                                        : Collections.<String, ModuleDescription.Requires>singletonMap("java.base", new ModuleDescription.Requires.Simple(null, Opcodes.ACC_MANDATED)),
1✔
5722
                                Collections.<String, ModuleDescription.Exports>emptyMap(),
1✔
5723
                                Collections.<String, ModuleDescription.Opens>emptyMap(),
1✔
5724
                                Collections.<String>emptySet(),
1✔
5725
                                Collections.<String, ModuleDescription.Provides>emptyMap());
1✔
5726
                    }
1✔
5727

5728
                    /**
5729
                     * Creates a new module definition adapter.
5730
                     *
5731
                     * @param name      The name of the module.
5732
                     * @param modifiers The modifiers of the module.
5733
                     * @param version   The module version or {@code null} if no version was specified.
5734
                     * @param mainClass The module's main class or {@code null} if no main class was specified.
5735
                     * @param packages  The module's packages.
5736
                     * @param requires  The modules that this module requires.
5737
                     * @param exports   The packages that this module exports.
5738
                     * @param opens     The packages that this module opens.
5739
                     * @param uses      The services that this module uses.
5740
                     * @param provides  The services that this module provides.
5741
                     */
5742
                    protected ModuleDefinitionAdapter(String name,
5743
                                                      int modifiers,
5744
                                                      @MaybeNull String version,
5745
                                                      @MaybeNull String mainClass,
5746
                                                      Set<String> packages,
5747
                                                      Map<String, ModuleDescription.Requires> requires,
5748
                                                      Map<String, ModuleDescription.Exports> exports,
5749
                                                      Map<String, ModuleDescription.Opens> opens,
5750
                                                      Set<String> uses,
5751
                                                      Map<String, ModuleDescription.Provides> provides) {
1✔
5752
                        this.name = name;
1✔
5753
                        this.modifiers = modifiers;
1✔
5754
                        this.version = version;
1✔
5755
                        this.mainClass = mainClass;
1✔
5756
                        this.packages = packages;
1✔
5757
                        this.requires = requires;
1✔
5758
                        this.exports = exports;
1✔
5759
                        this.opens = opens;
1✔
5760
                        this.uses = uses;
1✔
5761
                        this.provides = provides;
1✔
5762
                    }
1✔
5763

5764
                    /**
5765
                     * {@inheritDoc}
5766
                     */
5767
                    public ModuleDefinition<U> version(@MaybeNull String version) {
5768
                        return new ModuleDefinitionAdapter(name,
1✔
5769
                                modifiers,
5770
                                version,
5771
                                mainClass,
5772
                                packages,
5773
                                requires,
5774
                                exports,
5775
                                opens,
5776
                                uses,
5777
                                provides);
5778
                    }
5779

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

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

5814
                    /**
5815
                     * {@inheritDoc}
5816
                     */
5817
                    public RequiresDefinition<U> require(String module, int modifiers) {
5818
                        return new RequiresDefinitionAdapter(module, modifiers);
×
5819
                    }
5820

5821
                    /**
5822
                     * {@inheritDoc}
5823
                     */
5824
                    public ExportsDefinition<U> export(String aPackage, int modifiers) {
5825
                        return new ExportsDefinitionAdapter(aPackage, modifiers);
×
5826
                    }
5827

5828
                    /**
5829
                     * {@inheritDoc}
5830
                     */
5831
                    public OpensDefinition<U> open(String aPackage, int modifiers) {
5832
                        return new OpensDefinitionAdapter(aPackage, modifiers);
×
5833
                    }
5834

5835
                    /**
5836
                     * {@inheritDoc}
5837
                     */
5838
                    public ModuleDefinition<U> uses(Collection<String> services) {
5839
                        Set<String> uses = new LinkedHashSet<String>(this.uses);
×
5840
                        uses.addAll(services);
×
5841
                        return new ModuleDefinitionAdapter(name,
×
5842
                                modifiers,
5843
                                version,
5844
                                mainClass,
5845
                                packages,
5846
                                requires,
5847
                                exports,
5848
                                opens,
5849
                                uses,
5850
                                provides);
5851
                    }
5852

5853
                    /**
5854
                     * {@inheritDoc}
5855
                     */
5856
                    public ModuleDefinition<U> provides(String service, Collection<String> implementations) {
5857
                        Map<String, ModuleDescription.Provides> provides = new LinkedHashMap<String, ModuleDescription.Provides>(this.provides);
×
5858
                        provides.put(service, new ModuleDescription.Provides.Simple(new LinkedHashSet<String>(implementations)));
×
5859
                        return new ModuleDefinitionAdapter(name,
×
5860
                                modifiers,
5861
                                version,
5862
                                mainClass,
5863
                                packages,
5864
                                requires,
5865
                                exports,
5866
                                opens,
5867
                                uses,
5868
                                provides);
5869
                    }
5870

5871
                    @Override
5872
                    protected Builder<U> materialize() {
5873
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withModuleDescription(new ModuleDescription.Latent(name,
1✔
5874
                                        modifiers,
5875
                                        version,
5876
                                        mainClass,
5877
                                        packages,
5878
                                        requires,
5879
                                        exports,
5880
                                        opens,
5881
                                        uses,
5882
                                        provides,
5883
                                        instrumentedType.getDeclaredAnnotations())).withModifiers(modifiers),
1✔
5884
                                fieldRegistry,
5885
                                methodRegistry,
5886
                                recordComponentRegistry,
5887
                                typeAttributeAppender,
5888
                                asmVisitorWrapper,
5889
                                classFileVersion,
5890
                                auxiliaryTypeNamingStrategy,
5891
                                annotationValueFilterFactory,
5892
                                annotationRetention,
5893
                                implementationContextFactory,
5894
                                methodGraphCompiler,
5895
                                typeValidation,
5896
                                visibilityBridgeStrategy,
5897
                                classReaderFactory,
5898
                                classWriterFactory,
5899
                                ignoredMethods,
5900
                                auxiliaryTypes);
5901
                    }
5902

5903
                    /**
5904
                     * An adapter for definining a module requirement.
5905
                     */
5906
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5907
                    protected class RequiresDefinitionAdapter extends RequiresDefinition.Delegator<U> {
5908

5909
                        /**
5910
                         * The module that is being required.
5911
                         */
5912
                        private final String module;
5913

5914
                        /**
5915
                         * The modifiers of the required module.
5916
                         */
5917
                        private final int modifiers;
5918

5919
                        /**
5920
                         * The version of the required module or {@code null} if no particular version is required.
5921
                         */
5922
                        @MaybeNull
5923
                        @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
5924
                        private final String version;
5925

5926
                        /**
5927
                         * Creates a new module requirement definition.
5928
                         *
5929
                         * @param module    The module that is being required.
5930
                         * @param modifiers The modifiers of the required module.
5931
                         */
5932
                        protected RequiresDefinitionAdapter(String module, int modifiers) {
5933
                            this(module, modifiers, null);
×
5934
                        }
×
5935

5936
                        /**
5937
                         * Creates a new module requirement definition.
5938
                         *
5939
                         * @param module    The module that is being required.
5940
                         * @param modifiers The modifiers of the required module.
5941
                         * @param version   The version of the required module or {@code null} if no particular version is required.
5942
                         */
5943
                        protected RequiresDefinitionAdapter(String module, int modifiers, @MaybeNull String version) {
×
5944
                            this.module = module;
×
5945
                            this.modifiers = modifiers;
×
5946
                            this.version = version;
×
5947
                        }
×
5948

5949
                        /**
5950
                         * {@inheritDoc}
5951
                         */
5952
                        public RequiresDefinition<U> requiredVersion(@MaybeNull String version) {
5953
                            return new RequiresDefinitionAdapter(module, modifiers, version);
×
5954
                        }
5955

5956
                        @Override
5957
                        protected ModuleDefinition<U> materialize() {
5958
                            Map<String, ModuleDescription.Requires> requires = new LinkedHashMap<String, ModuleDescription.Requires>(ModuleDefinitionAdapter.this.requires);
×
5959
                            requires.put(module, new ModuleDescription.Requires.Simple(version, modifiers));
×
5960
                            return new ModuleDefinitionAdapter(name,
×
5961
                                    ModuleDefinitionAdapter.this.modifiers,
×
5962
                                    ModuleDefinitionAdapter.this.version,
×
5963
                                    mainClass,
×
5964
                                    packages,
×
5965
                                    requires,
5966
                                    exports,
×
5967
                                    opens,
×
5968
                                    uses,
×
5969
                                    provides);
×
5970
                        }
5971
                    }
5972

5973
                    /**
5974
                     * An adapter for defining a module export.
5975
                     */
5976
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5977
                    protected class ExportsDefinitionAdapter extends ExportsDefinition.Delegator<U> {
5978

5979
                        /**
5980
                         * The package that is being exported.
5981
                         */
5982
                        private final String aPackage;
5983

5984
                        /**
5985
                         * The modifiers for the exporting declaration.
5986
                         */
5987
                        private final int modifiers;
5988

5989
                        /**
5990
                         * The modules to which the package is exported, or no modules if exported to all modules.
5991
                         */
5992
                        private final Set<String> targets;
5993

5994
                        /**
5995
                         * Creates a new exporting definition adapter.
5996
                         *
5997
                         * @param aPackage  The package that is being exported.
5998
                         * @param modifiers The modifiers for the exporting declaration.
5999
                         */
6000
                        protected ExportsDefinitionAdapter(String aPackage, int modifiers) {
6001
                            this(aPackage, modifiers, Collections.<String>emptySet());
×
6002
                        }
×
6003

6004
                        /**
6005
                         * Creates a new exporting definition adapter.
6006
                         *
6007
                         * @param aPackage  The package that is being exported.
6008
                         * @param modifiers The modifiers for the exporting declaration.
6009
                         * @param targets   The modules to which the package is exported, or no modules if exported to all modules.
6010
                         */
6011
                        protected ExportsDefinitionAdapter(String aPackage, int modifiers, Set<String> targets) {
×
6012
                            this.aPackage = aPackage;
×
6013
                            this.modifiers = modifiers;
×
6014
                            this.targets = targets;
×
6015
                        }
×
6016

6017
                        /**
6018
                         * {@inheritDoc}
6019
                         */
6020
                        public ExportsDefinition<U> to(Collection<String> modules) {
6021
                            Set<String> targets = new LinkedHashSet<String>(this.targets);
×
6022
                            targets.addAll(modules);
×
6023
                            return new ExportsDefinitionAdapter(aPackage, modifiers, targets);
×
6024
                        }
6025

6026
                        @Override
6027
                        protected ModuleDefinition<U> materialize() {
6028
                            Map<String, ModuleDescription.Exports> exports = new LinkedHashMap<String, ModuleDescription.Exports>(ModuleDefinitionAdapter.this.exports);
×
6029
                            exports.put(aPackage, new ModuleDescription.Exports.Simple(targets, modifiers));
×
6030
                            return new ModuleDefinitionAdapter(name,
×
6031
                                    ModuleDefinitionAdapter.this.modifiers,
×
6032
                                    version,
×
6033
                                    mainClass,
×
6034
                                    packages,
×
6035
                                    requires,
×
6036
                                    exports,
6037
                                    opens,
×
6038
                                    uses,
×
6039
                                    provides);
×
6040
                        }
6041
                    }
6042

6043
                    /**
6044
                     * An adapter for defining a module opening.
6045
                     */
6046
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6047
                    protected class OpensDefinitionAdapter extends OpensDefinition.Delegator<U> {
6048

6049
                        /**
6050
                         * The package that is being opened.
6051
                         */
6052
                        private final String aPackage;
6053

6054
                        /**
6055
                         * The modifiers for the opening declaration.
6056
                         */
6057
                        private final int modifiers;
6058

6059
                        /**
6060
                         * The modules to which the package is opened, or no modules if opened to all modules.
6061
                         */
6062
                        private final Set<String> targets;
6063

6064
                        /**
6065
                         * Creates a new opens definition adapter.
6066
                         *
6067
                         * @param aPackage  The package that is being opened.
6068
                         * @param modifiers The modifiers for the opening declaration.
6069
                         */
6070
                        protected OpensDefinitionAdapter(String aPackage, int modifiers) {
6071
                            this(aPackage, modifiers, Collections.<String>emptySet());
×
6072
                        }
×
6073

6074
                        /**
6075
                         * Creates a new opens definition adapter.
6076
                         *
6077
                         * @param aPackage  The package that is being opened.
6078
                         * @param modifiers The modifiers for the opening declaration.
6079
                         * @param targets   The modules to which the package is opened, or no modules if opened to all modules.
6080
                         */
6081
                        protected OpensDefinitionAdapter(String aPackage, int modifiers, Set<String> targets) {
×
6082
                            this.aPackage = aPackage;
×
6083
                            this.modifiers = modifiers;
×
6084
                            this.targets = targets;
×
6085
                        }
×
6086

6087
                        /**
6088
                         * {@inheritDoc}
6089
                         */
6090
                        public OpensDefinition<U> to(Collection<String> modules) {
6091
                            Set<String> targets = new LinkedHashSet<String>(this.targets);
×
6092
                            targets.addAll(modules);
×
6093
                            return new OpensDefinitionAdapter(aPackage, modifiers, targets);
×
6094
                        }
6095

6096
                        @Override
6097
                        protected ModuleDefinition<U> materialize() {
6098
                            Map<String, ModuleDescription.Opens> opens = new LinkedHashMap<String, ModuleDescription.Opens>(ModuleDefinitionAdapter.this.opens);
×
6099
                            opens.put(aPackage, new ModuleDescription.Opens.Simple(targets, modifiers));
×
6100
                            return new ModuleDefinitionAdapter(name,
×
6101
                                    ModuleDefinitionAdapter.this.modifiers,
×
6102
                                    version,
×
6103
                                    mainClass,
×
6104
                                    packages,
×
6105
                                    requires,
×
6106
                                    exports,
×
6107
                                    opens,
6108
                                    uses,
×
6109
                                    provides);
×
6110
                        }
6111
                    }
6112
                }
6113

6114
                /**
6115
                 * An adapter for applying an inner type definition for an outer type.
6116
                 */
6117
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6118
                protected class InnerTypeDefinitionForTypeAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition.ForType<U> {
6119

6120
                    /**
6121
                     * A description of the type that is the defined outer type.
6122
                     */
6123
                    private final TypeDescription typeDescription;
6124

6125
                    /**
6126
                     * Creates a new adapter for an inner type definition for an outer type.
6127
                     *
6128
                     * @param typeDescription A description of the type that is the defined outer type.
6129
                     */
6130
                    protected InnerTypeDefinitionForTypeAdapter(TypeDescription typeDescription) {
1✔
6131
                        this.typeDescription = typeDescription;
1✔
6132
                    }
1✔
6133

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

6161
                    /**
6162
                     * {@inheritDoc}
6163
                     */
6164
                    public Builder<U> asMemberType() {
6165
                        return Adapter.this.materialize(instrumentedType
1✔
6166
                                        .withDeclaringType(typeDescription)
1✔
6167
                                        .withEnclosingType(typeDescription)
1✔
6168
                                        .withAnonymousClass(false)
1✔
6169
                                        .withLocalClass(false),
1✔
6170
                                fieldRegistry,
6171
                                methodRegistry,
6172
                                recordComponentRegistry,
6173
                                typeAttributeAppender,
6174
                                asmVisitorWrapper,
6175
                                classFileVersion,
6176
                                auxiliaryTypeNamingStrategy,
6177
                                annotationValueFilterFactory,
6178
                                annotationRetention,
6179
                                implementationContextFactory,
6180
                                methodGraphCompiler,
6181
                                typeValidation,
6182
                                visibilityBridgeStrategy,
6183
                                classReaderFactory,
6184
                                classWriterFactory,
6185
                                ignoredMethods,
6186
                                auxiliaryTypes);
6187
                    }
6188

6189
                    @Override
6190
                    protected Builder<U> materialize() {
6191
                        return Adapter.this.materialize(instrumentedType
1✔
6192
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6193
                                        .withEnclosingType(typeDescription)
1✔
6194
                                        .withLocalClass(true),
1✔
6195
                                fieldRegistry,
6196
                                methodRegistry,
6197
                                recordComponentRegistry,
6198
                                typeAttributeAppender,
6199
                                asmVisitorWrapper,
6200
                                classFileVersion,
6201
                                auxiliaryTypeNamingStrategy,
6202
                                annotationValueFilterFactory,
6203
                                annotationRetention,
6204
                                implementationContextFactory,
6205
                                methodGraphCompiler,
6206
                                typeValidation,
6207
                                visibilityBridgeStrategy,
6208
                                classReaderFactory,
6209
                                classWriterFactory,
6210
                                ignoredMethods,
6211
                                auxiliaryTypes);
6212
                    }
6213
                }
6214

6215
                /**
6216
                 * An adapter for applying an inner type definition for an outer method or constructor.
6217
                 */
6218
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6219
                protected class InnerTypeDefinitionForMethodAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition<U> {
6220

6221
                    /**
6222
                     * A description of the declaring method or constructor.
6223
                     */
6224
                    private final MethodDescription.InDefinedShape methodDescription;
6225

6226
                    /**
6227
                     * Creates a new adapter for defining a type that is declared within a method or constructor.
6228
                     *
6229
                     * @param methodDescription A description of the declaring method or constructor.
6230
                     */
6231
                    protected InnerTypeDefinitionForMethodAdapter(MethodDescription.InDefinedShape methodDescription) {
1✔
6232
                        this.methodDescription = methodDescription;
1✔
6233
                    }
1✔
6234

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

6262
                    @Override
6263
                    protected Builder<U> materialize() {
6264
                        return Adapter.this.materialize(instrumentedType
1✔
6265
                                        .withDeclaringType(TypeDescription.UNDEFINED)
1✔
6266
                                        .withEnclosingMethod(methodDescription)
1✔
6267
                                        .withLocalClass(true),
1✔
6268
                                fieldRegistry,
6269
                                methodRegistry,
6270
                                recordComponentRegistry,
6271
                                typeAttributeAppender,
6272
                                asmVisitorWrapper,
6273
                                classFileVersion,
6274
                                auxiliaryTypeNamingStrategy,
6275
                                annotationValueFilterFactory,
6276
                                annotationRetention,
6277
                                implementationContextFactory,
6278
                                methodGraphCompiler,
6279
                                typeValidation,
6280
                                visibilityBridgeStrategy,
6281
                                classReaderFactory,
6282
                                classWriterFactory,
6283
                                ignoredMethods,
6284
                                auxiliaryTypes);
6285
                    }
6286
                }
6287

6288
                /**
6289
                 * An adapter for defining a new type variable for the instrumented type.
6290
                 */
6291
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6292
                protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
6293

6294
                    /**
6295
                     * The current definition of the type variable.
6296
                     */
6297
                    private final TypeVariableToken token;
6298

6299
                    /**
6300
                     * Creates a new type variable definition adapter.
6301
                     *
6302
                     * @param token The current definition of the type variable.
6303
                     */
6304
                    protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
1✔
6305
                        this.token = token;
1✔
6306
                    }
1✔
6307

6308
                    /**
6309
                     * {@inheritDoc}
6310
                     */
6311
                    public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
6312
                        return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
1✔
6313
                                token.getBounds(),
1✔
6314
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6315
                    }
6316

6317
                    @Override
6318
                    protected Builder<U> materialize() {
6319
                        return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
1✔
6320
                                fieldRegistry,
6321
                                methodRegistry,
6322
                                recordComponentRegistry,
6323
                                typeAttributeAppender,
6324
                                asmVisitorWrapper,
6325
                                classFileVersion,
6326
                                auxiliaryTypeNamingStrategy,
6327
                                annotationValueFilterFactory,
6328
                                annotationRetention,
6329
                                implementationContextFactory,
6330
                                methodGraphCompiler,
6331
                                typeValidation,
6332
                                visibilityBridgeStrategy,
6333
                                classReaderFactory,
6334
                                classWriterFactory,
6335
                                ignoredMethods,
6336
                                auxiliaryTypes);
6337
                    }
6338
                }
6339

6340
                /**
6341
                 * An adapter for defining a new field.
6342
                 */
6343
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6344
                protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
6345

6346
                    /**
6347
                     * The token representing the current field definition.
6348
                     */
6349
                    private final FieldDescription.Token token;
6350

6351
                    /**
6352
                     * Creates a new field definition adapter.
6353
                     *
6354
                     * @param token The token representing the current field definition.
6355
                     */
6356
                    protected FieldDefinitionAdapter(FieldDescription.Token token) {
6357
                        this(FieldAttributeAppender.ForInstrumentedField.INSTANCE,
1✔
6358
                                Transformer.NoOp.<FieldDescription>make(),
1✔
6359
                                FieldDescription.NO_DEFAULT_VALUE,
6360
                                token);
6361
                    }
1✔
6362

6363
                    /**
6364
                     * Creates a new field definition adapter.
6365
                     *
6366
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
6367
                     * @param transformer                   The field transformer to apply.
6368
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
6369
                     * @param token                         The token representing the current field definition.
6370
                     */
6371
                    protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6372
                                                     Transformer<FieldDescription> transformer,
6373
                                                     @MaybeNull Object defaultValue,
6374
                                                     FieldDescription.Token token) {
1✔
6375
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
6376
                        this.token = token;
1✔
6377
                    }
1✔
6378

6379
                    /**
6380
                     * {@inheritDoc}
6381
                     */
6382
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
6383
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, new FieldDescription.Token(token.getName(),
1✔
6384
                                token.getModifiers(),
1✔
6385
                                token.getType(),
1✔
6386
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6387
                    }
6388

6389
                    @Override
6390
                    protected Builder<U> materialize() {
6391
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
1✔
6392
                                fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
6393
                                methodRegistry,
6394
                                recordComponentRegistry,
6395
                                typeAttributeAppender,
6396
                                asmVisitorWrapper,
6397
                                classFileVersion,
6398
                                auxiliaryTypeNamingStrategy,
6399
                                annotationValueFilterFactory,
6400
                                annotationRetention,
6401
                                implementationContextFactory,
6402
                                methodGraphCompiler,
6403
                                typeValidation,
6404
                                visibilityBridgeStrategy,
6405
                                classReaderFactory,
6406
                                classWriterFactory,
6407
                                ignoredMethods,
6408
                                auxiliaryTypes);
6409
                    }
6410

6411
                    @Override
6412
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6413
                                                      Transformer<FieldDescription> transformer,
6414
                                                      @MaybeNull Object defaultValue) {
6415
                        return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
1✔
6416
                    }
6417
                }
6418

6419
                /**
6420
                 * An adapter for matching an existing field.
6421
                 */
6422
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6423
                protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
6424

6425
                    /**
6426
                     * The matcher for any fields to apply this matcher to.
6427
                     */
6428
                    private final LatentMatcher<? super FieldDescription> matcher;
6429

6430
                    /**
6431
                     * Creates a new field match adapter.
6432
                     *
6433
                     * @param matcher The matcher for any fields to apply this matcher to.
6434
                     */
6435
                    protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
6436
                        this(FieldAttributeAppender.NoOp.INSTANCE,
1✔
6437
                                Transformer.NoOp.<FieldDescription>make(),
1✔
6438
                                FieldDescription.NO_DEFAULT_VALUE,
6439
                                matcher);
6440
                    }
1✔
6441

6442
                    /**
6443
                     * Creates a new field match adapter.
6444
                     *
6445
                     * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
6446
                     * @param transformer                   The field transformer to apply.
6447
                     * @param defaultValue                  The field's default value or {@code null} if no value is to be defined.
6448
                     * @param matcher                       The matcher for any fields to apply this matcher to.
6449
                     */
6450
                    protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6451
                                                Transformer<FieldDescription> transformer,
6452
                                                @MaybeNull Object defaultValue,
6453
                                                LatentMatcher<? super FieldDescription> matcher) {
1✔
6454
                        super(fieldAttributeAppenderFactory, transformer, defaultValue);
1✔
6455
                        this.matcher = matcher;
1✔
6456
                    }
1✔
6457

6458
                    /**
6459
                     * {@inheritDoc}
6460
                     */
6461
                    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
6462
                        return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
1✔
6463
                    }
6464

6465
                    @Override
6466
                    protected Builder<U> materialize() {
6467
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
6468
                                fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, transformer),
1✔
6469
                                methodRegistry,
6470
                                recordComponentRegistry,
6471
                                typeAttributeAppender,
6472
                                asmVisitorWrapper,
6473
                                classFileVersion,
6474
                                auxiliaryTypeNamingStrategy,
6475
                                annotationValueFilterFactory,
6476
                                annotationRetention,
6477
                                implementationContextFactory,
6478
                                methodGraphCompiler,
6479
                                typeValidation,
6480
                                visibilityBridgeStrategy,
6481
                                classReaderFactory,
6482
                                classWriterFactory,
6483
                                ignoredMethods,
6484
                                auxiliaryTypes);
6485
                    }
6486

6487
                    @Override
6488
                    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
6489
                                                      Transformer<FieldDescription> transformer,
6490
                                                      @MaybeNull Object defaultValue) {
6491
                        return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
1✔
6492
                    }
6493
                }
6494

6495
                /**
6496
                 * An adapter for defining a new method.
6497
                 */
6498
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6499
                protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
6500

6501
                    /**
6502
                     * A token representing the currently defined method.
6503
                     */
6504
                    private final MethodDescription.Token token;
6505

6506
                    /**
6507
                     * Creates a new method definition adapter.
6508
                     *
6509
                     * @param token A token representing the currently defined method.
6510
                     */
6511
                    protected MethodDefinitionAdapter(MethodDescription.Token token) {
1✔
6512
                        this.token = token;
1✔
6513
                    }
1✔
6514

6515
                    /**
6516
                     * {@inheritDoc}
6517
                     */
6518
                    public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
6519
                        return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
1✔
6520
                    }
6521

6522
                    /**
6523
                     * {@inheritDoc}
6524
                     */
6525
                    public Simple.Annotatable<U> withParameter(TypeDefinition type) {
6526
                        return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
1✔
6527
                    }
6528

6529
                    /**
6530
                     * {@inheritDoc}
6531
                     */
6532
                    public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
6533
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6534
                                token.getModifiers(),
1✔
6535
                                token.getTypeVariableTokens(),
1✔
6536
                                token.getReturnType(),
1✔
6537
                                token.getParameterTokens(),
1✔
6538
                                CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
1✔
6539
                                token.getAnnotations(),
1✔
6540
                                token.getDefaultValue(),
1✔
6541
                                token.getReceiverType()));
1✔
6542
                    }
6543

6544
                    /**
6545
                     * {@inheritDoc}
6546
                     */
6547
                    public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
6548
                        return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
1✔
6549
                    }
6550

6551
                    /**
6552
                     * {@inheritDoc}
6553
                     */
6554
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
6555
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
6556
                    }
6557

6558
                    /**
6559
                     * {@inheritDoc}
6560
                     */
6561
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
6562
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6563
                                (token.getModifiers() & Opcodes.ACC_NATIVE) == 0
1✔
6564
                                        ? ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers())
1✔
6565
                                        : token.getModifiers(),
1✔
6566
                                token.getTypeVariableTokens(),
1✔
6567
                                token.getReturnType(),
1✔
6568
                                token.getParameterTokens(),
1✔
6569
                                token.getExceptionTypes(),
1✔
6570
                                token.getAnnotations(),
1✔
6571
                                token.getDefaultValue(),
1✔
6572
                                token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
6573
                    }
6574

6575
                    /**
6576
                     * {@inheritDoc}
6577
                     */
6578
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
6579
                        return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6580
                                ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
1✔
6581
                                token.getTypeVariableTokens(),
1✔
6582
                                token.getReturnType(),
1✔
6583
                                token.getParameterTokens(),
1✔
6584
                                token.getExceptionTypes(),
1✔
6585
                                token.getAnnotations(),
1✔
6586
                                annotationValue,
6587
                                token.getReceiverType())).materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
6588
                    }
6589

6590
                    /**
6591
                     * Materializes the given handler as the implementation.
6592
                     *
6593
                     * @param handler The handler for implementing the method.
6594
                     * @return A method definition for the given handler.
6595
                     */
6596
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
6597
                        return new AnnotationAdapter(handler);
1✔
6598
                    }
6599

6600
                    /**
6601
                     * An adapter for defining a new type variable for the currently defined method.
6602
                     */
6603
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6604
                    protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
6605

6606
                        /**
6607
                         * The currently defined type variable.
6608
                         */
6609
                        private final TypeVariableToken token;
6610

6611
                        /**
6612
                         * Creates a new type variable annotation adapter.
6613
                         *
6614
                         * @param token The currently defined type variable.
6615
                         */
6616
                        protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
1✔
6617
                            this.token = token;
1✔
6618
                        }
1✔
6619

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

6633
                        /**
6634
                         * {@inheritDoc}
6635
                         */
6636
                        public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
6637
                            return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
1✔
6638
                                    token.getBounds(),
1✔
6639
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
1✔
6640
                        }
6641
                    }
6642

6643
                    /**
6644
                     * An annotation adapter for a parameter definition.
6645
                     */
6646
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6647
                    protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
6648

6649
                        /**
6650
                         * The token of the currently defined parameter.
6651
                         */
6652
                        private final ParameterDescription.Token token;
6653

6654
                        /**
6655
                         * Creates a new parameter annotation adapter.
6656
                         *
6657
                         * @param token The token of the currently defined parameter.
6658
                         */
6659
                        protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
6660
                            this.token = token;
1✔
6661
                        }
1✔
6662

6663
                        /**
6664
                         * {@inheritDoc}
6665
                         */
6666
                        public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
6667
                            return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
×
6668
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
6669
                                    token.getName(),
×
6670
                                    token.getModifiers()));
×
6671
                        }
6672

6673
                        @Override
6674
                        protected MethodDefinition.ParameterDefinition<U> materialize() {
6675
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6676
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6677
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
6678
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6679
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
6680
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6681
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6682
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6683
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6684
                        }
6685
                    }
6686

6687
                    /**
6688
                     * An annotation adapter for a simple parameter definition.
6689
                     */
6690
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6691
                    protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
6692

6693
                        /**
6694
                         * The token of the currently defined parameter.
6695
                         */
6696
                        private final ParameterDescription.Token token;
6697

6698
                        /**
6699
                         * Creates a new simple parameter annotation adapter.
6700
                         *
6701
                         * @param token The token of the currently defined parameter.
6702
                         */
6703
                        protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
1✔
6704
                            this.token = token;
1✔
6705
                        }
1✔
6706

6707
                        /**
6708
                         * {@inheritDoc}
6709
                         */
6710
                        public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
6711
                            return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
1✔
6712
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
6713
                                    token.getName(),
1✔
6714
                                    token.getModifiers()));
1✔
6715
                        }
6716

6717
                        @Override
6718
                        protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
6719
                            return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
1✔
6720
                                    MethodDefinitionAdapter.this.token.getModifiers(),
1✔
6721
                                    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
1✔
6722
                                    MethodDefinitionAdapter.this.token.getReturnType(),
1✔
6723
                                    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
1✔
6724
                                    MethodDefinitionAdapter.this.token.getExceptionTypes(),
1✔
6725
                                    MethodDefinitionAdapter.this.token.getAnnotations(),
1✔
6726
                                    MethodDefinitionAdapter.this.token.getDefaultValue(),
1✔
6727
                                    MethodDefinitionAdapter.this.token.getReceiverType()));
1✔
6728
                        }
6729
                    }
6730

6731
                    /**
6732
                     * An annotation adapter for a method definition.
6733
                     */
6734
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6735
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
6736

6737
                        /**
6738
                         * Creates a new annotation adapter.
6739
                         *
6740
                         * @param handler The handler that determines how a method is implemented.
6741
                         */
6742
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
6743
                            this(handler,
1✔
6744
                                    MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER,
6745
                                    Transformer.NoOp.<MethodDescription>make());
1✔
6746
                        }
1✔
6747

6748
                        /**
6749
                         * Creates a new annotation adapter.
6750
                         *
6751
                         * @param handler                        The handler that determines how a method is implemented.
6752
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
6753
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
6754
                         */
6755
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
6756
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6757
                                                    Transformer<MethodDescription> transformer) {
1✔
6758
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
6759
                        }
1✔
6760

6761
                        /**
6762
                         * {@inheritDoc}
6763
                         */
6764
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
6765
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6766
                                    token.getModifiers(),
1✔
6767
                                    token.getTypeVariableTokens(),
1✔
6768
                                    token.getReturnType(),
1✔
6769
                                    token.getParameterTokens(),
1✔
6770
                                    token.getExceptionTypes(),
1✔
6771
                                    token.getAnnotations(),
1✔
6772
                                    token.getDefaultValue(),
1✔
6773
                                    receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
6774
                        }
6775

6776
                        /**
6777
                         * {@inheritDoc}
6778
                         */
6779
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
6780
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
1✔
6781
                                    token.getModifiers(),
1✔
6782
                                    token.getTypeVariableTokens(),
1✔
6783
                                    token.getReturnType(),
1✔
6784
                                    token.getParameterTokens(),
1✔
6785
                                    token.getExceptionTypes(),
1✔
6786
                                    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
1✔
6787
                                    token.getDefaultValue(),
1✔
6788
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
6789
                        }
6790

6791
                        /**
6792
                         * {@inheritDoc}
6793
                         */
6794
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
6795
                            List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
×
6796
                            parameterTokens.set(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
×
6797
                                    CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
×
6798
                                    token.getParameterTokens().get(index).getName(),
×
6799
                                    token.getParameterTokens().get(index).getModifiers()));
×
6800
                            return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
×
6801
                                    token.getModifiers(),
×
6802
                                    token.getTypeVariableTokens(),
×
6803
                                    token.getReturnType(),
×
6804
                                    parameterTokens,
6805
                                    token.getExceptionTypes(),
×
6806
                                    token.getAnnotations(),
×
6807
                                    token.getDefaultValue(),
×
6808
                                    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
6809
                        }
6810

6811
                        @Override
6812
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
6813
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6814
                                                                  Transformer<MethodDescription> transformer) {
6815
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
×
6816
                        }
6817

6818
                        @Override
6819
                        protected Builder<U> materialize() {
6820
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
1✔
6821
                                    fieldRegistry,
6822
                                    methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
1✔
6823
                                            handler,
6824
                                            methodAttributeAppenderFactory,
6825
                                            transformer),
6826
                                    recordComponentRegistry,
6827
                                    typeAttributeAppender,
6828
                                    asmVisitorWrapper,
6829
                                    classFileVersion,
6830
                                    auxiliaryTypeNamingStrategy,
6831
                                    annotationValueFilterFactory,
6832
                                    annotationRetention,
6833
                                    implementationContextFactory,
6834
                                    methodGraphCompiler,
6835
                                    typeValidation,
6836
                                    visibilityBridgeStrategy,
6837
                                    classReaderFactory,
6838
                                    classWriterFactory,
6839
                                    ignoredMethods,
6840
                                    auxiliaryTypes);
6841
                        }
6842
                    }
6843
                }
6844

6845
                /**
6846
                 * An adapter for matching an existing method.
6847
                 */
6848
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6849
                protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
6850

6851
                    /**
6852
                     * The method matcher of this adapter.
6853
                     */
6854
                    private final LatentMatcher<? super MethodDescription> matcher;
6855

6856
                    /**
6857
                     * Creates a new method match adapter.
6858
                     *
6859
                     * @param matcher The method matcher of this adapter.
6860
                     */
6861
                    protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
1✔
6862
                        this.matcher = matcher;
1✔
6863
                    }
1✔
6864

6865
                    /**
6866
                     * {@inheritDoc}
6867
                     */
6868
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
6869
                        return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
1✔
6870
                    }
6871

6872
                    /**
6873
                     * {@inheritDoc}
6874
                     */
6875
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
6876
                        return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
1✔
6877
                    }
6878

6879
                    /**
6880
                     * {@inheritDoc}
6881
                     */
6882
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
6883
                        return materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
1✔
6884
                    }
6885

6886
                    /**
6887
                     * Materializes the method definition with the supplied handler.
6888
                     *
6889
                     * @param handler The handler that implements any method matched by this instances matcher.
6890
                     * @return A method definition where any matched method is implemented by the supplied handler.
6891
                     */
6892
                    private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
6893
                        return new AnnotationAdapter(handler);
1✔
6894
                    }
6895

6896
                    /**
6897
                     * An annotation adapter for implementing annotations during a method definition.
6898
                     */
6899
                    @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6900
                    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
6901

6902
                        /**
6903
                         * Creates a new annotation adapter.
6904
                         *
6905
                         * @param handler The handler that determines how a method is implemented.
6906
                         */
6907
                        protected AnnotationAdapter(MethodRegistry.Handler handler) {
6908
                            this(handler, MethodAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<MethodDescription>make());
1✔
6909
                        }
1✔
6910

6911
                        /**
6912
                         * Creates a new annotation adapter.
6913
                         *
6914
                         * @param handler                        The handler that determines how a method is implemented.
6915
                         * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
6916
                         * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
6917
                         */
6918
                        protected AnnotationAdapter(MethodRegistry.Handler handler,
6919
                                                    MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6920
                                                    Transformer<MethodDescription> transformer) {
1✔
6921
                            super(handler, methodAttributeAppenderFactory, transformer);
1✔
6922
                        }
1✔
6923

6924
                        /**
6925
                         * {@inheritDoc}
6926
                         */
6927
                        public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
6928
                            return new AnnotationAdapter(handler,
1✔
6929
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
6930
                                    transformer);
6931
                        }
6932

6933
                        /**
6934
                         * {@inheritDoc}
6935
                         */
6936
                        public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
6937
                            return new AnnotationAdapter(handler,
1✔
6938
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
6939
                                    transformer);
6940
                        }
6941

6942
                        /**
6943
                         * {@inheritDoc}
6944
                         */
6945
                        public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
6946
                            return new AnnotationAdapter(handler,
×
6947
                                    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
6948
                                    transformer);
6949
                        }
6950

6951
                        @Override
6952
                        protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
6953
                                                                  MethodAttributeAppender.Factory methodAttributeAppenderFactory,
6954
                                                                  Transformer<MethodDescription> transformer) {
6955
                            return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
1✔
6956
                        }
6957

6958
                        @Override
6959
                        protected Builder<U> materialize() {
6960
                            return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
1✔
6961
                                    fieldRegistry,
6962
                                    methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, transformer),
1✔
6963
                                    recordComponentRegistry,
6964
                                    typeAttributeAppender,
6965
                                    asmVisitorWrapper,
6966
                                    classFileVersion,
6967
                                    auxiliaryTypeNamingStrategy,
6968
                                    annotationValueFilterFactory,
6969
                                    annotationRetention,
6970
                                    implementationContextFactory,
6971
                                    methodGraphCompiler,
6972
                                    typeValidation,
6973
                                    visibilityBridgeStrategy,
6974
                                    classReaderFactory,
6975
                                    classWriterFactory,
6976
                                    ignoredMethods,
6977
                                    auxiliaryTypes);
6978
                        }
6979
                    }
6980
                }
6981

6982
                /**
6983
                 * An adapter for optionally matching methods defined by declared interfaces.
6984
                 */
6985
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
6986
                protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
6987

6988
                    /**
6989
                     * The interfaces whose methods are optionally matched.
6990
                     */
6991
                    private final TypeList.Generic interfaces;
6992

6993
                    /**
6994
                     * Creates a new optional method match adapter.
6995
                     *
6996
                     * @param interfaces The interfaces whose methods are optionally matched.
6997
                     */
6998
                    protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
1✔
6999
                        this.interfaces = interfaces;
1✔
7000
                    }
1✔
7001

7002
                    @Override
7003
                    protected Builder<U> materialize() {
7004
                        return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
1✔
7005
                                fieldRegistry,
7006
                                methodRegistry,
7007
                                recordComponentRegistry,
7008
                                typeAttributeAppender,
7009
                                asmVisitorWrapper,
7010
                                classFileVersion,
7011
                                auxiliaryTypeNamingStrategy,
7012
                                annotationValueFilterFactory,
7013
                                annotationRetention,
7014
                                implementationContextFactory,
7015
                                methodGraphCompiler,
7016
                                typeValidation,
7017
                                visibilityBridgeStrategy,
7018
                                classReaderFactory,
7019
                                classWriterFactory,
7020
                                ignoredMethods,
7021
                                auxiliaryTypes);
7022
                    }
7023

7024
                    /**
7025
                     * {@inheritDoc}
7026
                     */
7027
                    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
7028
                        return interfaceType().intercept(implementation);
1✔
7029
                    }
7030

7031
                    /**
7032
                     * {@inheritDoc}
7033
                     */
7034
                    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
7035
                        return interfaceType().withoutCode();
×
7036
                    }
7037

7038
                    /**
7039
                     * {@inheritDoc}
7040
                     */
7041
                    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
7042
                        return interfaceType().defaultValue(annotationValue);
×
7043
                    }
7044

7045
                    /**
7046
                     * {@inheritDoc}
7047
                     */
7048
                    public <V> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(V value, Class<? extends V> type) {
7049
                        return interfaceType().defaultValue(value, type);
×
7050
                    }
7051

7052
                    /**
7053
                     * Returns a matcher for the interfaces' methods.
7054
                     *
7055
                     * @return A matcher for the interfaces' methods.
7056
                     */
7057
                    private MethodDefinition.ImplementationDefinition<U> interfaceType() {
7058
                        ElementMatcher.Junction<TypeDescription> elementMatcher = none();
1✔
7059
                        for (TypeDescription typeDescription : interfaces.asErasures()) {
1✔
7060
                            elementMatcher = elementMatcher.or(isSuperTypeOf(typeDescription));
1✔
7061
                        }
1✔
7062
                        return materialize().invokable(isDeclaredBy(isInterface().and(elementMatcher)));
1✔
7063
                    }
7064
                }
7065

7066
                /**
7067
                 * An adapter for defining a record component.
7068
                 */
7069
                @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
7070
                protected class RecordComponentDefinitionAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
7071

7072
                    /**
7073
                     * The record component attribute appender factory to apply.
7074
                     */
7075
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
7076

7077
                    /**
7078
                     * A token representing the defined record component.
7079
                     */
7080
                    private final RecordComponentDescription.Token token;
7081

7082
                    /**
7083
                     * A transformer to apply on matched record component descriptions.
7084
                     */
7085
                    private final Transformer<RecordComponentDescription> transformer;
7086

7087
                    /**
7088
                     * Creates a new record component definition adapter.
7089
                     *
7090
                     * @param token A token representing the defined record component.
7091
                     */
7092
                    protected RecordComponentDefinitionAdapter(RecordComponentDescription.Token token) {
7093
                        this(RecordComponentAttributeAppender.ForInstrumentedRecordComponent.INSTANCE,
×
7094
                                Transformer.NoOp.<RecordComponentDescription>make(),
×
7095
                                token);
7096
                    }
×
7097

7098
                    /**
7099
                     * Creates a new record component definition adapter.
7100
                     *
7101
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
7102
                     * @param transformer                             A transformer to apply on matched record component descriptions.
7103
                     * @param token                                   A token representing the defined record component.
7104
                     */
7105
                    protected RecordComponentDefinitionAdapter(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
7106
                                                               Transformer<RecordComponentDescription> transformer,
7107
                                                               RecordComponentDescription.Token token) {
×
7108
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
7109
                        this.transformer = transformer;
×
7110
                        this.token = token;
×
7111
                    }
×
7112

7113
                    /**
7114
                     * {@inheritDoc}
7115
                     */
7116
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
7117
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory, transformer, new RecordComponentDescription.Token(token.getName(),
×
7118
                                token.getType(),
×
7119
                                CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
×
7120
                    }
7121

7122
                    /**
7123
                     * {@inheritDoc}
7124
                     */
7125
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
7126
                        return new RecordComponentDefinitionAdapter(new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
7127
                                recordComponentAttributeAppenderFactory), transformer, token);
7128
                    }
7129

7130
                    /**
7131
                     * {@inheritDoc}
7132
                     */
7133
                    @SuppressWarnings("unchecked") // In absence of @SafeVarargs
7134
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
7135
                        return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory,
×
7136
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer),
7137
                                token);
7138
                    }
7139

7140
                    @Override
7141
                    protected Builder<U> materialize() {
7142
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withRecordComponent(token),
×
7143
                                fieldRegistry,
7144
                                methodRegistry,
7145
                                recordComponentRegistry.prepend(new LatentMatcher.ForRecordComponentToken(token),
×
7146
                                        recordComponentAttributeAppenderFactory,
7147
                                        transformer),
7148
                                typeAttributeAppender,
7149
                                asmVisitorWrapper,
7150
                                classFileVersion,
7151
                                auxiliaryTypeNamingStrategy,
7152
                                annotationValueFilterFactory,
7153
                                annotationRetention,
7154
                                implementationContextFactory,
7155
                                methodGraphCompiler,
7156
                                typeValidation,
7157
                                visibilityBridgeStrategy,
7158
                                classReaderFactory,
7159
                                classWriterFactory,
7160
                                ignoredMethods,
7161
                                auxiliaryTypes);
7162
                    }
7163
                }
7164

7165
                /**
7166
                 * An adapter for matching record components.
7167
                 */
7168
                protected class RecordComponentMatchAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
7169

7170
                    /**
7171
                     * The matcher for identifying record components to match.
7172
                     */
7173
                    private final LatentMatcher<? super RecordComponentDescription> matcher;
7174

7175
                    /**
7176
                     * The record component attribute appender factory to apply.
7177
                     */
7178
                    private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
7179

7180
                    /**
7181
                     * A transformer to apply on matched record component descriptions.
7182
                     */
7183
                    private final Transformer<RecordComponentDescription> transformer;
7184

7185
                    /**
7186
                     * Creates a new record component match adapter.
7187
                     *
7188
                     * @param matcher The matcher for identifying record components to match.
7189
                     */
7190
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher) {
7191
                        this(matcher, RecordComponentAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<RecordComponentDescription>make());
×
7192
                    }
×
7193

7194
                    /**
7195
                     * Creates a new record component match adapter.
7196
                     *
7197
                     * @param matcher                                 The matcher for identifying record components to match.
7198
                     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
7199
                     * @param transformer                             A transformer to apply on matched record component descriptions.
7200
                     */
7201
                    protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher,
7202
                                                          RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
7203
                                                          Transformer<RecordComponentDescription> transformer) {
×
7204
                        this.matcher = matcher;
×
7205
                        this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
×
7206
                        this.transformer = transformer;
×
7207
                    }
×
7208

7209
                    /**
7210
                     * {@inheritDoc}
7211
                     */
7212
                    public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
7213
                        return attribute(new RecordComponentAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
×
7214
                    }
7215

7216
                    /**
7217
                     * {@inheritDoc}
7218
                     */
7219
                    public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
7220
                        return new RecordComponentMatchAdapter(matcher, new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
×
7221
                                recordComponentAttributeAppenderFactory), transformer);
7222
                    }
7223

7224
                    /**
7225
                     * {@inheritDoc}
7226
                     */
7227
                    @SuppressWarnings("unchecked")  // In absence of @SafeVarargs
7228
                    public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
7229
                        return new RecordComponentMatchAdapter(matcher,
×
7230
                                recordComponentAttributeAppenderFactory,
7231
                                new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer));
7232
                    }
7233

7234
                    @Override
7235
                    protected Builder<U> materialize() {
7236
                        return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
×
7237
                                fieldRegistry,
7238
                                methodRegistry,
7239
                                recordComponentRegistry.prepend(matcher, recordComponentAttributeAppenderFactory, transformer),
×
7240
                                typeAttributeAppender,
7241
                                asmVisitorWrapper,
7242
                                classFileVersion,
7243
                                auxiliaryTypeNamingStrategy,
7244
                                annotationValueFilterFactory,
7245
                                annotationRetention,
7246
                                implementationContextFactory,
7247
                                methodGraphCompiler,
7248
                                typeValidation,
7249
                                visibilityBridgeStrategy,
7250
                                classReaderFactory,
7251
                                classWriterFactory,
7252
                                ignoredMethods,
7253
                                auxiliaryTypes);
7254
                    }
7255
                }
7256
            }
7257
        }
7258
    }
7259

7260
    /**
7261
     * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
7262
     *
7263
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7264
     *            type itself, an interface or the direct super class.
7265
     */
7266
    interface Unloaded<T> extends DynamicType {
7267

7268
        /**
7269
         * <p>
7270
         * Attempts to load this dynamic type including all of its auxiliary types, if any. If the class loader is an
7271
         * unsealed instance of {@link InjectionClassLoader}, the classes are injected directy into the class loader, otherwise,
7272
         * a new class loader is created where the supplied class loader is set as parent.
7273
         * </p>
7274
         * <p>
7275
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
7276
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
7277
         * </p>
7278
         *
7279
         * @param classLoader The class loader to use for this class loading or {@code null} for using the boot loader.
7280
         * @return This dynamic type in its loaded state.
7281
         */
7282
        Loaded<T> load(@MaybeNull ClassLoader classLoader);
7283

7284
        /**
7285
         * <p>
7286
         * Attempts to load this dynamic type including all of its auxiliary types, if any.
7287
         * </p>
7288
         * <p>
7289
         * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
7290
         * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
7291
         * </p>
7292
         *
7293
         * @param classLoader          The class loader to use for this class loading.
7294
         * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
7295
         * @param <S>                  The least specific type of class loader this strategy can apply to.
7296
         * @return This dynamic type in its loaded state.
7297
         * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
7298
         */
7299
        <S extends ClassLoader> Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
7300

7301
        /**
7302
         * Includes the provided dynamic types as auxiliary types of this instance.
7303
         *
7304
         * @param dynamicType The dynamic types to include.
7305
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
7306
         */
7307
        Unloaded<T> include(DynamicType... dynamicType);
7308

7309
        /**
7310
         * Includes the provided dynamic types as auxiliary types of this instance.
7311
         *
7312
         * @param dynamicTypes The dynamic types to include.
7313
         * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
7314
         */
7315
        Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
7316
    }
7317

7318
    /**
7319
     * A dynamic type that has been loaded into the running instance of the Java virtual machine.
7320
     *
7321
     * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7322
     *            type itself, an interface or the direct super class.
7323
     */
7324
    interface Loaded<T> extends DynamicType {
7325

7326
        /**
7327
         * Returns the loaded main class.
7328
         *
7329
         * @return A loaded class representation of this dynamic type.
7330
         */
7331
        Class<? extends T> getLoaded();
7332

7333
        /**
7334
         * <p>
7335
         * Returns a map of all loaded auxiliary types to this dynamic type.
7336
         * </p>
7337
         * <p>
7338
         * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
7339
         * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
7340
         * </p>
7341
         *
7342
         * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
7343
         */
7344
        Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
7345

7346
        /**
7347
         * Returns all loaded types that are implied by this dynamic type.
7348
         *
7349
         * @return All loaded types that are implied by this dynamic type.
7350
         */
7351
        Map<TypeDescription, Class<?>> getAllLoaded();
7352
    }
7353

7354
    @HashCodeAndEqualsPlugin.Enhance
7355
    abstract class AbstractBase implements DynamicType {
1✔
7356

7357
        /**
7358
         * The default version of a jar file manifest.
7359
         */
7360
        private static final String MANIFEST_VERSION = "1.0";
7361

7362
        /**
7363
         * A suffix for temporary files.
7364
         */
7365
        private static final String TEMP_SUFFIX = "tmp";
7366

7367
        /**
7368
         * {@inheritDoc}
7369
         */
7370
        public Resolution locate(String name) throws IOException {
7371
            if (getTypeDescription().getName().equals(name)) {
1✔
7372
                return new Resolution.Explicit(getBytes());
1✔
7373
            }
7374
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7375
                Resolution resolution = auxiliaryType.locate(name);
1✔
7376
                if (resolution.isResolved()) {
1✔
7377
                    return resolution;
1✔
7378
                }
7379
            }
1✔
7380
            return new Resolution.Illegal(name);
1✔
7381
        }
7382

7383
        /**
7384
         * {@inheritDoc}
7385
         */
7386
        public void close() {
7387
            /* do nothing */
7388
        }
×
7389

7390
        /**
7391
         * {@inheritDoc}
7392
         */
7393
        public Set<TypeDescription> getAuxiliaryTypeDescriptions() {
7394
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
7395
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7396
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
7397
            }
1✔
7398
            return types;
1✔
7399
        }
7400

7401
        /**
7402
         * {@inheritDoc}
7403
         */
7404
        public Set<TypeDescription> getAllTypeDescriptions() {
7405
            Set<TypeDescription> types = new LinkedHashSet<TypeDescription>();
1✔
7406
            types.add(getTypeDescription());
1✔
7407
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7408
                types.addAll(auxiliaryType.getAllTypeDescriptions());
1✔
7409
            }
1✔
7410
            return types;
1✔
7411
        }
7412

7413
        /**
7414
         * {@inheritDoc}
7415
         */
7416
        public Map<TypeDescription, byte[]> getAllTypes() {
7417
            Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
1✔
7418
            allTypes.put(getTypeDescription(), getBytes());
1✔
7419
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7420
                allTypes.putAll(auxiliaryType.getAllTypes());
1✔
7421
            }
1✔
7422
            return allTypes;
1✔
7423
        }
7424

7425
        /**
7426
         * {@inheritDoc}
7427
         */
7428
        public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
7429
            Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
1✔
7430
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7431
                classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
1✔
7432
            }
1✔
7433
            classLoadingCallbacks.put(getTypeDescription(), getLoadedTypeInitializer());
1✔
7434
            return classLoadingCallbacks;
1✔
7435
        }
7436

7437
        /**
7438
         * {@inheritDoc}
7439
         */
7440
        public boolean hasAliveLoadedTypeInitializers() {
7441
            if (getLoadedTypeInitializer().isAlive()) {
1✔
7442
                return true;
1✔
7443
            }
7444
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7445
                if (auxiliaryType.hasAliveLoadedTypeInitializers()) {
1✔
7446
                    return true;
1✔
7447
                }
7448
            }
1✔
7449
            return false;
1✔
7450
        }
7451

7452
        /**
7453
         * {@inheritDoc}
7454
         */
7455
        public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
7456
            Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
1✔
7457
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7458
                auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
1✔
7459
                auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
1✔
7460
            }
1✔
7461
            return auxiliaryTypes;
1✔
7462
        }
7463

7464
        /**
7465
         * {@inheritDoc}
7466
         */
7467
        public Map<TypeDescription, File> saveIn(File folder) throws IOException {
7468
            Map<TypeDescription, File> files = new HashMap<TypeDescription, File>();
1✔
7469
            File target = new File(folder, getTypeDescription().getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
1✔
7470
            if (target.getParentFile() != null && !target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
1✔
7471
                throw new IllegalArgumentException("Could not create directory: " + target.getParentFile());
×
7472
            }
7473
            OutputStream outputStream = new FileOutputStream(target);
1✔
7474
            try {
7475
                outputStream.write(getBytes());
1✔
7476
            } finally {
7477
                outputStream.close();
1✔
7478
            }
7479
            files.put(getTypeDescription(), target);
1✔
7480
            for (DynamicType auxiliaryType : getAuxiliaries()) {
1✔
7481
                files.putAll(auxiliaryType.saveIn(folder));
1✔
7482
            }
1✔
7483
            return files;
1✔
7484
        }
7485

7486
        /**
7487
         * {@inheritDoc}
7488
         */
7489
        public File inject(File sourceJar, File targetJar) throws IOException {
7490
            return sourceJar.equals(targetJar)
1✔
7491
                    ? inject(sourceJar)
1✔
7492
                    : doInject(sourceJar, targetJar);
1✔
7493
        }
7494

7495
        /**
7496
         * {@inheritDoc}
7497
         */
7498
        public File inject(File jar) throws IOException {
7499
            FileSystem.getInstance().move(doInject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX)), jar);
1✔
7500
            return jar;
1✔
7501
        }
7502

7503
        /**
7504
         * Injects this dynamic type into a source jar and writes the result to the target jar.
7505
         *
7506
         * @param sourceJar The source jar.
7507
         * @param targetJar The target jar.
7508
         * @return The jar file that was written to.
7509
         * @throws IOException If an I/O error occurs.
7510
         */
7511
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
7512
        private File doInject(File sourceJar, File targetJar) throws IOException {
7513
            InputStream inputStream = new FileInputStream(sourceJar);
1✔
7514
            try {
7515
                JarInputStream jarInputStream = new JarInputStream(inputStream);
1✔
7516
                if (!targetJar.isFile() && !targetJar.createNewFile()) {
1✔
7517
                    throw new IllegalArgumentException("Could not create file: " + targetJar);
×
7518
                }
7519
                Manifest manifest = jarInputStream.getManifest();
1✔
7520
                OutputStream outputStream = new FileOutputStream(targetJar);
1✔
7521
                try {
7522
                    JarOutputStream jarOutputStream = manifest == null
1✔
7523
                            ? new JarOutputStream(outputStream)
7524
                            : new JarOutputStream(outputStream, manifest);
7525
                    Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
1✔
7526
                    Map<String, byte[]> files = new HashMap<String, byte[]>();
1✔
7527
                    for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
1✔
7528
                        files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
1✔
7529
                    }
1✔
7530
                    files.put(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION, getBytes());
1✔
7531
                    JarEntry jarEntry;
7532
                    while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
1✔
7533
                        byte[] replacement = files.remove(jarEntry.getName());
1✔
7534
                        if (replacement == null) {
1✔
7535
                            jarOutputStream.putNextEntry(jarEntry);
1✔
7536
                            byte[] buffer = new byte[1024];
1✔
7537
                            int index;
7538
                            while ((index = jarInputStream.read(buffer)) != -1) {
1✔
7539
                                jarOutputStream.write(buffer, 0, index);
1✔
7540
                            }
7541
                        } else {
1✔
7542
                            jarOutputStream.putNextEntry(new JarEntry(jarEntry.getName()));
1✔
7543
                            jarOutputStream.write(replacement);
1✔
7544
                        }
7545
                        jarInputStream.closeEntry();
1✔
7546
                        jarOutputStream.closeEntry();
1✔
7547
                    }
1✔
7548
                    for (Map.Entry<String, byte[]> entry : files.entrySet()) {
1✔
7549
                        jarOutputStream.putNextEntry(new JarEntry(entry.getKey()));
1✔
7550
                        jarOutputStream.write(entry.getValue());
1✔
7551
                        jarOutputStream.closeEntry();
1✔
7552
                    }
1✔
7553
                    jarOutputStream.close();
1✔
7554
                } finally {
7555
                    outputStream.close();
1✔
7556
                }
7557
                jarInputStream.close();
1✔
7558
            } finally {
7559
                inputStream.close();
1✔
7560
            }
7561
            return targetJar;
1✔
7562
        }
7563

7564
        /**
7565
         * {@inheritDoc}
7566
         */
7567
        public File toJar(File file) throws IOException {
7568
            Manifest manifest = new Manifest();
1✔
7569
            manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
1✔
7570
            return toJar(file, manifest);
1✔
7571
        }
7572

7573
        /**
7574
         * {@inheritDoc}
7575
         */
7576
        @SuppressFBWarnings(value = "OS_OPEN_STREAM_EXCEPTION_PATH", justification = "Outer stream holds file handle and is closed")
7577
        public File toJar(File file, Manifest manifest) throws IOException {
7578
            if (!file.isFile() && !file.createNewFile()) {
1✔
7579
                throw new IllegalArgumentException("Could not create file: " + file);
×
7580
            }
7581
            OutputStream outputStream = new FileOutputStream(file);
1✔
7582
            try {
7583
                JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest);
1✔
7584
                for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
1✔
7585
                    jarOutputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
1✔
7586
                    jarOutputStream.write(entry.getValue());
1✔
7587
                    jarOutputStream.closeEntry();
1✔
7588
                }
1✔
7589
                jarOutputStream.putNextEntry(new JarEntry(getTypeDescription().getInternalName() + CLASS_FILE_EXTENSION));
1✔
7590
                jarOutputStream.write(getBytes());
1✔
7591
                jarOutputStream.closeEntry();
1✔
7592
                jarOutputStream.close();
1✔
7593
            } finally {
7594
                outputStream.close();
1✔
7595
            }
7596
            return file;
1✔
7597
        }
7598
    }
7599

7600
    /**
7601
     * A default implementation of a dynamic type.
7602
     */
7603
    @HashCodeAndEqualsPlugin.Enhance
7604
    class Default extends AbstractBase {
7605

7606
        /**
7607
         * A type description of this dynamic type.
7608
         */
7609
        protected final TypeDescription typeDescription;
7610

7611
        /**
7612
         * The byte array representing this dynamic type.
7613
         */
7614
        protected final byte[] binaryRepresentation;
7615

7616
        /**
7617
         * The loaded type initializer for this dynamic type.
7618
         */
7619
        protected final LoadedTypeInitializer loadedTypeInitializer;
7620

7621
        /**
7622
         * A list of auxiliary types for this dynamic type.
7623
         */
7624
        protected final List<? extends DynamicType> auxiliaryTypes;
7625

7626
        /**
7627
         * Creates a new dynamic type.
7628
         *
7629
         * @param typeDescription       A description of this dynamic type.
7630
         * @param binaryRepresentation  A byte array containing the binary representation of this dynamic type. The array must not be modified.
7631
         * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
7632
         * @param auxiliaryTypes        The auxiliary type required for this dynamic type.
7633
         */
7634
        @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not modified by class contract.")
7635
        public Default(TypeDescription typeDescription,
7636
                       byte[] binaryRepresentation,
7637
                       LoadedTypeInitializer loadedTypeInitializer,
7638
                       List<? extends DynamicType> auxiliaryTypes) {
1✔
7639
            this.typeDescription = typeDescription;
1✔
7640
            this.binaryRepresentation = binaryRepresentation;
1✔
7641
            this.loadedTypeInitializer = loadedTypeInitializer;
1✔
7642
            this.auxiliaryTypes = auxiliaryTypes;
1✔
7643
        }
1✔
7644

7645
        /**
7646
         * {@inheritDoc}
7647
         */
7648
        public TypeDescription getTypeDescription() {
7649
            return typeDescription;
1✔
7650
        }
7651

7652
        /**
7653
         * {@inheritDoc}
7654
         */
7655
        @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not modified by class contract.")
7656
        public byte[] getBytes() {
7657
            return binaryRepresentation;
1✔
7658
        }
7659

7660
        /**
7661
         * {@inheritDoc}
7662
         */
7663
        public LoadedTypeInitializer getLoadedTypeInitializer() {
7664
            return loadedTypeInitializer;
1✔
7665
        }
7666

7667
        /**
7668
         * {@inheritDoc}
7669
         */
7670
        public List<? extends DynamicType> getAuxiliaries() {
7671
            return auxiliaryTypes;
1✔
7672
        }
7673

7674
        /**
7675
         * A default implementation of an unloaded dynamic type.
7676
         *
7677
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7678
         *            type itself, an interface or the direct super class.
7679
         */
7680
        @HashCodeAndEqualsPlugin.Enhance
7681
        public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
7682

7683
            /**
7684
             * The type resolution strategy to use for initializing the dynamic type.
7685
             */
7686
            private final TypeResolutionStrategy.Resolved typeResolutionStrategy;
7687

7688
            /**
7689
             * Creates a new unloaded representation of a dynamic type.
7690
             *
7691
             * @param typeDescription        A description of this dynamic type.
7692
             * @param binaryRepresentation   An array of byte of the binary representation of this dynamic type.
7693
             * @param loadedTypeInitializer  The type initializer of this dynamic type.
7694
             * @param auxiliaryTypes         The auxiliary types that are required for this dynamic type.
7695
             * @param typeResolutionStrategy The type resolution strategy to use for initializing the dynamic type.
7696
             */
7697
            public Unloaded(TypeDescription typeDescription,
7698
                            byte[] binaryRepresentation,
7699
                            LoadedTypeInitializer loadedTypeInitializer,
7700
                            List<? extends DynamicType> auxiliaryTypes,
7701
                            TypeResolutionStrategy.Resolved typeResolutionStrategy) {
7702
                super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
1✔
7703
                this.typeResolutionStrategy = typeResolutionStrategy;
1✔
7704
            }
1✔
7705

7706
            /**
7707
             * {@inheritDoc}
7708
             */
7709
            public DynamicType.Loaded<T> load(@MaybeNull ClassLoader classLoader) {
7710
                if (classLoader instanceof InjectionClassLoader && !((InjectionClassLoader) classLoader).isSealed()) {
1✔
7711
                    return load((InjectionClassLoader) classLoader, InjectionClassLoader.Strategy.INSTANCE);
1✔
7712
                } else {
7713
                    return load(classLoader, ClassLoadingStrategy.Default.WRAPPER);
1✔
7714
                }
7715
            }
7716

7717
            /**
7718
             * {@inheritDoc}
7719
             */
7720
            public <S extends ClassLoader> DynamicType.Loaded<T> load(@MaybeNull S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
7721
                return new Default.Loaded<T>(typeDescription,
1✔
7722
                        binaryRepresentation,
7723
                        loadedTypeInitializer,
7724
                        auxiliaryTypes,
7725
                        typeResolutionStrategy.initialize(this, classLoader, classLoadingStrategy));
1✔
7726
            }
7727

7728
            /**
7729
             * {@inheritDoc}
7730
             */
7731
            public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
7732
                return include(Arrays.asList(dynamicType));
1✔
7733
            }
7734

7735
            /**
7736
             * {@inheritDoc}
7737
             */
7738
            public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
7739
                return new Default.Unloaded<T>(typeDescription,
1✔
7740
                        binaryRepresentation,
7741
                        loadedTypeInitializer,
7742
                        CompoundList.of(auxiliaryTypes, dynamicType),
1✔
7743
                        typeResolutionStrategy);
7744
            }
7745
        }
7746

7747
        /**
7748
         * A default implementation of a loaded dynamic type.
7749
         *
7750
         * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
7751
         *            type itself, an interface or the direct super class.
7752
         */
7753
        @HashCodeAndEqualsPlugin.Enhance
7754
        protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
7755

7756
            /**
7757
             * The loaded types for the given loaded dynamic type.
7758
             */
7759
            private final Map<TypeDescription, Class<?>> loadedTypes;
7760

7761
            /**
7762
             * Creates a new representation of a loaded dynamic type.
7763
             *
7764
             * @param typeDescription       A description of this dynamic type.
7765
             * @param typeByte              An array of byte of the binary representation of this dynamic type.
7766
             * @param loadedTypeInitializer The type initializer of this dynamic type.
7767
             * @param auxiliaryTypes        The auxiliary types that are required for this dynamic type.
7768
             * @param loadedTypes           A map of loaded types for this dynamic type and all its auxiliary types.
7769
             */
7770
            protected Loaded(TypeDescription typeDescription,
7771
                             byte[] typeByte,
7772
                             LoadedTypeInitializer loadedTypeInitializer,
7773
                             List<? extends DynamicType> auxiliaryTypes,
7774
                             Map<TypeDescription, Class<?>> loadedTypes) {
7775
                super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
1✔
7776
                this.loadedTypes = loadedTypes;
1✔
7777
            }
1✔
7778

7779
            /**
7780
             * {@inheritDoc}
7781
             */
7782
            public Class<? extends T> getLoaded() {
7783
                @SuppressWarnings("unchecked")
7784
                Class<? extends T> type = (Class<? extends T>) loadedTypes.get(typeDescription);
1✔
7785
                if (type == null) {
1✔
7786
                    throw new IllegalStateException(typeDescription + " cannot be loaded explicitly");
×
7787
                }
7788
                return type;
1✔
7789
            }
7790

7791
            /**
7792
             * {@inheritDoc}
7793
             */
7794
            public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
7795
                Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
7796
                loadedAuxiliaryTypes.remove(typeDescription);
1✔
7797
                return loadedAuxiliaryTypes;
1✔
7798
            }
7799

7800
            /**
7801
             * {@inheritDoc}
7802
             */
7803
            public Map<TypeDescription, Class<?>> getAllLoaded() {
7804
                return new HashMap<TypeDescription, Class<?>>(loadedTypes);
1✔
7805
            }
7806
        }
7807
    }
7808
}
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