/*
 * Copyright 2014 - 2020 Rafael Winterhalter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.bytebuddy.dynamic.scaffold;

import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.annotation.AnnotationValue;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.description.modifier.ModifierContributor;
import net.bytebuddy.description.type.*;
import net.bytebuddy.dynamic.TargetType;
import net.bytebuddy.dynamic.Transformer;
import net.bytebuddy.implementation.LoadedTypeInitializer;
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.utility.CompoundList;
import net.bytebuddy.utility.JavaType;

import java.lang.annotation.ElementType;
import java.util.*;

import static net.bytebuddy.matcher.ElementMatchers.is;
import static net.bytebuddy.matcher.ElementMatchers.not;

Implementations of this interface represent an instrumented type that is subject to change. Implementations should however be immutable and return new instance when its builder methods are invoked.
/** * Implementations of this interface represent an instrumented type that is subject to change. Implementations * should however be immutable and return new instance when its builder methods are invoked. */
public interface InstrumentedType extends TypeDescription {
Creates a new instrumented type that includes a new field.
Params:
  • token – A token that represents the field's shape.
Returns:A new instrumented type that is equal to this instrumented type but with the additional field.
/** * Creates a new instrumented type that includes a new field. * * @param token A token that represents the field's shape. * @return A new instrumented type that is equal to this instrumented type but with the additional field. */
InstrumentedType withField(FieldDescription.Token token);
Creates a new instrumented type that includes a new method or constructor.
Params:
  • token – A token that represents the method's shape.
Returns:A new instrumented type that is equal to this instrumented type but with the additional method.
/** * Creates a new instrumented type that includes a new method or constructor. * * @param token A token that represents the method's shape. * @return A new instrumented type that is equal to this instrumented type but with the additional method. */
InstrumentedType withMethod(MethodDescription.Token token);
Creates a new instrumented type that includes a new record component.
Params:
  • token – A token that represents the record component's shape.
Returns:A new instrumented type that is equal to this instrumented type but with the additional record component.
/** * Creates a new instrumented type that includes a new record component. * * @param token A token that represents the record component's shape. * @return A new instrumented type that is equal to this instrumented type but with the additional record component. */
InstrumentedType withRecordComponent(RecordComponentDescription.Token token);
Creates a new instrumented type with changed modifiers.
Params:
  • modifiers – The instrumented type's modifiers.
Returns:A new instrumented type that is equal to this instrumented type but with the given modifiers.
/** * Creates a new instrumented type with changed modifiers. * * @param modifiers The instrumented type's modifiers. * @return A new instrumented type that is equal to this instrumented type but with the given modifiers. */
InstrumentedType withModifiers(int modifiers);
Creates a new instrumented type with the given interfaces implemented.
Params:
  • interfaceTypes – The interface types to implement.
Returns:A new instrumented type that is equal to this instrumented type but with the given interfaces implemented.
/** * Creates a new instrumented type with the given interfaces implemented. * * @param interfaceTypes The interface types to implement. * @return A new instrumented type that is equal to this instrumented type but with the given interfaces implemented. */
InstrumentedType withInterfaces(TypeList.Generic interfaceTypes);
Creates a new instrumented type with the given type variable defined.
Params:
  • typeVariable – The type variable to declare.
Returns:A new instrumented type that is equal to this instrumented type but with the given type variable declared.
/** * Creates a new instrumented type with the given type variable defined. * * @param typeVariable The type variable to declare. * @return A new instrumented type that is equal to this instrumented type but with the given type variable declared. */
InstrumentedType withTypeVariable(TypeVariableToken typeVariable);
Creates a new instrumented type with the given annotations.
Params:
  • annotationDescriptions – The annotations to add to the instrumented type.
Returns:A new instrumented type that is equal to this instrumented type but annotated with the given annotations
/** * Creates a new instrumented type with the given annotations. * * @param annotationDescriptions The annotations to add to the instrumented type. * @return A new instrumented type that is equal to this instrumented type but annotated with the given annotations */
InstrumentedType withAnnotations(List<? extends AnnotationDescription> annotationDescriptions);
Creates a new instrumented type with the supplied nest host. An instrumented type can be its own nest host. Setting a nest host removes all nest members from the instrumented type.
Params:
  • nestHost – The nest host of the created instrumented type.
Returns:A new instrumented type with the supplied type as its nest host.
/** * Creates a new instrumented type with the supplied nest host. An instrumented type can be its own nest host. * Setting a nest host removes all nest members from the instrumented type. * * @param nestHost The nest host of the created instrumented type. * @return A new instrumented type with the supplied type as its nest host. */
InstrumentedType withNestHost(TypeDescription nestHost);
Creates a new instrumented types with the supplied nest members added to this instrumented type. The instrumented type is defined as a nest host if this method is invoked. Any previous nest members are prepended to the supplied types.
Params:
  • nestMembers – The nest members to add to the created instrumented type.
Returns:A new instrumented type that applies the supplied nest members.
/** * Creates a new instrumented types with the supplied nest members added to this instrumented type. The instrumented * type is defined as a nest host if this method is invoked. Any previous nest members are prepended to the supplied types. * * @param nestMembers The nest members to add to the created instrumented type. * @return A new instrumented type that applies the supplied nest members. */
InstrumentedType withNestMembers(TypeList nestMembers);
Creates a new instrumented type with the supplied enclosing type.
Params:
  • enclosingType – The type to define as the created instrumented type's enclosing type.
Returns:A new instrumented type with the supplied type as its enclosing type.
/** * Creates a new instrumented type with the supplied enclosing type. * * @param enclosingType The type to define as the created instrumented type's enclosing type. * @return A new instrumented type with the supplied type as its enclosing type. */
InstrumentedType withEnclosingType(TypeDescription enclosingType);
Creates a new instrumented type with the supplied enclosing method.
Params:
  • enclosingMethod – The method to define as the created instrumented type's enclosing method.
Returns:A new instrumented type with the supplied method as its enclosing method.
/** * Creates a new instrumented type with the supplied enclosing method. * * @param enclosingMethod The method to define as the created instrumented type's enclosing method. * @return A new instrumented type with the supplied method as its enclosing method. */
InstrumentedType withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod);
Creates a new instrumented type that is declared by the supplied type..
Params:
  • declaringType – The type that declares the instrumented type.
Returns:A new instrumented type that is declared by the instrumented type.
/** * Creates a new instrumented type that is declared by the supplied type.. * * @param declaringType The type that declares the instrumented type. * @return A new instrumented type that is declared by the instrumented type. */
InstrumentedType withDeclaringType(TypeDescription declaringType);
Creates a new instrumented type that indicates that it declared the supplied types.
Params:
  • declaredTypes – The types to add to the created instrumented type as declared types.
