1 /*
2 * Copyright 2014 - 2020 Rafael Winterhalter
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.bytebuddy.dynamic;
17
18 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import net.bytebuddy.ClassFileVersion;
20 import net.bytebuddy.asm.AsmVisitorWrapper;
21 import net.bytebuddy.build.HashCodeAndEqualsPlugin;
22 import net.bytebuddy.description.annotation.AnnotationDescription;
23 import net.bytebuddy.description.annotation.AnnotationList;
24 import net.bytebuddy.description.annotation.AnnotationValue;
25 import net.bytebuddy.description.field.FieldDescription;
26 import net.bytebuddy.description.method.MethodDescription;
27 import net.bytebuddy.description.method.ParameterDescription;
28 import net.bytebuddy.description.method.ParameterList;
29 import net.bytebuddy.description.modifier.*;
30 import net.bytebuddy.description.type.*;
31 import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
32 import net.bytebuddy.dynamic.loading.InjectionClassLoader;
33 import net.bytebuddy.dynamic.scaffold.*;
34 import net.bytebuddy.implementation.*;
35 import net.bytebuddy.implementation.attribute.*;
36 import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
37 import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
38 import net.bytebuddy.matcher.ElementMatcher;
39 import net.bytebuddy.matcher.LatentMatcher;
40 import net.bytebuddy.pool.TypePool;
41 import net.bytebuddy.utility.CompoundList;
42 import net.bytebuddy.jar.asm.Opcodes;
43
44 import java.io.*;
45 import java.lang.annotation.Annotation;
46 import java.lang.reflect.*;
47 import java.security.AccessController;
48 import java.security.PrivilegedAction;
49 import java.util.*;
50 import java.util.jar.*;
51
52 import static net.bytebuddy.matcher.ElementMatchers.*;
53
54 /**
55 * A dynamic type that is created at runtime, usually as the result of applying a
56 * {@link net.bytebuddy.dynamic.DynamicType.Builder} or as the result of an
57 * {@link net.bytebuddy.implementation.auxiliary.AuxiliaryType}.
58 * <p> </p>
59 * Note that the {@link TypeDescription}s will represent their
60 * unloaded forms and therefore differ from the loaded types, especially with regards to annotations.
61 */
62 public interface DynamicType {
63
64 /**
65 * <p>
66 * Returns a description of this dynamic type.
67 * </p>
68 * <p>
69 * <b>Note</b>: This description will most likely differ from the binary representation of this type. Normally,
70 * annotations and intercepted methods are not added to this type description.
71 * </p>
72 *
73 * @return A description of this dynamic type.
74 */
75 TypeDescription getTypeDescription();
76
77 /**
78 * Returns a byte array representing this dynamic type. This byte array might be reused by this dynamic type and
79 * must therefore not be altered.
80 *
81 * @return A byte array of the type's binary representation.
82 */
83 byte[] getBytes();
84
85 /**
86 * <p>
87 * Returns a map of all auxiliary types that are required for making use of the main type.
88 * </p>
89 * <p>
90 * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
91 * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
92 * </p>
93 *
94 * @return A map of all auxiliary types by their descriptions to their binary representation.
95 */
96 Map<TypeDescription, byte[]> getAuxiliaryTypes();
97
98 /**
99 * Returns all types that are implied by this dynamic type.
100 *
101 * @return A mapping from all type descriptions, the actual type and its auxiliary types to their binary
102 * representation
103 */
104 Map<TypeDescription, byte[]> getAllTypes();
105
106 /**
107 * <p>
108 * Returns a map of all loaded type initializers for the main type and all auxiliary types, if any.
109 * </p>
110 * <p>
111 * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
112 * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
113 * </p>
114 *
115 * @return A mapping of all types' descriptions to their loaded type initializers.
116 */
117 Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers();
118
119 /**
120 * Checks if a dynamic type requires some form of explicit type initialization, either for itself or for one
121 * of its auxiliary types, if any. This is the case when this dynamic type was defined to delegate method calls
122 * to a specific instance which is stored in a field of the created type. If this class serialized, it could not
123 * be used without its loaded type initializers since the field value represents a specific runtime context.
124 *
125 * @return {@code true} if this type requires explicit type initialization.
126 */
127 boolean hasAliveLoadedTypeInitializers();
128
129 /**
130 * <p>
131 * Saves a dynamic type in a given folder using the Java class file format while respecting the naming conventions
132 * for saving compiled Java classes. All auxiliary types, if any, are saved in the same directory. The resulting
133 * folder structure will resemble the structure that is required for Java run times, i.e. each folder representing
134 * a segment of the package name. If the specified {@code folder} does not yet exist, it is created during the
135 * call of this method.
136 * </p>
137 * <p>
138 * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
139 * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
140 * </p>
141 *
142 * @param folder The base target folder for storing this dynamic type and its auxiliary types, if any.
143 * @return A map of type descriptions pointing to files with their stored binary representations within {@code folder}.
144 * @throws IOException Thrown if the underlying file operations cause an {@code IOException}.
145 */
146 Map<TypeDescription, File> saveIn(File folder) throws IOException;
147
148 /**
149 * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
150 * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
151 * patched version with a new central directory. No directory entries are added to the generated jar.
152 *
153 * @param sourceJar The original jar file.
154 * @param targetJar The {@code source} jar file with the injected contents.
155 * @return The {@code target} jar file.
156 * @throws IOException If an I/O exception occurs while injecting from the source into the target.
157 */
158 File inject(File sourceJar, File targetJar) throws IOException;
159
160 /**
161 * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
162 * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
163 * patched version with a new central directory. No directory entries are added to the generated jar.
164 *
165 * @param jar The jar file to replace with an injected version.
166 * @return The {@code jar} file.
167 * @throws IOException If an I/O exception occurs while injecting into the jar.
168 */
169 File inject(File jar) throws IOException;
170
171 /**
172 * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
173 * exist prior to calling this method. The jar file is created with a simple manifest that only contains a version
174 * number. No directory entries are added to the generated jar.
175 *
176 * @param file The target file to which the <i>jar</i> is written to.
177 * @return The given {@code file}.
178 * @throws IOException If an I/O exception occurs while writing the file.
179 */
180 File toJar(File file) throws IOException;
181
182 /**
183 * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
184 * exist prior to calling this method. No directory entries are added to the generated jar.
185 *
186 * @param file The target file to which the <i>jar</i> is written to.
187 * @param manifest The manifest of the created <i>jar</i>.
188 * @return The given {@code file}.
189 * @throws IOException If an I/O exception occurs while writing the file.
190 */
191 File toJar(File file, Manifest manifest) throws IOException;
192
193 /**
194 * A builder for creating a dynamic type.
195 *
196 * @param <T> A loaded type that the built type is guaranteed to be a subclass of.
197 */
198 interface Builder<T> {
199
200 /**
201 * Applies the supplied {@link AsmVisitorWrapper} onto the {@link net.bytebuddy.jar.asm.ClassVisitor} during building a dynamic type.
202 * Using an ASM visitor, it is possible to manipulate byte code directly. Byte Buddy does not validate directly created byte code
203 * and it remains the responsibility of the visitor's implementor to generate legal byte code. If several ASM visitor wrappers
204 * are registered, they are applied on top of another in their registration order.
205 *
206 * @param asmVisitorWrapper The ASM visitor wrapper to apply during
207 * @return A new builder that is equal to this builder and applies the ASM visitor wrapper.
208 */
209 Builder<T> visit(AsmVisitorWrapper asmVisitorWrapper);
210
211 /**
212 * Names the dynamic type by the supplied name. The name needs to be fully qualified and in the binary format (packages separated
213 * by dots: {@code foo.Bar}). A type's package determines what other types are visible to the instrumented type and what methods
214 * can be overridden or be represented in method signatures or as field types.
215 *
216 * @param name The fully qualified name of the generated class in a binary format.
217 * @return A new builder that is equal to this builder but with the instrumented type named by the supplied name.
218 */
219 Builder<T> name(String name);
220
221 /**
222 * Adds a suffix to the current type name without changing the type's package.
223 *
224 * @param suffix The suffix to append to the current type name.
225 * @return A new builder that is equal to this builder but with the instrumented type named suffixed by the supplied suffix.
226 */
227 Builder<T> suffix(String suffix);
228
229 /**
230 * Defines the supplied modifiers as the modifiers of the instrumented type.
231 *
232 * @param modifierContributor The modifiers of the instrumented type.
233 * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
234 */
235 Builder<T> modifiers(ModifierContributor.ForType... modifierContributor);
236
237 /**
238 * Defines the supplied modifiers as the modifiers of the instrumented type.
239 *
240 * @param modifierContributors The modifiers of the instrumented type.
241 * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
242 */
243 Builder<T> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors);
244
245 /**
246 * Defines the supplied modifiers as the modifiers of the instrumented type.
247 *
248 * @param modifiers The modifiers of the instrumented type.
249 * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
250 */
251 Builder<T> modifiers(int modifiers);
252
253 /**
254 * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
255 * type's new modifiers.
256 *
257 * @param modifierContributor The modifiers of the instrumented type.
258 * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
259 */
260 Builder<T> merge(ModifierContributor.ForType... modifierContributor);
261
262 /**
263 * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
264 * type's new modifiers.
265 *
266 * @param modifierContributors The modifiers of the instrumented type.
267 * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
268 */
269 Builder<T> merge(Collection<? extends ModifierContributor.ForType> modifierContributors);
270
271 /**
272 * <p>
273 * Defines this type as a top-level type that is not declared by another type or enclosed by another member.
274 * </p>
275 * <p>
276 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
277 * </p>
278 * <p>
279 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
280 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
281 * consistent among the definitions of connected types.
282 * </p>
283 *
284 * @return A new builder that is equal to this builder but without any declaration of a a declared or enclosed type.
285 */
286 Builder<T> topLevelType();
287
288 /**
289 * <p>
290 * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is defined
291 * as a local type.
292 * </p>
293 * <p>
294 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
295 * </p>
296 * <p>
297 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
298 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
299 * consistent among the definitions of connected types.
300 * </p>
301 *
302 * @param type The type to declare as the built type's outer type.
303 * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
304 */
305 InnerTypeDefinition.ForType<T> innerTypeOf(Class<?> type);
306
307 /**
308 * <p>
309 * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is
310 * defined as a local type.
311 * </p>
312 * <p>
313 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
314 * </p>
315 * <p>
316 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
317 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
318 * consistent among the definitions of connected types.
319 * </p>
320 *
321 * @param type The type to declare as the built type's outer type.
322 * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
323 */
324 InnerTypeDefinition.ForType<T> innerTypeOf(TypeDescription type);
325
326 /**
327 * <p>
328 * Defines this type as an inner type that was declared within the supplied method. Without any additional configuration, the type
329 * declaration is defined as a local type.
330 * </p>
331 * <p>
332 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
333 * </p>
334 * <p>
335 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
336 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
337 * consistent among the definitions of connected types.
338 * </p>
339 *
340 * @param method The method to declare as the built type's declaring method.
341 * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method.
342 */
343 InnerTypeDefinition<T> innerTypeOf(Method method);
344
345 /**
346 * <p>
347 * Defines this type as an inner type that was declared within the supplied constructor. Without any additional configuration, the type
348 * declaration is defined as a local type.
349 * </p>
350 * <p>
351 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
352 * </p>
353 * <p>
354 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
355 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
356 * consistent among the definitions of connected types.
357 * </p>
358 *
359 * @param constructor The constructor to declare as the built type's declaring method.
360 * @return A new builder that is equal to this builder with the supplied method as the built type's declaring constructor.
361 */
362 InnerTypeDefinition<T> innerTypeOf(Constructor<?> constructor);
363
364 /**
365 * <p>
366 * Defines this type as an inner type that was declared within the supplied method or constructor. Without any additional configuration,
367 * the type declaration is defined as a local type.
368 * </p>
369 * <p>
370 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
371 * </p>
372 * <p>
373 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
374 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
375 * consistent among the definitions of connected types.
376 * </p>
377 *
378 * @param methodDescription The method or constructor to declare as the built type's declaring method.
379 * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method or constructor.
380 */
381 InnerTypeDefinition<T> innerTypeOf(MethodDescription.InDefinedShape methodDescription);
382
383 /**
384 * <p>
385 * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
386 * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
387 * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
388 * </p>
389 * <p>
390 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
391 * </p>
392 * <p>
393 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
394 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
395 * consistent among the definitions of connected types.
396 * </p>
397 *
398 * @param type The types being declared.
399 * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
400 */
401 Builder<T> declaredTypes(Class<?>... type);
402
403 /**
404 * <p>
405 * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
406 * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
407 * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
408 * </p>
409 * <p>
410 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
411 * </p>
412 * <p>
413 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
414 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
415 * consistent among the definitions of connected types.
416 * </p>
417 *
418 * @param type The types being declared.
419 * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
420 */
421 Builder<T> declaredTypes(TypeDescription... type);
422
423 /**
424 * <p>
425 * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
426 * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
427 * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
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 types The types being declared.
439 * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
440 */
441 Builder<T> declaredTypes(List<? extends Class<?>> types);
442
443 /**
444 * <p>
445 * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
446 * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
447 * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
448 * </p>
449 * <p>
450 * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
451 * </p>
452 * <p>
453 * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
454 * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
455 * consistent among the definitions of connected types.
456 * </p>
457 *
458 * @param types The types being declared.
459 * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
460 */
461 Builder<T> declaredTypes(Collection<? extends TypeDescription> types);
462
463 /**
464 * <p>
465 * Defines this type as self-hosted, i.e. as only being a nest mate of itself.
466 * </p>
467 * <p>
468 * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
469 * </p>
470 * <p>
471 * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
472 * Otherwise, the runtime will not accept further nest mates. 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 * @return A new builder that is equal to this builder but where the built type is a self-hosted nest mate.
477 */
478 Builder<T> noNestMate();
479
480 /**
481 * <p>
482 * Defines this type as a nest member of the supplied type as a nest host.
483 * </p>
484 * <p>
485 * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
486 * </p>
487 * <p>
488 * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
489 * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
490 * consistent among the definitions of connected types.
491 * </p>
492 *
493 * @param type The nest host.
494 * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
495 */
496 Builder<T> nestHost(Class<?> type);
497
498 /**
499 * <p>
500 * Defines this type as a nest member of the supplied type as a nest host.
501 * </p>
502 * <p>
503 * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
504 * </p>
505 * <p>
506 * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
507 * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
508 * consistent among the definitions of connected types.
509 * </p>
510 *
511 * @param type The nest host.
512 * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
513 */
514 Builder<T> nestHost(TypeDescription type);
515
516 /**
517 * <p>
518 * Defines this type as a nest host for the supplied types.
519 * </p>
520 * <p>
521 * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
522 * </p>
523 * <p>
524 * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
525 * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
526 * consistent among the definitions of connected types.
527 * </p>
528 *
529 * @param type The nest members.
530 * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
531 */
532 Builder<T> nestMembers(Class<?>... type);
533
534 /**
535 * <p>
536 * Defines this type as a nest host for the supplied types.
537 * </p>
538 * <p>
539 * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
540 * </p>
541 * <p>
542 * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
543 * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
544 * consistent among the definitions of connected types.
545 * </p>
546 *
547 * @param type The nest members.
548 * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
549 */
550 Builder<T> nestMembers(TypeDescription... type);
551
552 /**
553 * <p>
554 * Defines this type as a nest host for the supplied types.
555 * </p>
556 * <p>
557 * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
558 * </p>
559 * <p>
560 * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
561 * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
562 * consistent among the definitions of connected types.
563 * </p>
564 *
565 * @param types The nest members.
566 * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
567 */
568 Builder<T> nestMembers(List<? extends Class<?>> types);
569
570 /**
571 * <p>
572 * Defines this type as a nest host for the supplied types.
573 * </p>
574 * <p>
575 * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
576 * </p>
577 * <p>
578 * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
579 * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
580 * consistent among the definitions of connected types.
581 * </p>
582 *
583 * @param types The nest members.
584 * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
585 */
586 Builder<T> nestMembers(Collection<? extends TypeDescription> types);
587
588 /**
589 * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
590 * this type was not previously sealed, only the supplied subclasses are permitted.
591 *
592 * @param type The permitted subclasses.
593 * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
594 */
595 Builder<T> permittedSubclass(Class<?>... type);
596
597 /**
598 * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
599 * this type was not previously sealed, only the supplied subclasses are permitted.
600 *
601 * @param type The permitted subclasses.
602 * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
603 */
604 Builder<T> permittedSubclass(TypeDescription... type);
605
606 /**
607 * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
608 * this type was not previously sealed, only the supplied subclasses are permitted.
609 *
610 * @param types The permitted subclasses.
611 * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
612 */
613 Builder<T> permittedSubclass(List<? extends Class<?>> types);
614
615 /**
616 * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
617 * this type was not previously sealed, only the supplied subclasses are permitted.
618 *
619 * @param types The permitted subclasses.
620 * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
621 */
622 Builder<T> permittedSubclass(Collection<? extends TypeDescription> types);
623
624 /**
625 * Unseales this type.
626 *
627 * @return A new builder that is equal to this builder but where the built type does not restrain its permitted subclasses.
628 */
629 Builder<T> unsealed();
630
631 /**
632 * Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
633 * any type of meta data to a type, not only Java {@link Annotation}s.
634 *
635 * @param typeAttributeAppender The type attribute appender to apply.
636 * @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
637 */
638 Builder<T> attribute(TypeAttributeAppender typeAttributeAppender);
639
640 /**
641 * Annotates the instrumented type with the supplied annotations.
642 *
643 * @param annotation The annotations to add to the instrumented type.
644 * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
645 */
646 Builder<T> annotateType(Annotation... annotation);
647
648 /**
649 * Annotates the instrumented type with the supplied annotations.
650 *
651 * @param annotations The annotations to add to the instrumented type.
652 * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
653 */
654 Builder<T> annotateType(List<? extends Annotation> annotations);
655
656 /**
657 * Annotates the instrumented type with the supplied annotations.
658 *
659 * @param annotation The annotations to add to the instrumented type.
660 * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
661 */
662 Builder<T> annotateType(AnnotationDescription... annotation);
663
664 /**
665 * Annotates the instrumented type with the supplied annotations.
666 *
667 * @param annotations The annotations to add to the instrumented type.
668 * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
669 */
670 Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
671
672 /**
673 * <p>
674 * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
675 * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
676 * are explicitly ignored.
677 * </p>
678 * <p>
679 * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
680 * as raw types if they declare type variables or an owner type.
681 * </p>
682 *
683 * @param interfaceType The interface types to implement.
684 * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
685 */
686 MethodDefinition.ImplementationDefinition.Optional<T> implement(Type... interfaceType);
687
688 /**
689 * <p>
690 * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
691 * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
692 * are explicitly ignored.
693 * </p>
694 * <p>
695 * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
696 * as raw types if they declare type variables or an owner type.
697 * </p>
698 *
699 * @param interfaceTypes The interface types to implement.
700 * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
701 */
702 MethodDefinition.ImplementationDefinition.Optional<T> implement(List<? extends Type> interfaceTypes);
703
704 /**
705 * <p>
706 * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
707 * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
708 * are explicitly ignored.
709 * </p>
710 * <p>
711 * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
712 * implemented as raw types if they declare type variables or an owner type.
713 * </p>
714 *
715 * @param interfaceType The interface types to implement.
716 * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
717 */
718 MethodDefinition.ImplementationDefinition.Optional<T> implement(TypeDefinition... interfaceType);
719
720 /**
721 * <p>
722 * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
723 * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
724 * are explicitly ignored.
725 * </p>
726 * <p>
727 * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
728 * implemented as raw types if they declare type variables or an owner type.
729 * </p>
730 *
731 * @param interfaceTypes The interface types to implement.
732 * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
733 */
734 MethodDefinition.ImplementationDefinition.Optional<T> implement(Collection<? extends TypeDefinition> interfaceTypes);
735
736 /**
737 * <p>
738 * Executes the supplied byte code appender within the beginning of the instrumented type's type initializer. The
739 * supplied byte code appender <b>must not return</b> from the method. If several byte code appenders are supplied,
740 * they are executed within their application order.
741 * </p>
742 * <p>
743 * This method should only be used for preparing an instrumented type with a specific configuration. Normally,
744 * a byte code appender is applied via Byte Buddy's standard API by invoking {@link Builder#invokable(ElementMatcher)}
745 * using the {@link net.bytebuddy.matcher.ElementMatchers#isTypeInitializer()} matcher.
746 * </p>
747 *
748 * @param byteCodeAppender The byte code appender to execute within the instrumented type's type initializer.
749 * @return A new builder that is equal to this builder but with the supplied byte code appender being executed within
750 * the instrumented type's type initializer.
751 */
752 Builder<T> initializer(ByteCodeAppender byteCodeAppender);
753
754 /**
755 * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
756 * type initializers are supplied, each loaded type initializer is executed in its registration order.
757 *
758 * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
759 * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
760 * loading the instrumented type.
761 */
762 Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
763
764 /**
765 * Explicitly requires another dynamic type for the creation of this type.
766 *
767 * @param type The type to require.
768 * @param binaryRepresentation The type's binary representation.
769 * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
770 */
771 Builder<T> require(TypeDescription type, byte[] binaryRepresentation);
772
773 /**
774 * Explicitly requires another dynamic type for the creation of this type.
775 *
776 * @param type The type to require.
777 * @param binaryRepresentation The type's binary representation.
778 * @param typeInitializer The type's loaded type initializer.
779 * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
780 */
781 Builder<T> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
782
783 /**
784 * Explicitly requires other dynamic types for the creation of this type.
785 *
786 * @param auxiliaryType The required dynamic types.
787 * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
788 */
789 Builder<T> require(DynamicType... auxiliaryType);
790
791 /**
792 * Explicitly requires other dynamic types for the creation of this type.
793 *
794 * @param auxiliaryTypes The required dynamic types.
795 * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
796 */
797 Builder<T> require(Collection<DynamicType> auxiliaryTypes);
798
799 /**
800 * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
801 *
802 * @param symbol The type variable's symbol.
803 * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
804 */
805 TypeVariableDefinition<T> typeVariable(String symbol);
806
807 /**
808 * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
809 *
810 * @param symbol The type variable's symbol.
811 * @param bound The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
812 * should be equal to the currently instrumented type.
813 * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
814 */
815 TypeVariableDefinition<T> typeVariable(String symbol, Type... bound);
816
817 /**
818 * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
819 *
820 * @param symbol The type variable's symbol.
821 * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
822 * should be equal to the currently instrumented type.
823 * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
824 */
825 TypeVariableDefinition<T> typeVariable(String symbol, List<? extends Type> bounds);
826
827 /**
828 * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
829 *
830 * @param symbol The type variable's symbol.
831 * @param bound The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
832 * should be equal to the currently instrumented type.
833 * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
834 */
835 TypeVariableDefinition<T> typeVariable(String symbol, TypeDefinition... bound);
836
837 /**
838 * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
839 *
840 * @param symbol The type variable's symbol.
841 * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
842 * should be equal to the currently instrumented type.
843 * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
844 */
845 TypeVariableDefinition<T> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
846
847 /**
848 * Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
849 *
850 * @param matcher The matcher to decide what type variables to transform.
851 * @param transformer The transformer to apply to the matched type variables.
852 * @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
853 */
854 Builder<T> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer);
855
856 /**
857 * Defines the specified field as a field of the built dynamic type.
858 *
859 * @param name The name of the field.
860 * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
861 * should be equal to the currently instrumented type.
862 * @param modifierContributor The modifiers of the field.
863 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
864 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
865 */
866 FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor);
867
868 /**
869 * Defines the specified field as a field of the built dynamic type.
870 *
871 * @param name The name of the field.
872 * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
873 * should be equal to the currently instrumented type.
874 * @param modifierContributors The modifiers of the field.
875 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
876 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
877 */
878 FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors);
879
880 /**
881 * Defines the specified field as a field of the built dynamic type.
882 *
883 * @param name The name of the field.
884 * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
885 * should be equal to the currently instrumented type.
886 * @param modifiers The modifiers of the field.
887 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
888 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
889 */
890 FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, int modifiers);
891
892 /**
893 * Defines the specified field as a field of the built dynamic type.
894 *
895 * @param name The name of the field.
896 * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
897 * should be equal to the currently instrumented type.
898 * @param modifierContributor The modifiers of the field.
899 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
900 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
901 */
902 FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor);
903
904 /**
905 * Defines the specified field as a field of the built dynamic type.
906 *
907 * @param name The name of the field.
908 * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
909 * should be equal to the currently instrumented type.
910 * @param modifierContributors The modifiers of the field.
911 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
912 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
913 */
914 FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors);
915
916 /**
917 * Defines the specified field as a field of the built dynamic type.
918 *
919 * @param name The name of the field.
920 * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
921 * should be equal to the currently instrumented type.
922 * @param modifiers The modifiers of the field.
923 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
924 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
925 */
926 FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, int modifiers);
927
928 /**
929 * Defines a field that is similar to the supplied field but without copying any annotations on the field.
930 *
931 * @param field The field to imitate as a field of the instrumented type.
932 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
933 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
934 */
935 FieldDefinition.Optional.Valuable<T> define(Field field);
936
937 /**
938 * Defines a field that is similar to the supplied field but without copying any annotations on the field.
939 *
940 * @param field The field to imitate as a field of the instrumented type.
941 * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
942 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
943 */
944 FieldDefinition.Optional.Valuable<T> define(FieldDescription field);
945
946 /**
947 * Defines a private, static, final field for a serial version UID of the given value.
948 *
949 * @param serialVersionUid The serial version UID to define as a value.
950 * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
951 * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
952 */
953 FieldDefinition.Optional<T> serialVersionUid(long serialVersionUid);
954
955 /**
956 * <p>
957 * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
958 * default value, annotations or custom attributes.
959 * </p>
960 * <p>
961 * When a type is redefined or rebased, any annotations that the field declared previously is preserved
962 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
963 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
964 * altered, annotation retention must be disabled.
965 * </p>
966 * <p>
967 * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
968 * over the previous definition, i.e. the previous field definition is no longer applied.
969 * </p>
970 *
971 * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
972 * @return A builder that allows for changing a field's definition.
973 */
974 FieldDefinition.Valuable<T> field(ElementMatcher<? super FieldDescription> matcher);
975
976 /**
977 * <p>
978 * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
979 * default value, annotations or custom attributes. Using a latent matcher gives opportunity to resolve an
980 * {@link ElementMatcher} based on the instrumented type before applying the matcher.
981 * </p>
982 * <p>
983 * When a type is redefined or rebased, any annotations that the field declared previously is preserved
984 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
985 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
986 * altered, annotation retention must be disabled.
987 * </p>
988 * <p>
989 * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
990 * over the previous definition, i.e. the previous field definition is no longer applied.
991 * </p>
992 *
993 * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
994 * @return A builder that allows for changing a field's definition.
995 */
996 FieldDefinition.Valuable<T> field(LatentMatcher<? super FieldDescription> matcher);
997
998 /**
999 * <p>
1000 * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1001 * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1002 * </p>
1003 * <p>
1004 * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1005 * is to be ignored, this matcher is no longer executed.
1006 * </p>
1007 *
1008 * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1009 * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1010 * instrumentation.
1011 */
1012 Builder<T> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods);
1013
1014 /**
1015 * <p>
1016 * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1017 * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1018 * Using a latent matcher gives opportunity to resolve an {@link ElementMatcher} based on the instrumented type before applying the
1019 * matcher.
1020 * </p>
1021 * <p>
1022 * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1023 * is to be ignored, this matcher is no longer executed.
1024 * </p>
1025 *
1026 * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1027 * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1028 * instrumentation.
1029 */
1030 Builder<T> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods);
1031
1032 /**
1033 * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1034 * type variables can be defined in subsequent steps.
1035 *
1036 * @param name The name of the method.
1037 * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1038 * should be equal to the currently instrumented type.
1039 * @param modifierContributor The method's modifiers.
1040 * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1041 */
1042 MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor);
1043
1044 /**
1045 * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1046 * type variables can be defined in subsequent steps.
1047 *
1048 * @param name The name of the method.
1049 * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1050 * should be equal to the currently instrumented type.
1051 * @param modifierContributors The method's modifiers.
1052 * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1053 */
1054 MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1055
1056 /**
1057 * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1058 * type variables can be defined in subsequent steps.
1059 *
1060 * @param name The name of the method.
1061 * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1062 * should be equal to the currently instrumented type.
1063 * @param modifiers The method's modifiers.
1064 * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1065 */
1066 MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, int modifiers);
1067
1068 /**
1069 * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1070 * type variables can be defined in subsequent steps.
1071 *
1072 * @param name The name of the method.
1073 * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1074 * should be equal to the currently instrumented type.
1075 * @param modifierContributor The method's modifiers.
1076 * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1077 */
1078 MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor);
1079
1080 /**
1081 * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1082 * type variables can be defined in subsequent steps.
1083 *
1084 * @param name The name of the method.
1085 * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1086 * should be equal to the currently instrumented type.
1087 * @param modifierContributors The method's modifiers.
1088 * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1089 */
1090 MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1091
1092 /**
1093 * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1094 * type variables can be defined in subsequent steps.
1095 *
1096 * @param name The name of the method.
1097 * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1098 * should be equal to the currently instrumented type.
1099 * @param modifiers The method's modifiers.
1100 * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1101 */
1102 MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, int modifiers);
1103
1104 /**
1105 * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1106 * type variables can be defined in subsequent steps.
1107 *
1108 * @param modifierContributor The constructor's modifiers.
1109 * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1110 */
1111 MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(ModifierContributor.ForMethod... modifierContributor);
1112
1113 /**
1114 * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1115 * type variables can be defined in subsequent steps.
1116 *
1117 * @param modifierContributors The constructor's modifiers.
1118 * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1119 */
1120 MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1121
1122 /**
1123 * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1124 * type variables can be defined in subsequent steps.
1125 *
1126 * @param modifiers The constructor's modifiers.
1127 * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1128 */
1129 MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(int modifiers);
1130
1131 /**
1132 * Defines a method that is similar to the supplied method but without copying any annotations of the method or method parameters.
1133 *
1134 * @param method The method to imitate as a method of the instrumented type.
1135 * @return A builder that allows for defining an implementation for the method.
1136 */
1137 MethodDefinition.ImplementationDefinition<T> define(Method method);
1138
1139 /**
1140 * Defines a constructor that is similar to the supplied constructor but without copying any annotations of the constructor or
1141 * constructor parameters.
1142 *
1143 * @param constructor The constructor to imitate as a method of the instrumented type.
1144 * @return A builder that allows for defining an implementation for the constructor.
1145 */
1146 MethodDefinition.ImplementationDefinition<T> define(Constructor<?> constructor);
1147
1148 /**
1149 * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
1150 * the method/constructor or method/constructor parameters.
1151 *
1152 * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
1153 * @return A builder that allows for defining an implementation for the method or constructor.
1154 */
1155 MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
1156
1157 /**
1158 * Defines a Java bean property with the specified name.
1159 *
1160 * @param name The name of the property.
1161 * @param type The property type.
1162 * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1163 */
1164 FieldDefinition.Optional<T> defineProperty(String name, Type type);
1165
1166 /**
1167 * Defines a Java bean property with the specified name.
1168 *
1169 * @param name The name of the property.
1170 * @param type The property type.
1171 * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1172 * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1173 */
1174 FieldDefinition.Optional<T> defineProperty(String name, Type type, boolean readOnly);
1175
1176 /**
1177 * Defines a Java bean property with the specified name.
1178 *
1179 * @param name The name of the property.
1180 * @param type The property type.
1181 * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1182 */
1183 FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type);
1184
1185 /**
1186 * Defines a Java bean property with the specified name.
1187 *
1188 * @param name The name of the property.
1189 * @param type The property type.
1190 * @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1191 * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1192 */
1193 FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type, boolean readOnly);
1194
1195 /**
1196 * <p>
1197 * Matches a method that is already declared or inherited by the instrumented type. This gives opportunity to change or to
1198 * override that method's implementation, default value, annotations or custom attributes. It is also possible to make
1199 * a method abstract.
1200 * </p>
1201 * <p>
1202 * When a type is redefined or rebased, any annotations that the method declared previously is preserved
1203 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1204 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1205 * altered, annotation retention must be disabled.
1206 * </p>
1207 * <p>
1208 * If a method is already matched by a previously specified matcher, the new method definition gets precedence
1209 * over the previous definition, i.e. the previous method definition is no longer applied.
1210 * </p>
1211 * <p>
1212 * Note that the specified definition does never apply for methods that are explicitly ignored.
1213 * </p>
1214 *
1215 * @param matcher The matcher that determines what methods are affected by the subsequent specification.
1216 * @return A builder that allows for changing a method's or constructor's definition.
1217 */
1218 MethodDefinition.ImplementationDefinition<T> method(ElementMatcher<? super MethodDescription> matcher);
1219
1220 /**
1221 * <p>
1222 * Matches a constructor that is already declared by the instrumented type. This gives opportunity to change that constructor's
1223 * implementation, default value, annotations or custom attributes.
1224 * </p>
1225 * <p>
1226 * When a type is redefined or rebased, any annotations that the constructor declared previously is preserved
1227 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1228 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1229 * altered, annotation retention must be disabled.
1230 * </p>
1231 * <p>
1232 * If a constructor is already matched by a previously specified matcher, the new constructor definition gets precedence
1233 * over the previous definition, i.e. the previous constructor definition is no longer applied.
1234 * </p>
1235 * <p>
1236 * Note that the specified definition does never apply for methods that are explicitly ignored.
1237 * </p>
1238 *
1239 * @param matcher The matcher that determines what constructors are affected by the subsequent specification.
1240 * @return A builder that allows for changing a method's or constructor's definition.
1241 */
1242 MethodDefinition.ImplementationDefinition<T> constructor(ElementMatcher<? super MethodDescription> matcher);
1243
1244 /**
1245 * <p>
1246 * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1247 * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1248 * or custom attributes. It is also possible to make a method abstract.
1249 * </p>
1250 * <p>
1251 * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1252 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1253 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1254 * altered, annotation retention must be disabled.
1255 * </p>
1256 * <p>
1257 * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1258 * over the previous definition, i.e. the previous definition is no longer applied.
1259 * </p>
1260 * <p>
1261 * Note that the specified definition does never apply for methods that are explicitly ignored.
1262 * </p>
1263 * <p>
1264 * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1265 * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1266 * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1267 * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1268 * </p>
1269 *
1270 * @param matcher The matcher that determines what methods or constructors are affected by the subsequent specification.
1271 * @return A builder that allows for changing a method's or constructor's definition.
1272 */
1273 MethodDefinition.ImplementationDefinition<T> invokable(ElementMatcher<? super MethodDescription> matcher);
1274
1275 /**
1276 * <p>
1277 * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1278 * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1279 * or custom attributes. It is also possible to make a method abstract. Using a latent matcher gives opportunity
1280 * to resolve an {@link ElementMatcher} based on the instrumented type before applying the matcher.
1281 * </p>
1282 * <p>
1283 * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1284 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1285 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1286 * altered, annotation retention must be disabled.
1287 * </p>
1288 * <p>
1289 * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1290 * over the previous definition, i.e. the previous definition is no longer applied.
1291 * </p>
1292 * <p>
1293 * Note that the specified definition does never apply for methods that are explicitly ignored.
1294 * </p>
1295 * <p>
1296 * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1297 * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1298 * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1299 * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1300 * </p>
1301 *
1302 * @param matcher The matcher that determines what declared methods or constructors are affected by the subsequent specification.
1303 * @return A builder that allows for changing a method's or constructor's definition.
1304 */
1305 MethodDefinition.ImplementationDefinition<T> invokable(LatentMatcher<? super MethodDescription> matcher);
1306
1307 /**
1308 * Implements {@link Object#hashCode()} and {@link Object#equals(Object)} methods for the instrumented type if those
1309 * methods are not declared as {@code final} by a super class. The implementations do not consider any implementations
1310 * of a super class and compare a class field by field without considering synthetic fields.
1311 *
1312 * @return A new type builder that defines {@link Object#hashCode()} and {@link Object#equals(Object)} methods accordingly.
1313 */
1314 Builder<T> withHashCodeEquals();
1315
1316 /**
1317 * Implements a {@link Object#toString()} method for the instrumented type if such a method is not declared as {@code final}
1318 * by a super class. The implementation prefixes the string with the simple class name and prints each non-synthetic field's
1319 * value after the field's name.
1320 *
1321 * @return A new type builder that defines {@link Object#toString()} method accordingly.
1322 */
1323 Builder<T> withToString();
1324
1325 /**
1326 * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1327 * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1328 *
1329 * @param name The record component's name.
1330 * @param type The record component's type.
1331 * @return A new builder that is equal to this builder but also defines the supplied record component.
1332 */
1333 RecordComponentDefinition.Optional<T> defineRecordComponent(String name, Type type);
1334
1335 /**
1336 * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1337 * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1338 *
1339 * @param name The record component's name.
1340 * @param type The record component's type.
1341 * @return A new builder that is equal to this builder but also defines the supplied record component.
1342 */
1343 RecordComponentDefinition.Optional<T> defineRecordComponent(String name, TypeDefinition type);
1344
1345 /**
1346 * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1347 * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1348 *
1349 * @param recordComponentDescription A description of the record component to immitate.
1350 * @return A new builder that is equal to this builder but also defines the supplied record component.
1351 */
1352 RecordComponentDefinition.Optional<T> define(RecordComponentDescription recordComponentDescription);
1353
1354 /**
1355 * <p>
1356 * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1357 * record component's annotations or custom attributes.
1358 * </p>
1359 * <p>
1360 * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1361 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1362 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1363 * altered, annotation retention must be disabled.
1364 * </p>
1365 * <p>
1366 * If a record component is already matched by a previously specified record component matcher, the new record component
1367 * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1368 * </p>
1369 *
1370 * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1371 * @return A builder that allows for changing a record component's definition.
1372 */
1373 RecordComponentDefinition<T> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher);
1374
1375 /**
1376 * <p>
1377 * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1378 * record component's annotations or custom attributes.
1379 * </p>
1380 * <p>
1381 * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1382 * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1383 * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1384 * altered, annotation retention must be disabled.
1385 * </p>
1386 * <p>
1387 * If a record component is already matched by a previously specified record component matcher, the new record component
1388 * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1389 * </p>
1390 *
1391 * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1392 * @return A builder that allows for changing a record component's definition.
1393 */
1394 RecordComponentDefinition<T> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher);
1395
1396 /**
1397 * <p>
1398 * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1399 * </p>
1400 * <p>
1401 * Other than {@link DynamicType.Builder#make(TypePool)}, this method supplies a context-dependant type pool to the underlying class writer.
1402 * Supplying a type pool only makes sense if custom byte code is created by adding a custom {@link AsmVisitorWrapper} where ASM might be
1403 * required to compute stack map frames by processing information over any mentioned type's class hierarchy.
1404 * </p>
1405 * <p>
1406 * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1407 * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1408 * executing the initializer must rely on such an initializer.
1409 * </p>
1410 *
1411 * @return An unloaded dynamic type representing the type specified by this builder.
1412 */
1413 DynamicType.Unloaded<T> make();
1414
1415 /**
1416 * <p>
1417 * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1418 * </p>
1419 * <p>
1420 * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1421 * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1422 * executing the initializer must rely on such an initializer.
1423 * </p>
1424 *
1425 * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1426 * @return An unloaded dynamic type representing the type specified by this builder.
1427 */
1428 DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy);
1429
1430 /**
1431 * <p>
1432 * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1433 * </p>
1434 * <p>
1435 * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1436 * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1437 * executing the initializer must rely on such an initializer.
1438 * </p>
1439 *
1440 * @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
1441 * @return An unloaded dynamic type representing the type specified by this builder.
1442 */
1443 DynamicType.Unloaded<T> make(TypePool typePool);
1444
1445 /**
1446 * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1447 *
1448 * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1449 * @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
1450 * @return An unloaded dynamic type representing the type specified by this builder.
1451 */
1452 DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool);
1453
1454 /**
1455 * Returns a {@link TypeDescription} for the currently built type.
1456 *
1457 * @return A {@link TypeDescription} for the currently built type.
1458 */
1459 TypeDescription toTypeDescription();
1460
1461 /**
1462 * An inner type definition for defining a type that is contained within another type, method or constructor.
1463 *
1464 * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1465 */
1466 interface InnerTypeDefinition<S> extends Builder<S> {
1467
1468 /**
1469 * Defines this inner type declaration as an anonymous type.
1470 *
1471 * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
1472 */
1473 Builder<S> asAnonymousType();
1474
1475 /**
1476 * An inner type definition for defining a type that is contained within another type.
1477 *
1478 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1479 */
1480 interface ForType<U> extends InnerTypeDefinition<U> {
1481
1482 /**
1483 * Defines this inner type declaration as a member type.
1484 *
1485 * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
1486 */
1487 Builder<U> asMemberType();
1488 }
1489 }
1490
1491 /**
1492 * A builder for a type variable definition.
1493 *
1494 * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1495 */
1496 interface TypeVariableDefinition<S> extends Builder<S> {
1497
1498 /**
1499 * Annotates the previously defined type variable with the supplied annotations.
1500 *
1501 * @param annotation The annotations to declare on the previously defined type variable.
1502 * @return A new builder that is equal to this builder but with the given annotations declared
1503 * on the previously defined type variable.
1504 */
1505 TypeVariableDefinition<S> annotateTypeVariable(Annotation... annotation);
1506
1507 /**
1508 * Annotates the previously defined type variable with the supplied annotations.
1509 *
1510 * @param annotations The annotations to declare on the previously defined type variable.
1511 * @return A new builder that is equal to this builder but with the given annotations declared
1512 * on the previously defined type variable.
1513 */
1514 TypeVariableDefinition<S> annotateTypeVariable(List<? extends Annotation> annotations);
1515
1516 /**
1517 * Annotates the previously defined type variable with the supplied annotations.
1518 *
1519 * @param annotation The annotations to declare on the previously defined type variable.
1520 * @return A new builder that is equal to this builder but with the given annotations declared
1521 * on the previously defined type variable.
1522 */
1523 TypeVariableDefinition<S> annotateTypeVariable(AnnotationDescription... annotation);
1524
1525 /**
1526 * Annotates the previously defined type variable with the supplied annotations.
1527 *
1528 * @param annotations The annotations to declare on the previously defined type variable.
1529 * @return A new builder that is equal to this builder but with the given annotations declared
1530 * on the previously defined type variable.
1531 */
1532 TypeVariableDefinition<S> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
1533
1534 /**
1535 * An abstract base implementation of a type variable definition.
1536 *
1537 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1538 */
1539 abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
1540
1541 /**
1542 * {@inheritDoc}
1543 */
1544 public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
1545 return annotateTypeVariable(Arrays.asList(annotation));
1546 }
1547
1548 /**
1549 * {@inheritDoc}
1550 */
1551 public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
1552 return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
1553 }
1554
1555 /**
1556 * {@inheritDoc}
1557 */
1558 public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
1559 return annotateTypeVariable(Arrays.asList(annotation));
1560 }
1561 }
1562 }
1563
1564 /**
1565 * A builder for a field definition.
1566 *
1567 * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1568 */
1569 interface FieldDefinition<S> {
1570
1571 /**
1572 * Annotates the previously defined or matched field with the supplied annotations.
1573 *
1574 * @param annotation The annotations to declare on the previously defined or matched field.
1575 * @return A new builder that is equal to this builder but with the given annotations declared
1576 * on the previously defined or matched field.
1577 */
1578 FieldDefinition.Optional<S> annotateField(Annotation... annotation);
1579
1580 /**
1581 * Annotates the previously defined or matched field with the supplied annotations.
1582 *
1583 * @param annotations The annotations to declare on the previously defined or matched field.
1584 * @return A new builder that is equal to this builder but with the given annotations declared
1585 * on the previously defined or matched field.
1586 */
1587 FieldDefinition.Optional<S> annotateField(List<? extends Annotation> annotations);
1588
1589 /**
1590 * Annotates the previously defined or matched field with the supplied annotations.
1591 *
1592 * @param annotation The annotations to declare on the previously defined or matched field.
1593 * @return A new builder that is equal to this builder but with the given annotations declared
1594 * on the previously defined or matched field.
1595 */
1596 FieldDefinition.Optional<S> annotateField(AnnotationDescription... annotation);
1597
1598 /**
1599 * Annotates the previously defined or matched field with the supplied annotations.
1600 *
1601 * @param annotations The annotations to declare on the previously defined or matched field.
1602 * @return A new builder that is equal to this builder but with the given annotations declared
1603 * on the previously defined or matched field.
1604 */
1605 FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
1606
1607 /**
1608 * Applies the supplied attribute appender factory onto the previously defined or matched field.
1609 *
1610 * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
1611 * previously defined or matched field.
1612 * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
1613 * applied to the previously defined or matched field.
1614 */
1615 FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
1616
1617 /**
1618 * Applies the supplied transformer onto the previously defined or matched field. The transformed
1619 * field is written <i>as it is</i> and it not subject to any validations.
1620 *
1621 * @param transformer The transformer to apply to the previously defined or matched field.
1622 * @return A new builder that is equal to this builder but with the supplied field transformer
1623 * applied to the previously defined or matched field.
1624 */
1625 FieldDefinition.Optional<S> transform(Transformer<FieldDescription> transformer);
1626
1627 /**
1628 * A builder for a field definition that allows for defining a value.
1629 *
1630 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1631 */
1632 interface Valuable<U> extends FieldDefinition<U> {
1633
1634 /**
1635 * <p>
1636 * Defines the supplied {@code boolean} value as a default value of the previously defined or matched field. The value can only
1637 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int}. For non-boolean
1638 * fields, the field's value is set to {@code 0} for {@code false} or {@code 1} for {@code true}.
1639 * </p>
1640 * <p>
1641 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1642 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1643 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1644 * </p>
1645 *
1646 * @param value The value to define as a default value of the defined field.
1647 * @return A new builder that is equal to this builder but with the given default value declared for the
1648 * previously defined or matched field.
1649 */
1650 FieldDefinition.Optional<U> value(boolean value);
1651
1652 /**
1653 * <p>
1654 * Defines the supplied {@code int} value as a default value of the previously defined or matched field. The value can only
1655 * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int} where the
1656 * value must be within the numeric type's range. The {@code boolean} type is regarded as a numeric type with the possible
1657 * values of {@code 0} and {@code 1} representing {@code false} and {@code true}.
1658 * </p>
1659 * <p>
1660 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1661 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1662 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1663 * </p>
1664 *
1665 * @param value The value to define as a default value of the defined field.
1666 * @return A new builder that is equal to this builder but with the given default value declared for the
1667 * previously defined or matched field.
1668 */
1669 FieldDefinition.Optional<U> value(int value);
1670
1671 /**
1672 * <p>
1673 * Defines the supplied {@code long} value as a default value of the previously defined or matched field.
1674 * </p>
1675 * <p>
1676 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1677 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1678 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1679 * </p>
1680 *
1681 * @param value The value to define as a default value of the defined field.
1682 * @return A new builder that is equal to this builder but with the given default value declared for the
1683 * previously defined or matched field.
1684 */
1685 FieldDefinition.Optional<U> value(long value);
1686
1687 /**
1688 * <p>
1689 * Defines the supplied {@code float} value as a default value of the previously defined or matched field.
1690 * </p>
1691 * <p>
1692 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1693 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1694 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1695 * </p>
1696 *
1697 * @param value The value to define as a default value of the defined field.
1698 * @return A new builder that is equal to this builder but with the given default value declared for the
1699 * previously defined or matched field.
1700 */
1701 FieldDefinition.Optional<U> value(float value);
1702
1703 /**
1704 * <p>
1705 * Defines the supplied {@code double} value as a default value of the previously defined or matched field.
1706 * </p>
1707 * <p>
1708 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1709 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1710 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1711 * </p>
1712 *
1713 * @param value The value to define as a default value of the defined field.
1714 * @return A new builder that is equal to this builder but with the given default value declared for the
1715 * previously defined or matched field.
1716 */
1717 FieldDefinition.Optional<U> value(double value);
1718
1719 /**
1720 * <p>
1721 * Defines the supplied {@link String} value as a default value of the previously defined or matched field.
1722 * </p>
1723 * <p>
1724 * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1725 * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1726 * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1727 * </p>
1728 *
1729 * @param value The value to define as a default value of the defined field.
1730 * @return A new builder that is equal to this builder but with the given default value declared for the
1731 * previously defined or matched field.
1732 */
1733 FieldDefinition.Optional<U> value(String value);
1734 }
1735
1736 /**
1737 * A builder for an optional field definition.
1738 *
1739 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1740 */
1741 interface Optional<U> extends FieldDefinition<U>, Builder<U> {
1742
1743 /**
1744 * A builder for an optional field definition that allows for defining a value.
1745 *
1746 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1747 */
1748 interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
1749
1750 /**
1751 * An abstract base implementation of an optional field definition that allows for defining a value.
1752 *
1753 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1754 */
1755 abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1756
1757 /**
1758 * {@inheritDoc}
1759 */
1760 public FieldDefinition.Optional<U> value(boolean value) {
1761 return defaultValue(value ? 1 : 0);
1762 }
1763
1764 /**
1765 * {@inheritDoc}
1766 */
1767 public FieldDefinition.Optional<U> value(int value) {
1768 return defaultValue(value);
1769 }
1770
1771 /**
1772 * {@inheritDoc}
1773 */
1774 public FieldDefinition.Optional<U> value(long value) {
1775 return defaultValue(value);
1776 }
1777
1778 /**
1779 * {@inheritDoc}
1780 */
1781 public FieldDefinition.Optional<U> value(float value) {
1782 return defaultValue(value);
1783 }
1784
1785 /**
1786 * {@inheritDoc}
1787 */
1788 public FieldDefinition.Optional<U> value(double value) {
1789 return defaultValue(value);
1790 }
1791
1792 /**
1793 * {@inheritDoc}
1794 */
1795 public FieldDefinition.Optional<U> value(String value) {
1796 if (value == null) {
1797 throw new IllegalArgumentException("Cannot set null as a default value");
1798 }
1799 return defaultValue(value);
1800 }
1801
1802 /**
1803 * Defines the supplied value as a default value of the previously defined or matched field.
1804 *
1805 * @param defaultValue The value to define as a default value of the defined field.
1806 * @return A new builder that is equal to this builder but with the given default value declared for the
1807 * previously defined or matched field.
1808 */
1809 protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
1810
1811 /**
1812 * An adapter for an optional field definition that allows for defining a value.
1813 *
1814 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1815 */
1816 @HashCodeAndEqualsPlugin.Enhance
1817 private abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
1818
1819 /**
1820 * The field attribute appender factory to apply.
1821 */
1822 protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
1823
1824 /**
1825 * The field transformer to apply.
1826 */
1827 protected final Transformer<FieldDescription> transformer;
1828
1829 /**
1830 * The field's default value or {@code null} if no value is to be defined.
1831 */
1832 @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
1833 protected final Object defaultValue;
1834
1835 /**
1836 * Creates a new field adapter.
1837 *
1838 * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1839 * @param transformer The field transformer to apply.
1840 * @param defaultValue The field's default value or {@code null} if no value is to be defined.
1841 */
1842 protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
1843 Transformer<FieldDescription> transformer,
1844 Object defaultValue) {
1845 this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
1846 this.transformer = transformer;
1847 this.defaultValue = defaultValue;
1848 }
1849
1850 /**
1851 * {@inheritDoc}
1852 */
1853 public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
1854 return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
1855 }
1856
1857 /**
1858 * {@inheritDoc}
1859 */
1860 @SuppressWarnings("unchecked") // In absence of @SafeVarargs
1861 public FieldDefinition.Optional<V> transform(Transformer<FieldDescription> transformer) {
1862 return materialize(fieldAttributeAppenderFactory, new Transformer.Compound<FieldDescription>(this.transformer, transformer), defaultValue);
1863 }
1864
1865 @Override
1866 protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
1867 return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
1868 }
1869
1870 /**
1871 * Creates a new optional field definition for which all of the supplied values are represented.
1872 *
1873 * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1874 * @param transformer The field transformer to apply.
1875 * @param defaultValue The field's default value or {@code null} if no value is to be defined.
1876 * @return A new field definition that represents the supplied values.
1877 */
1878 protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
1879 Transformer<FieldDescription> transformer,
1880 Object defaultValue);
1881 }
1882 }
1883 }
1884
1885 /**
1886 * An abstract base implementation for an optional field definition.
1887 *
1888 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1889 */
1890 abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1891
1892 /**
1893 * {@inheritDoc}
1894 */
1895 public FieldDefinition.Optional<U> annotateField(Annotation... annotation) {
1896 return annotateField(Arrays.asList(annotation));
1897 }
1898
1899 /**
1900 * {@inheritDoc}
1901 */
1902 public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
1903 return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1904 }
1905
1906 /**
1907 * {@inheritDoc}
1908 */
1909 public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
1910 return annotateField(Arrays.asList(annotation));
1911 }
1912 }
1913 }
1914 }
1915
1916 /**
1917 * A builder for a method definition.
1918 *
1919 * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1920 */
1921 interface MethodDefinition<S> extends Builder<S> {
1922
1923 /**
1924 * Annotates the previously defined or matched method with the supplied annotations.
1925 *
1926 * @param annotation The annotations to declare on the previously defined or matched method.
1927 * @return A new builder that is equal to this builder but with the given annotations declared
1928 * on the previously defined or matched method.
1929 */
1930 MethodDefinition<S> annotateMethod(Annotation... annotation);
1931
1932 /**
1933 * Annotates the previously defined or matched method with the supplied annotations.
1934 *
1935 * @param annotations The annotations to declare on the previously defined or matched method.
1936 * @return A new builder that is equal to this builder but with the given annotations declared
1937 * on the previously defined or matched method.
1938 */
1939 MethodDefinition<S> annotateMethod(List<? extends Annotation> annotations);
1940
1941 /**
1942 * Annotates the previously defined or matched method with the supplied annotations.
1943 *
1944 * @param annotation The annotations to declare on the previously defined or matched method.
1945 * @return A new builder that is equal to this builder but with the given annotations declared
1946 * on the previously defined or matched method.
1947 */
1948 MethodDefinition<S> annotateMethod(AnnotationDescription... annotation);
1949
1950 /**
1951 * Annotates the previously defined or matched method with the supplied annotations.
1952 *
1953 * @param annotations The annotations to declare on the previously defined or matched method.
1954 * @return A new builder that is equal to this builder but with the given annotations declared
1955 * on the previously defined or matched method.
1956 */
1957 MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
1958
1959 /**
1960 * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1961 *
1962 * @param index The parameter's index.
1963 * @param annotation The annotations to declare on the previously defined or matched method.
1964 * @return A new builder that is equal to this builder but with the given annotations declared
1965 * on the previously defined or matched method's parameter of the given index.
1966 */
1967 MethodDefinition<S> annotateParameter(int index, Annotation... annotation);
1968
1969 /**
1970 * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1971 *
1972 * @param index The parameter's index.
1973 * @param annotations The annotations to declare on the previously defined or matched method.
1974 * @return A new builder that is equal to this builder but with the given annotations declared
1975 * on the previously defined or matched method's parameter of the given index.
1976 */
1977 MethodDefinition<S> annotateParameter(int index, List<? extends Annotation> annotations);
1978
1979 /**
1980 * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1981 *
1982 * @param index The parameter's index.
1983 * @param annotation The annotations to declare on the previously defined or matched method.
1984 * @return A new builder that is equal to this builder but with the given annotations declared
1985 * on the previously defined or matched method's parameter of the given index.
1986 */
1987 MethodDefinition<S> annotateParameter(int index, AnnotationDescription... annotation);
1988
1989 /**
1990 * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1991 *
1992 * @param index The parameter's index.
1993 * @param annotations The annotations to declare on the previously defined or matched method.
1994 * @return A new builder that is equal to this builder but with the given annotations declared
1995 * on the previously defined or matched method's parameter of the given index.
1996 */
1997 MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
1998
1999 /**
2000 * Applies the supplied method attribute appender factory onto the previously defined or matched method.
2001 *
2002 * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
2003 * previously defined or matched method.
2004 * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
2005 * applied to the previously defined or matched method.
2006 */
2007 MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
2008
2009 /**
2010 * Applies the supplied transformer onto the previously defined or matched method. The transformed
2011 * method is written <i>as it is</i> and it not subject to any validations.
2012 *
2013 * @param transformer The transformer to apply to the previously defined or matched method.
2014 * @return A new builder that is equal to this builder but with the supplied transformer
2015 * applied to the previously defined or matched method.
2016 */
2017 MethodDefinition<S> transform(Transformer<MethodDescription> transformer);
2018
2019 /**
2020 * A builder for a method definition with a receiver type.
2021 *
2022 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2023 */
2024 interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
2025
2026 /**
2027 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2028 *
2029 * @param receiverType The receiver type to define on the previously defined or matched method.
2030 * @return A new builder that is equal to this builder but with the given type defined as the
2031 * receiver on the previously defined or matched method.
2032 */
2033 MethodDefinition<U> receiverType(AnnotatedElement receiverType);
2034
2035 /**
2036 * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2037 *
2038 * @param receiverType The receiver type to define on the previously defined or matched method.
2039 * @return A new builder that is equal to this builder but with the given type defined as the
2040 * receiver on the previously defined or matched method.
2041 */
2042 MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
2043
2044 /**
2045 * An abstract base implementation of a method definition that can accept a receiver type.
2046 *
2047 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2048 */
2049 abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
2050
2051 /**
2052 * {@inheritDoc}
2053 */
2054 public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
2055 return receiverType(TypeDescription.Generic.AnnotationReader.DISPATCHER.resolve(receiverType));
2056 }
2057 }
2058 }
2059
2060 /**
2061 * A builder for defining an implementation of a method.
2062 *
2063 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2064 */
2065 interface ImplementationDefinition<U> {
2066
2067 /**
2068 * Implements the previously defined or matched method by the supplied implementation. A method interception
2069 * is typically implemented in one of the following ways:
2070 * <ol>
2071 * <li>If a method is declared by the instrumented type and the type builder creates a subclass or redefinition,
2072 * any preexisting method is replaced by the given implementation. Any previously defined implementation is lost.</li>
2073 * <li>If a method is declared by the instrumented type and the type builder creates a rebased version of the
2074 * instrumented type, the original method is preserved within a private, synthetic method within the instrumented
2075 * type. The original method therefore remains invokeable and is treated as the direct super method of the new
2076 * method. When rebasing a type, it therefore becomes possible to invoke a non-virtual method's super method
2077 * when a preexisting method body is replaced.</li>
2078 * <li>If a virtual method is inherited from a super type, it is overridden. The overridden method is available
2079 * for super method invocation.</li>
2080 * </ol>
2081 *
2082 * @param implementation The implementation for implementing the previously defined or matched method.
2083 * @return A new builder where the previously defined or matched method is implemented by the
2084 * supplied implementation.
2085 */
2086 MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation);
2087
2088 /**
2089 * Defines the previously defined or matched method not to declare a method body. This implies the
2090 * method to be {@code abstract} unless it was already declared to be {@code native}.
2091 *
2092 * @return A new builder where the previously defined or matched method is implemented to be abstract.
2093 */
2094 MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
2095
2096 /**
2097 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2098 * value must be supplied in its unloaded state, i.e. enumerations as {@link net.bytebuddy.description.enumeration.EnumerationDescription},
2099 * types as {@link TypeDescription} and annotations as {@link AnnotationDescription}. For supplying loaded types, use
2100 * {@link ImplementationDefinition#defaultValue(Object, Class)} must be used.
2101 *
2102 * @param annotationValue The value to be defined as a default value.
2103 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2104 */
2105 MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue);
2106
2107 /**
2108 * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2109 * value must be supplied in its loaded state paired with the property type of the value.
2110 *
2111 * @param value The value to be defined as a default value.
2112 * @param type The type of the annotation property.
2113 * @param <W> The type of the annotation property.
2114 * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2115 */
2116 <W> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(W value, Class<? extends W> type);
2117
2118 /**
2119 * A builder for optionally defining an implementation of a method.
2120 *
2121 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2122 */
2123 interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
2124 /* union type */
2125 }
2126
2127 /**
2128 * An abstract base implementation for a builder optionally defining an implementation of a method.
2129 *
2130 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2131 */
2132 abstract class AbstractBase<V> implements ImplementationDefinition<V> {
2133
2134 /**
2135 * {@inheritDoc}
2136 */
2137 public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) {
2138 return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
2139 }
2140 }
2141 }
2142
2143 /**
2144 * A builder for defining an implementation of a method and optionally defining a type variable.
2145 *
2146 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2147 */
2148 interface TypeVariableDefinition<U> extends ImplementationDefinition<U> {
2149
2150 /**
2151 * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
2152 *
2153 * @param symbol The symbol of the type variable.
2154 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2155 */
2156 Annotatable<U> typeVariable(String symbol);
2157
2158 /**
2159 * Defines a method variable to be declared by the currently defined method.
2160 *
2161 * @param symbol The symbol of the type variable.
2162 * @param bound The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2163 * if a bound type should be equal to the currently instrumented type.
2164 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2165 */
2166 Annotatable<U> typeVariable(String symbol, Type... bound);
2167
2168 /**
2169 * Defines a method variable to be declared by the currently defined method.
2170 *
2171 * @param symbol The symbol of the type variable.
2172 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2173 * if a bound type should be equal to the currently instrumented type.
2174 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2175 */
2176 Annotatable<U> typeVariable(String symbol, List<? extends Type> bounds);
2177
2178 /**
2179 * Defines a method variable to be declared by the currently defined method.
2180 *
2181 * @param symbol The symbol of the type variable.
2182 * @param bound The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2183 * if a bound type should be equal to the currently instrumented type.
2184 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2185 */
2186 Annotatable<U> typeVariable(String symbol, TypeDefinition... bound);
2187
2188 /**
2189 * Defines a method variable to be declared by the currently defined method.
2190 *
2191 * @param symbol The symbol of the type variable.
2192 * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2193 * if a bound type should be equal to the currently instrumented type.
2194 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2195 */
2196 Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
2197
2198 /**
2199 * A builder for optionally defining an annotation for a type variable.
2200 *
2201 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2202 */
2203 interface Annotatable<V> extends TypeVariableDefinition<V> {
2204
2205 /**
2206 * Annotates the previously defined type variable with the supplied annotations.
2207 *
2208 * @param annotation The annotations to declare on the previously defined type variable.
2209 * @return A new builder that is equal to this builder but with the given annotations declared
2210 * on the previously defined type variable.
2211 */
2212 Annotatable<V> annotateTypeVariable(Annotation... annotation);
2213
2214 /**
2215 * Annotates the previously defined type variable with the supplied annotations.
2216 *
2217 * @param annotations The annotations to declare on the previously defined type variable.
2218 * @return A new builder that is equal to this builder but with the given annotations declared
2219 * on the previously defined type variable.
2220 */
2221 Annotatable<V> annotateTypeVariable(List<? extends Annotation> annotations);
2222
2223 /**
2224 * Annotates the previously defined type variable with the supplied annotations.
2225 *
2226 * @param annotation The annotations to declare on the previously defined type variable.
2227 * @return A new builder that is equal to this builder but with the given annotations declared
2228 * on the previously defined type variable.
2229 */
2230 Annotatable<V> annotateTypeVariable(AnnotationDescription... annotation);
2231
2232 /**
2233 * Annotates the previously defined type variable with the supplied annotations.
2234 *
2235 * @param annotations The annotations to declare on the previously defined type variable.
2236 * @return A new builder that is equal to this builder but with the given annotations declared
2237 * on the previously defined type variable.
2238 */
2239 Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
2240
2241 /**
2242 * An abstract base implementation for defining an annotation on a parameter.
2243 *
2244 * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2245 */
2246 abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
2247
2248 /**
2249 * {@inheritDoc}
2250 */
2251 public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
2252 return annotateTypeVariable(Arrays.asList(annotation));
2253 }
2254
2255 /**
2256 * {@inheritDoc}
2257 */
2258 public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
2259 return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
2260 }
2261
2262 /**
2263 * {@inheritDoc}
2264 */
2265 public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
2266 return annotateTypeVariable(Arrays.asList(annotation));
2267 }
2268
2269 /**
2270 * An adapter implementation for an annotatable type variable definition.
2271 *
2272 * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2273 */
2274 protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
2275
2276 /**
2277 * {@inheritDoc}
2278 */
2279 public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2280 return materialize().typeVariable(symbol, bounds);
2281 }
2282
2283 /**
2284 * {@inheritDoc}
2285 */
2286 public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2287 return materialize().intercept(implementation);
2288 }
2289
2290 /**
2291 * {@inheritDoc}
2292 */
2293 public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2294 return materialize().withoutCode();
2295 }
2296
2297 /**
2298 * {@inheritDoc}
2299 */
2300 public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2301 return materialize().defaultValue(annotationValue);
2302 }
2303
2304 /**
2305 * {@inheritDoc}
2306 */
2307 public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2308 return materialize().defaultValue(value, type);
2309 }
2310
2311 /**
2312 * Materializes this instance as a parameter definition with the currently defined properties.
2313 *
2314 * @return A parameter definition with the currently defined properties.
2315 */
2316 protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2317 }
2318 }
2319 }
2320
2321 /**
2322 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
2323 *
2324 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2325 */
2326 abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
2327
2328 /**
2329 * {@inheritDoc}
2330 */
2331 public Annotatable<V> typeVariable(String symbol) {
2332 return typeVariable(symbol, Collections.singletonList(Object.class));
2333 }
2334
2335 /**
2336 * {@inheritDoc}
2337 */
2338 public Annotatable<V> typeVariable(String symbol, Type... bound) {
2339 return typeVariable(symbol, Arrays.asList(bound));
2340 }
2341
2342 /**
2343 * {@inheritDoc}
2344 */
2345 public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
2346 return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
2347 }
2348
2349 /**
2350 * {@inheritDoc}
2351 */
2352 public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
2353 return typeVariable(symbol, Arrays.asList(bound));
2354 }
2355 }
2356 }
2357
2358 /**
2359 * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
2360 *
2361 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2362 */
2363 interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
2364
2365 /**
2366 * Defines a method variable to be declared by the currently defined method.
2367 *
2368 * @param type The type of the exception being declared by the currently defined method.
2369 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2370 */
2371 ExceptionDefinition<U> throwing(Type... type);
2372
2373 /**
2374 * Defines a method variable to be declared by the currently defined method.
2375 *
2376 * @param types The type of the exception being declared by the currently defined method.
2377 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2378 */
2379 ExceptionDefinition<U> throwing(List<? extends Type> types);
2380
2381 /**
2382 * Defines a method variable to be declared by the currently defined method.
2383 *
2384 * @param type The type of the exception being declared by the currently defined method.
2385 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2386 */
2387 ExceptionDefinition<U> throwing(TypeDefinition... type);
2388
2389 /**
2390 * Defines a method variable to be declared by the currently defined method.
2391 *
2392 * @param types The type of the exception being declared by the currently defined method.
2393 * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2394 */
2395 ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
2396
2397 /**
2398 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
2399 *
2400 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2401 */
2402 abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
2403
2404 /**
2405 * {@inheritDoc}
2406 */
2407 public ExceptionDefinition<V> throwing(Type... type) {
2408 return throwing(Arrays.asList(type));
2409 }
2410
2411 /**
2412 * {@inheritDoc}
2413 */
2414 public ExceptionDefinition<V> throwing(List<? extends Type> types) {
2415 return throwing(new TypeList.Generic.ForLoadedTypes(types));
2416 }
2417
2418 /**
2419 * {@inheritDoc}
2420 */
2421 public ExceptionDefinition<V> throwing(TypeDefinition... type) {
2422 return throwing(Arrays.asList(type));
2423 }
2424 }
2425 }
2426
2427 /**
2428 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2429 *
2430 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2431 */
2432 interface ParameterDefinition<U> extends ExceptionDefinition<U> {
2433
2434 /**
2435 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2436 *
2437 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2438 * should be equal to the currently instrumented type.
2439 * @param name The parameter's name.
2440 * @param modifierContributor The parameter's modifiers.
2441 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2442 */
2443 Annotatable<U> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor);
2444
2445 /**
2446 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2447 *
2448 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2449 * should be equal to the currently instrumented type.
2450 * @param name The parameter's name.
2451 * @param modifierContributors The parameter's modifiers.
2452 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2453 */
2454 Annotatable<U> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2455
2456 /**
2457 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2458 *
2459 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2460 * should be equal to the currently instrumented type.
2461 * @param name The parameter's name.
2462 * @param modifiers The parameter's modifiers.
2463 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2464 */
2465 Annotatable<U> withParameter(Type type, String name, int modifiers);
2466
2467 /**
2468 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2469 *
2470 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2471 * should be equal to the currently instrumented type.
2472 * @param name The parameter's name.
2473 * @param modifierContributor The parameter's modifiers.
2474 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2475 */
2476 Annotatable<U> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor);
2477
2478 /**
2479 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2480 *
2481 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2482 * should be equal to the currently instrumented type.
2483 * @param name The parameter's name.
2484 * @param modifierContributors The parameter's modifiers.
2485 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2486 */
2487 Annotatable<U> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2488
2489 /**
2490 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2491 *
2492 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2493 * should be equal to the currently instrumented type.
2494 * @param name The parameter's name.
2495 * @param modifiers The parameter's modifiers.
2496 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2497 */
2498 Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers);
2499
2500 /**
2501 * A builder for optionally defining an annotation on a parameter.
2502 *
2503 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2504 */
2505 interface Annotatable<V> extends ParameterDefinition<V> {
2506
2507 /**
2508 * Annotates the previously defined parameter with the specified annotations.
2509 *
2510 * @param annotation The annotations to declare on the previously defined parameter.
2511 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2512 * the specified annotations.
2513 */
2514 Annotatable<V> annotateParameter(Annotation... annotation);
2515
2516 /**
2517 * Annotates the previously defined parameter with the specified annotations.
2518 *
2519 * @param annotations The annotations to declare on the previously defined parameter.
2520 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2521 * the specified annotations.
2522 */
2523 Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2524
2525 /**
2526 * Annotates the previously defined parameter with the specified annotations.
2527 *
2528 * @param annotation The annotations to declare on the previously defined parameter.
2529 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2530 * the specified annotations.
2531 */
2532 Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2533
2534 /**
2535 * Annotates the previously defined parameter with the specified annotations.
2536 *
2537 * @param annotations The annotations to declare on the previously defined parameter.
2538 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2539 * the specified annotations.
2540 */
2541 Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2542
2543 /**
2544 * An abstract base implementation for defining an annotation on a parameter.
2545 *
2546 * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2547 */
2548 abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
2549
2550 /**
2551 * {@inheritDoc}
2552 */
2553 public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
2554 return annotateParameter(Arrays.asList(annotation));
2555 }
2556
2557 /**
2558 * {@inheritDoc}
2559 */
2560 public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2561 return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
2562 }
2563
2564 /**
2565 * {@inheritDoc}
2566 */
2567 public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2568 return annotateParameter(Arrays.asList(annotation));
2569 }
2570
2571 /**
2572 * An adapter implementation for defining an annotation on a parameter.
2573 *
2574 * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2575 */
2576 protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
2577
2578 /**
2579 * {@inheritDoc}
2580 */
2581 public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
2582 return materialize().withParameter(type, name, modifiers);
2583 }
2584
2585 /**
2586 * {@inheritDoc}
2587 */
2588 public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2589 return materialize().throwing(types);
2590 }
2591
2592 /**
2593 * {@inheritDoc}
2594 */
2595 public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2596 return materialize().typeVariable(symbol, bounds);
2597 }
2598
2599 /**
2600 * {@inheritDoc}
2601 */
2602 public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2603 return materialize().intercept(implementation);
2604 }
2605
2606 /**
2607 * {@inheritDoc}
2608 */
2609 public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2610 return materialize().withoutCode();
2611 }
2612
2613 /**
2614 * {@inheritDoc}
2615 */
2616 public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2617 return materialize().defaultValue(annotationValue);
2618 }
2619
2620 /**
2621 * {@inheritDoc}
2622 */
2623 public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2624 return materialize().defaultValue(value, type);
2625 }
2626
2627 /**
2628 * Materializes this instance as a parameter definition with the currently defined properties.
2629 *
2630 * @return A parameter definition with the currently defined properties.
2631 */
2632 protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2633 }
2634 }
2635 }
2636
2637 /**
2638 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
2639 *
2640 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2641 */
2642 interface Simple<V> extends ExceptionDefinition<V> {
2643
2644 /**
2645 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2646 *
2647 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2648 * should be equal to the currently instrumented type.
2649 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2650 */
2651 Annotatable<V> withParameter(Type type);
2652
2653 /**
2654 * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2655 *
2656 * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2657 * should be equal to the currently instrumented type.
2658 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2659 */
2660 Annotatable<V> withParameter(TypeDefinition type);
2661
2662 /**
2663 * A builder for optionally defining an annotation on a parameter.
2664 *
2665 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2666 */
2667 interface Annotatable<V> extends Simple<V> {
2668
2669 /**
2670 * Annotates the previously defined parameter with the specified annotations.
2671 *
2672 * @param annotation The annotations to declare on the previously defined parameter.
2673 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2674 * the specified annotations.
2675 */
2676 Annotatable<V> annotateParameter(Annotation... annotation);
2677
2678 /**
2679 * Annotates the previously defined parameter with the specified annotations.
2680 *
2681 * @param annotations The annotations to declare on the previously defined parameter.
2682 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2683 * the specified annotations.
2684 */
2685 Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2686
2687 /**
2688 * Annotates the previously defined parameter with the specified annotations.
2689 *
2690 * @param annotation The annotations to declare on the previously defined parameter.
2691 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2692 * the specified annotations.
2693 */
2694 Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2695
2696 /**
2697 * Annotates the previously defined parameter with the specified annotations.
2698 *
2699 * @param annotations The annotations to declare on the previously defined parameter.
2700 * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2701 * the specified annotations.
2702 */
2703 Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2704
2705 /**
2706 * An abstract base implementation of a simple parameter definition.
2707 *
2708 * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2709 */
2710 abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
2711
2712 /**
2713 * {@inheritDoc}
2714 */
2715 public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
2716 return annotateParameter(Arrays.asList(annotation));
2717 }
2718
2719 /**
2720 * {@inheritDoc}
2721 */
2722 public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2723 return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
2724 }
2725
2726 /**
2727 * {@inheritDoc}
2728 */
2729 public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2730 return annotateParameter(Arrays.asList(annotation));
2731 }
2732
2733 /**
2734 * An adapter implementation of a simple parameter definition.
2735 *
2736 * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2737 */
2738 protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
2739
2740 /**
2741 * {@inheritDoc}
2742 */
2743 public Simple.Annotatable<X> withParameter(TypeDefinition type) {
2744 return materialize().withParameter(type);
2745 }
2746
2747 /**
2748 * {@inheritDoc}
2749 */
2750 public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2751 return materialize().throwing(types);
2752 }
2753
2754 /**
2755 * {@inheritDoc}
2756 */
2757 public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2758 return materialize().typeVariable(symbol, bounds);
2759 }
2760
2761 /**
2762 * {@inheritDoc}
2763 */
2764 public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2765 return materialize().intercept(implementation);
2766 }
2767
2768 /**
2769 * {@inheritDoc}
2770 */
2771 public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2772 return materialize().withoutCode();
2773 }
2774
2775 /**
2776 * {@inheritDoc}
2777 */
2778 public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2779 return materialize().defaultValue(annotationValue);
2780 }
2781
2782 /**
2783 * {@inheritDoc}
2784 */
2785 public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2786 return materialize().defaultValue(value, type);
2787 }
2788
2789 /**
2790 * Materializes this instance as a simple parameter definition with the currently defined properties.
2791 *
2792 * @return A simple parameter definition with the currently defined properties.
2793 */
2794 protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
2795 }
2796 }
2797 }
2798
2799 /**
2800 * An abstract base implementation of an exception definition.
2801 *
2802 * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2803 */
2804 abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
2805
2806 /**
2807 * {@inheritDoc}
2808 */
2809 public Simple.Annotatable<W> withParameter(Type type) {
2810 return withParameter(TypeDefinition.Sort.describe(type));
2811 }
2812 }
2813 }
2814
2815 /**
2816 * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2817 * Implementations allow for the <i>one-by-one</i> definition of parameters what gives opportunity to annotate parameters in a fluent
2818 * style. Doing so, it is optionally possible to define parameter names and modifiers. This can be done for either all or no parameters.
2819 * Alternatively, parameters without annotations, names or modifiers can be defined by a single step.
2820 *
2821 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2822 */
2823 interface Initial<V> extends ParameterDefinition<V>, Simple<V> {
2824
2825 /**
2826 * Defines the specified parameters for the currently defined method.
2827 *
2828 * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2829 * should be equal to the currently instrumented type.
2830 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2831 */
2832 ExceptionDefinition<V> withParameters(Type... type);
2833
2834 /**
2835 * Defines the specified parameters for the currently defined method.
2836 *
2837 * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2838 * should be equal to the currently instrumented type.
2839 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2840 */
2841 ExceptionDefinition<V> withParameters(List<? extends Type> types);
2842
2843 /**
2844 * Defines the specified parameters for the currently defined method.
2845 *
2846 * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2847 * should be equal to the currently instrumented type.
2848 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2849 */
2850 ExceptionDefinition<V> withParameters(TypeDefinition... type);
2851
2852 /**
2853 * Defines the specified parameters for the currently defined method.
2854 *
2855 * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2856 * should be equal to the currently instrumented type.
2857 * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2858 */
2859 ExceptionDefinition<V> withParameters(Collection<? extends TypeDefinition> types);
2860
2861 /**
2862 * An abstract base implementation for an initial parameter definition.
2863 *
2864 * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2865 */
2866 abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
2867
2868 /**
2869 * {@inheritDoc}
2870 */
2871 public Simple.Annotatable<W> withParameter(Type type) {
2872 return withParameter(TypeDefinition.Sort.describe(type));
2873 }
2874
2875 /**
2876 * {@inheritDoc}
2877 */
2878 public ExceptionDefinition<W> withParameters(Type... type) {
2879 return withParameters(Arrays.asList(type));
2880 }
2881
2882 /**
2883 * {@inheritDoc}
2884 */
2885 public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
2886 return withParameters(new TypeList.Generic.ForLoadedTypes(types));
2887 }
2888
2889 /**
2890 * {@inheritDoc}
2891 */
2892 public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
2893 return withParameters(Arrays.asList(type));
2894 }
2895
2896 /**
2897 * {@inheritDoc}
2898 */
2899 public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
2900 ParameterDefinition.Simple<W> parameterDefinition = this;
2901 for (TypeDefinition type : types) {
2902 parameterDefinition = parameterDefinition.withParameter(type);
2903 }
2904 return parameterDefinition;
2905 }
2906 }
2907 }
2908
2909 /**
2910 * An abstract base implementation for defining an implementation of a method and optionally defining a type variable, thrown exception or parameter type.
2911 *
2912 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2913 */
2914 abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
2915
2916 /**
2917 * {@inheritDoc}
2918 */
2919 public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
2920 return withParameter(type, name, Arrays.asList(modifierContributor));
2921 }
2922
2923 /**
2924 * {@inheritDoc}
2925 */
2926 public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
2927 return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
2928 }
2929
2930 /**
2931 * {@inheritDoc}
2932 */
2933 public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
2934 return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
2935 }
2936
2937 /**
2938 * {@inheritDoc}
2939 */
2940 public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
2941 return withParameter(type, name, Arrays.asList(modifierContributor));
2942 }
2943
2944 /**
2945 * {@inheritDoc}
2946 */
2947 public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
2948 return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
2949 }
2950 }
2951 }
2952
2953 /**
2954 * An abstract base implementation of a method definition.
2955 *
2956 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2957 */
2958 abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
2959
2960 /**
2961 * {@inheritDoc}
2962 */
2963 public MethodDefinition<U> annotateMethod(Annotation... annotation) {
2964 return annotateMethod(Arrays.asList(annotation));
2965 }
2966
2967 /**
2968 * {@inheritDoc}
2969 */
2970 public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
2971 return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
2972 }
2973
2974 /**
2975 * {@inheritDoc}
2976 */
2977 public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
2978 return annotateMethod(Arrays.asList(annotation));
2979 }
2980
2981 /**
2982 * {@inheritDoc}
2983 */
2984 public MethodDefinition<U> annotateParameter(int index, Annotation... annotation) {
2985 return annotateParameter(index, Arrays.asList(annotation));
2986 }
2987
2988 /**
2989 * {@inheritDoc}
2990 */
2991 public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
2992 return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
2993 }
2994
2995 /**
2996 * {@inheritDoc}
2997 */
2998 public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
2999 return annotateParameter(index, Arrays.asList(annotation));
3000 }
3001
3002 /**
3003 * An adapter implementation of a method definition.
3004 *
3005 * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3006 */
3007 @HashCodeAndEqualsPlugin.Enhance
3008 protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
3009
3010 /**
3011 * The handler that determines how a method is implemented.
3012 */
3013 protected final MethodRegistry.Handler handler;
3014
3015 /**
3016 * The method attribute appender factory to apply onto the method that is currently being implemented.
3017 */
3018 protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
3019
3020 /**
3021 * The transformer to apply onto the method that is currently being implemented.
3022 */
3023 protected final Transformer<MethodDescription> transformer;
3024
3025 /**
3026 * Creates a new adapter for a method definition.
3027 *
3028 * @param handler The handler that determines how a method is implemented.
3029 * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3030 * @param transformer The transformer to apply onto the method that is currently being implemented.
3031 */
3032 protected Adapter(MethodRegistry.Handler handler,
3033 MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3034 Transformer<MethodDescription> transformer) {
3035 this.handler = handler;
3036 this.methodAttributeAppenderFactory = methodAttributeAppenderFactory;
3037 this.transformer = transformer;
3038 }
3039
3040 /**
3041 * {@inheritDoc}
3042 */
3043 public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
3044 return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), transformer);
3045 }
3046
3047 /**
3048 * {@inheritDoc}
3049 */
3050 @SuppressWarnings("unchecked") // In absence of @SafeVarargs
3051 public MethodDefinition<V> transform(Transformer<MethodDescription> transformer) {
3052 return materialize(handler, methodAttributeAppenderFactory, new Transformer.Compound<MethodDescription>(this.transformer, transformer));
3053 }
3054
3055 /**
3056 * Materializes the current builder as a method definition.
3057 *
3058 * @param handler The handler that determines how a method is implemented.
3059 * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3060 * @param transformer The method transformer to apply onto the method that is currently being implemented.
3061 * @return Returns a method definition for the supplied properties.
3062 */
3063 protected abstract MethodDefinition<V> materialize(MethodRegistry.Handler handler,
3064 MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3065 Transformer<MethodDescription> transformer);
3066 }
3067 }
3068 }
3069
3070 /**
3071 * A builder for a record component definition.
3072 *
3073 * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3074 */
3075 interface RecordComponentDefinition<S> {
3076
3077 /**
3078 * Annotates the record component with the supplied annotations.
3079 *
3080 * @param annotation The annotations to declare.
3081 * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3082 */
3083 Optional<S> annotateRecordComponent(Annotation... annotation);
3084
3085 /**
3086 * Annotates the record component with the supplied annotations.
3087 *
3088 * @param annotations The annotations to declare.
3089 * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3090 */
3091 Optional<S> annotateRecordComponent(List<? extends Annotation> annotations);
3092
3093 /**
3094 * Annotates the record component with the supplied annotations.
3095 *
3096 * @param annotation The annotations to declare.
3097 * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3098 */
3099 Optional<S> annotateRecordComponent(AnnotationDescription... annotation);
3100
3101 /**
3102 * Annotates the record component with the supplied annotations.
3103 *
3104 * @param annotations The annotations to declare.
3105 * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3106 */
3107 Optional<S> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations);
3108
3109 /**
3110 * Applies the supplied record component attribute appender factory onto the previously defined record component.
3111 *
3112 * @param recordComponentAttributeAppenderFactory The record component attribute appender factory that should be applied on the
3113 * previously defined or matched method.
3114 * @return A new builder that is equal to this builder but with the supplied record component attribute appender factory
3115 * applied to the previously defined record component.
3116 */
3117 Optional<S> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory);
3118
3119 /**
3120 * Transforms a record component description before writing.
3121 *
3122 * @param transformer The transformer to apply.
3123 * @return new builder that is equal to this builder but with the supplied transformer being applied.
3124 */
3125 Optional<S> transform(Transformer<RecordComponentDescription> transformer);
3126
3127 /**
3128 * A {@link RecordComponentDefinition} as an optional build step.
3129 *
3130 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3131 */
3132 interface Optional<U> extends RecordComponentDefinition<U>, Builder<U> {
3133
3134 /**
3135 * An abstract base implementation of a record definition.
3136 *
3137 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3138 */
3139 abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements RecordComponentDefinition.Optional<U> {
3140
3141 /**
3142 * {@inheritDoc}
3143 */
3144 public Optional<U> annotateRecordComponent(Annotation... annotation) {
3145 return annotateRecordComponent(Arrays.asList(annotation));
3146 }
3147
3148 /**
3149 * {@inheritDoc}
3150 */
3151 public Optional<U> annotateRecordComponent(List<? extends Annotation> annotations) {
3152 return annotateRecordComponent(new AnnotationList.ForLoadedAnnotations(annotations));
3153 }
3154
3155 /**
3156 * {@inheritDoc}
3157 */
3158 public Optional<U> annotateRecordComponent(AnnotationDescription... annotation) {
3159 return annotateRecordComponent(Arrays.asList(annotation));
3160 }
3161 }
3162 }
3163 }
3164
3165 /**
3166 * An abstract base implementation of a dynamic type builder.
3167 *
3168 * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3169 */
3170 abstract class AbstractBase<S> implements Builder<S> {
3171
3172 /**
3173 * {@inheritDoc}
3174 */
3175 public InnerTypeDefinition.ForType<S> innerTypeOf(Class<?> type) {
3176 return innerTypeOf(TypeDescription.ForLoadedType.of(type));
3177 }
3178
3179 /**
3180 * {@inheritDoc}
3181 */
3182 public InnerTypeDefinition<S> innerTypeOf(Method method) {
3183 return innerTypeOf(new MethodDescription.ForLoadedMethod(method));
3184 }
3185
3186 /**
3187 * {@inheritDoc}
3188 */
3189 public InnerTypeDefinition<S> innerTypeOf(Constructor<?> constructor) {
3190 return innerTypeOf(new MethodDescription.ForLoadedConstructor(constructor));
3191 }
3192
3193 /**
3194 * {@inheritDoc}
3195 */
3196 public Builder<S> declaredTypes(Class<?>... type) {
3197 return declaredTypes(Arrays.asList(type));
3198 }
3199
3200 /**
3201 * {@inheritDoc}
3202 */
3203 public Builder<S> declaredTypes(TypeDescription... type) {
3204 return declaredTypes(Arrays.asList(type));
3205 }
3206
3207 /**
3208 * {@inheritDoc}
3209 */
3210 public Builder<S> declaredTypes(List<? extends Class<?>> type) {
3211 return declaredTypes(new TypeList.ForLoadedTypes(type));
3212 }
3213
3214 /**
3215 * {@inheritDoc}
3216 */
3217 public Builder<S> noNestMate() {
3218 return nestHost(TargetType.DESCRIPTION);
3219 }
3220
3221 /**
3222 * {@inheritDoc}
3223 */
3224 public Builder<S> nestHost(Class<?> type) {
3225 return nestHost(TypeDescription.ForLoadedType.of(type));
3226 }
3227
3228 /**
3229 * {@inheritDoc}
3230 */
3231 public Builder<S> nestMembers(Class<?>... type) {
3232 return nestMembers(Arrays.asList(type));
3233 }
3234
3235 /**
3236 * {@inheritDoc}
3237 */
3238 public Builder<S> nestMembers(TypeDescription... type) {
3239 return nestMembers(Arrays.asList(type));
3240 }
3241
3242 /**
3243 * {@inheritDoc}
3244 */
3245 public Builder<S> nestMembers(List<? extends Class<?>> types) {
3246 return nestMembers(new TypeList.ForLoadedTypes(types));
3247 }
3248
3249 /**
3250 * {@inheritDoc}
3251 */
3252 public Builder<S> permittedSubclass(Class<?>... type) {
3253 return permittedSubclass(Arrays.asList(type));
3254 }
3255
3256 /**
3257 * {@inheritDoc}
3258 */
3259 public Builder<S> permittedSubclass(TypeDescription... type) {
3260 return permittedSubclass(Arrays.asList(type));
3261 }
3262
3263 /**
3264 * {@inheritDoc}
3265 */
3266 public Builder<S> permittedSubclass(List<? extends Class<?>> types) {
3267 return permittedSubclass(new TypeList.ForLoadedTypes(types));
3268 }
3269
3270 /**
3271 * {@inheritDoc}
3272 */
3273 public Builder<S> annotateType(Annotation... annotation) {
3274 return annotateType(Arrays.asList(annotation));
3275 }
3276
3277 /**
3278 * {@inheritDoc}
3279 */
3280 public Builder<S> annotateType(List<? extends Annotation> annotations) {
3281 return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
3282 }
3283
3284 /**
3285 * {@inheritDoc}
3286 */
3287 public Builder<S> annotateType(AnnotationDescription... annotation) {
3288 return annotateType(Arrays.asList(annotation));
3289 }
3290
3291 /**
3292 * {@inheritDoc}
3293 */
3294 public Builder<S> modifiers(ModifierContributor.ForType... modifierContributor) {
3295 return modifiers(Arrays.asList(modifierContributor));
3296 }
3297
3298 /**
3299 * {@inheritDoc}
3300 */
3301 public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3302 return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
3303 }
3304
3305 /**
3306 * {@inheritDoc}
3307 */
3308 public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
3309 return merge(Arrays.asList(modifierContributor));
3310 }
3311
3312 /**
3313 * {@inheritDoc}
3314 */
3315 public MethodDefinition.ImplementationDefinition.Optional<S> implement(Type... interfaceType) {
3316 return implement(Arrays.asList(interfaceType));
3317 }
3318
3319 /**
3320 * {@inheritDoc}
3321 */
3322 public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
3323 return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
3324 }
3325
3326 /**
3327 * {@inheritDoc}
3328 */
3329 public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
3330 return implement(Arrays.asList(interfaceType));
3331 }
3332
3333 /**
3334 * {@inheritDoc}
3335 */
3336 public TypeVariableDefinition<S> typeVariable(String symbol) {
3337 return typeVariable(symbol, TypeDescription.Generic.OBJECT);
3338 }
3339
3340 /**
3341 * {@inheritDoc}
3342 */
3343 public TypeVariableDefinition<S> typeVariable(String symbol, Type... bound) {
3344 return typeVariable(symbol, Arrays.asList(bound));
3345 }
3346
3347 /**
3348 * {@inheritDoc}
3349 */
3350 public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
3351 return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
3352 }
3353
3354 /**
3355 * {@inheritDoc}
3356 */
3357 public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
3358 return typeVariable(symbol, Arrays.asList(bound));
3359 }
3360
3361 /**
3362 * {@inheritDoc}
3363 */
3364 public RecordComponentDefinition.Optional<S> defineRecordComponent(String name, Type type) {
3365 return defineRecordComponent(name, TypeDefinition.Sort.describe(type));
3366 }
3367
3368 /**
3369 * {@inheritDoc}
3370 */
3371 public RecordComponentDefinition.Optional<S> define(RecordComponentDescription recordComponentDescription) {
3372 return defineRecordComponent(recordComponentDescription.getActualName(), recordComponentDescription.getType());
3373 }
3374
3375 /**
3376 * {@inheritDoc}
3377 */
3378 public RecordComponentDefinition<S> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
3379 return recordComponent(new LatentMatcher.Resolved<RecordComponentDescription>(matcher));
3380 }
3381
3382 /**
3383 * {@inheritDoc}
3384 */
3385 public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor) {
3386 return defineField(name, type, Arrays.asList(modifierContributor));
3387 }
3388
3389 /**
3390 * {@inheritDoc}
3391 */
3392 public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3393 return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
3394 }
3395
3396 /**
3397 * {@inheritDoc}
3398 */
3399 public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
3400 return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
3401 }
3402
3403 /**
3404 * {@inheritDoc}
3405 */
3406 public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
3407 return defineField(name, type, Arrays.asList(modifierContributor));
3408 }
3409
3410 /**
3411 * {@inheritDoc}
3412 */
3413 public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3414 return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
3415 }
3416
3417 /**
3418 * {@inheritDoc}
3419 */
3420 public FieldDefinition.Optional.Valuable<S> define(Field field) {
3421 return define(new FieldDescription.ForLoadedField(field));
3422 }
3423
3424 /**
3425 * {@inheritDoc}
3426 */
3427 public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
3428 return defineField(field.getName(), field.getType(), field.getModifiers());
3429 }
3430
3431 /**
3432 * {@inheritDoc}
3433 */
3434 public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
3435 return defineField("serialVersionUID", long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
3436 }
3437
3438 /**
3439 * {@inheritDoc}
3440 */
3441 public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
3442 return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
3443 }
3444
3445 /**
3446 * {@inheritDoc}
3447 */
3448 public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3449 return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
3450 }
3451
3452 /**
3453 * {@inheritDoc}
3454 */
3455 public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor) {
3456 return defineMethod(name, returnType, Arrays.asList(modifierContributor));
3457 }
3458
3459 /**
3460 * {@inheritDoc}
3461 */
3462 public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3463 return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
3464 }
3465
3466 /**
3467 * {@inheritDoc}
3468 */
3469 public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
3470 return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
3471 }
3472
3473 /**
3474 * {@inheritDoc}
3475 */
3476 public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
3477 return defineMethod(name, returnType, Arrays.asList(modifierContributor));
3478 }
3479
3480 /**
3481 * {@inheritDoc}
3482 */
3483 public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3484 return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
3485 }
3486
3487 /**
3488 * {@inheritDoc}
3489 */
3490 public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
3491 return defineConstructor(Arrays.asList(modifierContributor));
3492 }
3493
3494 /**
3495 * {@inheritDoc}
3496 */
3497 public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3498 return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
3499 }
3500
3501 /**
3502 * {@inheritDoc}
3503 */
3504 public MethodDefinition.ImplementationDefinition<S> define(Method method) {
3505 return define(new MethodDescription.ForLoadedMethod(method));
3506 }
3507
3508 /**
3509 * {@inheritDoc}
3510 */
3511 public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
3512 return define(new MethodDescription.ForLoadedConstructor(constructor));
3513 }
3514
3515 /**
3516 * {@inheritDoc}
3517 */
3518 public MethodDefinition.ImplementationDefinition<S> define(MethodDescription methodDescription) {
3519 MethodDefinition.ParameterDefinition.Initial<S> initialParameterDefinition = methodDescription.isConstructor()
3520 ? defineConstructor(methodDescription.getModifiers())
3521 : defineMethod(methodDescription.getInternalName(), methodDescription.getReturnType(), methodDescription.getModifiers());
3522 ParameterList<?> parameterList = methodDescription.getParameters();
3523 MethodDefinition.ExceptionDefinition<S> exceptionDefinition;
3524 if (parameterList.hasExplicitMetaData()) {
3525 MethodDefinition.ParameterDefinition<S> parameterDefinition = initialParameterDefinition;
3526 for (ParameterDescription parameter : parameterList) {
3527 parameterDefinition = parameterDefinition.withParameter(parameter.getType(), parameter.getName(), parameter.getModifiers());
3528 }
3529 exceptionDefinition = parameterDefinition;
3530 } else {
3531 exceptionDefinition = initialParameterDefinition.withParameters(parameterList.asTypeList());
3532 }
3533 MethodDefinition.TypeVariableDefinition<S> typeVariableDefinition = exceptionDefinition.throwing(methodDescription.getExceptionTypes());
3534 for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
3535 typeVariableDefinition = typeVariableDefinition.typeVariable(typeVariable.getSymbol(), typeVariable.getUpperBounds());
3536 }
3537 return typeVariableDefinition;
3538 }
3539
3540 /**
3541 * {@inheritDoc}
3542 */
3543 public FieldDefinition.Optional<S> defineProperty(String name, Type type) {
3544 return defineProperty(name, TypeDefinition.Sort.describe(type));
3545 }
3546
3547 /**
3548 * {@inheritDoc}
3549 */
3550 public FieldDefinition.Optional<S> defineProperty(String name, Type type, boolean readOnly) {
3551 return defineProperty(name, TypeDefinition.Sort.describe(type), readOnly);
3552 }
3553
3554 /**
3555 * {@inheritDoc}
3556 */
3557 public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type) {
3558 return defineProperty(name, type, false);
3559 }
3560
3561 /**
3562 * {@inheritDoc}
3563 */
3564 public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type, boolean readOnly) {
3565 if (name.length() == 0) {
3566 throw new IllegalArgumentException("A bean property cannot have an empty name");
3567 } else if (type.represents(void.class)) {
3568 throw new IllegalArgumentException("A bean property cannot have a void type");
3569 }
3570 DynamicType.Builder<S> builder = this;
3571 FieldManifestation fieldManifestation;
3572 if (!readOnly) {
3573 builder = builder
3574 .defineMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), void.class, Visibility.PUBLIC)
3575 .withParameters(type)
3576 .intercept(FieldAccessor.ofField(name));
3577 fieldManifestation = FieldManifestation.PLAIN;
3578 } else {
3579 fieldManifestation = FieldManifestation.FINAL;
3580 }
3581 return builder
3582 .defineMethod((type.represents(boolean.class) || type.represents(Boolean.class)
3583 ? "is"
3584 : "get") + Character.toUpperCase(name.charAt(0)) + name.substring(1), type, Visibility.PUBLIC)
3585 .intercept(FieldAccessor.ofField(name))
3586 .defineField(name, type, Visibility.PRIVATE, fieldManifestation);
3587 }
3588
3589 /**
3590 * {@inheritDoc}
3591 */
3592 public MethodDefinition.ImplementationDefinition<S> method(ElementMatcher<? super MethodDescription> matcher) {
3593 return invokable(isMethod().and(matcher));
3594 }
3595
3596 /**
3597 * {@inheritDoc}
3598 */
3599 public MethodDefinition.ImplementationDefinition<S> constructor(ElementMatcher<? super MethodDescription> matcher) {
3600 return invokable(isConstructor().and(matcher));
3601 }
3602
3603 /**
3604 * {@inheritDoc}
3605 */
3606 public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
3607 return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
3608 }
3609
3610 /**
3611 * {@inheritDoc}
3612 */
3613 public Builder<S> withHashCodeEquals() {
3614 return method(isHashCode())
3615 .intercept(HashCodeMethod.usingDefaultOffset().withIgnoredFields(isSynthetic()))
3616 .method(isEquals())
3617 .intercept(EqualsMethod.isolated().withIgnoredFields(isSynthetic()));
3618 }
3619
3620 /**
3621 * {@inheritDoc}
3622 */
3623 public Builder<S> withToString() {
3624 return method(isToString()).intercept(ToStringMethod.prefixedBySimpleClassName());
3625 }
3626
3627 /**
3628 * {@inheritDoc}
3629 */
3630 public Builder<S> require(TypeDescription type, byte[] binaryRepresentation) {
3631 return require(type, binaryRepresentation, LoadedTypeInitializer.NoOp.INSTANCE);
3632 }
3633
3634 /**
3635 * {@inheritDoc}
3636 */
3637 public Builder<S> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer) {
3638 return require(new Default(type, binaryRepresentation, typeInitializer, Collections.<DynamicType>emptyList()));
3639 }
3640
3641 /**
3642 * {@inheritDoc}
3643 */
3644 public Builder<S> require(DynamicType... auxiliaryType) {
3645 return require(Arrays.asList(auxiliaryType));
3646 }
3647
3648 /**
3649 * {@inheritDoc}
3650 */
3651 public Unloaded<S> make(TypePool typePool) {
3652 return make(TypeResolutionStrategy.Passive.INSTANCE, typePool);
3653 }
3654
3655 /**
3656 * {@inheritDoc}
3657 */
3658 public Unloaded<S> make() {
3659 return make(TypeResolutionStrategy.Passive.INSTANCE);
3660 }
3661
3662 /**
3663 * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
3664 *
3665 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3666 */
3667 public abstract static class Delegator<U> extends AbstractBase<U> {
3668
3669 /**
3670 * {@inheritDoc}
3671 */
3672 public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
3673 return materialize().visit(asmVisitorWrapper);
3674 }
3675
3676 /**
3677 * {@inheritDoc}
3678 */
3679 public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
3680 return materialize().initializer(loadedTypeInitializer);
3681 }
3682
3683 /**
3684 * {@inheritDoc}
3685 */
3686 public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
3687 return materialize().annotateType(annotations);
3688 }
3689
3690 /**
3691 * {@inheritDoc}
3692 */
3693 public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
3694 return materialize().attribute(typeAttributeAppender);
3695 }
3696
3697 /**
3698 * {@inheritDoc}
3699 */
3700 public Builder<U> modifiers(int modifiers) {
3701 return materialize().modifiers(modifiers);
3702 }
3703
3704 /**
3705 * {@inheritDoc}
3706 */
3707 public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3708 return materialize().merge(modifierContributors);
3709 }
3710
3711 /**
3712 * {@inheritDoc}
3713 */
3714 public Builder<U> suffix(String suffix) {
3715 return materialize().suffix(suffix);
3716 }
3717
3718 /**
3719 * {@inheritDoc}
3720 */
3721 public Builder<U> name(String name) {
3722 return materialize().name(name);
3723 }
3724
3725 /**
3726 * {@inheritDoc}
3727 */
3728 public Builder<U> topLevelType() {
3729 return materialize().topLevelType();
3730 }
3731
3732 /**
3733 * {@inheritDoc}
3734 */
3735 public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
3736 return materialize().innerTypeOf(type);
3737 }
3738
3739 /**
3740 * {@inheritDoc}
3741 */
3742 public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
3743 return materialize().innerTypeOf(methodDescription);
3744 }
3745
3746 /**
3747 * {@inheritDoc}
3748 */
3749 public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
3750 return materialize().declaredTypes(types);
3751 }
3752
3753 /**
3754 * {@inheritDoc}
3755 */
3756 public Builder<U> nestHost(TypeDescription type) {
3757 return materialize().nestHost(type);
3758 }
3759
3760 /**
3761 * {@inheritDoc}
3762 */
3763 public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
3764 return materialize().nestMembers(types);
3765 }
3766
3767 /**
3768 * {@inheritDoc}
3769 */
3770 public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
3771 return materialize().permittedSubclass(types);
3772 }
3773
3774 /**
3775 * {@inheritDoc}
3776 */
3777 public Builder<U> unsealed() {
3778 return materialize().unsealed();
3779 }
3780
3781 /**
3782 * {@inheritDoc}
3783 */
3784 public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
3785 return materialize().implement(interfaceTypes);
3786 }
3787
3788 /**
3789 * {@inheritDoc}
3790 */
3791 public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
3792 return materialize().initializer(byteCodeAppender);
3793 }
3794
3795 /**
3796 * {@inheritDoc}
3797 */
3798 public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3799 return materialize().ignoreAlso(ignoredMethods);
3800 }
3801
3802 /**
3803 * {@inheritDoc}
3804 */
3805 public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
3806 return materialize().ignoreAlso(ignoredMethods);
3807 }
3808
3809 /**
3810 * {@inheritDoc}
3811 */
3812 public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3813 return materialize().typeVariable(symbol, bounds);
3814 }
3815
3816 /**
3817 * {@inheritDoc}
3818 */
3819 public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
3820 return materialize().transform(matcher, transformer);
3821 }
3822
3823 /**
3824 * {@inheritDoc}
3825 */
3826 public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
3827 return materialize().defineField(name, type, modifiers);
3828 }
3829
3830 /**
3831 * {@inheritDoc}
3832 */
3833 public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
3834 return materialize().field(matcher);
3835 }
3836
3837 /**
3838 * {@inheritDoc}
3839 */
3840 public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
3841 return materialize().defineMethod(name, returnType, modifiers);
3842 }
3843
3844 /**
3845 * {@inheritDoc}
3846 */
3847 public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
3848 return materialize().defineConstructor(modifiers);
3849 }
3850
3851 /**
3852 * {@inheritDoc}
3853 */
3854 public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
3855 return materialize().invokable(matcher);
3856 }
3857
3858 /**
3859 * {@inheritDoc}
3860 */
3861 public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
3862 return materialize().require(auxiliaryTypes);
3863 }
3864
3865 /**
3866 * {@inheritDoc}
3867 */
3868 public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
3869 return materialize().defineRecordComponent(name, type);
3870 }
3871
3872 /**
3873 * {@inheritDoc}
3874 */
3875 public RecordComponentDefinition.Optional<U> define(RecordComponentDescription recordComponentDescription) {
3876 return materialize().define(recordComponentDescription);
3877 }
3878
3879 /**
3880 * {@inheritDoc}
3881 */
3882 public RecordComponentDefinition<U> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
3883 return materialize().recordComponent(matcher);
3884 }
3885
3886 /**
3887 * {@inheritDoc}
3888 */
3889 public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
3890 return materialize().recordComponent(matcher);
3891 }
3892
3893 /**
3894 * {@inheritDoc}
3895 */
3896 public DynamicType.Unloaded<U> make() {
3897 return materialize().make();
3898 }
3899
3900 /**
3901 * {@inheritDoc}
3902 */
3903 public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
3904 return materialize().make(typeResolutionStrategy);
3905 }
3906
3907 /**
3908 * {@inheritDoc}
3909 */
3910 public Unloaded<U> make(TypePool typePool) {
3911 return materialize().make(typePool);
3912 }
3913
3914 /**
3915 * {@inheritDoc}
3916 */
3917 public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
3918 return materialize().make(typeResolutionStrategy, typePool);
3919 }
3920
3921 /**
3922 * {@inheritDoc}
3923 */
3924 public TypeDescription toTypeDescription() {
3925 return materialize().toTypeDescription();
3926 }
3927
3928 /**
3929 * Creates a new builder that realizes the current state of the builder.
3930 *
3931 * @return A new builder that realizes the current state of the builder.
3932 */
3933 protected abstract Builder<U> materialize();
3934 }
3935
3936 /**
3937 * An adapter implementation of a dynamic type builder.
3938 *
3939 * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3940 */
3941 @HashCodeAndEqualsPlugin.Enhance
3942 public abstract static class Adapter<U> extends AbstractBase<U> {
3943
3944 /**
3945 * The instrumented type to be created.
3946 */
3947 protected final InstrumentedType.WithFlexibleName instrumentedType;
3948
3949 /**
3950 * The current field registry.
3951 */
3952 protected final FieldRegistry fieldRegistry;
3953
3954 /**
3955 * The current method registry.
3956 */
3957 protected final MethodRegistry methodRegistry;
3958
3959 /**
3960 * The current record component registry.
3961 */
3962 protected final RecordComponentRegistry recordComponentRegistry;
3963
3964 /**
3965 * The type attribute appender to apply onto the instrumented type.
3966 */
3967 protected final TypeAttributeAppender typeAttributeAppender;
3968
3969 /**
3970 * The ASM visitor wrapper to apply onto the class writer.
3971 */
3972 protected final AsmVisitorWrapper asmVisitorWrapper;
3973
3974 /**
3975 * The class file version to define auxiliary types in.
3976 */
3977 protected final ClassFileVersion classFileVersion;
3978
3979 /**
3980 * The naming strategy for auxiliary types to apply.
3981 */
3982 protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
3983
3984 /**
3985 * The annotation value filter factory to apply.
3986 */
3987 protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
3988
3989 /**
3990 * The annotation retention to apply.
3991 */
3992 protected final AnnotationRetention annotationRetention;
3993
3994 /**
3995 * The implementation context factory to apply.
3996 */
3997 protected final Implementation.Context.Factory implementationContextFactory;
3998
3999 /**
4000 * The method graph compiler to use.
4001 */
4002 protected final MethodGraph.Compiler methodGraphCompiler;
4003
4004 /**
4005 * Determines if a type should be explicitly validated.
4006 */
4007 protected final TypeValidation typeValidation;
4008
4009 /**
4010 * The visibility bridge strategy to apply.
4011 */
4012 protected final VisibilityBridgeStrategy visibilityBridgeStrategy;
4013
4014 /**
4015 * The class writer strategy to use.
4016 */
4017 protected final ClassWriterStrategy classWriterStrategy;
4018
4019 /**
4020 * A matcher for identifying methods that should be excluded from instrumentation.
4021 */
4022 protected final LatentMatcher<? super MethodDescription> ignoredMethods;
4023
4024 /**
4025 * A list of explicitly defined auxiliary types.
4026 */
4027 protected final List<? extends DynamicType> auxiliaryTypes;
4028
4029 /**
4030 * Creates a new default type writer for creating a new type that is not based on an existing class file.
4031 *
4032 * @param instrumentedType The instrumented type to be created.
4033 * @param fieldRegistry The current field registry.
4034 * @param methodRegistry The current method registry.
4035 * @param recordComponentRegistry The record component pool to use.
4036 * @param typeAttributeAppender The type attribute appender to apply onto the instrumented type.
4037 * @param asmVisitorWrapper The ASM visitor wrapper to apply onto the class writer.
4038 * @param classFileVersion The class file version to define auxiliary types in.
4039 * @param auxiliaryTypeNamingStrategy The naming strategy for auxiliary types to apply.
4040 * @param annotationValueFilterFactory The annotation value filter factory to apply.
4041 * @param annotationRetention The annotation retention to apply.
4042 * @param implementationContextFactory The implementation context factory to apply.
4043 * @param methodGraphCompiler The method graph compiler to use.
4044 * @param typeValidation Determines if a type should be explicitly validated.
4045 * @param visibilityBridgeStrategy The visibility bridge strategy to apply.
4046 * @param classWriterStrategy The class writer strategy to use.
4047 * @param ignoredMethods A matcher for identifying methods that should be excluded from instrumentation.
4048 * @param auxiliaryTypes A list of explicitly defined auxiliary types.
4049 */
4050 protected Adapter(InstrumentedType.WithFlexibleName instrumentedType,
4051 FieldRegistry fieldRegistry,
4052 MethodRegistry methodRegistry,
4053 RecordComponentRegistry recordComponentRegistry,
4054 TypeAttributeAppender typeAttributeAppender,
4055 AsmVisitorWrapper asmVisitorWrapper,
4056 ClassFileVersion classFileVersion,
4057 AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4058 AnnotationValueFilter.Factory annotationValueFilterFactory,
4059 AnnotationRetention annotationRetention,
4060 Implementation.Context.Factory implementationContextFactory,
4061 MethodGraph.Compiler methodGraphCompiler,
4062 TypeValidation typeValidation,
4063 VisibilityBridgeStrategy visibilityBridgeStrategy,
4064 ClassWriterStrategy classWriterStrategy,
4065 LatentMatcher<? super MethodDescription> ignoredMethods,
4066 List<? extends DynamicType> auxiliaryTypes) {
4067 this.instrumentedType = instrumentedType;
4068 this.fieldRegistry = fieldRegistry;
4069 this.methodRegistry = methodRegistry;
4070 this.recordComponentRegistry = recordComponentRegistry;
4071 this.typeAttributeAppender = typeAttributeAppender;
4072 this.asmVisitorWrapper = asmVisitorWrapper;
4073 this.classFileVersion = classFileVersion;
4074 this.auxiliaryTypeNamingStrategy = auxiliaryTypeNamingStrategy;
4075 this.annotationValueFilterFactory = annotationValueFilterFactory;
4076 this.annotationRetention = annotationRetention;
4077 this.implementationContextFactory = implementationContextFactory;
4078 this.methodGraphCompiler = methodGraphCompiler;
4079 this.typeValidation = typeValidation;
4080 this.visibilityBridgeStrategy = visibilityBridgeStrategy;
4081 this.classWriterStrategy = classWriterStrategy;
4082 this.ignoredMethods = ignoredMethods;
4083 this.auxiliaryTypes = auxiliaryTypes;
4084 }
4085
4086 /**
4087 * {@inheritDoc}
4088 */
4089 public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
4090 return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
4091 }
4092
4093 /**
4094 * {@inheritDoc}
4095 */
4096 public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
4097 return new FieldMatchAdapter(matcher);
4098 }
4099
4100 /**
4101 * {@inheritDoc}
4102 */
4103 public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4104 return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
4105 }
4106
4107 /**
4108 * {@inheritDoc}
4109 */
4110 public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4111 return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
4112 }
4113
4114 /**
4115 * {@inheritDoc}
4116 */
4117 public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4118 return new MethodMatchAdapter(matcher);
4119 }
4120
4121 /**
4122 * {@inheritDoc}
4123 */
4124 public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
4125 return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
4126 }
4127
4128 /**
4129 * {@inheritDoc}
4130 */
4131 @SuppressWarnings("unchecked") // In absence of @SafeVarargs
4132 public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
4133 return materialize(instrumentedType,
4134 fieldRegistry,
4135 methodRegistry,
4136 recordComponentRegistry,
4137 typeAttributeAppender,
4138 asmVisitorWrapper,
4139 classFileVersion,
4140 auxiliaryTypeNamingStrategy,
4141 annotationValueFilterFactory,
4142 annotationRetention,
4143 implementationContextFactory,
4144 methodGraphCompiler,
4145 typeValidation,
4146 visibilityBridgeStrategy,
4147 classWriterStrategy,
4148 new LatentMatcher.Disjunction<MethodDescription>(this.ignoredMethods, ignoredMethods),
4149 auxiliaryTypes);
4150 }
4151
4152 /**
4153 * {@inheritDoc}
4154 */
4155 public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
4156 return new RecordComponentDefinitionAdapter(new RecordComponentDescription.Token(name, type.asGenericType()));
4157 }
4158
4159 /**
4160 * {@inheritDoc}
4161 */
4162 public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
4163 return new RecordComponentMatchAdapter(matcher);
4164 }
4165
4166 /**
4167 * {@inheritDoc}
4168 */
4169 public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
4170 return materialize(instrumentedType.withInitializer(byteCodeAppender),
4171 fieldRegistry,
4172 methodRegistry,
4173 recordComponentRegistry,
4174 typeAttributeAppender,
4175 asmVisitorWrapper,
4176 classFileVersion,
4177 auxiliaryTypeNamingStrategy,
4178 annotationValueFilterFactory,
4179 annotationRetention,
4180 implementationContextFactory,
4181 methodGraphCompiler,
4182 typeValidation,
4183 visibilityBridgeStrategy,
4184 classWriterStrategy,
4185 ignoredMethods,
4186 auxiliaryTypes);
4187 }
4188
4189 /**
4190 * {@inheritDoc}
4191 */
4192 public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
4193 return materialize(instrumentedType.withInitializer(loadedTypeInitializer),
4194 fieldRegistry,
4195 methodRegistry,
4196 recordComponentRegistry,
4197 typeAttributeAppender,
4198 asmVisitorWrapper,
4199 classFileVersion,
4200 auxiliaryTypeNamingStrategy,
4201 annotationValueFilterFactory,
4202 annotationRetention,
4203 implementationContextFactory,
4204 methodGraphCompiler,
4205 typeValidation,
4206 visibilityBridgeStrategy,
4207 classWriterStrategy,
4208 ignoredMethods,
4209 auxiliaryTypes);
4210 }
4211
4212 /**
4213 * {@inheritDoc}
4214 */
4215 public Builder<U> name(String name) {
4216 return materialize(instrumentedType.withName(name),
4217 fieldRegistry,
4218 methodRegistry,
4219 recordComponentRegistry,
4220 typeAttributeAppender,
4221 asmVisitorWrapper,
4222 classFileVersion,
4223 auxiliaryTypeNamingStrategy,
4224 annotationValueFilterFactory,
4225 annotationRetention,
4226 implementationContextFactory,
4227 methodGraphCompiler,
4228 typeValidation,
4229 visibilityBridgeStrategy,
4230 classWriterStrategy,
4231 ignoredMethods,
4232 auxiliaryTypes);
4233 }
4234
4235 /**
4236 * {@inheritDoc}
4237 */
4238 public Builder<U> suffix(String suffix) {
4239 return name(instrumentedType.getName() + "$" + suffix);
4240 }
4241
4242 /**
4243 * {@inheritDoc}
4244 */
4245 public Builder<U> modifiers(int modifiers) {
4246 return materialize(instrumentedType.withModifiers(modifiers),
4247 fieldRegistry,
4248 methodRegistry,
4249 recordComponentRegistry,
4250 typeAttributeAppender,
4251 asmVisitorWrapper,
4252 classFileVersion,
4253 auxiliaryTypeNamingStrategy,
4254 annotationValueFilterFactory,
4255 annotationRetention,
4256 implementationContextFactory,
4257 methodGraphCompiler,
4258 typeValidation,
4259 visibilityBridgeStrategy,
4260 classWriterStrategy,
4261 ignoredMethods,
4262 auxiliaryTypes);
4263 }
4264
4265 /**
4266 * {@inheritDoc}
4267 */
4268 public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4269 return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
4270 fieldRegistry,
4271 methodRegistry,
4272 recordComponentRegistry,
4273 typeAttributeAppender,
4274 asmVisitorWrapper,
4275 classFileVersion,
4276 auxiliaryTypeNamingStrategy,
4277 annotationValueFilterFactory,
4278 annotationRetention,
4279 implementationContextFactory,
4280 methodGraphCompiler,
4281 typeValidation,
4282 visibilityBridgeStrategy,
4283 classWriterStrategy,
4284 ignoredMethods,
4285 auxiliaryTypes);
4286 }
4287
4288 /**
4289 * {@inheritDoc}
4290 */
4291 public Builder<U> topLevelType() {
4292 return Adapter.this.materialize(instrumentedType
4293 .withDeclaringType(TypeDescription.UNDEFINED)
4294 .withEnclosingType(TypeDescription.UNDEFINED)
4295 .withLocalClass(false),
4296 fieldRegistry,
4297 methodRegistry,
4298 recordComponentRegistry,
4299 typeAttributeAppender,
4300 asmVisitorWrapper,
4301 classFileVersion,
4302 auxiliaryTypeNamingStrategy,
4303 annotationValueFilterFactory,
4304 annotationRetention,
4305 implementationContextFactory,
4306 methodGraphCompiler,
4307 typeValidation,
4308 visibilityBridgeStrategy,
4309 classWriterStrategy,
4310 ignoredMethods,
4311 auxiliaryTypes);
4312 }
4313
4314 /**
4315 * {@inheritDoc}
4316 */
4317 public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
4318 return new InnerTypeDefinitionForTypeAdapter(type);
4319 }
4320
4321 /**
4322 * {@inheritDoc}
4323 */
4324 public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
4325 return methodDescription.isTypeInitializer()
4326 ? new InnerTypeDefinitionForTypeAdapter(methodDescription.getDeclaringType())
4327 : new InnerTypeDefinitionForMethodAdapter(methodDescription);
4328 }
4329
4330 /**
4331 * {@inheritDoc}
4332 */
4333 public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
4334 return materialize(instrumentedType.withDeclaredTypes(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
4335 fieldRegistry,
4336 methodRegistry,
4337 recordComponentRegistry,
4338 typeAttributeAppender,
4339 asmVisitorWrapper,
4340 classFileVersion,
4341 auxiliaryTypeNamingStrategy,
4342 annotationValueFilterFactory,
4343 annotationRetention,
4344 implementationContextFactory,
4345 methodGraphCompiler,
4346 typeValidation,
4347 visibilityBridgeStrategy,
4348 classWriterStrategy,
4349 ignoredMethods,
4350 auxiliaryTypes);
4351 }
4352
4353 /**
4354 * {@inheritDoc}
4355 */
4356 public Builder<U> nestHost(TypeDescription type) {
4357 return materialize(instrumentedType.withNestHost(type),
4358 fieldRegistry,
4359 methodRegistry,
4360 recordComponentRegistry,
4361 typeAttributeAppender,
4362 asmVisitorWrapper,
4363 classFileVersion,
4364 auxiliaryTypeNamingStrategy,
4365 annotationValueFilterFactory,
4366 annotationRetention,
4367 implementationContextFactory,
4368 methodGraphCompiler,
4369 typeValidation,
4370 visibilityBridgeStrategy,
4371 classWriterStrategy,
4372 ignoredMethods,
4373 auxiliaryTypes);
4374 }
4375
4376 /**
4377 * {@inheritDoc}
4378 */
4379 public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
4380 return materialize(instrumentedType.withNestMembers(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
4381 fieldRegistry,
4382 methodRegistry,
4383 recordComponentRegistry,
4384 typeAttributeAppender,
4385 asmVisitorWrapper,
4386 classFileVersion,
4387 auxiliaryTypeNamingStrategy,
4388 annotationValueFilterFactory,
4389 annotationRetention,
4390 implementationContextFactory,
4391 methodGraphCompiler,
4392 typeValidation,
4393 visibilityBridgeStrategy,
4394 classWriterStrategy,
4395 ignoredMethods,
4396 auxiliaryTypes);
4397 }
4398
4399 /**
4400 * {@inheritDoc}
4401 */
4402 public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
4403 return materialize(instrumentedType.withPermittedSubclasses(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
4404 fieldRegistry,
4405 methodRegistry,
4406 recordComponentRegistry,
4407 typeAttributeAppender,
4408 asmVisitorWrapper,
4409 classFileVersion,
4410 auxiliaryTypeNamingStrategy,
4411 annotationValueFilterFactory,
4412 annotationRetention,
4413 implementationContextFactory,
4414 methodGraphCompiler,
4415 typeValidation,
4416 visibilityBridgeStrategy,
4417 classWriterStrategy,
4418 ignoredMethods,
4419 auxiliaryTypes);
4420 }
4421
4422 /**
4423 * {@inheritDoc}
4424 */
4425 public Builder<U> unsealed() {
4426 return materialize(instrumentedType.withSealed(false),
4427 fieldRegistry,
4428 methodRegistry,
4429 recordComponentRegistry,
4430 typeAttributeAppender,
4431 asmVisitorWrapper,
4432 classFileVersion,
4433 auxiliaryTypeNamingStrategy,
4434 annotationValueFilterFactory,
4435 annotationRetention,
4436 implementationContextFactory,
4437 methodGraphCompiler,
4438 typeValidation,
4439 visibilityBridgeStrategy,
4440 classWriterStrategy,
4441 ignoredMethods,
4442 auxiliaryTypes);
4443 }
4444
4445 /**
4446 * {@inheritDoc}
4447 */
4448 public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
4449 return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
4450 }
4451
4452 /**
4453 * {@inheritDoc}
4454 */
4455 public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
4456 return materialize(instrumentedType.withTypeVariables(matcher, transformer),
4457 fieldRegistry,
4458 methodRegistry,
4459 recordComponentRegistry,
4460 typeAttributeAppender,
4461 asmVisitorWrapper,
4462 classFileVersion,
4463 auxiliaryTypeNamingStrategy,
4464 annotationValueFilterFactory,
4465 annotationRetention,
4466 implementationContextFactory,
4467 methodGraphCompiler,
4468 typeValidation,
4469 visibilityBridgeStrategy,
4470 classWriterStrategy,
4471 ignoredMethods,
4472 auxiliaryTypes);
4473 }
4474
4475 /**
4476 * {@inheritDoc}
4477 */
4478 public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
4479 return materialize(instrumentedType,
4480 fieldRegistry,
4481 methodRegistry,
4482 recordComponentRegistry,
4483 new TypeAttributeAppender.Compound(this.typeAttributeAppender, typeAttributeAppender),
4484 asmVisitorWrapper,
4485 classFileVersion,
4486 auxiliaryTypeNamingStrategy,
4487 annotationValueFilterFactory,
4488 annotationRetention,
4489 implementationContextFactory,
4490 methodGraphCompiler,
4491 typeValidation,
4492 visibilityBridgeStrategy,
4493 classWriterStrategy,
4494 ignoredMethods,
4495 auxiliaryTypes);
4496 }
4497
4498 /**
4499 * {@inheritDoc}
4500 */
4501 public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
4502 return materialize(instrumentedType.withAnnotations(new ArrayList<AnnotationDescription>(annotations)),
4503 fieldRegistry,
4504 methodRegistry,
4505 recordComponentRegistry,
4506 typeAttributeAppender,
4507 asmVisitorWrapper,
4508 classFileVersion,
4509 auxiliaryTypeNamingStrategy,
4510 annotationValueFilterFactory,
4511 annotationRetention,
4512 implementationContextFactory,
4513 methodGraphCompiler,
4514 typeValidation,
4515 visibilityBridgeStrategy,
4516 classWriterStrategy,
4517 ignoredMethods,
4518 auxiliaryTypes);
4519 }
4520
4521 /**
4522 * {@inheritDoc}
4523 */
4524 public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
4525 return materialize(instrumentedType,
4526 fieldRegistry,
4527 methodRegistry,
4528 recordComponentRegistry,
4529 typeAttributeAppender,
4530 new AsmVisitorWrapper.Compound(this.asmVisitorWrapper, asmVisitorWrapper),
4531 classFileVersion,
4532 auxiliaryTypeNamingStrategy,
4533 annotationValueFilterFactory,
4534 annotationRetention,
4535 implementationContextFactory,
4536 methodGraphCompiler,
4537 typeValidation,
4538 visibilityBridgeStrategy,
4539 classWriterStrategy,
4540 ignoredMethods,
4541 auxiliaryTypes);
4542 }
4543
4544 /**
4545 * {@inheritDoc}
4546 */
4547 public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
4548 return materialize(instrumentedType,
4549 fieldRegistry,
4550 methodRegistry,
4551 recordComponentRegistry,
4552 typeAttributeAppender,
4553 asmVisitorWrapper,
4554 classFileVersion,
4555 auxiliaryTypeNamingStrategy,
4556 annotationValueFilterFactory,
4557 annotationRetention,
4558 implementationContextFactory,
4559 methodGraphCompiler,
4560 typeValidation,
4561 visibilityBridgeStrategy,
4562 classWriterStrategy,
4563 ignoredMethods,
4564 CompoundList.of(this.auxiliaryTypes, new ArrayList<DynamicType>(auxiliaryTypes)));
4565 }
4566
4567 /**
4568 * {@inheritDoc}
4569 */
4570 public TypeDescription toTypeDescription() {
4571 return instrumentedType;
4572 }
4573
4574 /**
4575 * Materializes the supplied state of a dynamic type builder.
4576 *
4577 * @param instrumentedType The instrumented type.
4578 * @param fieldRegistry The current field registry.
4579 * @param methodRegistry The current method registry.
4580 * @param recordComponentRegistry The record component pool to use.
4581 * @param typeAttributeAppender The type attribute appender to apply onto the instrumented type.
4582 * @param asmVisitorWrapper The ASM visitor wrapper to apply onto the class writer.
4583 * @param classFileVersion The class file version to define auxiliary types in.
4584 * @param auxiliaryTypeNamingStrategy The naming strategy for auxiliary types to apply.
4585 * @param annotationValueFilterFactory The annotation value filter factory to apply.
4586 * @param annotationRetention The annotation retention to apply.
4587 * @param implementationContextFactory The implementation context factory to apply.
4588 * @param methodGraphCompiler The method graph compiler to use.
4589 * @param typeValidation The type validation state.
4590 * @param visibilityBridgeStrategy The visibility bridge strategy to apply.
4591 * @param classWriterStrategy The class writer strategy to use.
4592 * @param ignoredMethods A matcher for identifying methods that should be excluded from instrumentation.
4593 * @param auxiliaryTypes A list of explicitly required auxiliary types.
4594 * @return A type builder that represents the supplied arguments.
4595 */
4596 protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
4597 FieldRegistry fieldRegistry,
4598 MethodRegistry methodRegistry,
4599 RecordComponentRegistry recordComponentRegistry,
4600 TypeAttributeAppender typeAttributeAppender,
4601 AsmVisitorWrapper asmVisitorWrapper,
4602 ClassFileVersion classFileVersion,
4603 AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4604 AnnotationValueFilter.Factory annotationValueFilterFactory,
4605 AnnotationRetention annotationRetention,
4606 Implementation.Context.Factory implementationContextFactory,
4607 MethodGraph.Compiler methodGraphCompiler,
4608 TypeValidation typeValidation,
4609 VisibilityBridgeStrategy visibilityBridgeStrategy,
4610 ClassWriterStrategy classWriterStrategy,
4611 LatentMatcher<? super MethodDescription> ignoredMethods,
4612 List<? extends DynamicType> auxiliaryTypes);
4613
4614 /**
4615 * An adapter for applying an inner type definition for an outer type.
4616 */
4617 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4618 protected class InnerTypeDefinitionForTypeAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition.ForType<U> {
4619
4620 /**
4621 * A description of the type that is the defined outer type.
4622 */
4623 private final TypeDescription typeDescription;
4624
4625 /**
4626 * Creates a new adapter for an inner type definition for an outer type.
4627 *
4628 * @param typeDescription A description of the type that is the defined outer type.
4629 */
4630 protected InnerTypeDefinitionForTypeAdapter(TypeDescription typeDescription) {
4631 this.typeDescription = typeDescription;
4632 }
4633
4634 /**
4635 * {@inheritDoc}
4636 */
4637 public Builder<U> asAnonymousType() {
4638 return Adapter.this.materialize(instrumentedType
4639 .withDeclaringType(TypeDescription.UNDEFINED)
4640 .withEnclosingType(typeDescription)
4641 .withAnonymousClass(true),
4642 fieldRegistry,
4643 methodRegistry,
4644 recordComponentRegistry,
4645 typeAttributeAppender,
4646 asmVisitorWrapper,
4647 classFileVersion,
4648 auxiliaryTypeNamingStrategy,
4649 annotationValueFilterFactory,
4650 annotationRetention,
4651 implementationContextFactory,
4652 methodGraphCompiler,
4653 typeValidation,
4654 visibilityBridgeStrategy,
4655 classWriterStrategy,
4656 ignoredMethods,
4657 auxiliaryTypes);
4658 }
4659
4660 /**
4661 * {@inheritDoc}
4662 */
4663 public Builder<U> asMemberType() {
4664 return Adapter.this.materialize(instrumentedType
4665 .withDeclaringType(typeDescription)
4666 .withEnclosingType(typeDescription)
4667 .withAnonymousClass(false)
4668 .withLocalClass(false),
4669 fieldRegistry,
4670 methodRegistry,
4671 recordComponentRegistry,
4672 typeAttributeAppender,
4673 asmVisitorWrapper,
4674 classFileVersion,
4675 auxiliaryTypeNamingStrategy,
4676 annotationValueFilterFactory,
4677 annotationRetention,
4678 implementationContextFactory,
4679 methodGraphCompiler,
4680 typeValidation,
4681 visibilityBridgeStrategy,
4682 classWriterStrategy,
4683 ignoredMethods,
4684 auxiliaryTypes);
4685 }
4686
4687 @Override
4688 protected Builder<U> materialize() {
4689 return Adapter.this.materialize(instrumentedType
4690 .withDeclaringType(TypeDescription.UNDEFINED)
4691 .withEnclosingType(typeDescription)
4692 .withLocalClass(true),
4693 fieldRegistry,
4694 methodRegistry,
4695 recordComponentRegistry,
4696 typeAttributeAppender,
4697 asmVisitorWrapper,
4698 classFileVersion,
4699 auxiliaryTypeNamingStrategy,
4700 annotationValueFilterFactory,
4701 annotationRetention,
4702 implementationContextFactory,
4703 methodGraphCompiler,
4704 typeValidation,
4705 visibilityBridgeStrategy,
4706 classWriterStrategy,
4707 ignoredMethods,
4708 auxiliaryTypes);
4709 }
4710 }
4711
4712 /**
4713 * An adapter for applying an inner type definition for an outer method or constructor.
4714 */
4715 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4716 protected class InnerTypeDefinitionForMethodAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition<U> {
4717
4718 /**
4719 * A description of the declaring method or constructor.
4720 */
4721 private final MethodDescription.InDefinedShape methodDescription;
4722
4723 /**
4724 * Creates a new adapter for defining a type that is declared within a method or constructor.
4725 *
4726 * @param methodDescription A description of the declaring method or constructor.
4727 */
4728 protected InnerTypeDefinitionForMethodAdapter(MethodDescription.InDefinedShape methodDescription) {
4729 this.methodDescription = methodDescription;
4730 }
4731
4732 /**
4733 * {@inheritDoc}
4734 */
4735 public Builder<U> asAnonymousType() {
4736 return Adapter.this.materialize(instrumentedType
4737 .withDeclaringType(TypeDescription.UNDEFINED)
4738 .withEnclosingMethod(methodDescription)
4739 .withAnonymousClass(true),
4740 fieldRegistry,
4741 methodRegistry,
4742 recordComponentRegistry,
4743 typeAttributeAppender,
4744 asmVisitorWrapper,
4745 classFileVersion,
4746 auxiliaryTypeNamingStrategy,
4747 annotationValueFilterFactory,
4748 annotationRetention,
4749 implementationContextFactory,
4750 methodGraphCompiler,
4751 typeValidation,
4752 visibilityBridgeStrategy,
4753 classWriterStrategy,
4754 ignoredMethods,
4755 auxiliaryTypes);
4756 }
4757
4758 @Override
4759 protected Builder<U> materialize() {
4760 return Adapter.this.materialize(instrumentedType
4761 .withDeclaringType(TypeDescription.UNDEFINED)
4762 .withEnclosingMethod(methodDescription)
4763 .withLocalClass(true),
4764 fieldRegistry,
4765 methodRegistry,
4766 recordComponentRegistry,
4767 typeAttributeAppender,
4768 asmVisitorWrapper,
4769 classFileVersion,
4770 auxiliaryTypeNamingStrategy,
4771 annotationValueFilterFactory,
4772 annotationRetention,
4773 implementationContextFactory,
4774 methodGraphCompiler,
4775 typeValidation,
4776 visibilityBridgeStrategy,
4777 classWriterStrategy,
4778 ignoredMethods,
4779 auxiliaryTypes);
4780 }
4781 }
4782
4783 /**
4784 * An adapter for defining a new type variable for the instrumented type.
4785 */
4786 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4787 protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
4788
4789 /**
4790 * The current definition of the type variable.
4791 */
4792 private final TypeVariableToken token;
4793
4794 /**
4795 * Creates a new type variable definition adapter.
4796 *
4797 * @param token The current definition of the type variable.
4798 */
4799 protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
4800 this.token = token;
4801 }
4802
4803 /**
4804 * {@inheritDoc}
4805 */
4806 public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
4807 return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
4808 token.getBounds(),
4809 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
4810 }
4811
4812 @Override
4813 protected Builder<U> materialize() {
4814 return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
4815 fieldRegistry,
4816 methodRegistry,
4817 recordComponentRegistry,
4818 typeAttributeAppender,
4819 asmVisitorWrapper,
4820 classFileVersion,
4821 auxiliaryTypeNamingStrategy,
4822 annotationValueFilterFactory,
4823 annotationRetention,
4824 implementationContextFactory,
4825 methodGraphCompiler,
4826 typeValidation,
4827 visibilityBridgeStrategy,
4828 classWriterStrategy,
4829 ignoredMethods,
4830 auxiliaryTypes);
4831 }
4832 }
4833
4834 /**
4835 * An adapter for defining a new field.
4836 */
4837 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4838 protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
4839
4840 /**
4841 * The token representing the current field definition.
4842 */
4843 private final FieldDescription.Token token;
4844
4845 /**
4846 * Creates a new field definition adapter.
4847 *
4848 * @param token The token representing the current field definition.
4849 */
4850 protected FieldDefinitionAdapter(FieldDescription.Token token) {
4851 this(FieldAttributeAppender.ForInstrumentedField.INSTANCE,
4852 Transformer.NoOp.<FieldDescription>make(),
4853 FieldDescription.NO_DEFAULT_VALUE,
4854 token);
4855 }
4856
4857 /**
4858 * Creates a new field definition adapter.
4859 *
4860 * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
4861 * @param transformer The field transformer to apply.
4862 * @param defaultValue The field's default value or {@code null} if no value is to be defined.
4863 * @param token The token representing the current field definition.
4864 */
4865 protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4866 Transformer<FieldDescription> transformer,
4867 Object defaultValue,
4868 FieldDescription.Token token) {
4869 super(fieldAttributeAppenderFactory, transformer, defaultValue);
4870 this.token = token;
4871 }
4872
4873 /**
4874 * {@inheritDoc}
4875 */
4876 public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
4877 return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, new FieldDescription.Token(token.getName(),
4878 token.getModifiers(),
4879 token.getType(),
4880 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
4881 }
4882
4883 @Override
4884 protected Builder<U> materialize() {
4885 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
4886 fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, transformer),
4887 methodRegistry,
4888 recordComponentRegistry,
4889 typeAttributeAppender,
4890 asmVisitorWrapper,
4891 classFileVersion,
4892 auxiliaryTypeNamingStrategy,
4893 annotationValueFilterFactory,
4894 annotationRetention,
4895 implementationContextFactory,
4896 methodGraphCompiler,
4897 typeValidation,
4898 visibilityBridgeStrategy,
4899 classWriterStrategy,
4900 ignoredMethods,
4901 auxiliaryTypes);
4902 }
4903
4904 @Override
4905 protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4906 Transformer<FieldDescription> transformer,
4907 Object defaultValue) {
4908 return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
4909 }
4910 }
4911
4912 /**
4913 * An adapter for matching an existing field.
4914 */
4915 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4916 protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
4917
4918 /**
4919 * The matcher for any fields to apply this matcher to.
4920 */
4921 private final LatentMatcher<? super FieldDescription> matcher;
4922
4923 /**
4924 * Creates a new field match adapter.
4925 *
4926 * @param matcher The matcher for any fields to apply this matcher to.
4927 */
4928 protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
4929 this(FieldAttributeAppender.NoOp.INSTANCE,
4930 Transformer.NoOp.<FieldDescription>make(),
4931 FieldDescription.NO_DEFAULT_VALUE,
4932 matcher);
4933 }
4934
4935 /**
4936 * Creates a new field match adapter.
4937 *
4938 * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
4939 * @param transformer The field transformer to apply.
4940 * @param defaultValue The field's default value or {@code null} if no value is to be defined.
4941 * @param matcher The matcher for any fields to apply this matcher to.
4942 */
4943 protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4944 Transformer<FieldDescription> transformer,
4945 Object defaultValue,
4946 LatentMatcher<? super FieldDescription> matcher) {
4947 super(fieldAttributeAppenderFactory, transformer, defaultValue);
4948 this.matcher = matcher;
4949 }
4950
4951 /**
4952 * {@inheritDoc}
4953 */
4954 public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
4955 return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
4956 }
4957
4958 @Override
4959 protected Builder<U> materialize() {
4960 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
4961 fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, transformer),
4962 methodRegistry,
4963 recordComponentRegistry,
4964 typeAttributeAppender,
4965 asmVisitorWrapper,
4966 classFileVersion,
4967 auxiliaryTypeNamingStrategy,
4968 annotationValueFilterFactory,
4969 annotationRetention,
4970 implementationContextFactory,
4971 methodGraphCompiler,
4972 typeValidation,
4973 visibilityBridgeStrategy,
4974 classWriterStrategy,
4975 ignoredMethods,
4976 auxiliaryTypes);
4977 }
4978
4979 @Override
4980 protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4981 Transformer<FieldDescription> transformer,
4982 Object defaultValue) {
4983 return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
4984 }
4985 }
4986
4987 /**
4988 * An adapter for defining a new method.
4989 */
4990 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4991 protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
4992
4993 /**
4994 * A token representing the currently defined method.
4995 */
4996 private final MethodDescription.Token token;
4997
4998 /**
4999 * Creates a new method definition adapter.
5000 *
5001 * @param token A token representing the currently defined method.
5002 */
5003 protected MethodDefinitionAdapter(MethodDescription.Token token) {
5004 this.token = token;
5005 }
5006
5007 /**
5008 * {@inheritDoc}
5009 */
5010 public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
5011 return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
5012 }
5013
5014 /**
5015 * {@inheritDoc}
5016 */
5017 public Simple.Annotatable<U> withParameter(TypeDefinition type) {
5018 return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
5019 }
5020
5021 /**
5022 * {@inheritDoc}
5023 */
5024 public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
5025 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5026 token.getModifiers(),
5027 token.getTypeVariableTokens(),
5028 token.getReturnType(),
5029 token.getParameterTokens(),
5030 CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
5031 token.getAnnotations(),
5032 token.getDefaultValue(),
5033 token.getReceiverType()));
5034 }
5035
5036 /**
5037 * {@inheritDoc}
5038 */
5039 public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
5040 return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
5041 }
5042
5043 /**
5044 * {@inheritDoc}
5045 */
5046 public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5047 return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
5048 }
5049
5050 /**
5051 * {@inheritDoc}
5052 */
5053 public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5054 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5055 (token.getModifiers() & Opcodes.ACC_NATIVE) == 0
5056 ? ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers())
5057 : token.getModifiers(),
5058 token.getTypeVariableTokens(),
5059 token.getReturnType(),
5060 token.getParameterTokens(),
5061 token.getExceptionTypes(),
5062 token.getAnnotations(),
5063 token.getDefaultValue(),
5064 token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
5065 }
5066
5067 /**
5068 * {@inheritDoc}
5069 */
5070 public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5071 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5072 ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
5073 token.getTypeVariableTokens(),
5074 token.getReturnType(),
5075 token.getParameterTokens(),
5076 token.getExceptionTypes(),
5077 token.getAnnotations(),
5078 annotationValue,
5079 token.getReceiverType())).materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
5080 }
5081
5082 /**
5083 * Materializes the given handler as the implementation.
5084 *
5085 * @param handler The handler for implementing the method.
5086 * @return A method definition for the given handler.
5087 */
5088 private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5089 return new AnnotationAdapter(handler);
5090 }
5091
5092 /**
5093 * An adapter for defining a new type variable for the currently defined method.
5094 */
5095 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5096 protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
5097
5098 /**
5099 * The currently defined type variable.
5100 */
5101 private final TypeVariableToken token;
5102
5103 /**
5104 * Creates a new type variable annotation adapter.
5105 *
5106 * @param token The currently defined type variable.
5107 */
5108 protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
5109 this.token = token;
5110 }
5111
5112 @Override
5113 protected MethodDefinition.ParameterDefinition<U> materialize() {
5114 return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
5115 MethodDefinitionAdapter.this.token.getModifiers(),
5116 CompoundList.of(MethodDefinitionAdapter.this.token.getTypeVariableTokens(), token),
5117 MethodDefinitionAdapter.this.token.getReturnType(),
5118 MethodDefinitionAdapter.this.token.getParameterTokens(),
5119 MethodDefinitionAdapter.this.token.getExceptionTypes(),
5120 MethodDefinitionAdapter.this.token.getAnnotations(),
5121 MethodDefinitionAdapter.this.token.getDefaultValue(),
5122 MethodDefinitionAdapter.this.token.getReceiverType()));
5123 }
5124
5125 /**
5126 * {@inheritDoc}
5127 */
5128 public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
5129 return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
5130 token.getBounds(),
5131 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
5132 }
5133 }
5134
5135 /**
5136 * An annotation adapter for a parameter definition.
5137 */
5138 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5139 protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
5140
5141 /**
5142 * The token of the currently defined parameter.
5143 */
5144 private final ParameterDescription.Token token;
5145
5146 /**
5147 * Creates a new parameter annotation adapter.
5148 *
5149 * @param token The token of the currently defined parameter.
5150 */
5151 protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
5152 this.token = token;
5153 }
5154
5155 /**
5156 * {@inheritDoc}
5157 */
5158 public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5159 return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
5160 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5161 token.getName(),
5162 token.getModifiers()));
5163 }
5164
5165 @Override
5166 protected MethodDefinition.ParameterDefinition<U> materialize() {
5167 return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
5168 MethodDefinitionAdapter.this.token.getModifiers(),
5169 MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
5170 MethodDefinitionAdapter.this.token.getReturnType(),
5171 CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
5172 MethodDefinitionAdapter.this.token.getExceptionTypes(),
5173 MethodDefinitionAdapter.this.token.getAnnotations(),
5174 MethodDefinitionAdapter.this.token.getDefaultValue(),
5175 MethodDefinitionAdapter.this.token.getReceiverType()));
5176 }
5177 }
5178
5179 /**
5180 * An annotation adapter for a simple parameter definition.
5181 */
5182 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5183 protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
5184
5185 /**
5186 * The token of the currently defined parameter.
5187 */
5188 private final ParameterDescription.Token token;
5189
5190 /**
5191 * Creates a new simple parameter annotation adapter.
5192 *
5193 * @param token The token of the currently defined parameter.
5194 */
5195 protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
5196 this.token = token;
5197 }
5198
5199 /**
5200 * {@inheritDoc}
5201 */
5202 public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5203 return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
5204 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5205 token.getName(),
5206 token.getModifiers()));
5207 }
5208
5209 @Override
5210 protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
5211 return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
5212 MethodDefinitionAdapter.this.token.getModifiers(),
5213 MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
5214 MethodDefinitionAdapter.this.token.getReturnType(),
5215 CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
5216 MethodDefinitionAdapter.this.token.getExceptionTypes(),
5217 MethodDefinitionAdapter.this.token.getAnnotations(),
5218 MethodDefinitionAdapter.this.token.getDefaultValue(),
5219 MethodDefinitionAdapter.this.token.getReceiverType()));
5220 }
5221 }
5222
5223 /**
5224 * An annotation adapter for a method definition.
5225 */
5226 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5227 protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5228
5229 /**
5230 * Creates a new annotation adapter.
5231 *
5232 * @param handler The handler that determines how a method is implemented.
5233 */
5234 protected AnnotationAdapter(MethodRegistry.Handler handler) {
5235 this(handler,
5236 MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER,
5237 Transformer.NoOp.<MethodDescription>make());
5238 }
5239
5240 /**
5241 * Creates a new annotation adapter.
5242 *
5243 * @param handler The handler that determines how a method is implemented.
5244 * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5245 * @param transformer The method transformer to apply onto the method that is currently being implemented.
5246 */
5247 protected AnnotationAdapter(MethodRegistry.Handler handler,
5248 MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5249 Transformer<MethodDescription> transformer) {
5250 super(handler, methodAttributeAppenderFactory, transformer);
5251 }
5252
5253 /**
5254 * {@inheritDoc}
5255 */
5256 public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5257 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5258 token.getModifiers(),
5259 token.getTypeVariableTokens(),
5260 token.getReturnType(),
5261 token.getParameterTokens(),
5262 token.getExceptionTypes(),
5263 token.getAnnotations(),
5264 token.getDefaultValue(),
5265 receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5266 }
5267
5268 /**
5269 * {@inheritDoc}
5270 */
5271 public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5272 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5273 token.getModifiers(),
5274 token.getTypeVariableTokens(),
5275 token.getReturnType(),
5276 token.getParameterTokens(),
5277 token.getExceptionTypes(),
5278 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5279 token.getDefaultValue(),
5280 token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5281 }
5282
5283 /**
5284 * {@inheritDoc}
5285 */
5286 public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5287 List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
5288 parameterTokens.set(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
5289 CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5290 token.getParameterTokens().get(index).getName(),
5291 token.getParameterTokens().get(index).getModifiers()));
5292 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5293 token.getModifiers(),
5294 token.getTypeVariableTokens(),
5295 token.getReturnType(),
5296 parameterTokens,
5297 token.getExceptionTypes(),
5298 token.getAnnotations(),
5299 token.getDefaultValue(),
5300 token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5301 }
5302
5303 @Override
5304 protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5305 MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5306 Transformer<MethodDescription> transformer) {
5307 return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5308 }
5309
5310 @Override
5311 protected Builder<U> materialize() {
5312 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
5313 fieldRegistry,
5314 methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
5315 handler,
5316 methodAttributeAppenderFactory,
5317 transformer),
5318 recordComponentRegistry,
5319 typeAttributeAppender,
5320 asmVisitorWrapper,
5321 classFileVersion,
5322 auxiliaryTypeNamingStrategy,
5323 annotationValueFilterFactory,
5324 annotationRetention,
5325 implementationContextFactory,
5326 methodGraphCompiler,
5327 typeValidation,
5328 visibilityBridgeStrategy,
5329 classWriterStrategy,
5330 ignoredMethods,
5331 auxiliaryTypes);
5332 }
5333 }
5334 }
5335
5336 /**
5337 * An adapter for matching an existing method.
5338 */
5339 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5340 protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
5341
5342 /**
5343 * The method matcher of this adapter.
5344 */
5345 private final LatentMatcher<? super MethodDescription> matcher;
5346
5347 /**
5348 * Creates a new method match adapter.
5349 *
5350 * @param matcher The method matcher of this adapter.
5351 */
5352 protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
5353 this.matcher = matcher;
5354 }
5355
5356 /**
5357 * {@inheritDoc}
5358 */
5359 public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5360 return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
5361 }
5362
5363 /**
5364 * {@inheritDoc}
5365 */
5366 public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5367 return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
5368 }
5369
5370 /**
5371 * {@inheritDoc}
5372 */
5373 public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5374 return materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
5375 }
5376
5377 /**
5378 * Materializes the method definition with the supplied handler.
5379 *
5380 * @param handler The handler that implements any method matched by this instances matcher.
5381 * @return A method definition where any matched method is implemented by the supplied handler.
5382 */
5383 private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5384 return new AnnotationAdapter(handler);
5385 }
5386
5387 /**
5388 * An annotation adapter for implementing annotations during a method definition.
5389 */
5390 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5391 protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5392
5393 /**
5394 * Creates a new annotation adapter.
5395 *
5396 * @param handler The handler that determines how a method is implemented.
5397 */
5398 protected AnnotationAdapter(MethodRegistry.Handler handler) {
5399 this(handler, MethodAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<MethodDescription>make());
5400 }
5401
5402 /**
5403 * Creates a new annotation adapter.
5404 *
5405 * @param handler The handler that determines how a method is implemented.
5406 * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5407 * @param transformer The method transformer to apply onto the method that is currently being implemented.
5408 */
5409 protected AnnotationAdapter(MethodRegistry.Handler handler,
5410 MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5411 Transformer<MethodDescription> transformer) {
5412 super(handler, methodAttributeAppenderFactory, transformer);
5413 }
5414
5415 /**
5416 * {@inheritDoc}
5417 */
5418 public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5419 return new AnnotationAdapter(handler,
5420 new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
5421 transformer);
5422 }
5423
5424 /**
5425 * {@inheritDoc}
5426 */
5427 public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5428 return new AnnotationAdapter(handler,
5429 new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
5430 transformer);
5431 }
5432
5433 /**
5434 * {@inheritDoc}
5435 */
5436 public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5437 return new AnnotationAdapter(handler,
5438 new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
5439 transformer);
5440 }
5441
5442 @Override
5443 protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5444 MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5445 Transformer<MethodDescription> transformer) {
5446 return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5447 }
5448
5449 @Override
5450 protected Builder<U> materialize() {
5451 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
5452 fieldRegistry,
5453 methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, transformer),
5454 recordComponentRegistry,
5455 typeAttributeAppender,
5456 asmVisitorWrapper,
5457 classFileVersion,
5458 auxiliaryTypeNamingStrategy,
5459 annotationValueFilterFactory,
5460 annotationRetention,
5461 implementationContextFactory,
5462 methodGraphCompiler,
5463 typeValidation,
5464 visibilityBridgeStrategy,
5465 classWriterStrategy,
5466 ignoredMethods,
5467 auxiliaryTypes);
5468 }
5469 }
5470 }
5471
5472 /**
5473 * An adapter for optionally matching methods defined by declared interfaces.
5474 */
5475 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5476 protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
5477
5478 /**
5479 * The interfaces whose methods are optionally matched.
5480 */
5481 private final TypeList.Generic interfaces;
5482
5483 /**
5484 * Creates a new optional method match adapter.
5485 *
5486 * @param interfaces The interfaces whose methods are optionally matched.
5487 */
5488 protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
5489 this.interfaces = interfaces;
5490 }
5491
5492 @Override
5493 protected Builder<U> materialize() {
5494 return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
5495 fieldRegistry,
5496 methodRegistry,
5497 recordComponentRegistry,
5498 typeAttributeAppender,
5499 asmVisitorWrapper,
5500 classFileVersion,
5501 auxiliaryTypeNamingStrategy,
5502 annotationValueFilterFactory,
5503 annotationRetention,
5504 implementationContextFactory,
5505 methodGraphCompiler,
5506 typeValidation,
5507 visibilityBridgeStrategy,
5508 classWriterStrategy,
5509 ignoredMethods,
5510 auxiliaryTypes);
5511 }
5512
5513 /**
5514 * {@inheritDoc}
5515 */
5516 public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5517 return interfaceType().intercept(implementation);
5518 }
5519
5520 /**
5521 * {@inheritDoc}
5522 */
5523 public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5524 return interfaceType().withoutCode();
5525 }
5526
5527 /**
5528 * {@inheritDoc}
5529 */
5530 public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5531 return interfaceType().defaultValue(annotationValue);
5532 }
5533
5534 /**
5535 * {@inheritDoc}
5536 */
5537 public <V> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(V value, Class<? extends V> type) {
5538 return interfaceType().defaultValue(value, type);
5539 }
5540
5541 /**
5542 * Returns a matcher for the interfaces' methods.
5543 *
5544 * @return A matcher for the interfaces' methods.
5545 */
5546 private MethodDefinition.ImplementationDefinition<U> interfaceType() {
5547 ElementMatcher.Junction<TypeDescription> elementMatcher = none();
5548 for (TypeDescription typeDescription : interfaces.asErasures()) {
5549 elementMatcher = elementMatcher.or(isSuperTypeOf(typeDescription));
5550 }
5551 return materialize().invokable(isDeclaredBy(isInterface().and(elementMatcher)));
5552 }
5553 }
5554
5555 /**
5556 * An adapter for defining a record component.
5557 */
5558 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5559 protected class RecordComponentDefinitionAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5560
5561 /**
5562 * The record component attribute appender factory to apply.
5563 */
5564 private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5565
5566 /**
5567 * A token representing the defined record component.
5568 */
5569 private final RecordComponentDescription.Token token;
5570
5571 /**
5572 * A transformer to apply on matched record component descriptions.
5573 */
5574 private final Transformer<RecordComponentDescription> transformer;
5575
5576 /**
5577 * Creates a new record component definition adapter.
5578 *
5579 * @param token A token representing the defined record component.
5580 */
5581 protected RecordComponentDefinitionAdapter(RecordComponentDescription.Token token) {
5582 this(RecordComponentAttributeAppender.ForInstrumentedRecordComponent.INSTANCE,
5583 Transformer.NoOp.<RecordComponentDescription>make(),
5584 token);
5585 }
5586
5587 /**
5588 * Creates a new record component definition adapter.
5589 *
5590 * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5591 * @param transformer A transformer to apply on matched record component descriptions.
5592 * @param token A token representing the defined record component.
5593 */
5594 protected RecordComponentDefinitionAdapter(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5595 Transformer<RecordComponentDescription> transformer,
5596 RecordComponentDescription.Token token) {
5597 this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
5598 this.transformer = transformer;
5599 this.token = token;
5600 }
5601
5602 /**
5603 * {@inheritDoc}
5604 */
5605 public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5606 return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory, transformer, new RecordComponentDescription.Token(token.getName(),
5607 token.getType(),
5608 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
5609 }
5610
5611 /**
5612 * {@inheritDoc}
5613 */
5614 public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5615 return new RecordComponentDefinitionAdapter(new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
5616 recordComponentAttributeAppenderFactory), transformer, token);
5617 }
5618
5619 /**
5620 * {@inheritDoc}
5621 */
5622 @SuppressWarnings("unchecked") // In absence of @SafeVarargs
5623 public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5624 return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory,
5625 new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer),
5626 token);
5627 }
5628
5629 @Override
5630 protected Builder<U> materialize() {
5631 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withRecordComponent(token),
5632 fieldRegistry,
5633 methodRegistry,
5634 recordComponentRegistry.prepend(new LatentMatcher.ForRecordComponentToken(token),
5635 recordComponentAttributeAppenderFactory,
5636 transformer),
5637 typeAttributeAppender,
5638 asmVisitorWrapper,
5639 classFileVersion,
5640 auxiliaryTypeNamingStrategy,
5641 annotationValueFilterFactory,
5642 annotationRetention,
5643 implementationContextFactory,
5644 methodGraphCompiler,
5645 typeValidation,
5646 visibilityBridgeStrategy,
5647 classWriterStrategy,
5648 ignoredMethods,
5649 auxiliaryTypes);
5650 }
5651 }
5652
5653 /**
5654 * An adapter for matching record components.
5655 */
5656 protected class RecordComponentMatchAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5657
5658 /**
5659 * The matcher for identifying record components to match.
5660 */
5661 private final LatentMatcher<? super RecordComponentDescription> matcher;
5662
5663 /**
5664 * The record component attribute appender factory to apply.
5665 */
5666 private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5667
5668 /**
5669 * A transformer to apply on matched record component descriptions.
5670 */
5671 private final Transformer<RecordComponentDescription> transformer;
5672
5673 /**
5674 * Creates a new record component match adapter.
5675 *
5676 * @param matcher The matcher for identifying record components to match.
5677 */
5678 protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher) {
5679 this(matcher, RecordComponentAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<RecordComponentDescription>make());
5680 }
5681
5682 /**
5683 * Creates a new record component match adapter.
5684 *
5685 * @param matcher The matcher for identifying record components to match.
5686 * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5687 * @param transformer A transformer to apply on matched record component descriptions.
5688 */
5689 protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher,
5690 RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5691 Transformer<RecordComponentDescription> transformer) {
5692 this.matcher = matcher;
5693 this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
5694 this.transformer = transformer;
5695 }
5696
5697 /**
5698 * {@inheritDoc}
5699 */
5700 public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5701 return attribute(new RecordComponentAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
5702 }
5703
5704 /**
5705 * {@inheritDoc}
5706 */
5707 public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5708 return new RecordComponentMatchAdapter(matcher, new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
5709 recordComponentAttributeAppenderFactory), transformer);
5710 }
5711
5712 /**
5713 * {@inheritDoc}
5714 */
5715 @SuppressWarnings("unchecked") // In absence of @SafeVarargs
5716 public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5717 return new RecordComponentMatchAdapter(matcher,
5718 recordComponentAttributeAppenderFactory,
5719 new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer));
5720 }
5721
5722 @Override
5723 protected Builder<U> materialize() {
5724 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
5725 fieldRegistry,
5726 methodRegistry,
5727 recordComponentRegistry.prepend(matcher, recordComponentAttributeAppenderFactory, transformer),
5728 typeAttributeAppender,
5729 asmVisitorWrapper,
5730 classFileVersion,
5731 auxiliaryTypeNamingStrategy,
5732 annotationValueFilterFactory,
5733 annotationRetention,
5734 implementationContextFactory,
5735 methodGraphCompiler,
5736 typeValidation,
5737 visibilityBridgeStrategy,
5738 classWriterStrategy,
5739 ignoredMethods,
5740 auxiliaryTypes);
5741 }
5742 }
5743 }
5744 }
5745 }
5746
5747 /**
5748 * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
5749 *
5750 * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
5751 * type itself, an interface or the direct super class.
5752 */
5753 interface Unloaded<T> extends DynamicType {
5754
5755 /**
5756 * <p>
5757 * Attempts to load this dynamic type including all of its auxiliary types, if any. If the class loader is an
5758 * unsealed instance of {@link InjectionClassLoader}, the classes are injected directy into the class loader, otherwise,
5759 * a new class loader is created where the supplied class loader is set as parent.
5760 * </p>
5761 * <p>
5762 * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
5763 * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
5764 * </p>
5765 *
5766 * @param classLoader The class loader to use for this class loading.
5767 * @return This dynamic type in its loaded state.
5768 */
5769 Loaded<T> load(ClassLoader classLoader);
5770
5771 /**
5772 * <p>
5773 * Attempts to load this dynamic type including all of its auxiliary types, if any.
5774 * </p>
5775 * <p>
5776 * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
5777 * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
5778 * </p>
5779 *
5780 * @param classLoader The class loader to use for this class loading.
5781 * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
5782 * @param <S> The least specific type of class loader this strategy can apply to.
5783 * @return This dynamic type in its loaded state.
5784 * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
5785 */
5786 <S extends ClassLoader> Loaded<T> load(S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
5787
5788 /**
5789 * Includes the provided dynamic types as auxiliary types of this instance.
5790 *
5791 * @param dynamicType The dynamic types to include.
5792 * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
5793 */
5794 Unloaded<T> include(DynamicType... dynamicType);
5795
5796 /**
5797 * Includes the provided dynamic types as auxiliary types of this instance.
5798 *
5799 * @param dynamicTypes The dynamic types to include.
5800 * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
5801 */
5802 Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
5803 }
5804
5805 /**
5806 * A dynamic type that has been loaded into the running instance of the Java virtual machine.
5807 *
5808 * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
5809 * type itself, an interface or the direct super class.
5810 */
5811 interface Loaded<T> extends DynamicType {
5812
5813 /**
5814 * Returns the loaded main class.
5815 *
5816 * @return A loaded class representation of this dynamic type.
5817 */
5818 Class<? extends T> getLoaded();
5819
5820 /**
5821 * <p>
5822 * Returns a map of all loaded auxiliary types to this dynamic type.
5823 * </p>
5824 * <p>
5825 * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
5826 * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
5827 * </p>
5828 *
5829 * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
5830 */
5831 Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
5832 }
5833
5834 /**
5835 * A default implementation of a dynamic type.
5836 */
5837 @HashCodeAndEqualsPlugin.Enhance
5838 class Default implements DynamicType {
5839
5840 /**
5841 * The file name extension for Java class files.
5842 */
5843 private static final String CLASS_FILE_EXTENSION = ".class";
5844
5845 /**
5846 * The default version of a jar file manifest.
5847 */
5848 private static final String MANIFEST_VERSION = "1.0";
5849
5850 /**
5851 * The size of a writing buffer.
5852 */
5853 private static final int BUFFER_SIZE = 1024;
5854
5855 /**
5856 * A convenience index for the beginning of an array to improve the readability of the code.
5857 */
5858 private static final int FROM_BEGINNING = 0;
5859
5860 /**
5861 * A convenience representative of an {@link java.io.InputStream}'s end to improve the readability of the code.
5862 */
5863 private static final int END_OF_FILE = -1;
5864
5865 /**
5866 * A suffix for temporary files.
5867 */
5868 private static final String TEMP_SUFFIX = "tmp";
5869
5870 /**
5871 * A dispacher for applying a file copy.
5872 */
5873 protected static final Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE);
5874
5875 /**
5876 * A type description of this dynamic type.
5877 */
5878 protected final TypeDescription typeDescription;
5879
5880 /**
5881 * The byte array representing this dynamic type.
5882 */
5883 protected final byte[] binaryRepresentation;
5884
5885 /**
5886 * The loaded type initializer for this dynamic type.
5887 */
5888 protected final LoadedTypeInitializer loadedTypeInitializer;
5889
5890 /**
5891 * A list of auxiliary types for this dynamic type.
5892 */
5893 protected final List<? extends DynamicType> auxiliaryTypes;
5894
5895 /**
5896 * Creates a new dynamic type.
5897 *
5898 * @param typeDescription A description of this dynamic type.
5899 * @param binaryRepresentation A byte array containing the binary representation of this dynamic type. The array must not be modified.
5900 * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
5901 * @param auxiliaryTypes The auxiliary type required for this dynamic type.
5902 */
5903 @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not to be modified by contract")
5904 public Default(TypeDescription typeDescription,
5905 byte[] binaryRepresentation,
5906 LoadedTypeInitializer loadedTypeInitializer,
5907 List<? extends DynamicType> auxiliaryTypes) {
5908 this.typeDescription = typeDescription;
5909 this.binaryRepresentation = binaryRepresentation;
5910 this.loadedTypeInitializer = loadedTypeInitializer;
5911 this.auxiliaryTypes = auxiliaryTypes;
5912 }
5913
5914 /**
5915 * {@inheritDoc}
5916 */
5917 public TypeDescription getTypeDescription() {
5918 return typeDescription;
5919 }
5920
5921 /**
5922 * {@inheritDoc}
5923 */
5924 public Map<TypeDescription, byte[]> getAllTypes() {
5925 Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
5926 allTypes.put(typeDescription, binaryRepresentation);
5927 for (DynamicType auxiliaryType : auxiliaryTypes) {
5928 allTypes.putAll(auxiliaryType.getAllTypes());
5929 }
5930 return allTypes;
5931 }
5932
5933 /**
5934 * {@inheritDoc}
5935 */
5936 public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
5937 Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
5938 for (DynamicType auxiliaryType : auxiliaryTypes) {
5939 classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
5940 }
5941 classLoadingCallbacks.put(typeDescription, loadedTypeInitializer);
5942 return classLoadingCallbacks;
5943 }
5944
5945 /**
5946 * {@inheritDoc}
5947 */
5948 public boolean hasAliveLoadedTypeInitializers() {
5949 for (LoadedTypeInitializer loadedTypeInitializer : getLoadedTypeInitializers().values()) {
5950 if (loadedTypeInitializer.isAlive()) {
5951 return true;
5952 }
5953 }
5954 return false;
5955 }
5956
5957 /**
5958 * {@inheritDoc}
5959 */
5960 @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not to be modified by contract")
5961 public byte[] getBytes() {
5962 return binaryRepresentation;
5963 }
5964
5965 /**
5966 * {@inheritDoc}
5967 */
5968 public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
5969 Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
5970 for (DynamicType auxiliaryType : this.auxiliaryTypes) {
5971 auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
5972 auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
5973 }
5974 return auxiliaryTypes;
5975 }
5976
5977 /**
5978 * {@inheritDoc}
5979 */
5980 public Map<TypeDescription, File> saveIn(File folder) throws IOException {
5981 Map<TypeDescription, File> files = new HashMap<TypeDescription, File>();
5982 File target = new File(folder, typeDescription.getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
5983 if (target.getParentFile() != null && !target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
5984 throw new IllegalArgumentException("Could not create directory: " + target.getParentFile());
5985 }
5986 OutputStream outputStream = new FileOutputStream(target);
5987 try {
5988 outputStream.write(binaryRepresentation);
5989 } finally {
5990 outputStream.close();
5991 }
5992 files.put(typeDescription, target);
5993 for (DynamicType auxiliaryType : auxiliaryTypes) {
5994 files.putAll(auxiliaryType.saveIn(folder));
5995 }
5996 return files;
5997 }
5998
5999 /**
6000 * {@inheritDoc}
6001 */
6002 public File inject(File sourceJar, File targetJar) throws IOException {
6003 return sourceJar.equals(targetJar)
6004 ? inject(sourceJar)
6005 : doInject(sourceJar, targetJar);
6006 }
6007
6008 /**
6009 * {@inheritDoc}
6010 */
6011 public File inject(File jar) throws IOException {
6012 File temporary = doInject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX));
6013 boolean delete = true;
6014 try {
6015 delete = DISPATCHER.copy(temporary, jar);
6016 } finally {
6017 if (delete && !temporary.delete()) {
6018 temporary.deleteOnExit();
6019 }
6020 }
6021 return jar;
6022 }
6023
6024 /**
6025 * Injects this dynamic type into a source jar and writes the result to the target jar.
6026 *
6027 * @param sourceJar The source jar.
6028 * @param targetJar The target jar.
6029 * @return The jar file that was written to.
6030 * @throws IOException If an I/O error occurs.
6031 */
6032 private File doInject(File sourceJar, File targetJar) throws IOException {
6033 JarInputStream inputStream = new JarInputStream(new FileInputStream(sourceJar));
6034 try {
6035 if (!targetJar.isFile() && !targetJar.createNewFile()) {
6036 throw new IllegalArgumentException("Could not create file: " + targetJar);
6037 }
6038 Manifest manifest = inputStream.getManifest();
6039 JarOutputStream outputStream = manifest == null
6040 ? new JarOutputStream(new FileOutputStream(targetJar))
6041 : new JarOutputStream(new FileOutputStream(targetJar), manifest);
6042 try {
6043 Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
6044 Map<String, byte[]> files = new HashMap<String, byte[]>();
6045 for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
6046 files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
6047 }
6048 files.put(typeDescription.getInternalName() + CLASS_FILE_EXTENSION, binaryRepresentation);
6049 JarEntry jarEntry;
6050 while ((jarEntry = inputStream.getNextJarEntry()) != null) {
6051 byte[] replacement = files.remove(jarEntry.getName());
6052 if (replacement == null) {
6053 outputStream.putNextEntry(jarEntry);
6054 byte[] buffer = new byte[BUFFER_SIZE];
6055 int index;
6056 while ((index = inputStream.read(buffer)) != END_OF_FILE) {
6057 outputStream.write(buffer, FROM_BEGINNING, index);
6058 }
6059 } else {
6060 outputStream.putNextEntry(new JarEntry(jarEntry.getName()));
6061 outputStream.write(replacement);
6062 }
6063 inputStream.closeEntry();
6064 outputStream.closeEntry();
6065 }
6066 for (Map.Entry<String, byte[]> entry : files.entrySet()) {
6067 outputStream.putNextEntry(new JarEntry(entry.getKey()));
6068 outputStream.write(entry.getValue());
6069 outputStream.closeEntry();
6070 }
6071 } finally {
6072 outputStream.close();
6073 }
6074 } finally {
6075 inputStream.close();
6076 }
6077 return targetJar;
6078 }
6079
6080 /**
6081 * {@inheritDoc}
6082 */
6083 public File toJar(File file) throws IOException {
6084 Manifest manifest = new Manifest();
6085 manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
6086 return toJar(file, manifest);
6087 }
6088
6089 /**
6090 * {@inheritDoc}
6091 */
6092 public File toJar(File file, Manifest manifest) throws IOException {
6093 if (!file.isFile() && !file.createNewFile()) {
6094 throw new IllegalArgumentException("Could not create file: " + file);
6095 }
6096 JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(file), manifest);
6097 try {
6098 for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
6099 outputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
6100 outputStream.write(entry.getValue());
6101 outputStream.closeEntry();
6102 }
6103 outputStream.putNextEntry(new JarEntry(typeDescription.getInternalName() + CLASS_FILE_EXTENSION));
6104 outputStream.write(binaryRepresentation);
6105 outputStream.closeEntry();
6106 } finally {
6107 outputStream.close();
6108 }
6109 return file;
6110 }
6111
6112 /**
6113 * A dispatcher that allows for file copy operations based on NIO2 if available.
6114 */
6115 protected interface Dispatcher {
6116
6117 /**
6118 * Copies the source file to the target location.
6119 *
6120 * @param source The source file.
6121 * @param target The target file.
6122 * @return {@code true} if the source file needs to be deleted.
6123 * @throws IOException If an I/O error occurs.
6124 */
6125 boolean copy(File source, File target) throws IOException;
6126
6127 /**
6128 * An action for creating a dispatcher.
6129 */
6130 enum CreationAction implements PrivilegedAction<Dispatcher> {
6131
6132 /**
6133 * The singleton instance.
6134 */
6135 INSTANCE;
6136
6137 /**
6138 * {@inheritDoc}
6139 */
6140 @SuppressWarnings("unchecked")
6141 public Dispatcher run() {
6142 try {
6143 Class<?> path = Class.forName("java.nio.file.Path");
6144 Object[] arguments = (Object[]) Array.newInstance(Class.forName("java.nio.file.CopyOption"), 1);
6145 arguments[0] = Enum.valueOf((Class) Class.forName("java.nio.file.StandardCopyOption"), "REPLACE_EXISTING");
6146 return new ForJava7CapableVm(File.class.getMethod("toPath"),
6147 Class.forName("java.nio.file.Files").getMethod("move", path, path, arguments.getClass()),
6148 arguments);
6149 } catch (Throwable ignored) {
6150 return ForLegacyVm.INSTANCE;
6151 }
6152 }
6153 }
6154
6155 /**
6156 * A legacy dispatcher that is not capable of NIO.
6157 */
6158 enum ForLegacyVm implements Dispatcher {
6159
6160 /**
6161 * The singleton instance.
6162 */
6163 INSTANCE;
6164
6165 /**
6166 * {@inheritDoc}
6167 */
6168 public boolean copy(File source, File target) throws IOException {
6169 InputStream inputStream = new FileInputStream(source);
6170 try {
6171 OutputStream outputStream = new FileOutputStream(target);
6172 try {
6173 byte[] buffer = new byte[BUFFER_SIZE];
6174 int index;
6175 while ((index = inputStream.read(buffer)) != END_OF_FILE) {
6176 outputStream.write(buffer, FROM_BEGINNING, index);
6177 }
6178 } finally {
6179 outputStream.close();
6180 }
6181 } finally {
6182 inputStream.close();
6183 }
6184 return true;
6185 }
6186 }
6187
6188 /**
6189 * A dispatcher for VMs that are capable of NIO2.
6190 */
6191 @HashCodeAndEqualsPlugin.Enhance
6192 class ForJava7CapableVm implements Dispatcher {
6193
6194 /**
6195 * The {@code java.io.File#toPath()} method.
6196 */
6197 private final Method toPath;
6198
6199 /**
6200 * The {@code java.nio.Files#copy(Path,Path,CopyOption[])} method.
6201 */
6202 private final Method move;
6203
6204 /**
6205 * The copy options to apply.
6206 */
6207 private final Object[] copyOptions;
6208
6209 /**
6210 * Creates a new NIO2 capable dispatcher.
6211 *
6212 * @param toPath The {@code java.io.File#toPath()} method.
6213 * @param move The {@code java.nio.Files#move(Path,Path,CopyOption[])} method.
6214 * @param copyOptions The copy options to apply.
6215 */
6216 protected ForJava7CapableVm(Method toPath, Method move, Object[] copyOptions) {
6217 this.toPath = toPath;
6218 this.move = move;
6219 this.copyOptions = copyOptions;
6220 }
6221
6222 /**
6223 * {@inheritDoc}
6224 */
6225 public boolean copy(File source, File target) throws IOException {
6226 try {
6227 move.invoke(null, toPath.invoke(source), toPath.invoke(target), copyOptions);
6228 return false;
6229 } catch (IllegalAccessException exception) {
6230 throw new IllegalStateException("Cannot access NIO file copy", exception);
6231 } catch (InvocationTargetException exception) {
6232 Throwable cause = exception.getCause();
6233 if (cause instanceof IOException) {
6234 throw (IOException) cause;
6235 } else {
6236 throw new IllegalStateException("Cannot execute NIO file copy", cause);
6237 }
6238 }
6239 }
6240 }
6241 }
6242
6243 /**
6244 * A default implementation of an unloaded dynamic type.
6245 *
6246 * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6247 * type itself, an interface or the direct super class.
6248 */
6249 @HashCodeAndEqualsPlugin.Enhance
6250 public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
6251
6252 /**
6253 * The type resolution strategy to use for initializing the dynamic type.
6254 */
6255 private final TypeResolutionStrategy.Resolved typeResolutionStrategy;
6256
6257 /**
6258 * Creates a new unloaded representation of a dynamic type.
6259 *
6260 * @param typeDescription A description of this dynamic type.
6261 * @param binaryRepresentation An array of byte of the binary representation of this dynamic type.
6262 * @param loadedTypeInitializer The type initializer of this dynamic type.
6263 * @param auxiliaryTypes The auxiliary types that are required for this dynamic type.
6264 * @param typeResolutionStrategy The type resolution strategy to use for initializing the dynamic type.
6265 */
6266 public Unloaded(TypeDescription typeDescription,
6267 byte[] binaryRepresentation,
6268 LoadedTypeInitializer loadedTypeInitializer,
6269 List<? extends DynamicType> auxiliaryTypes,
6270 TypeResolutionStrategy.Resolved typeResolutionStrategy) {
6271 super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
6272 this.typeResolutionStrategy = typeResolutionStrategy;
6273 }
6274
6275 /**
6276 * {@inheritDoc}
6277 */
6278 public DynamicType.Loaded<T> load(ClassLoader classLoader) {
6279 return classLoader instanceof InjectionClassLoader && !((InjectionClassLoader) classLoader).isSealed()
6280 ? load((InjectionClassLoader) classLoader, InjectionClassLoader.Strategy.INSTANCE)
6281 : load(classLoader, ClassLoadingStrategy.Default.WRAPPER);
6282 }
6283
6284 /**
6285 * {@inheritDoc}
6286 */
6287 public <S extends ClassLoader> DynamicType.Loaded<T> load(S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
6288 return new Default.Loaded<T>(typeDescription,
6289 binaryRepresentation,
6290 loadedTypeInitializer,
6291 auxiliaryTypes,
6292 typeResolutionStrategy.initialize(this, classLoader, classLoadingStrategy));
6293 }
6294
6295 /**
6296 * {@inheritDoc}
6297 */
6298 public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
6299 return include(Arrays.asList(dynamicType));
6300 }
6301
6302 /**
6303 * {@inheritDoc}
6304 */
6305 public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
6306 return new Default.Unloaded<T>(typeDescription,
6307 binaryRepresentation,
6308 loadedTypeInitializer,
6309 CompoundList.of(auxiliaryTypes, dynamicType),
6310 typeResolutionStrategy);
6311 }
6312 }
6313
6314 /**
6315 * A default implementation of a loaded dynamic type.
6316 *
6317 * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6318 * type itself, an interface or the direct super class.
6319 */
6320 @HashCodeAndEqualsPlugin.Enhance
6321 protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
6322
6323 /**
6324 * The loaded types for the given loaded dynamic type.
6325 */
6326 private final Map<TypeDescription, Class<?>> loadedTypes;
6327
6328 /**
6329 * Creates a new representation of a loaded dynamic type.
6330 *
6331 * @param typeDescription A description of this dynamic type.
6332 * @param typeByte An array of byte of the binary representation of this dynamic type.
6333 * @param loadedTypeInitializer The type initializer of this dynamic type.
6334 * @param auxiliaryTypes The auxiliary types that are required for this dynamic type.
6335 * @param loadedTypes A map of loaded types for this dynamic type and all its auxiliary types.
6336 */
6337 protected Loaded(TypeDescription typeDescription,
6338 byte[] typeByte,
6339 LoadedTypeInitializer loadedTypeInitializer,
6340 List<? extends DynamicType> auxiliaryTypes,
6341 Map<TypeDescription, Class<?>> loadedTypes) {
6342 super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
6343 this.loadedTypes = loadedTypes;
6344 }
6345
6346 /**
6347 * {@inheritDoc}
6348 */
6349 @SuppressWarnings("unchecked")
6350 public Class<? extends T> getLoaded() {
6351 return (Class<? extends T>) loadedTypes.get(typeDescription);
6352 }
6353
6354 /**
6355 * {@inheritDoc}
6356 */
6357 public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
6358 Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(
6359 loadedTypes);
6360 loadedAuxiliaryTypes.remove(typeDescription);
6361 return loadedAuxiliaryTypes;
6362 }
6363 }
6364 }
6365 }
6366