org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.DynamicType Maven / Gradle / Ivy
package org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.ClassFileVersion;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.asm.AsmVisitorWrapper;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.build.HashCodeAndEqualsPlugin;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.annotation.AnnotationDescription;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.annotation.AnnotationList;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.annotation.AnnotationValue;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.field.FieldDescription;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.method.MethodDescription;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.method.ParameterDescription;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.method.ParameterList;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.modifier.*;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeDefinition;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeDescription;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeList;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.description.type.TypeVariableToken;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.loading.InjectionClassLoader;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.scaffold.*;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.*;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.attribute.*;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.auxiliary.AuxiliaryType;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatcher;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.LatentMatcher;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.pool.TypePool;
import org.apache.skywalking.apm.dependencies.net.bytebuddy.utility.CompoundList;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.jar.*;
import static org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatchers.*;
/**
* A dynamic type that is created at runtime, usually as the result of applying a
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.DynamicType.Builder} or as the result of an
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.auxiliary.AuxiliaryType}.
*
* Note that the {@link TypeDescription}s will represent their
* unloaded forms and therefore differ from the loaded types, especially with regards to annotations.
*/
public interface DynamicType {
/**
*
* Returns a description of this dynamic type.
*
*
* Note: This description will most likely differ from the binary representation of this type. Normally,
* annotations and intercepted methods are not added to this type description.
*
*
* @return A description of this dynamic type.
*/
TypeDescription getTypeDescription();
/**
* Returns a byte array representing this dynamic type. This byte array might be reused by this dynamic type and
* must therefore not be altered.
*
* @return A byte array of the type's binary representation.
*/
byte[] getBytes();
/**
*
* Returns a map of all auxiliary types that are required for making use of the main type.
*
*
* Note: The type descriptions will most likely differ from the binary representation of this type.
* Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
*
*
* @return A map of all auxiliary types by their descriptions to their binary representation.
*/
Map getAuxiliaryTypes();
/**
* Returns all types that are implied by this dynamic type.
*
* @return A mapping from all type descriptions, the actual type and its auxiliary types to their binary
* representation
*/
Map getAllTypes();
/**
*
* Returns a map of all loaded type initializers for the main type and all auxiliary types, if any.
*
*
* Note: The type descriptions will most likely differ from the binary representation of this type.
* Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
*
*
* @return A mapping of all types' descriptions to their loaded type initializers.
*/
Map getLoadedTypeInitializers();
/**
* Checks if a dynamic type requires some form of explicit type initialization, either for itself or for one
* of its auxiliary types, if any. This is the case when this dynamic type was defined to delegate method calls
* to a specific instance which is stored in a field of the created type. If this class serialized, it could not
* be used without its loaded type initializers since the field value represents a specific runtime context.
*
* @return {@code true} if this type requires explicit type initialization.
*/
boolean hasAliveLoadedTypeInitializers();
/**
*
* Saves a dynamic type in a given folder using the Java class file format while respecting the naming conventions
* for saving compiled Java classes. All auxiliary types, if any, are saved in the same directory. The resulting
* folder structure will resemble the structure that is required for Java run times, i.e. each folder representing
* a segment of the package name. If the specified {@code folder} does not yet exist, it is created during the
* call of this method.
*
*
* Note: The type descriptions will most likely differ from the binary representation of this type.
* Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
*
*
* @param folder The base target folder for storing this dynamic type and its auxiliary types, if any.
* @return A map of type descriptions pointing to files with their stored binary representations within {@code folder}.
* @throws IOException Thrown if the underlying file operations cause an {@code IOException}.
*/
Map saveIn(File folder) throws IOException;
/**
* Injects the types of this dynamic type into a given jar file. Any pre-existent type with the same name
* is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
* patched version with a new central directory. No directory entries are added to the generated jar.
*
* @param sourceJar The original jar file.
* @param targetJar The {@code source} jar file with the injected contents.
* @return The {@code target} jar file.
* @throws IOException If an I/O exception occurs while injecting from the source into the target.
*/
File inject(File sourceJar, File targetJar) throws IOException;
/**
* Injects the types of this dynamic type into a given jar file. Any pre-existent type with the same name
* is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
* patched version with a new central directory. No directory entries are added to the generated jar.
*
* @param jar The jar file to replace with an injected version.
* @return The {@code jar} file.
* @throws IOException If an I/O exception occurs while injecting into the jar.
*/
File inject(File jar) throws IOException;
/**
* Saves the contents of this dynamic type inside a jar file. The folder of the given {@code file} must
* exist prior to calling this method. The jar file is created with a simple manifest that only contains a version
* number. No directory entries are added to the generated jar.
*
* @param file The target file to which the jar is written to.
* @return The given {@code file}.
* @throws IOException If an I/O exception occurs while writing the file.
*/
File toJar(File file) throws IOException;
/**
* Saves the contents of this dynamic type inside a jar file. The folder of the given {@code file} must
* exist prior to calling this method. No directory entries are added to the generated jar.
*
* @param file The target file to which the jar is written to.
* @param manifest The manifest of the created jar.
* @return The given {@code file}.
* @throws IOException If an I/O exception occurs while writing the file.
*/
File toJar(File file, Manifest manifest) throws IOException;
/**
* A builder for creating a dynamic type.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface Builder {
/**
* Applies the supplied {@link AsmVisitorWrapper} onto the {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.jar.asm.ClassVisitor} during building a dynamic type.
* Using an ASM visitor, it is possible to manipulate byte code directly. Byte Buddy does not validate directly created byte code
* and it remains the responsibility of the visitor's implementor to generate legal byte code. If several ASM visitor wrappers
* are registered, they are applied on top of another in their registration order.
*
* @param asmVisitorWrapper The ASM visitor wrapper to apply during
* @return A new builder that is equal to this builder and applies the ASM visitor wrapper.
*/
Builder visit(AsmVisitorWrapper asmVisitorWrapper);
/**
* Names the dynamic type by the supplied name. The name needs to be fully qualified and in the binary format (packages separated
* by dots: {@code foo.Bar}). A type's package determines what other types are visible to the instrumented type and what methods
* can be overridden or be represented in method signatures or as field types.
*
* @param name The fully qualified name of the generated class in a binary format.
* @return A new builder that is equal to this builder but with the instrumented type named by the supplied name.
*/
Builder name(String name);
/**
* Defines the supplied modifiers as the modifiers of the instrumented type.
*
* @param modifierContributor The modifiers of the instrumented type.
* @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
*/
Builder modifiers(ModifierContributor.ForType... modifierContributor);
/**
* Defines the supplied modifiers as the modifiers of the instrumented type.
*
* @param modifierContributors The modifiers of the instrumented type.
* @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
*/
Builder modifiers(Collection modifierContributors);
/**
* Defines the supplied modifiers as the modifiers of the instrumented type.
*
* @param modifiers The modifiers of the instrumented type.
* @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
*/
Builder modifiers(int modifiers);
/**
* Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
* type's new modifiers.
*
* @param modifierContributor The modifiers of the instrumented type.
* @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
*/
Builder merge(ModifierContributor.ForType... modifierContributor);
/**
* Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
* type's new modifiers.
*
* @param modifierContributors The modifiers of the instrumented type.
* @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
*/
Builder merge(Collection modifierContributors);
/**
*
* Defines this type as a top-level type that is not declared by another type or enclosed by another member.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @return A new builder that is equal to this builder but without any declaration of a a declared or enclosed type.
*/
Builder topLevelType();
/**
*
* Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is defined
* as a local type.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The type to declare as the built type's outer type.
* @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
*/
InnerTypeDefinition.ForType innerTypeOf(Class type);
/**
*
* Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is
* defined as a local type.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The type to declare as the built type's outer type.
* @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
*/
InnerTypeDefinition.ForType innerTypeOf(TypeDescription type);
/**
*
* Defines this type as an inner type that was declared within the supplied method. Without any additional configuration, the type
* declaration is defined as a local type.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param method The method to declare as the built type's declaring method.
* @return A new builder that is equal to this builder with the supplied method as the built type's declaring method.
*/
InnerTypeDefinition innerTypeOf(Method method);
/**
*
* Defines this type as an inner type that was declared within the supplied constructor. Without any additional configuration, the type
* declaration is defined as a local type.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param constructor The constructor to declare as the built type's declaring method.
* @return A new builder that is equal to this builder with the supplied method as the built type's declaring constructor.
*/
InnerTypeDefinition innerTypeOf(Constructor constructor);
/**
*
* Defines this type as an inner type that was declared within the supplied method or constructor. Without any additional configuration,
* the type declaration is defined as a local type.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param methodDescription The method or constructor to declare as the built type's declaring method.
* @return A new builder that is equal to this builder with the supplied method as the built type's declaring method or constructor.
*/
InnerTypeDefinition innerTypeOf(MethodDescription.InDefinedShape methodDescription);
/**
*
* Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
* for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
* Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The types being declared.
* @return A new builder that is equal to this builder with the supplied types being declared by the built type.
*/
Builder declaredTypes(Class... type);
/**
*
* Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
* for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
* Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The types being declared.
* @return A new builder that is equal to this builder with the supplied types being declared by the built type.
*/
Builder declaredTypes(TypeDescription... type);
/**
*
* Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
* for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
* Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param types The types being declared.
* @return A new builder that is equal to this builder with the supplied types being declared by the built type.
*/
Builder declaredTypes(List> types);
/**
*
* Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
* for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
* Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
*
*
* Important: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
*
*
* Warning: By changing this type's declaration, any other type will not change its declaration of enclosing members or
* declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param types The types being declared.
* @return A new builder that is equal to this builder with the supplied types being declared by the built type.
*/
Builder declaredTypes(Collection types);
/**
*
* Defines this type as self-hosted, i.e. as only being a nest mate of itself.
*
*
* Important: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
*
*
* Warning: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
* Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @return A new builder that is equal to this builder but where the built type is a self-hosted nest mate.
*/
Builder noNestMate();
/**
*
* Defines this type as a nest member of the supplied type as a nest host.
*
*
* Important: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
*
*
* Warning: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
* Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The nest host.
* @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
*/
Builder nestHost(Class type);
/**
*
* Defines this type as a nest member of the supplied type as a nest host.
*
*
* Important: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
*
*
* Warning: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
* Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The nest host.
* @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
*/
Builder nestHost(TypeDescription type);
/**
*
* Defines this type as a nest host for the supplied types.
*
*
* Important: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
*
*
* Warning: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
* Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The nest members.
* @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
*/
Builder nestMembers(Class... type);
/**
*
* Defines this type as a nest host for the supplied types.
*
*
* Important: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
*
*
* Warning: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
* Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param type The nest members.
* @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
*/
Builder nestMembers(TypeDescription... type);
/**
*
* Defines this type as a nest host for the supplied types.
*
*
* Important: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
*
*
* Warning: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
* Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param types The nest members.
* @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
*/
Builder nestMembers(List> types);
/**
*
* Defines this type as a nest host for the supplied types.
*
*
* Important: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
*
*
* Warning: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
* Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
* consistent among the definitions of connected types.
*
*
* @param types The nest members.
* @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
*/
Builder nestMembers(Collection types);
/**
* Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
* any type of meta data to a type, not only Java {@link Annotation}s.
*
* @param typeAttributeAppender The type attribute appender to apply.
* @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
*/
Builder attribute(TypeAttributeAppender typeAttributeAppender);
/**
* Annotates the instrumented type with the supplied annotations.
*
* @param annotation The annotations to add to the instrumented type.
* @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
*/
Builder annotateType(Annotation... annotation);
/**
* Annotates the instrumented type with the supplied annotations.
*
* @param annotations The annotations to add to the instrumented type.
* @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
*/
Builder annotateType(List annotations);
/**
* Annotates the instrumented type with the supplied annotations.
*
* @param annotation The annotations to add to the instrumented type.
* @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
*/
Builder annotateType(AnnotationDescription... annotation);
/**
* Annotates the instrumented type with the supplied annotations.
*
* @param annotations The annotations to add to the instrumented type.
* @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
*/
Builder annotateType(Collection annotations);
/**
*
* Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
* methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
* are explicitly ignored.
*
*
* Note: This methods implements the supplied types as is, i.e. any {@link Class} values are implemented
* as raw types if they declare type variables or an owner type.
*
*
* @param interfaceType The interface types to implement.
* @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
*/
MethodDefinition.ImplementationDefinition.Optional implement(Type... interfaceType);
/**
*
* Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
* methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
* are explicitly ignored.
*
*
* Note: This methods implements the supplied types as is, i.e. any {@link Class} values are implemented
* as raw types if they declare type variables or an owner type.
*
*
* @param interfaceTypes The interface types to implement.
* @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
*/
MethodDefinition.ImplementationDefinition.Optional implement(List interfaceTypes);
/**
*
* Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
* methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
* are explicitly ignored.
*
*
* Note: This methods implements the supplied types as is, i.e. any {@link TypeDescription} values are
* implemented as raw types if they declare type variables or an owner type.
*
*
* @param interfaceType The interface types to implement.
* @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
*/
MethodDefinition.ImplementationDefinition.Optional implement(TypeDefinition... interfaceType);
/**
*
* Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
* methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
* are explicitly ignored.
*
*
* Note: This methods implements the supplied types as is, i.e. any {@link TypeDescription} values are
* implemented as raw types if they declare type variables or an owner type.
*
*
* @param interfaceTypes The interface types to implement.
* @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
*/
MethodDefinition.ImplementationDefinition.Optional implement(Collection interfaceTypes);
/**
*
* Executes the supplied byte code appender within the beginning of the instrumented type's type initializer. The
* supplied byte code appender must not return from the method. If several byte code appenders are supplied,
* they are executed within their application order.
*
*
* This method should only be used for preparing an instrumented type with a specific configuration. Normally,
* a byte code appender is applied via Byte Buddy's standard API by invoking {@link Builder#invokable(ElementMatcher)}
* using the {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.matcher.ElementMatchers#isTypeInitializer()} matcher.
*
*
* @param byteCodeAppender The byte code appender to execute within the instrumented type's type initializer.
* @return A new builder that is equal to this builder but with the supplied byte code appender being executed within
* the instrumented type's type initializer.
*/
Builder initializer(ByteCodeAppender byteCodeAppender);
/**
* Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
* type initializers are supplied, each loaded type initializer is executed in its registration order.
*
* @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
* @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
* loading the instrumented type.
*/
Builder initializer(LoadedTypeInitializer loadedTypeInitializer);
/**
* Explicitly requires another dynamic type for the creation of this type.
*
* @param type The type to require.
* @param binaryRepresentation The type's binary representation.
* @return A new builder that is equal to this builder but which explicitly requires the supplied type.
*/
Builder require(TypeDescription type, byte[] binaryRepresentation);
/**
* Explicitly requires another dynamic type for the creation of this type.
*
* @param type The type to require.
* @param binaryRepresentation The type's binary representation.
* @param typeInitializer The type's loaded type initializer.
* @return A new builder that is equal to this builder but which explicitly requires the supplied type.
*/
Builder require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
/**
* Explicitly requires other dynamic types for the creation of this type.
*
* @param auxiliaryType The required dynamic types.
* @return A new builder that is equal to this builder but which explicitly requires the supplied types.
*/
Builder require(DynamicType... auxiliaryType);
/**
* Explicitly requires other dynamic types for the creation of this type.
*
* @param auxiliaryTypes The required dynamic types.
* @return A new builder that is equal to this builder but which explicitly requires the supplied types.
*/
Builder require(Collection auxiliaryTypes);
/**
* Defines the supplied type variable without any bounds as a type variable of the instrumented type.
*
* @param symbol The type variable's symbol.
* @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
*/
TypeVariableDefinition typeVariable(String symbol);
/**
* Defines the supplied type variable with the given bound as a type variable of the instrumented type.
*
* @param symbol The type variable's symbol.
* @param bound The type variable's upper bounds. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the bound type
* should be equal to the currently instrumented type.
* @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
*/
TypeVariableDefinition typeVariable(String symbol, Type... bound);
/**
* Defines the supplied type variable with the given bound as a type variable of the instrumented type.
*
* @param symbol The type variable's symbol.
* @param bounds The type variable's upper bounds. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the bound type
* should be equal to the currently instrumented type.
* @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
*/
TypeVariableDefinition typeVariable(String symbol, List bounds);
/**
* Defines the supplied type variable with the given bound as a type variable of the instrumented type.
*
* @param symbol The type variable's symbol.
* @param bound The type variable's upper bounds. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the bound type
* should be equal to the currently instrumented type.
* @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
*/
TypeVariableDefinition typeVariable(String symbol, TypeDefinition... bound);
/**
* Defines the supplied type variable with the given bound as a type variable of the instrumented type.
*
* @param symbol The type variable's symbol.
* @param bounds The type variable's upper bounds. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the bound type
* should be equal to the currently instrumented type.
* @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
*/
TypeVariableDefinition typeVariable(String symbol, Collection bounds);
/**
* Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
*
* @param matcher The matcher to decide what type variables to transform.
* @param transformer The transformer to apply to the matched type variables.
* @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
*/
Builder transform(ElementMatcher matcher, Transformer transformer);
/**
* Defines the specified field as a field of the built dynamic type.
*
* @param name The name of the field.
* @param type The type of the field. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the field type
* should be equal to the currently instrumented type.
* @param modifierContributor The modifiers of the field.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable defineField(String name, Type type, ModifierContributor.ForField... modifierContributor);
/**
* Defines the specified field as a field of the built dynamic type.
*
* @param name The name of the field.
* @param type The type of the field. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the field type
* should be equal to the currently instrumented type.
* @param modifierContributors The modifiers of the field.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable defineField(String name, Type type, Collection modifierContributors);
/**
* Defines the specified field as a field of the built dynamic type.
*
* @param name The name of the field.
* @param type The type of the field. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the field type
* should be equal to the currently instrumented type.
* @param modifiers The modifiers of the field.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable defineField(String name, Type type, int modifiers);
/**
* Defines the specified field as a field of the built dynamic type.
*
* @param name The name of the field.
* @param type The type of the field. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the field type
* should be equal to the currently instrumented type.
* @param modifierContributor The modifiers of the field.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor);
/**
* Defines the specified field as a field of the built dynamic type.
*
* @param name The name of the field.
* @param type The type of the field. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the field type
* should be equal to the currently instrumented type.
* @param modifierContributors The modifiers of the field.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable defineField(String name, TypeDefinition type, Collection modifierContributors);
/**
* Defines the specified field as a field of the built dynamic type.
*
* @param name The name of the field.
* @param type The type of the field. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the field type
* should be equal to the currently instrumented type.
* @param modifiers The modifiers of the field.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable defineField(String name, TypeDefinition type, int modifiers);
/**
* Defines a field that is similar to the supplied field but without copying any annotations on the field.
*
* @param field The field to imitate as a field of the instrumented type.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable define(Field field);
/**
* Defines a field that is similar to the supplied field but without copying any annotations on the field.
*
* @param field The field to imitate as a field of the instrumented type.
* @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional.Valuable define(FieldDescription field);
/**
* Defines a private, static, final field for a serial version UID of the given value.
*
* @param serialVersionUid The serial version UID to define as a value.
* @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
* Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
*/
FieldDefinition.Optional serialVersionUid(long serialVersionUid);
/**
*
* Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
* default value, annotations or custom attributes.
*
*
* When a type is redefined or rebased, any annotations that the field declared previously is preserved
* as it is if Byte Buddy is configured to retain such annotations by
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
* altered, annotation retention must be disabled.
*
*
* If a field is already matched by a previously specified field matcher, the new field definition gets precedence
* over the previous definition, i.e. the previous field definition is no longer applied.
*
*
* @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
* @return A builder that allows for changing a field's definition.
*/
FieldDefinition.Valuable field(ElementMatcher matcher);
/**
*
* Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
* default value, annotations or custom attributes. Using a latent matcher gives opportunity to resolve an
* {@link ElementMatcher} based on the instrumented type before applying the matcher.
*
*
* When a type is redefined or rebased, any annotations that the field declared previously is preserved
* as it is if Byte Buddy is configured to retain such annotations by
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
* altered, annotation retention must be disabled.
*
*
* If a field is already matched by a previously specified field matcher, the new field definition gets precedence
* over the previous definition, i.e. the previous field definition is no longer applied.
*
*
* @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
* @return A builder that allows for changing a field's definition.
*/
FieldDefinition.Valuable field(LatentMatcher matcher);
/**
*
* Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
* remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
*
*
* When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
* is to be ignored, this matcher is no longer executed.
*
*
* @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
* @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
* instrumentation.
*/
Builder ignoreAlso(ElementMatcher ignoredMethods);
/**
*
* Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
* remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
* Using a latent matcher gives opportunity to resolve an {@link ElementMatcher} based on the instrumented type before applying the
* matcher.
*
*
* When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
* is to be ignored, this matcher is no longer executed.
*
*
* @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
* @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
* instrumentation.
*/
Builder ignoreAlso(LatentMatcher ignoredMethods);
/**
* Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param name The name of the method.
* @param returnType The method's return type. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the return type
* should be equal to the currently instrumented type.
* @param modifierContributor The method's modifiers.
* @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor);
/**
* Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param name The name of the method.
* @param returnType The method's return type. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the return type
* should be equal to the currently instrumented type.
* @param modifierContributors The method's modifiers.
* @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineMethod(String name, Type returnType, Collection modifierContributors);
/**
* Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param name The name of the method.
* @param returnType The method's return type. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the return type
* should be equal to the currently instrumented type.
* @param modifiers The method's modifiers.
* @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineMethod(String name, Type returnType, int modifiers);
/**
* Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param name The name of the method.
* @param returnType The method's return type. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the return type
* should be equal to the currently instrumented type.
* @param modifierContributor The method's modifiers.
* @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor);
/**
* Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param name The name of the method.
* @param returnType The method's return type. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the return type
* should be equal to the currently instrumented type.
* @param modifierContributors The method's modifiers.
* @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineMethod(String name, TypeDefinition returnType, Collection modifierContributors);
/**
* Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param name The name of the method.
* @param returnType The method's return type. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} if the return type
* should be equal to the currently instrumented type.
* @param modifiers The method's modifiers.
* @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineMethod(String name, TypeDefinition returnType, int modifiers);
/**
* Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param modifierContributor The constructor's modifiers.
* @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineConstructor(ModifierContributor.ForMethod... modifierContributor);
/**
* Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param modifierContributors The constructor's modifiers.
* @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineConstructor(Collection modifierContributors);
/**
* Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
* type variables can be defined in subsequent steps.
*
* @param modifiers The constructor's modifiers.
* @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
*/
MethodDefinition.ParameterDefinition.Initial defineConstructor(int modifiers);
/**
* Defines a method that is similar to the supplied method but without copying any annotations of the method or method parameters.
*
* @param method The method to imitate as a method of the instrumented type.
* @return A builder that allows for defining an implementation for the method.
*/
MethodDefinition.ImplementationDefinition define(Method method);
/**
* Defines a constructor that is similar to the supplied constructor but without copying any annotations of the constructor or
* constructor parameters.
*
* @param constructor The constructor to imitate as a method of the instrumented type.
* @return A builder that allows for defining an implementation for the constructor.
*/
MethodDefinition.ImplementationDefinition define(Constructor constructor);
/**
* Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
* the method/constructor or method/constructor parameters.
*
* @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
* @return A builder that allows for defining an implementation for the method or constructor.
*/
MethodDefinition.ImplementationDefinition define(MethodDescription methodDescription);
/**
* Defines a Java bean property with the specified name.
*
* @param name The name of the property.
* @param type The property type.
* @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
*/
FieldDefinition.Optional defineProperty(String name, Type type);
/**
* Defines a Java bean property with the specified name.
*
* @param name The name of the property.
* @param type The property type.
* @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
* @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
*/
FieldDefinition.Optional defineProperty(String name, Type type, boolean readOnly);
/**
* Defines a Java bean property with the specified name.
*
* @param name The name of the property.
* @param type The property type.
* @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
*/
FieldDefinition.Optional defineProperty(String name, TypeDefinition type);
/**
* Defines a Java bean property with the specified name.
*
* @param name The name of the property.
* @param type The property type.
* @param readOnly {@code true} if the property is read only, i.e. no setter should be defined and the field should be {@code final}.
* @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
*/
FieldDefinition.Optional defineProperty(String name, TypeDefinition type, boolean readOnly);
/**
*
* Matches a method that is already declared or inherited by the instrumented type. This gives opportunity to change or to
* override that method's implementation, default value, annotations or custom attributes. It is also possible to make
* a method abstract.
*
*
* When a type is redefined or rebased, any annotations that the method declared previously is preserved
* as it is if Byte Buddy is configured to retain such annotations by
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
* altered, annotation retention must be disabled.
*
*
* If a method is already matched by a previously specified matcher, the new method definition gets precedence
* over the previous definition, i.e. the previous method definition is no longer applied.
*
*
* Note that the specified definition does never apply for methods that are explicitly ignored.
*
*
* @param matcher The matcher that determines what methods are affected by the subsequent specification.
* @return A builder that allows for changing a method's or constructor's definition.
*/
MethodDefinition.ImplementationDefinition method(ElementMatcher matcher);
/**
*
* Matches a constructor that is already declared by the instrumented type. This gives opportunity to change that constructor's
* implementation, default value, annotations or custom attributes.
*
*
* When a type is redefined or rebased, any annotations that the constructor declared previously is preserved
* as it is if Byte Buddy is configured to retain such annotations by
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
* altered, annotation retention must be disabled.
*
*
* If a constructor is already matched by a previously specified matcher, the new constructor definition gets precedence
* over the previous definition, i.e. the previous constructor definition is no longer applied.
*
*
* Note that the specified definition does never apply for methods that are explicitly ignored.
*
*
* @param matcher The matcher that determines what constructors are affected by the subsequent specification.
* @return A builder that allows for changing a method's or constructor's definition.
*/
MethodDefinition.ImplementationDefinition constructor(ElementMatcher matcher);
/**
*
* Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
* opportunity to change or to override that method's or constructor's implementation, default value, annotations
* or custom attributes. It is also possible to make a method abstract.
*
*
* When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
* as it is if Byte Buddy is configured to retain such annotations by
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
* altered, annotation retention must be disabled.
*
*
* If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
* over the previous definition, i.e. the previous definition is no longer applied.
*
*
* Note that the specified definition does never apply for methods that are explicitly ignored.
*
*
* Important: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
* the type initializer might be run before Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
* responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
* executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
*
*
* @param matcher The matcher that determines what methods or constructors are affected by the subsequent specification.
* @return A builder that allows for changing a method's or constructor's definition.
*/
MethodDefinition.ImplementationDefinition invokable(ElementMatcher matcher);
/**
*
* Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
* opportunity to change or to override that method's or constructor's implementation, default value, annotations
* or custom attributes. It is also possible to make a method abstract. Using a latent matcher gives opportunity
* to resolve an {@link ElementMatcher} based on the instrumented type before applying the matcher.
*
*
* When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
* as it is if Byte Buddy is configured to retain such annotations by
* {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
* altered, annotation retention must be disabled.
*
*
* If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
* over the previous definition, i.e. the previous definition is no longer applied.
*
*
* Note that the specified definition does never apply for methods that are explicitly ignored.
*
*
* Important: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
* the type initializer might be run before Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
* responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
* executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
*
*
* @param matcher The matcher that determines what declared methods or constructors are affected by the subsequent specification.
* @return A builder that allows for changing a method's or constructor's definition.
*/
MethodDefinition.ImplementationDefinition invokable(LatentMatcher matcher);
/**
* Implements {@link Object#hashCode()} and {@link Object#equals(Object)} methods for the instrumented type if those
* methods are not declared as {@code final} by a super class. The implementations do not consider any implementations
* of a super class and compare a class field by field without considering synthetic fields.
*
* @return A new type builder that defines {@link Object#hashCode()} and {@link Object#equals(Object)} methods accordingly.
*/
Builder withHashCodeEquals();
/**
* Implements a {@link Object#toString()} method for the instrumented type if such a method is not declared as {@code final}
* by a super class. The implementation prefixes the string with the simple class name and prints each non-synthetic field's
* value after the field's name.
*
* @return A new type builder that defines {@link Object#toString()} method accordingly.
*/
Builder withToString();
/**
*
* Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
*
*
* Other than {@link DynamicType.Builder#make(TypePool)}, this method supplies a context-dependant type pool to the underlying class writer.
* Supplying a type pool only makes sense if custom byte code is created by adding a custom {@link AsmVisitorWrapper} where ASM might be
* required to compute stack map frames by processing information over any mentioned type's class hierarchy.
*
*
* The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
* {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
* executing the initializer must rely on such an initializer.
*
*
* @return An unloaded dynamic type representing the type specified by this builder.
*/
DynamicType.Unloaded make();
/**
*
* Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
*
*
* The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
* {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
* executing the initializer must rely on such an initializer.
*
*
* @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
* @return An unloaded dynamic type representing the type specified by this builder.
*/
DynamicType.Unloaded make(TypeResolutionStrategy typeResolutionStrategy);
/**
*
* Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
*
*
* The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
* {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
* executing the initializer must rely on such an initializer.
*
*
* @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
* @return An unloaded dynamic type representing the type specified by this builder.
*/
DynamicType.Unloaded make(TypePool typePool);
/**
* Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
*
* @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
* @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
* @return An unloaded dynamic type representing the type specified by this builder.
*/
DynamicType.Unloaded make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool);
/**
* An inner type definition for defining a type that is contained within another type, method or constructor.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface InnerTypeDefinition extends Builder {
/**
* Defines this inner type declaration as an anonymous type.
*
* @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
*/
Builder asAnonymousType();
/**
* An inner type definition for defining a type that is contained within another type.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface ForType extends InnerTypeDefinition {
/**
* Defines this inner type declaration as a member type.
*
* @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
*/
Builder asMemberType();
}
}
/**
* A builder for a type variable definition.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface TypeVariableDefinition extends Builder {
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
TypeVariableDefinition annotateTypeVariable(Annotation... annotation);
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
TypeVariableDefinition annotateTypeVariable(List annotations);
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
TypeVariableDefinition annotateTypeVariable(AnnotationDescription... annotation);
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
TypeVariableDefinition annotateTypeVariable(Collection annotations);
/**
* An abstract base implementation of a type variable definition.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase extends Builder.AbstractBase.Delegator implements TypeVariableDefinition {
/**
* {@inheritDoc}
*/
public TypeVariableDefinition annotateTypeVariable(Annotation... annotation) {
return annotateTypeVariable(Arrays.asList(annotation));
}
/**
* {@inheritDoc}
*/
public TypeVariableDefinition annotateTypeVariable(List annotations) {
return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
}
/**
* {@inheritDoc}
*/
public TypeVariableDefinition annotateTypeVariable(AnnotationDescription... annotation) {
return annotateTypeVariable(Arrays.asList(annotation));
}
}
}
/**
* A builder for a field definition.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface FieldDefinition {
/**
* Annotates the previously defined or matched field with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined or matched field.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched field.
*/
FieldDefinition.Optional annotateField(Annotation... annotation);
/**
* Annotates the previously defined or matched field with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined or matched field.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched field.
*/
FieldDefinition.Optional annotateField(List annotations);
/**
* Annotates the previously defined or matched field with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined or matched field.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched field.
*/
FieldDefinition.Optional annotateField(AnnotationDescription... annotation);
/**
* Annotates the previously defined or matched field with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined or matched field.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched field.
*/
FieldDefinition.Optional annotateField(Collection annotations);
/**
* Applies the supplied attribute appender factory onto the previously defined or matched field.
*
* @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
* previously defined or matched field.
* @return A new builder that is equal to this builder but with the supplied field attribute appender factory
* applied to the previously defined or matched field.
*/
FieldDefinition.Optional attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
/**
* Applies the supplied transformer onto the previously defined or matched field. The transformed
* field is written as it is and it not subject to any validations.
*
* @param transformer The transformer to apply to the previously defined or matched field.
* @return A new builder that is equal to this builder but with the supplied field transformer
* applied to the previously defined or matched field.
*/
FieldDefinition.Optional transform(Transformer transformer);
/**
* A builder for a field definition that allows for defining a value.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface Valuable extends FieldDefinition {
/**
*
* Defines the supplied {@code boolean} value as a default value of the previously defined or matched field. The value can only
* be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int}. For non-boolean
* fields, the field's value is set to {@code 0} for {@code false} or {@code 1} for {@code true}.
*
*
* Important: A default value in a Java class file defines a field's value prior to the class's initialization. This value
* is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
* the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
*
*
* @param value The value to define as a default value of the defined field.
* @return A new builder that is equal to this builder but with the given default value declared for the
* previously defined or matched field.
*/
FieldDefinition.Optional value(boolean value);
/**
*
* Defines the supplied {@code int} value as a default value of the previously defined or matched field. The value can only
* be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int} where the
* value must be within the numeric type's range. The {@code boolean} type is regarded as a numeric type with the possible
* values of {@code 0} and {@code 1} representing {@code false} and {@code true}.
*
*
* Important: A default value in a Java class file defines a field's value prior to the class's initialization. This value
* is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
* the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
*
*
* @param value The value to define as a default value of the defined field.
* @return A new builder that is equal to this builder but with the given default value declared for the
* previously defined or matched field.
*/
FieldDefinition.Optional value(int value);
/**
*
* Defines the supplied {@code long} value as a default value of the previously defined or matched field.
*
*
* Important: A default value in a Java class file defines a field's value prior to the class's initialization. This value
* is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
* the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
*
*
* @param value The value to define as a default value of the defined field.
* @return A new builder that is equal to this builder but with the given default value declared for the
* previously defined or matched field.
*/
FieldDefinition.Optional value(long value);
/**
*
* Defines the supplied {@code float} value as a default value of the previously defined or matched field.
*
*
* Important: A default value in a Java class file defines a field's value prior to the class's initialization. This value
* is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
* the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
*
*
* @param value The value to define as a default value of the defined field.
* @return A new builder that is equal to this builder but with the given default value declared for the
* previously defined or matched field.
*/
FieldDefinition.Optional value(float value);
/**
*
* Defines the supplied {@code double} value as a default value of the previously defined or matched field.
*
*
* Important: A default value in a Java class file defines a field's value prior to the class's initialization. This value
* is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
* the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
*
*
* @param value The value to define as a default value of the defined field.
* @return A new builder that is equal to this builder but with the given default value declared for the
* previously defined or matched field.
*/
FieldDefinition.Optional value(double value);
/**
*
* Defines the supplied {@link String} value as a default value of the previously defined or matched field.
*
*
* Important: A default value in a Java class file defines a field's value prior to the class's initialization. This value
* is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
* the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
*
*
* @param value The value to define as a default value of the defined field.
* @return A new builder that is equal to this builder but with the given default value declared for the
* previously defined or matched field.
*/
FieldDefinition.Optional value(String value);
}
/**
* A builder for an optional field definition.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface Optional extends FieldDefinition, Builder {
/**
* A builder for an optional field definition that allows for defining a value.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface Valuable extends FieldDefinition.Valuable, Optional {
/**
* An abstract base implementation of an optional field definition that allows for defining a value.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase extends Optional.AbstractBase implements Optional.Valuable {
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional value(boolean value) {
return defaultValue(value ? 1 : 0);
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional value(int value) {
return defaultValue(value);
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional value(long value) {
return defaultValue(value);
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional value(float value) {
return defaultValue(value);
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional value(double value) {
return defaultValue(value);
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional value(String value) {
if (value == null) {
throw new IllegalArgumentException("Cannot set null as a default value");
}
return defaultValue(value);
}
/**
* Defines the supplied value as a default value of the previously defined or matched field.
*
* @param defaultValue The value to define as a default value of the defined field.
* @return A new builder that is equal to this builder but with the given default value declared for the
* previously defined or matched field.
*/
protected abstract FieldDefinition.Optional defaultValue(Object defaultValue);
/**
* An adapter for an optional field definition that allows for defining a value.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
@HashCodeAndEqualsPlugin.Enhance
private abstract static class Adapter extends Optional.Valuable.AbstractBase {
/**
* The field attribute appender factory to apply.
*/
protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
/**
* The field transformer to apply.
*/
protected final Transformer transformer;
/**
* The field's default value or {@code null} if no value is to be defined.
*/
@HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
protected final Object defaultValue;
/**
* Creates a new field adapter.
*
* @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
* @param transformer The field transformer to apply.
* @param defaultValue The field's default value or {@code null} if no value is to be defined.
*/
protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
Transformer transformer,
Object defaultValue) {
this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
this.transformer = transformer;
this.defaultValue = defaultValue;
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked") // In absence of @SafeVarargs
public FieldDefinition.Optional transform(Transformer transformer) {
return materialize(fieldAttributeAppenderFactory, new Transformer.Compound(this.transformer, transformer), defaultValue);
}
@Override
protected FieldDefinition.Optional defaultValue(Object defaultValue) {
return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
}
/**
* Creates a new optional field definition for which all of the supplied values are represented.
*
* @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
* @param transformer The field transformer to apply.
* @param defaultValue The field's default value or {@code null} if no value is to be defined.
* @return A new field definition that represents the supplied values.
*/
protected abstract FieldDefinition.Optional materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
Transformer transformer,
Object defaultValue);
}
}
}
/**
* An abstract base implementation for an optional field definition.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase extends Builder.AbstractBase.Delegator implements FieldDefinition.Optional {
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional annotateField(Annotation... annotation) {
return annotateField(Arrays.asList(annotation));
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional annotateField(List annotations) {
return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
}
/**
* {@inheritDoc}
*/
public FieldDefinition.Optional annotateField(AnnotationDescription... annotation) {
return annotateField(Arrays.asList(annotation));
}
}
}
}
/**
* A builder for a method definition.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface MethodDefinition extends Builder {
/**
* Annotates the previously defined or matched method with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method.
*/
MethodDefinition annotateMethod(Annotation... annotation);
/**
* Annotates the previously defined or matched method with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method.
*/
MethodDefinition annotateMethod(List annotations);
/**
* Annotates the previously defined or matched method with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method.
*/
MethodDefinition annotateMethod(AnnotationDescription... annotation);
/**
* Annotates the previously defined or matched method with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method.
*/
MethodDefinition annotateMethod(Collection annotations);
/**
* Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
*
* @param index The parameter's index.
* @param annotation The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method's parameter of the given index.
*/
MethodDefinition annotateParameter(int index, Annotation... annotation);
/**
* Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
*
* @param index The parameter's index.
* @param annotations The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method's parameter of the given index.
*/
MethodDefinition annotateParameter(int index, List annotations);
/**
* Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
*
* @param index The parameter's index.
* @param annotation The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method's parameter of the given index.
*/
MethodDefinition annotateParameter(int index, AnnotationDescription... annotation);
/**
* Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
*
* @param index The parameter's index.
* @param annotations The annotations to declare on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined or matched method's parameter of the given index.
*/
MethodDefinition annotateParameter(int index, Collection annotations);
/**
* Applies the supplied method attribute appender factory onto the previously defined or matched method.
*
* @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
* previously defined or matched method.
* @return A new builder that is equal to this builder but with the supplied method attribute appender factory
* applied to the previously defined or matched method.
*/
MethodDefinition attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
/**
* Applies the supplied transformer onto the previously defined or matched method. The transformed
* method is written as it is and it not subject to any validations.
*
* @param transformer The transformer to apply to the previously defined or matched method.
* @return A new builder that is equal to this builder but with the supplied transformer
* applied to the previously defined or matched method.
*/
MethodDefinition transform(Transformer transformer);
/**
* A builder for a method definition with a receiver type.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface ReceiverTypeDefinition extends MethodDefinition {
/**
* Defines the supplied (annotated) receiver type for the previously defined or matched method.
*
* @param receiverType The receiver type to define on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given type defined as the
* receiver on the previously defined or matched method.
*/
MethodDefinition receiverType(AnnotatedElement receiverType);
/**
* Defines the supplied (annotated) receiver type for the previously defined or matched method.
*
* @param receiverType The receiver type to define on the previously defined or matched method.
* @return A new builder that is equal to this builder but with the given type defined as the
* receiver on the previously defined or matched method.
*/
MethodDefinition receiverType(TypeDescription.Generic receiverType);
/**
* An abstract base implementation of a method definition that can accept a receiver type.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase extends MethodDefinition.AbstractBase implements ReceiverTypeDefinition {
/**
* {@inheritDoc}
*/
public MethodDefinition receiverType(AnnotatedElement receiverType) {
return receiverType(TypeDescription.Generic.AnnotationReader.DISPATCHER.resolve(receiverType));
}
}
}
/**
* A builder for defining an implementation of a method.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface ImplementationDefinition {
/**
* Implements the previously defined or matched method by the supplied implementation. A method interception
* is typically implemented in one of the following ways:
*
* - If a method is declared by the instrumented type and the type builder creates a subclass or redefinition,
* any preexisting method is replaced by the given implementation. Any previously defined implementation is lost.
* - If a method is declared by the instrumented type and the type builder creates a rebased version of the
* instrumented type, the original method is preserved within a private, synthetic method within the instrumented
* type. The original method therefore remains invokeable and is treated as the direct super method of the new
* method. When rebasing a type, it therefore becomes possible to invoke a non-virtual method's super method
* when a preexisting method body is replaced.
* - If a virtual method is inherited from a super type, it is overridden. The overridden method is available
* for super method invocation.
*
*
* @param implementation The implementation for implementing the previously defined or matched method.
* @return A new builder where the previously defined or matched method is implemented by the
* supplied implementation.
*/
MethodDefinition.ReceiverTypeDefinition intercept(Implementation implementation);
/**
* Defines the previously defined or matched method to be {@code abstract}.
*
* @return A new builder where the previously defined or matched method is implemented to be abstract.
*/
MethodDefinition.ReceiverTypeDefinition withoutCode();
/**
* Defines the previously defined or matched method to return the supplied value as an annotation default value. The
* value must be supplied in its unloaded state, i.e. enumerations as {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.description.enumeration.EnumerationDescription},
* types as {@link TypeDescription} and annotations as {@link AnnotationDescription}. For supplying loaded types, use
* {@link ImplementationDefinition#defaultValue(Object, Class)} must be used.
*
* @param annotationValue The value to be defined as a default value.
* @return A builder where the previously defined or matched method is implemented to return an annotation default value.
*/
MethodDefinition.ReceiverTypeDefinition defaultValue(AnnotationValue annotationValue);
/**
* Defines the previously defined or matched method to return the supplied value as an annotation default value. The
* value must be supplied in its loaded state paired with the property type of the value.
*
* @param value The value to be defined as a default value.
* @param type The type of the annotation property.
* @param The type of the annotation property.
* @return A builder where the previously defined or matched method is implemented to return an annotation default value.
*/
MethodDefinition.ReceiverTypeDefinition defaultValue(W value, Class type);
/**
* A builder for optionally defining an implementation of a method.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface Optional extends ImplementationDefinition, Builder {
/* union type */
}
/**
* An abstract base implementation for a builder optionally defining an implementation of a method.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase implements ImplementationDefinition {
/**
* {@inheritDoc}
*/
public MethodDefinition.ReceiverTypeDefinition defaultValue(W value, Class type) {
return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
}
}
}
/**
* A builder for defining an implementation of a method and optionally defining a type variable.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface TypeVariableDefinition extends ImplementationDefinition {
/**
* Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
*
* @param symbol The symbol of the type variable.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
*/
Annotatable typeVariable(String symbol);
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param symbol The symbol of the type variable.
* @param bound The bounds of the type variables. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} for any type
* if a bound type should be equal to the currently instrumented type.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
*/
Annotatable typeVariable(String symbol, Type... bound);
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param symbol The symbol of the type variable.
* @param bounds The bounds of the type variables. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} for any type
* if a bound type should be equal to the currently instrumented type.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
*/
Annotatable typeVariable(String symbol, List bounds);
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param symbol The symbol of the type variable.
* @param bound The bounds of the type variables. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} for any type
* if a bound type should be equal to the currently instrumented type.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
*/
Annotatable typeVariable(String symbol, TypeDefinition... bound);
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param symbol The symbol of the type variable.
* @param bounds The bounds of the type variables. Can also be {@link org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.TargetType} for any type
* if a bound type should be equal to the currently instrumented type.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
*/
Annotatable typeVariable(String symbol, Collection bounds);
/**
* A builder for optionally defining an annotation for a type variable.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface Annotatable extends TypeVariableDefinition {
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
Annotatable annotateTypeVariable(Annotation... annotation);
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
Annotatable annotateTypeVariable(List annotations);
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotation The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
Annotatable annotateTypeVariable(AnnotationDescription... annotation);
/**
* Annotates the previously defined type variable with the supplied annotations.
*
* @param annotations The annotations to declare on the previously defined type variable.
* @return A new builder that is equal to this builder but with the given annotations declared
* on the previously defined type variable.
*/
Annotatable annotateTypeVariable(Collection annotations);
/**
* An abstract base implementation for defining an annotation on a parameter.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase extends TypeVariableDefinition.AbstractBase implements Annotatable {
/**
* {@inheritDoc}
*/
public TypeVariableDefinition.Annotatable annotateTypeVariable(Annotation... annotation) {
return annotateTypeVariable(Arrays.asList(annotation));
}
/**
* {@inheritDoc}
*/
public TypeVariableDefinition.Annotatable annotateTypeVariable(List annotations) {
return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
}
/**
* {@inheritDoc}
*/
public TypeVariableDefinition.Annotatable annotateTypeVariable(AnnotationDescription... annotation) {
return annotateTypeVariable(Arrays.asList(annotation));
}
/**
* An adapter implementation for an annotatable type variable definition.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
protected abstract static class Adapter extends TypeVariableDefinition.Annotatable.AbstractBase {
/**
* {@inheritDoc}
*/
public TypeVariableDefinition.Annotatable typeVariable(String symbol, Collection bounds) {
return materialize().typeVariable(symbol, bounds);
}
/**
* {@inheritDoc}
*/
public MethodDefinition.ReceiverTypeDefinition intercept(Implementation implementation) {
return materialize().intercept(implementation);
}
/**
* {@inheritDoc}
*/
public MethodDefinition.ReceiverTypeDefinition withoutCode() {
return materialize().withoutCode();
}
/**
* {@inheritDoc}
*/
public MethodDefinition.ReceiverTypeDefinition defaultValue(AnnotationValue annotationValue) {
return materialize().defaultValue(annotationValue);
}
/**
* {@inheritDoc}
*/
public MethodDefinition.ReceiverTypeDefinition defaultValue(V value, Class type) {
return materialize().defaultValue(value, type);
}
/**
* Materializes this instance as a parameter definition with the currently defined properties.
*
* @return A parameter definition with the currently defined properties.
*/
protected abstract MethodDefinition.ParameterDefinition materialize();
}
}
}
/**
* An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase extends ImplementationDefinition.AbstractBase implements TypeVariableDefinition {
/**
* {@inheritDoc}
*/
public Annotatable typeVariable(String symbol) {
return typeVariable(symbol, Collections.singletonList(Object.class));
}
/**
* {@inheritDoc}
*/
public Annotatable typeVariable(String symbol, Type... bound) {
return typeVariable(symbol, Arrays.asList(bound));
}
/**
* {@inheritDoc}
*/
public Annotatable typeVariable(String symbol, List bounds) {
return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
}
/**
* {@inheritDoc}
*/
public Annotatable typeVariable(String symbol, TypeDefinition... bound) {
return typeVariable(symbol, Arrays.asList(bound));
}
}
}
/**
* A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
interface ExceptionDefinition extends TypeVariableDefinition {
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param type The type of the exception being declared by the currently defined method.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
*/
ExceptionDefinition throwing(Type... type);
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param types The type of the exception being declared by the currently defined method.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
*/
ExceptionDefinition throwing(List types);
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param type The type of the exception being declared by the currently defined method.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
*/
ExceptionDefinition throwing(TypeDefinition... type);
/**
* Defines a method variable to be declared by the currently defined method.
*
* @param types The type of the exception being declared by the currently defined method.
* @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
*/
ExceptionDefinition throwing(Collection types);
/**
* An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
*
* @param A loaded type that the built type is guaranteed to be a subclass of.
*/
abstract class AbstractBase