Returns:A new instrumented type that indicates that it has declared the supplied types.
/** * Creates a new instrumented type that indicates that it declared the supplied types. * * @param declaredTypes The types to add to the created instrumented type as declared types. * @return A new instrumented type that indicates that it has declared the supplied types. */
InstrumentedType withDeclaredTypes(TypeList declaredTypes);
Creates a new instrumented type that includes the supplied permitted subclasses.
Params:
  • permittedSubclasses – A list of permitted subclasses to include.
Returns:A new instrumented type that includes the supplied permitted subclasses.
/** * Creates a new instrumented type that includes the supplied permitted subclasses. * * @param permittedSubclasses A list of permitted subclasses to include. * @return A new instrumented type that includes the supplied permitted subclasses. */
InstrumentedType withPermittedSubclasses(TypeList permittedSubclasses);
Creates a new instrumented type that indicates that is defined as a local class. Setting this property resets the anonymous class property.
Params:
  • localClass – true if the instrumented type is supposed to be treated as a local class.
Returns:A new instrumented type that is treated as a local class.
/** * Creates a new instrumented type that indicates that is defined as a local class. Setting this property * resets the anonymous class property. * * @param localClass {@code true} if the instrumented type is supposed to be treated as a local class. * @return A new instrumented type that is treated as a local class. */
InstrumentedType withLocalClass(boolean localClass);
Creates a new instrumented type that indicates that it is defined as an anonymous class. Setting this property resets the local class property.
Params:
  • anonymousClass – true if the instrumented type is supposed to be treated as an anonymous class.
Returns:A new instrumented type that is treated as an anonymous class.
/** * Creates a new instrumented type that indicates that it is defined as an anonymous class. Setting this property * resets the local class property. * * @param anonymousClass {@code true} if the instrumented type is supposed to be treated as an anonymous class. * @return A new instrumented type that is treated as an anonymous class. */
InstrumentedType withAnonymousClass(boolean anonymousClass);
Creates a new instrumented type that indicates that it defined as a record type. Setting this property to false removes all record components.
Params:
  • record – true if the instrumented type is supposed to be a record.
Returns:A new instrumented type that is defined as a record.
/** * Creates a new instrumented type that indicates that it defined as a record type. Setting this property to false * removes all record components. * * @param record {@code true} if the instrumented type is supposed to be a record. * @return A new instrumented type that is defined as a record. */
InstrumentedType withRecord(boolean record);
Creates a new instrumented type that indicates that it defined as a sealed type.
Params:
  • sealed – true if the instrumented type is supposed to be sealed.
Returns:A new instrumented type that is defined as a sealed type if any permitted subclasses are set.
/** * Creates a new instrumented type that indicates that it defined as a sealed type. * * @param sealed {@code true} if the instrumented type is supposed to be sealed. * @return A new instrumented type that is defined as a sealed type if any permitted subclasses are set. */
InstrumentedType withSealed(boolean sealed);
Creates a new instrumented type that includes the given LoadedTypeInitializer.
Params:
  • loadedTypeInitializer – The type initializer to include.
Returns:A new instrumented type that is equal to this instrumented type but with the additional type initializer.
/** * Creates a new instrumented type that includes the given {@link net.bytebuddy.implementation.LoadedTypeInitializer}. * * @param loadedTypeInitializer The type initializer to include. * @return A new instrumented type that is equal to this instrumented type but with the additional type initializer. */
InstrumentedType withInitializer(LoadedTypeInitializer loadedTypeInitializer);
Creates a new instrumented type that executes the given initializer in the instrumented type's type initializer.
Params:
  • byteCodeAppender – The byte code to add to the type initializer.
Returns:A new instrumented type that is equal to this instrumented type but with the given stack manipulation attached to its type initializer.
/** * Creates a new instrumented type that executes the given initializer in the instrumented type's * type initializer. * * @param byteCodeAppender The byte code to add to the type initializer. * @return A new instrumented type that is equal to this instrumented type but with the given stack manipulation * attached to its type initializer. */
InstrumentedType withInitializer(ByteCodeAppender byteCodeAppender);
Returns the LoadedTypeInitializers that were registered for this instrumented type.
Returns:The registered loaded type initializers for this instrumented type.
/** * Returns the {@link net.bytebuddy.implementation.LoadedTypeInitializer}s that were registered * for this instrumented type. * * @return The registered loaded type initializers for this instrumented type. */
LoadedTypeInitializer getLoadedTypeInitializer();
Returns this instrumented type's type initializer.
Returns:This instrumented type's type initializer.
/** * Returns this instrumented type's type initializer. * * @return This instrumented type's type initializer. */
TypeInitializer getTypeInitializer();
Validates the instrumented type to define a legal Java type.
Returns:This instrumented type as a non-modifiable type description.
/** * Validates the instrumented type to define a legal Java type. * * @return This instrumented type as a non-modifiable type description. */
TypeDescription validated();
Implementations represent an InstrumentedType with a flexible name.
/** * Implementations represent an {@link InstrumentedType} with a flexible name. */
interface WithFlexibleName extends InstrumentedType {
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withField(FieldDescription.Token token);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withMethod(MethodDescription.Token token);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withRecordComponent(RecordComponentDescription.Token token);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withModifiers(int modifiers);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withNestHost(TypeDescription nestHost);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withNestMembers(TypeList nestMembers);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withEnclosingType(TypeDescription enclosingType);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withDeclaringType(TypeDescription declaringType);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withDeclaredTypes(TypeList declaredTypes);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withPermittedSubclasses(TypeList permittedSubclasses);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withLocalClass(boolean localClass);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withAnonymousClass(boolean anonymousClass);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withRecord(boolean record);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withSealed(boolean sealed);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withTypeVariable(TypeVariableToken typeVariable);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withAnnotations(List<? extends AnnotationDescription> annotationDescriptions);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer);
{@inheritDoc}
/** * {@inheritDoc} */
WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender);
Creates a new instrumented type with a changed name.
Params:
  • name – The name of the instrumented type.
Returns:A new instrumented type that has the given name.
/** * Creates a new instrumented type with a changed name. * * @param name The name of the instrumented type. * @return A new instrumented type that has the given name. */
WithFlexibleName withName(String name);
Applies a transformation onto all existing type variables of this instrumented type. A transformation is potentially unsafe and it is the responsibility of the supplier to return a valid type variable token from the transformer.
Params:
  • matcher – The matcher to decide what type variables to transform.
  • transformer – The transformer to apply on all matched type variables.
Returns:A new instrumented type with all matched type variables transformed.
/** * Applies a transformation onto all existing type variables of this instrumented type. A transformation is potentially unsafe * and it is the responsibility of the supplier to return a valid type variable token from the transformer. * * @param matcher The matcher to decide what type variables to transform. * @param transformer The transformer to apply on all matched type variables. * @return A new instrumented type with all matched type variables transformed. */
WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer); }
Implementations are able to prepare an InstrumentedType.
/** * Implementations are able to prepare an {@link InstrumentedType}. */
interface Prepareable {
Prepares a given instrumented type.
Params:
  • instrumentedType – The instrumented type in its current form.
Returns:The prepared instrumented type.
/** * Prepares a given instrumented type. * * @param instrumentedType The instrumented type in its current form. * @return The prepared instrumented type. */
InstrumentedType prepare(InstrumentedType instrumentedType); }
A factory for creating an InstrumentedType.
/** * A factory for creating an {@link InstrumentedType}. */
interface Factory {
Creates an instrumented type that represents the provided type.
Params:
  • typeDescription – The type to represent.
Returns:An appropriate instrumented type.
/** * Creates an instrumented type that represents the provided type. * * @param typeDescription The type to represent. * @return An appropriate instrumented type. */
InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription);
Creates a new instrumented type as a subclass.
Params:
  • name – The type's name.
  • modifiers – The type's modifiers.
  • superClass – The type's super class.
Returns:A new instrumented type representing a subclass of the given parameters.
/** * Creates a new instrumented type as a subclass. * * @param name The type's name. * @param modifiers The type's modifiers. * @param superClass The type's super class. * @return A new instrumented type representing a subclass of the given parameters. */
InstrumentedType.WithFlexibleName subclass(String name, int modifiers, TypeDescription.Generic superClass);
Default implementations of instrumented type factories.
/** * Default implementations of instrumented type factories. */
enum Default implements Factory {
A factory for an instrumented type that allows to modify represented types.
/** * A factory for an instrumented type that allows to modify represented types. */
MODIFIABLE {
{@inheritDoc}
/** {@inheritDoc} */
public InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription) { return new InstrumentedType.Default(typeDescription.getName(), typeDescription.getModifiers(), typeDescription.getSuperClass(), typeDescription.getTypeVariables().asTokenList(is(typeDescription)), typeDescription.getInterfaces().accept(Generic.Visitor.Substitutor.ForDetachment.of(typeDescription)), typeDescription.getDeclaredFields().asTokenList(is(typeDescription)), typeDescription.getDeclaredMethods().asTokenList(is(typeDescription)), typeDescription.getRecordComponents().asTokenList(is(typeDescription)), typeDescription.getDeclaredAnnotations(), TypeInitializer.None.INSTANCE, LoadedTypeInitializer.NoOp.INSTANCE, typeDescription.getDeclaringType(), typeDescription.getEnclosingMethod(), typeDescription.getEnclosingType(), typeDescription.getDeclaredTypes(), typeDescription.getPermittedSubclasses(), typeDescription.isAnonymousType(), typeDescription.isLocalType(), typeDescription.isRecord(), typeDescription.isNestHost() ? TargetType.DESCRIPTION : typeDescription.getNestHost(), typeDescription.isNestHost() ? typeDescription.getNestMembers().filter(not(is(typeDescription))) : Collections.<TypeDescription>emptyList()); } },
A factory for an instrumented type that does not allow to modify represented types.
/** * A factory for an instrumented type that does not allow to modify represented types. */
FROZEN {
{@inheritDoc}
/** {@inheritDoc} */
public InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription) { return new Frozen(typeDescription, LoadedTypeInitializer.NoOp.INSTANCE); } };
{@inheritDoc}
/** * {@inheritDoc} */
public InstrumentedType.WithFlexibleName subclass(String name, int modifiers, TypeDescription.Generic superClass) { return new InstrumentedType.Default(name, modifiers, superClass, Collections.<TypeVariableToken>emptyList(), Collections.<Generic>emptyList(), Collections.<FieldDescription.Token>emptyList(), Collections.<MethodDescription.Token>emptyList(), Collections.<RecordComponentDescription.Token>emptyList(), Collections.<AnnotationDescription>emptyList(), TypeInitializer.None.INSTANCE, LoadedTypeInitializer.NoOp.INSTANCE, TypeDescription.UNDEFINED, MethodDescription.UNDEFINED, TypeDescription.UNDEFINED, Collections.<TypeDescription>emptyList(), Collections.<TypeDescription>emptyList(), false, false, false, TargetType.DESCRIPTION, Collections.<TypeDescription>emptyList()); } } }
A default implementation of an instrumented type.
/** * A default implementation of an instrumented type. */
class Default extends AbstractBase.OfSimpleType implements InstrumentedType.WithFlexibleName {
A set containing all keywords of the Java programming language.
/** * A set containing all keywords of the Java programming language. */
private static final Set<String> KEYWORDS = new HashSet<String>(Arrays.asList( "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", "while" ));
The binary name of the instrumented type.
/** * The binary name of the instrumented type. */
private final String name;
The modifiers of the instrumented type.
/** * The modifiers of the instrumented type. */
private final int modifiers;
The generic super type of the instrumented type.
/** * The generic super type of the instrumented type. */
private final Generic superClass;
The instrumented type's type variables in their tokenized form.
/** * The instrumented type's type variables in their tokenized form. */
private final List<? extends TypeVariableToken> typeVariables;
A list of interfaces of the instrumented type.
/** * A list of interfaces of the instrumented type. */
private final List<? extends Generic> interfaceTypes;
A list of field tokens describing the fields of the instrumented type.
/** * A list of field tokens describing the fields of the instrumented type. */
private final List<? extends FieldDescription.Token> fieldTokens;
A list of method tokens describing the methods of the instrumented type.
/** * A list of method tokens describing the methods of the instrumented type. */
private final List<? extends MethodDescription.Token> methodTokens;
A list of record component tokens describing the record components of the instrumented type.
/** * A list of record component tokens describing the record components of the instrumented type. */
private final List<? extends RecordComponentDescription.Token> recordComponentTokens;
A list of annotations of the annotated type.
/** * A list of annotations of the annotated type. */
private final List<? extends AnnotationDescription> annotationDescriptions;
The type initializer of the instrumented type.
/** * The type initializer of the instrumented type. */
private final TypeInitializer typeInitializer;
The loaded type initializer of the instrumented type.
/** * The loaded type initializer of the instrumented type. */
private final LoadedTypeInitializer loadedTypeInitializer;
The declaring type of the instrumented type or null if no such type exists.
/** * The declaring type of the instrumented type or {@code null} if no such type exists. */
private final TypeDescription declaringType;
The enclosing method of the instrumented type or null if no such type exists.
/** * The enclosing method of the instrumented type or {@code null} if no such type exists. */
private final MethodDescription.InDefinedShape enclosingMethod;
The enclosing type of the instrumented type or null if no such type exists.
/** * The enclosing type of the instrumented type or {@code null} if no such type exists. */
private final TypeDescription enclosingType;
A list of types that are declared by this type.
/** * A list of types that are declared by this type. */
private final List<? extends TypeDescription> declaredTypes;
A list of permitted subclasses.
/** * A list of permitted subclasses. */
private final List<? extends TypeDescription> permittedSubclasses;
true if this type is a anonymous class.
/** * {@code true} if this type is a anonymous class. */
private final boolean anonymousClass;
true if this type is a local class.
/** * {@code true} if this type is a local class. */
private final boolean localClass;
true if this class is a record class.
/** * {@code true} if this class is a record class. */
private final boolean record;
The nest host of this instrumented type or a description of TargetType if this type is its own nest host.
/** * The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host. */
private final TypeDescription nestHost;
A list of all members of this types nest group excluding this type.
/** * A list of all members of this types nest group excluding this type. */
private final List<? extends TypeDescription> nestMembers;
Creates a new instrumented type.
Params:
  • name – The binary name of the instrumented type.
  • modifiers – The modifiers of the instrumented type.
  • typeVariables – The instrumented type's type variables in their tokenized form.
  • superClass – The generic super type of the instrumented type.
  • interfaceTypes – A list of interfaces of the instrumented type.
  • fieldTokens – A list of field tokens describing the fields of the instrumented type.
  • methodTokens – A list of method tokens describing the methods of the instrumented type.
  • recordComponentTokens – A list of record component tokens describing the record components of the instrumented type.
  • annotationDescriptions – A list of annotations of the annotated type.
  • typeInitializer – The type initializer of the instrumented type.
  • loadedTypeInitializer – The loaded type initializer of the instrumented type.
  • declaringType – The declaring type of the instrumented type or null if no such type exists.
  • enclosingMethod – The enclosing method of the instrumented type or null if no such type exists.
  • enclosingType – The enclosing type of the instrumented type or null if no such type exists.
  • declaredTypes – A list of types that are declared by this type.
  • permittedSubclasses – A list of permitted subclasses.
  • anonymousClass – true if this type is a anonymous class.
  • localClass – true if this type is a local class.
  • record – true if this type is a record class.
  • nestHost – The nest host of this instrumented type or a description of TargetType if this type is its own nest host.
  • nestMembers – A list of all members of this types nest group excluding this type.
/** * Creates a new instrumented type. * * @param name The binary name of the instrumented type. * @param modifiers The modifiers of the instrumented type. * @param typeVariables The instrumented type's type variables in their tokenized form. * @param superClass The generic super type of the instrumented type. * @param interfaceTypes A list of interfaces of the instrumented type. * @param fieldTokens A list of field tokens describing the fields of the instrumented type. * @param methodTokens A list of method tokens describing the methods of the instrumented type. * @param recordComponentTokens A list of record component tokens describing the record components of the instrumented type. * @param annotationDescriptions A list of annotations of the annotated type. * @param typeInitializer The type initializer of the instrumented type. * @param loadedTypeInitializer The loaded type initializer of the instrumented type. * @param declaringType The declaring type of the instrumented type or {@code null} if no such type exists. * @param enclosingMethod The enclosing method of the instrumented type or {@code null} if no such type exists. * @param enclosingType The enclosing type of the instrumented type or {@code null} if no such type exists. * @param declaredTypes A list of types that are declared by this type. * @param permittedSubclasses A list of permitted subclasses. * @param anonymousClass {@code true} if this type is a anonymous class. * @param localClass {@code true} if this type is a local class. * @param record {@code true} if this type is a record class. * @param nestHost The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host. * @param nestMembers A list of all members of this types nest group excluding this type. */
protected Default(String name, int modifiers, Generic superClass, List<? extends TypeVariableToken> typeVariables, List<? extends Generic> interfaceTypes, List<? extends FieldDescription.Token> fieldTokens, List<? extends MethodDescription.Token> methodTokens, List<? extends RecordComponentDescription.Token> recordComponentTokens, List<? extends AnnotationDescription> annotationDescriptions, TypeInitializer typeInitializer, LoadedTypeInitializer loadedTypeInitializer, TypeDescription declaringType, MethodDescription.InDefinedShape enclosingMethod, TypeDescription enclosingType, List<? extends TypeDescription> declaredTypes, List<? extends TypeDescription> permittedSubclasses, boolean anonymousClass, boolean localClass, boolean record, TypeDescription nestHost, List<? extends TypeDescription> nestMembers) { this.name = name; this.modifiers = modifiers; this.typeVariables = typeVariables; this.superClass = superClass; this.interfaceTypes = interfaceTypes; this.fieldTokens = fieldTokens; this.methodTokens = methodTokens; this.recordComponentTokens = recordComponentTokens; this.annotationDescriptions = annotationDescriptions; this.typeInitializer = typeInitializer; this.loadedTypeInitializer = loadedTypeInitializer; this.declaringType = declaringType; this.enclosingMethod = enclosingMethod; this.enclosingType = enclosingType; this.declaredTypes = declaredTypes; this.permittedSubclasses = permittedSubclasses; this.anonymousClass = anonymousClass; this.localClass = localClass; this.record = record; this.nestHost = nestHost; this.nestMembers = nestMembers; }
Creates a new instrumented type.
Params:
  • name – The type's name.
  • superClass – The type's super class.
  • modifierContributor – The type's modifiers.
Returns:An appropriate instrumented type.
/** * Creates a new instrumented type. * * @param name The type's name. * @param superClass The type's super class. * @param modifierContributor The type's modifiers. * @return An appropriate instrumented type. */
public static InstrumentedType of(String name, TypeDescription.Generic superClass, ModifierContributor.ForType... modifierContributor) { return of(name, superClass, ModifierContributor.Resolver.of(modifierContributor).resolve()); }
Creates a new instrumented type.
Params:
  • name – The type's name.
  • superClass – The type's super class.
  • modifiers – The type's modifiers.
Returns:An appropriate instrumented type.
/** * Creates a new instrumented type. * * @param name The type's name. * @param superClass The type's super class. * @param modifiers The type's modifiers. * @return An appropriate instrumented type. */
public static InstrumentedType of(String name, TypeDescription.Generic superClass, int modifiers) { return Factory.Default.MODIFIABLE.subclass(name, modifiers, superClass); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withModifiers(int modifiers) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withField(FieldDescription.Token token) { return new Default(this.name, modifiers, superClass, typeVariables, interfaceTypes, CompoundList.of(fieldTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))), methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withMethod(MethodDescription.Token token) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, CompoundList.of(methodTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))), recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withRecordComponent(RecordComponentDescription.Token token) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, CompoundList.of(recordComponentTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))), annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, true, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes) { return new Default(name, modifiers, superClass, typeVariables, CompoundList.of(this.interfaceTypes, interfaceTypes.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))), fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withAnnotations(List<? extends AnnotationDescription> annotationDescriptions) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, CompoundList.of(this.annotationDescriptions, annotationDescriptions), typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withNestHost(TypeDescription nestHost) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost.equals(this) ? TargetType.DESCRIPTION : nestHost, Collections.<TypeDescription>emptyList()); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withNestMembers(TypeList nestMembers) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, TargetType.DESCRIPTION, CompoundList.of(this.nestMembers, nestMembers)); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withEnclosingType(TypeDescription enclosingType) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, MethodDescription.UNDEFINED, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingMethod.getDeclaringType(), declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withDeclaringType(TypeDescription declaringType) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withDeclaredTypes(TypeList declaredTypes) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, CompoundList.of(this.declaredTypes, declaredTypes), permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withPermittedSubclasses(TypeList permittedSubclasses) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, CompoundList.of(this.permittedSubclasses, permittedSubclasses), anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withTypeVariable(TypeVariableToken typeVariable) { return new Default(name, modifiers, superClass, CompoundList.of(typeVariables, typeVariable.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))), interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withName(String name) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer) { List<TypeVariableToken> typeVariables = new ArrayList<TypeVariableToken>(this.typeVariables.size()); int index = 0; for (TypeVariableToken typeVariableToken : this.typeVariables) { typeVariables.add(matcher.matches(getTypeVariables().get(index++)) ? transformer.transform(this, typeVariableToken) : typeVariableToken); } return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withLocalClass(boolean localClass) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, false, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withAnonymousClass(boolean anonymousClass) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, false, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withRecord(boolean record) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, record ? recordComponentTokens : Collections.<RecordComponentDescription.Token>emptyList(), annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withSealed(boolean sealed) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, sealed ? permittedSubclasses : Collections.<TypeDescription>emptyList(), anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer, new LoadedTypeInitializer.Compound(this.loadedTypeInitializer, loadedTypeInitializer), declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender) { return new Default(name, modifiers, superClass, typeVariables, interfaceTypes, fieldTokens, methodTokens, recordComponentTokens, annotationDescriptions, typeInitializer.expandWith(byteCodeAppender), loadedTypeInitializer, declaringType, enclosingMethod, enclosingType, declaredTypes, permittedSubclasses, anonymousClass, localClass, record, nestHost, nestMembers); }
{@inheritDoc}
/** * {@inheritDoc} */
public LoadedTypeInitializer getLoadedTypeInitializer() { return loadedTypeInitializer; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeInitializer getTypeInitializer() { return typeInitializer; }
{@inheritDoc}
/** * {@inheritDoc} */
public MethodDescription.InDefinedShape getEnclosingMethod() { return enclosingMethod; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getEnclosingType() { return enclosingType; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList getDeclaredTypes() { return new TypeList.Explicit(declaredTypes); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isAnonymousType() { return anonymousClass; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isLocalType() { return localClass; }
{@inheritDoc}
/** * {@inheritDoc} */
public PackageDescription getPackage() { int packageIndex = name.lastIndexOf('.'); return new PackageDescription.Simple(packageIndex == -1 ? EMPTY_NAME : name.substring(0, packageIndex)); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationList getDeclaredAnnotations() { return new AnnotationList.Explicit(annotationDescriptions); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getDeclaringType() { return declaringType; }
{@inheritDoc}
/** * {@inheritDoc} */
public Generic getSuperClass() { return superClass == null ? Generic.UNDEFINED : new Generic.LazyProjection.WithResolvedErasure(superClass, Generic.Visitor.Substitutor.ForAttachment.of(this)); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getInterfaces() { return new TypeList.Generic.ForDetachedTypes.WithResolvedErasure(interfaceTypes, TypeDescription.Generic.Visitor.Substitutor.ForAttachment.of(this)); }
{@inheritDoc}
/** * {@inheritDoc} */
public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() { return new FieldList.ForTokens(this, fieldTokens); }
{@inheritDoc}
/** * {@inheritDoc} */
public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() { return new MethodList.ForTokens(this, methodTokens); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getTypeVariables() { return TypeList.Generic.ForDetachedTypes.attachVariables(this, typeVariables); }
{@inheritDoc}
/** * {@inheritDoc} */
public int getModifiers() { return modifiers; }
{@inheritDoc}
/** * {@inheritDoc} */
public String getName() { return name; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getNestHost() { return nestHost.represents(TargetType.class) ? this : nestHost; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList getNestMembers() { return nestHost.represents(TargetType.class) ? new TypeList.Explicit(CompoundList.of(this, nestMembers)) : nestHost.getNestMembers(); }
{@inheritDoc}
/** * {@inheritDoc} */
public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() { return new RecordComponentList.ForTokens(this, recordComponentTokens); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isRecord() { return record && getSuperClass().asErasure().equals(JavaType.RECORD.getTypeStub()); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList getPermittedSubclasses() { return new TypeList.Explicit(permittedSubclasses); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription validated() { if (!isValidIdentifier(getName().split("\\."))) { throw new IllegalStateException("Illegal type name: " + getName() + " for " + this); } else if ((getModifiers() & ~ModifierContributor.ForType.MASK) != EMPTY_MASK) { throw new IllegalStateException("Illegal modifiers " + getModifiers() + " for " + this); } else if (isPackageType() && getModifiers() != PackageDescription.PACKAGE_MODIFIERS) { throw new IllegalStateException("Illegal modifiers " + getModifiers() + " for package " + this); } TypeDescription.Generic superClass = getSuperClass(); if (superClass != null) { if (!superClass.accept(Generic.Visitor.Validator.SUPER_CLASS)) { throw new IllegalStateException("Illegal super class " + superClass + " for " + this); } else if (!superClass.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on super class " + superClass + " for " + this); } else if (!superClass.asErasure().isVisibleTo(this)) { throw new IllegalStateException("Invisible super type " + superClass + " for " + this); } } Set<TypeDescription> interfaceErasures = new HashSet<TypeDescription>(); for (TypeDescription.Generic interfaceType : getInterfaces()) { if (!interfaceType.accept(Generic.Visitor.Validator.INTERFACE)) { throw new IllegalStateException("Illegal interface " + interfaceType + " for " + this); } else if (!interfaceType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on interface " + interfaceType + " for " + this); } else if (!interfaceErasures.add(interfaceType.asErasure())) { throw new IllegalStateException("Already implemented interface " + interfaceType + " for " + this); } else if (!interfaceType.asErasure().isVisibleTo(this)) { throw new IllegalStateException("Invisible interface type " + interfaceType + " for " + this); } } TypeList.Generic typeVariables = getTypeVariables(); if (!typeVariables.isEmpty() && isAssignableTo(Throwable.class)) { throw new IllegalStateException("Cannot define throwable " + this + " to be generic"); } Set<String> typeVariableNames = new HashSet<String>(); for (TypeDescription.Generic typeVariable : typeVariables) { String variableSymbol = typeVariable.getSymbol(); if (!typeVariableNames.add(variableSymbol)) { throw new IllegalStateException("Duplicate type variable symbol '" + typeVariable + "' for " + this); } else if (!isValidIdentifier(variableSymbol)) { throw new IllegalStateException("Illegal type variable name '" + typeVariable + "' for " + this); } else if (!Generic.Visitor.Validator.ForTypeAnnotations.ofFormalTypeVariable(typeVariable)) { throw new IllegalStateException("Illegal type annotation on '" + typeVariable + "' for " + this); } boolean interfaceBound = false; Set<TypeDescription.Generic> bounds = new HashSet<Generic>(); for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) { if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) { throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + " for " + this); } else if (!bound.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on type variable " + bound + " for " + this); } else if (!bounds.add(bound)) { throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + " for " + this); } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) { throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + this); } interfaceBound = true; } if (!interfaceBound) { throw new IllegalStateException("Type variable " + typeVariable + " for " + this + " does not define at least one bound"); } } TypeDescription enclosingType = getEnclosingType(); if (enclosingType != null && (enclosingType.isArray() || enclosingType.isPrimitive())) { throw new IllegalStateException("Cannot define array type or primitive type " + enclosingType + " + as enclosing type for " + this); } MethodDescription.InDefinedShape enclosingMethod = getEnclosingMethod(); if (enclosingMethod != null && enclosingMethod.isTypeInitializer()) { throw new IllegalStateException("Cannot enclose type declaration in class initializer " + enclosingMethod); } TypeDescription declaringType = getDeclaringType(); if (declaringType != null) { if (declaringType.isPrimitive() || declaringType.isArray()) { throw new IllegalStateException("Cannot define array type or primitive type " + declaringType + " as declaring type for " + this); } } else if (enclosingType == null && enclosingMethod == null && (isLocalType() || isAnonymousType())) { throw new IllegalStateException("Cannot define an anonymous or local class without a declaring type for " + this); } Set<TypeDescription> declaredTypes = new HashSet<TypeDescription>(); for (TypeDescription declaredType : getDeclaredTypes()) { if (declaredType.isArray() || declaredType.isPrimitive()) { throw new IllegalStateException("Cannot define array type or primitive type " + declaredType + " + as declared type for " + this); } else if (!declaredTypes.add(declaredType)) { throw new IllegalStateException("Duplicate definition of declared type " + declaredType); } } TypeDescription nestHost = getNestHost(); if (nestHost.equals(this)) { Set<TypeDescription> nestMembers = new HashSet<TypeDescription>(); for (TypeDescription nestMember : getNestMembers()) { if (nestMember.isArray() || nestMember.isPrimitive()) { throw new IllegalStateException("Cannot define array type or primitive type " + nestMember + " + as nest member of " + this); } else if (!nestMember.isSamePackage(this)) { throw new IllegalStateException("Cannot define nest member " + nestMember + " + within different package then " + this); } else if (!nestMembers.add(nestMember)) { throw new IllegalStateException("Duplicate definition of nest member " + nestMember); } } } else if (nestHost.isArray() || nestHost.isPrimitive()) { throw new IllegalStateException("Cannot define array type or primitive type " + nestHost + " + as nest host for " + this); } else if (!nestHost.isSamePackage(this)) { throw new IllegalStateException("Cannot define nest host " + nestHost + " + within different package then " + this); } for (TypeDescription permittedSubclass : getPermittedSubclasses()) { if (!permittedSubclass.isAssignableTo(this) || permittedSubclass.equals(this)) { throw new IllegalStateException("Cannot assign permitted subclass " + permittedSubclass + " to " + this); } } Set<TypeDescription> typeAnnotationTypes = new HashSet<TypeDescription>(); for (AnnotationDescription annotationDescription : getDeclaredAnnotations()) { if (!annotationDescription.getElementTypes().contains(ElementType.TYPE) && !(isAnnotation() && annotationDescription.getElementTypes().contains(ElementType.ANNOTATION_TYPE)) && !(isPackageType() && annotationDescription.getElementTypes().contains(ElementType.PACKAGE))) { throw new IllegalStateException("Cannot add " + annotationDescription + " on " + this); } else if (!typeAnnotationTypes.add(annotationDescription.getAnnotationType())) { throw new IllegalStateException("Duplicate annotation " + annotationDescription + " for " + this); } } Set<FieldDescription.SignatureToken> fieldSignatureTokens = new HashSet<FieldDescription.SignatureToken>(); for (FieldDescription.InDefinedShape fieldDescription : getDeclaredFields()) { String fieldName = fieldDescription.getName(); if (!fieldSignatureTokens.add(fieldDescription.asSignatureToken())) { throw new IllegalStateException("Duplicate field definition for " + fieldDescription); } else if (!isValidIdentifier(fieldName)) { throw new IllegalStateException("Illegal field name for " + fieldDescription); } else if ((fieldDescription.getModifiers() & ~ModifierContributor.ForField.MASK) != EMPTY_MASK) { throw new IllegalStateException("Illegal field modifiers " + fieldDescription.getModifiers() + " for " + fieldDescription); } Generic fieldType = fieldDescription.getType(); if (!fieldType.accept(Generic.Visitor.Validator.FIELD)) { throw new IllegalStateException("Illegal field type " + fieldType + " for " + fieldDescription); } else if (!fieldType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on " + fieldType + " for " + this); } else if (!fieldDescription.isSynthetic() && !fieldType.asErasure().isVisibleTo(this)) { throw new IllegalStateException("Invisible field type " + fieldDescription.getType() + " for " + fieldDescription); } Set<TypeDescription> fieldAnnotationTypes = new HashSet<TypeDescription>(); for (AnnotationDescription annotationDescription : fieldDescription.getDeclaredAnnotations()) { if (!annotationDescription.getElementTypes().contains(ElementType.FIELD)) { throw new IllegalStateException("Cannot add " + annotationDescription + " on " + fieldDescription); } else if (!fieldAnnotationTypes.add(annotationDescription.getAnnotationType())) { throw new IllegalStateException("Duplicate annotation " + annotationDescription + " for " + fieldDescription); } } } Set<MethodDescription.SignatureToken> methodSignatureTokens = new HashSet<MethodDescription.SignatureToken>(); for (MethodDescription.InDefinedShape methodDescription : getDeclaredMethods()) { if (!methodSignatureTokens.add(methodDescription.asSignatureToken())) { throw new IllegalStateException("Duplicate method signature for " + methodDescription); } else if ((methodDescription.getModifiers() & ~ModifierContributor.ForMethod.MASK) != 0) { throw new IllegalStateException("Illegal modifiers " + methodDescription.getModifiers() + " for " + methodDescription); } else if (isInterface() && !methodDescription.isPublic() && !methodDescription.isPrivate()) { throw new IllegalStateException("Methods declared by an interface must be public or private " + methodDescription); } Set<String> methodTypeVariableNames = new HashSet<String>(); for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) { String variableSymbol = typeVariable.getSymbol(); if (!methodTypeVariableNames.add(variableSymbol)) { throw new IllegalStateException("Duplicate type variable symbol '" + typeVariable + "' for " + methodDescription); } else if (!isValidIdentifier(variableSymbol)) { throw new IllegalStateException("Illegal type variable name '" + typeVariable + "' for " + methodDescription); } else if (!Generic.Visitor.Validator.ForTypeAnnotations.ofFormalTypeVariable(typeVariable)) { throw new IllegalStateException("Illegal type annotation on '" + typeVariable + "' for " + methodDescription); } boolean interfaceBound = false; Set<TypeDescription.Generic> bounds = new HashSet<Generic>(); for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) { if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) { throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + " for " + methodDescription); } else if (!bound.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on bound " + bound + " of " + typeVariable + " for " + this); } else if (!bounds.add(bound)) { throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + " for " + methodDescription); } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) { throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + methodDescription); } interfaceBound = true; } if (!interfaceBound) { throw new IllegalStateException("Type variable " + typeVariable + " for " + methodDescription + " does not define at least one bound"); } } Generic returnType = methodDescription.getReturnType(); if (methodDescription.isTypeInitializer()) { throw new IllegalStateException("Illegal explicit declaration of a type initializer by " + this); } else if (methodDescription.isConstructor()) { if (!returnType.represents(void.class)) { throw new IllegalStateException("A constructor must return void " + methodDescription); } else if (!returnType.getDeclaredAnnotations().isEmpty()) { throw new IllegalStateException("The void non-type must not be annotated for " + methodDescription); } } else if (!isValidIdentifier(methodDescription.getInternalName())) { throw new IllegalStateException("Illegal method name " + returnType + " for " + methodDescription); } else if (!returnType.accept(Generic.Visitor.Validator.METHOD_RETURN)) { throw new IllegalStateException("Illegal return type " + returnType + " for " + methodDescription); } else if (!returnType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on return type " + returnType + " for " + methodDescription); } else if (!methodDescription.isSynthetic() && !methodDescription.getReturnType().asErasure().isVisibleTo(this)) { throw new IllegalStateException("Invisible return type " + methodDescription.getReturnType() + " for " + methodDescription); } Set<String> parameterNames = new HashSet<String>(); for (ParameterDescription.InDefinedShape parameterDescription : methodDescription.getParameters()) { Generic parameterType = parameterDescription.getType(); if (!parameterType.accept(Generic.Visitor.Validator.METHOD_PARAMETER)) { throw new IllegalStateException("Illegal parameter type of " + parameterDescription + " for " + methodDescription); } else if (!parameterType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on parameter " + parameterDescription + " for " + methodDescription); } else if (!methodDescription.isSynthetic() && !parameterType.asErasure().isVisibleTo(this)) { throw new IllegalStateException("Invisible parameter type of " + parameterDescription + " for " + methodDescription); } if (parameterDescription.isNamed()) { String parameterName = parameterDescription.getName(); if (!parameterNames.add(parameterName)) { throw new IllegalStateException("Duplicate parameter name of " + parameterDescription + " for " + methodDescription); } else if (!isValidIdentifier(parameterName)) { throw new IllegalStateException("Illegal parameter name of " + parameterDescription + " for " + methodDescription); } } if (parameterDescription.hasModifiers() && (parameterDescription.getModifiers() & ~ModifierContributor.ForParameter.MASK) != EMPTY_MASK) { throw new IllegalStateException("Illegal modifiers of " + parameterDescription + " for " + methodDescription); } Set<TypeDescription> parameterAnnotationTypes = new HashSet<TypeDescription>(); for (AnnotationDescription annotationDescription : parameterDescription.getDeclaredAnnotations()) { if (!annotationDescription.getElementTypes().contains(ElementType.PARAMETER)) { throw new IllegalStateException("Cannot add " + annotationDescription + " on " + parameterDescription); } else if (!parameterAnnotationTypes.add(annotationDescription.getAnnotationType())) { throw new IllegalStateException("Duplicate annotation " + annotationDescription + " of " + parameterDescription + " for " + methodDescription); } } } for (TypeDescription.Generic exceptionType : methodDescription.getExceptionTypes()) { if (!exceptionType.accept(Generic.Visitor.Validator.EXCEPTION)) { throw new IllegalStateException("Illegal exception type " + exceptionType + " for " + methodDescription); } else if (!exceptionType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) { throw new IllegalStateException("Illegal type annotations on " + exceptionType + " for " + methodDescription); } else if (!methodDescription.isSynthetic() && !exceptionType.asErasure().isVisibleTo(this)) { throw new IllegalStateException("Invisible exception type " + exceptionType + " for " + methodDescription); } } Set<TypeDescription> methodAnnotationTypes = new HashSet<TypeDescription>(); for (AnnotationDescription annotationDescription : methodDescription.getDeclaredAnnotations()) { if (!annotationDescription.getElementTypes().contains(methodDescription.isMethod() ? ElementType.METHOD : ElementType.CONSTRUCTOR)) { throw new IllegalStateException("Cannot add " + annotationDescription + " on " + methodDescription); } else if (!methodAnnotationTypes.add(annotationDescription.getAnnotationType())) { throw new IllegalStateException("Duplicate annotation " + annotationDescription + " for " + methodDescription); } } AnnotationValue<?, ?> defaultValue = methodDescription.getDefaultValue(); if (defaultValue != null && !methodDescription.isDefaultValue(defaultValue)) { throw new IllegalStateException("Illegal default value " + defaultValue + "for " + methodDescription); } Generic receiverType = methodDescription.getReceiverType(); if (receiverType != null && !receiverType.accept(Generic.Visitor.Validator.RECEIVER)) { throw new IllegalStateException("Illegal receiver type " + receiverType + " for " + methodDescription); } else if (methodDescription.isStatic()) { if (receiverType != null) { throw new IllegalStateException("Static method " + methodDescription + " defines a non-null receiver " + receiverType); } } else if (methodDescription.isConstructor()) { if (receiverType == null || !receiverType.asErasure().equals(enclosingType == null ? this : enclosingType)) { throw new IllegalStateException("Constructor " + methodDescription + " defines an illegal receiver " + receiverType); } } else if (/* methodDescription.isMethod() */ receiverType == null || !equals(receiverType.asErasure())) { throw new IllegalStateException("Method " + methodDescription + " defines an illegal receiver " + receiverType); } } return this; }
Checks if an array of identifiers is a valid compound Java identifier.
Params:
  • identifier – an array of potentially invalid Java identifiers.
Returns:true if all identifiers are valid and the array is not empty.
/** * Checks if an array of identifiers is a valid compound Java identifier. * * @param identifier an array of potentially invalid Java identifiers. * @return {@code true} if all identifiers are valid and the array is not empty. */
private static boolean isValidIdentifier(String[] identifier) { if (identifier.length == 0) { return false; } for (String part : identifier) { if (!isValidIdentifier(part)) { return false; } } return true; }
Checks if a Java identifier is valid.
Params:
  • identifier – The identifier to check for validity.
Returns:true if the given identifier is valid.
/** * Checks if a Java identifier is valid. * * @param identifier The identifier to check for validity. * @return {@code true} if the given identifier is valid. */
private static boolean isValidIdentifier(String identifier) { if (KEYWORDS.contains(identifier) || identifier.length() == 0 || !Character.isJavaIdentifierStart(identifier.charAt(0))) { return false; } else if (identifier.equals(PackageDescription.PACKAGE_CLASS_NAME)) { return true; } for (int index = 1; index < identifier.length(); index++) { if (!Character.isJavaIdentifierPart(identifier.charAt(index))) { return false; } } return true; } }
A frozen representation of an instrumented type of which the structure must not be modified.
/** * A frozen representation of an instrumented type of which the structure must not be modified. */
class Frozen extends AbstractBase.OfSimpleType implements InstrumentedType.WithFlexibleName {
The represented type description.
/** * The represented type description. */
private final TypeDescription typeDescription;
The type's loaded type initializer.
/** * The type's loaded type initializer. */
private final LoadedTypeInitializer loadedTypeInitializer;
Creates a new frozen representation of an instrumented type.
Params:
  • typeDescription – The represented type description.
  • loadedTypeInitializer – The type's loaded type initializer.
/** * Creates a new frozen representation of an instrumented type. * * @param typeDescription The represented type description. * @param loadedTypeInitializer The type's loaded type initializer. */
protected Frozen(TypeDescription typeDescription, LoadedTypeInitializer loadedTypeInitializer) { this.typeDescription = typeDescription; this.loadedTypeInitializer = loadedTypeInitializer; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationList getDeclaredAnnotations() { return typeDescription.getDeclaredAnnotations(); }
{@inheritDoc}
/** * {@inheritDoc} */
public int getModifiers() { return typeDescription.getModifiers(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getTypeVariables() { return typeDescription.getTypeVariables(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getName() { return typeDescription.getName(); }
{@inheritDoc}
/** * {@inheritDoc} */
public Generic getSuperClass() { return typeDescription.getSuperClass(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getInterfaces() { return typeDescription.getInterfaces(); }
{@inheritDoc}
/** * {@inheritDoc} */
public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() { return typeDescription.getDeclaredFields(); }
{@inheritDoc}
/** * {@inheritDoc} */
public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() { return typeDescription.getDeclaredMethods(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isAnonymousType() { return typeDescription.isAnonymousType(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isLocalType() { return typeDescription.isLocalType(); }
{@inheritDoc}
/** * {@inheritDoc} */
public PackageDescription getPackage() { return typeDescription.getPackage(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getEnclosingType() { return typeDescription.getEnclosingType(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getDeclaringType() { return typeDescription.getDeclaringType(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList getDeclaredTypes() { return typeDescription.getDeclaredTypes(); }
{@inheritDoc}
/** * {@inheritDoc} */
public MethodDescription.InDefinedShape getEnclosingMethod() { return typeDescription.getEnclosingMethod(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getGenericSignature() { // Embrace use of native generic signature by direct delegation. return typeDescription.getGenericSignature(); }
{@inheritDoc}
/** * {@inheritDoc} */
public int getActualModifiers(boolean superFlag) { // Embrace use of native actual modifiers by direct delegation. return typeDescription.getActualModifiers(superFlag); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getNestHost() { return typeDescription.getNestHost(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList getNestMembers() { return typeDescription.getNestMembers(); }
{@inheritDoc}
/** * {@inheritDoc} */
public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() { return typeDescription.getRecordComponents(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isRecord() { return typeDescription.isRecord(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList getPermittedSubclasses() { return typeDescription.getPermittedSubclasses(); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withField(FieldDescription.Token token) { throw new IllegalStateException("Cannot define field for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withMethod(MethodDescription.Token token) { throw new IllegalStateException("Cannot define method for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withRecordComponent(RecordComponentDescription.Token token) { throw new IllegalStateException("Cannot define record component for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withModifiers(int modifiers) { throw new IllegalStateException("Cannot change modifiers for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes) { throw new IllegalStateException("Cannot add interfaces for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withTypeVariable(TypeVariableToken typeVariable) { throw new IllegalStateException("Cannot define type variable for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withAnnotations(List<? extends AnnotationDescription> annotationDescriptions) { throw new IllegalStateException("Cannot add annotation to frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withNestHost(TypeDescription nestHost) { throw new IllegalStateException("Cannot set nest host of frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withNestMembers(TypeList nestMembers) { throw new IllegalStateException("Cannot add nest members to frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withEnclosingType(TypeDescription enclosingType) { throw new IllegalStateException("Cannot set enclosing type of frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod) { throw new IllegalStateException("Cannot set enclosing method of frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withDeclaringType(TypeDescription declaringType) { throw new IllegalStateException("Cannot add declaring type to frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withDeclaredTypes(TypeList declaredTypes) { throw new IllegalStateException("Cannot add declared types to frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withPermittedSubclasses(TypeList permittedSubclasses) { throw new IllegalStateException("Cannot add permitted subclasses to frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withLocalClass(boolean localClass) { throw new IllegalStateException("Cannot define local class state for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withAnonymousClass(boolean anonymousClass) { throw new IllegalStateException("Cannot define anonymous class state for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withRecord(boolean record) { throw new IllegalStateException("Cannot define record state for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withSealed(boolean sealed) { throw new IllegalStateException("Cannot define seal state for frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer) { return new Frozen(typeDescription, new LoadedTypeInitializer.Compound(this.loadedTypeInitializer, loadedTypeInitializer)); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender) { throw new IllegalStateException("Cannot add initializer to frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withName(String name) { throw new IllegalStateException("Cannot change name of frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer) { throw new IllegalStateException("Cannot add type variables of frozen type: " + typeDescription); }
{@inheritDoc}
/** * {@inheritDoc} */
public LoadedTypeInitializer getLoadedTypeInitializer() { return loadedTypeInitializer; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeInitializer getTypeInitializer() { return TypeInitializer.None.INSTANCE; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription validated() { return typeDescription; } } }