/*
 * Copyright 2014 - 2019 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.description.method;

import net.bytebuddy.build.CachedReturnPlugin;
import net.bytebuddy.description.ByteCodeElement;
import net.bytebuddy.description.ModifierReviewable;
import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.TypeVariableSource;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.annotation.AnnotationValue;
import net.bytebuddy.description.enumeration.EnumerationDescription;
import net.bytebuddy.description.modifier.ModifierContributor;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDefinition;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.TypeList;
import net.bytebuddy.description.type.TypeVariableToken;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaConstant;
import net.bytebuddy.utility.JavaType;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureWriter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericSignatureFormatError;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

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

Implementations of this interface describe a Java method, i.e. a method or a constructor. Implementations of this interface must provide meaningful equal(Object) and hashCode() implementations.
/** * Implementations of this interface describe a Java method, i.e. a method or a constructor. Implementations of this * interface must provide meaningful {@code equal(Object)} and {@code hashCode()} implementations. */
public interface MethodDescription extends TypeVariableSource, ModifierReviewable.ForMethodDescription, NamedElement.WithGenericName, ByteCodeElement, ByteCodeElement.TypeDependant<MethodDescription.InDefinedShape, MethodDescription.Token> {
The internal name of a Java constructor.
/** * The internal name of a Java constructor. */
String CONSTRUCTOR_INTERNAL_NAME = "<init>";
The internal name of a Java static initializer.
/** * The internal name of a Java static initializer. */
String TYPE_INITIALIZER_INTERNAL_NAME = "<clinit>";
The type initializer of any representation of a type initializer.
/** * The type initializer of any representation of a type initializer. */
int TYPE_INITIALIZER_MODIFIER = Opcodes.ACC_STATIC;
Represents any undefined property of a type description that is instead represented as null in order to resemble the Java reflection API which returns null and is intuitive to many Java developers.
/** * Represents any undefined property of a type description that is instead represented as {@code null} in order * to resemble the Java reflection API which returns {@code null} and is intuitive to many Java developers. */
InDefinedShape UNDEFINED = null;
Returns the return type of the described method.
Returns:The return type of the described method.
/** * Returns the return type of the described method. * * @return The return type of the described method. */
TypeDescription.Generic getReturnType();
Returns a list of this method's parameters.
Returns:A list of this method's parameters.
/** * Returns a list of this method's parameters. * * @return A list of this method's parameters. */
ParameterList<?> getParameters();
Returns the exception types of the described method.
Returns:The exception types of the described method.
/** * Returns the exception types of the described method. * * @return The exception types of the described method. */
TypeList.Generic getExceptionTypes();
Returns this method's actual modifiers as it is present in a class file, i.e. includes a flag if this method is marked Deprecated.
Returns:The method's actual modifiers.
/** * Returns this method's actual modifiers as it is present in a class file, i.e. includes a flag if this method * is marked {@link Deprecated}. * * @return The method's actual modifiers. */
int getActualModifiers();
Returns this method's actual modifiers as it is present in a class file, i.e. includes a flag if this method is marked Deprecated and adjusts the modifiers for being abstract or not.
Params:
  • manifest – true if the method should be treated as non-abstract.
Returns:The method's actual modifiers.
/** * Returns this method's actual modifiers as it is present in a class file, i.e. includes a flag if this method * is marked {@link Deprecated} and adjusts the modifiers for being abstract or not. * * @param manifest {@code true} if the method should be treated as non-abstract. * @return The method's actual modifiers. */
int getActualModifiers(boolean manifest);
Returns this method's actual modifiers as it is present in a class file, i.e. includes a flag if this method is marked Deprecated and adjusts the modifiers for being abstract or not. Additionally, this method resolves a required minimal visibility.
Params:
  • manifest – true if the method should be treated as non-abstract.
  • visibility – The minimal visibility to enforce for this method.
Returns:The method's actual modifiers.
/** * Returns this method's actual modifiers as it is present in a class file, i.e. includes a flag if this method * is marked {@link Deprecated} and adjusts the modifiers for being abstract or not. Additionally, this method * resolves a required minimal visibility. * * @param manifest {@code true} if the method should be treated as non-abstract. * @param visibility The minimal visibility to enforce for this method. * @return The method's actual modifiers. */
int getActualModifiers(boolean manifest, Visibility visibility);
Checks if this method description represents a constructor.
Returns:true if this method description represents a constructor.
/** * Checks if this method description represents a constructor. * * @return {@code true} if this method description represents a constructor. */
boolean isConstructor();
Checks if this method description represents a method, i.e. not a constructor or a type initializer.
Returns:true if this method description represents a Java method.
/** * Checks if this method description represents a method, i.e. not a constructor or a type initializer. * * @return {@code true} if this method description represents a Java method. */
boolean isMethod();
Checks if this method is a type initializer.
Returns:true if this method description represents a type initializer.
/** * Checks if this method is a type initializer. * * @return {@code true} if this method description represents a type initializer. */
boolean isTypeInitializer();
Verifies if a method description represents a given loaded method.
Params:
  • method – The method to be checked.
Returns:true if this method description represents the given loaded method.
/** * Verifies if a method description represents a given loaded method. * * @param method The method to be checked. * @return {@code true} if this method description represents the given loaded method. */
boolean represents(Method method);
Verifies if a method description represents a given loaded constructor.
Params:
  • constructor – The constructor to be checked.
Returns:true if this method description represents the given loaded constructor.
/** * Verifies if a method description represents a given loaded constructor. * * @param constructor The constructor to be checked. * @return {@code true} if this method description represents the given loaded constructor. */
boolean represents(Constructor<?> constructor);
Verifies if this method describes a virtual method, i.e. a method that is inherited by a sub type of this type.
Returns:true if this method is virtual.
/** * Verifies if this method describes a virtual method, i.e. a method that is inherited by a sub type of this type. * * @return {@code true} if this method is virtual. */
boolean isVirtual();
Returns the size of the local variable array that is required for this method, i.e. the size of all parameters if they were loaded on the stack including a reference to this if this method represented a non-static method.
Returns:The size of this method on the operand stack.
/** * Returns the size of the local variable array that is required for this method, i.e. the size of all parameters * if they were loaded on the stack including a reference to {@code this} if this method represented a non-static * method. * * @return The size of this method on the operand stack. */
int getStackSize();
Checks if this method represents a default (defender) method.
Returns:true if this method is a default method.
/** * Checks if this method represents a default (defender) method. * * @return {@code true} if this method is a default method. */
boolean isDefaultMethod();
Checks if this method can be called using the INVOKESPECIAL for a given type.
Params:
  • typeDescription – The type o
Returns:true if this method can be called using the INVOKESPECIAL instruction using the given type.
/** * Checks if this method can be called using the {@code INVOKESPECIAL} for a given type. * * @param typeDescription The type o * @return {@code true} if this method can be called using the {@code INVOKESPECIAL} instruction * using the given type. */
boolean isSpecializableFor(TypeDescription typeDescription);
Returns the method's default annotation value or null if no default value is defined for this method.
Returns:The method's default annotation value or null if no default value is defined for this method.
/** * Returns the method's default annotation value or {@code null} if no default value is defined for this method. * * @return The method's default annotation value or {@code null} if no default value is defined for this method. */
AnnotationValue<?, ?> getDefaultValue();
Returns the default value but casts it to the given type. If the type differs from the value, a ClassCastException is thrown.
Params:
  • type – The type to cast the default value to.
Type parameters:
  • <T> – The type to cast the default value to.
Returns:The casted default value.
/** * Returns the default value but casts it to the given type. If the type differs from the value, a * {@link java.lang.ClassCastException} is thrown. * * @param type The type to cast the default value to. * @param <T> The type to cast the default value to. * @return The casted default value. */
<T> T getDefaultValue(Class<T> type);
Asserts if this method is invokable on an instance of the given type, i.e. the method is an instance method or a constructor and the method is visible to the type and can be invoked on the given instance.
Params:
  • typeDescription – The type to check.
Returns:true if this method is invokable on an instance of the given type.
/** * Asserts if this method is invokable on an instance of the given type, i.e. the method is an instance method or * a constructor and the method is visible to the type and can be invoked on the given instance. * * @param typeDescription The type to check. * @return {@code true} if this method is invokable on an instance of the given type. */
boolean isInvokableOn(TypeDescription typeDescription);
Checks if this method is a valid bootstrap method for an invokedynamic call.
Returns:true if this method is a valid bootstrap method for an invokedynamic call.
/** * Checks if this method is a valid bootstrap method for an invokedynamic call. * * @return {@code true} if this method is a valid bootstrap method for an invokedynamic call. */
boolean isInvokeBootstrap();
Checks if this method is a valid bootstrap method for an invokedynamic call.
Params:
Returns:true if this method is a valid bootstrap method for an invokedynamic call.
/** * Checks if this method is a valid bootstrap method for an invokedynamic call. * * @param arguments The arguments to the bootstrap method represented by instances of primitive wrapper types, * {@link String}, {@link TypeDescription} and {@link JavaConstant} values. * @return {@code true} if this method is a valid bootstrap method for an invokedynamic call. */
boolean isInvokeBootstrap(List<?> arguments);
Checks if this method is a valid bootstrap method for an constantdynamic call.
Returns:true if this method is a valid bootstrap method for an constantdynamic call.
/** * Checks if this method is a valid bootstrap method for an constantdynamic call. * * @return {@code true} if this method is a valid bootstrap method for an constantdynamic call. */
boolean isConstantBootstrap();
Checks if this method is a valid bootstrap method for an constantdynamic call.
Params:
Returns:true if this method is a valid bootstrap method for an constantdynamic call.
/** * Checks if this method is a valid bootstrap method for an constantdynamic call. * * @param arguments The arguments to the bootstrap method represented by instances of primitive wrapper types, * {@link String}, {@link TypeDescription} and {@link JavaConstant} values. * @return {@code true} if this method is a valid bootstrap method for an constantdynamic call. */
boolean isConstantBootstrap(List<?> arguments);
Checks if this method is capable of defining a default annotation value.
Returns:true if it is possible to define a default annotation value for this method.
/** * Checks if this method is capable of defining a default annotation value. * * @return {@code true} if it is possible to define a default annotation value for this method. */
boolean isDefaultValue();
Checks if the given value can describe a default annotation value for this method.
Params:
  • annotationValue – The value that describes the default annotation value for this method.
Returns:true if the given value can describe a default annotation value for this method.
/** * Checks if the given value can describe a default annotation value for this method. * * @param annotationValue The value that describes the default annotation value for this method. * @return {@code true} if the given value can describe a default annotation value for this method. */
boolean isDefaultValue(AnnotationValue<?, ?> annotationValue);
Returns this methods receiver type. A receiver type is undefined for static methods where null is returned. Other than a receiver type that is provided by the Java reflection API, Byte Buddy is capable of extracting annotations on type parameters of receiver types when directly accessing a class file. Therefore, a receiver type might be parameterized.
Returns:This method's (annotated) receiver type.
/** * Returns this methods receiver type. A receiver type is undefined for {@code static} methods * where {@code null} is returned. Other than a receiver type that is provided by the Java reflection * API, Byte Buddy is capable of extracting annotations on type parameters of receiver types when * directly accessing a class file. Therefore, a receiver type might be parameterized. * * @return This method's (annotated) receiver type. */
TypeDescription.Generic getReceiverType();
Returns a signature token representing this method.
Returns:A signature token representing this method.
/** * Returns a signature token representing this method. * * @return A signature token representing this method. */
SignatureToken asSignatureToken();
Returns a type token that represents this method's raw return and parameter types.
Returns:A type token that represents this method's raw return and parameter types.
/** * Returns a type token that represents this method's raw return and parameter types. * * @return A type token that represents this method's raw return and parameter types. */
TypeToken asTypeToken();
Validates that the supplied type token can implement a bridge method to this method.
Params:
  • typeToken – A type token representing a potential bridge method to this method.
Returns:true if the supplied type token can represent a bridge method to this method.
/** * Validates that the supplied type token can implement a bridge method to this method. * * @param typeToken A type token representing a potential bridge method to this method. * @return {@code true} if the supplied type token can represent a bridge method to this method. */
boolean isBridgeCompatible(TypeToken typeToken);
Represents a method description in its generic shape, i.e. in the shape it is defined by a generic or raw type.
/** * Represents a method description in its generic shape, i.e. in the shape it is defined by a generic or raw type. */
interface InGenericShape extends MethodDescription {
{@inheritDoc}
/** * {@inheritDoc} */
TypeDescription.Generic getDeclaringType();
{@inheritDoc}
/** * {@inheritDoc} */
ParameterList<ParameterDescription.InGenericShape> getParameters(); }
Represents a method in its defined shape, i.e. in the form it is defined by a class without its type variables being resolved.
/** * Represents a method in its defined shape, i.e. in the form it is defined by a class without its type variables being resolved. */
interface InDefinedShape extends MethodDescription {
{@inheritDoc}
/** * {@inheritDoc} */
TypeDescription getDeclaringType();
{@inheritDoc}
/** * {@inheritDoc} */
ParameterList<ParameterDescription.InDefinedShape> getParameters();
An abstract base implementation of a method description in its defined shape.
/** * An abstract base implementation of a method description in its defined shape. */
abstract class AbstractBase extends MethodDescription.AbstractBase implements InDefinedShape {
{@inheritDoc}
/** * {@inheritDoc} */
public InDefinedShape asDefined() { return this; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReceiverType() { if (isStatic()) { return TypeDescription.Generic.UNDEFINED; } else if (isConstructor()) { TypeDescription declaringType = getDeclaringType(), enclosingDeclaringType = getDeclaringType().getEnclosingType(); if (enclosingDeclaringType == null) { return TypeDescription.Generic.OfParameterizedType.ForGenerifiedErasure.of(declaringType); } else { return declaringType.isStatic() ? enclosingDeclaringType.asGenericType() : TypeDescription.Generic.OfParameterizedType.ForGenerifiedErasure.of(enclosingDeclaringType); } } else { return TypeDescription.Generic.OfParameterizedType.ForGenerifiedErasure.of(getDeclaringType()); } } } }
An abstract base implementation of a method description.
/** * An abstract base implementation of a method description. */
abstract class AbstractBase extends TypeVariableSource.AbstractBase implements MethodDescription {
A merger of all method modifiers that are visible in the Java source code.
/** * A merger of all method modifiers that are visible in the Java source code. */
private static final int SOURCE_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED | Modifier.NATIVE;
{@inheritDoc}
/** * {@inheritDoc} */
public int getStackSize() { return getParameters().asTypeList().getStackSize() + (isStatic() ? 0 : 1); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isMethod() { return !isConstructor() && !isTypeInitializer(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isConstructor() { return CONSTRUCTOR_INTERNAL_NAME.equals(getInternalName()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isTypeInitializer() { return TYPE_INITIALIZER_INTERNAL_NAME.equals(getInternalName()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Method method) { return equals(new ForLoadedMethod(method)); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Constructor<?> constructor) { return equals(new ForLoadedConstructor(constructor)); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getName() { return isMethod() ? getInternalName() : getDeclaringType().asErasure().getName(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getActualName() { return isMethod() ? getName() : EMPTY_NAME; }
{@inheritDoc}
/** * {@inheritDoc} */
public String getDescriptor() { StringBuilder descriptor = new StringBuilder().append('('); for (TypeDescription parameterType : getParameters().asTypeList().asErasures()) { descriptor.append(parameterType.getDescriptor()); } return descriptor.append(')').append(getReturnType().asErasure().getDescriptor()).toString(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getGenericSignature() { try { SignatureWriter signatureWriter = new SignatureWriter(); boolean generic = false; for (TypeDescription.Generic typeVariable : getTypeVariables()) { signatureWriter.visitFormalTypeParameter(typeVariable.getSymbol()); boolean classBound = true; for (TypeDescription.Generic upperBound : typeVariable.getUpperBounds()) { upperBound.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(classBound ? signatureWriter.visitClassBound() : signatureWriter.visitInterfaceBound())); classBound = false; } generic = true; } for (TypeDescription.Generic parameterType : getParameters().asTypeList()) { parameterType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(signatureWriter.visitParameterType())); generic = generic || !parameterType.getSort().isNonGeneric(); } TypeDescription.Generic returnType = getReturnType(); returnType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(signatureWriter.visitReturnType())); generic = generic || !returnType.getSort().isNonGeneric(); TypeList.Generic exceptionTypes = getExceptionTypes(); if (!exceptionTypes.filter(not(ofSort(TypeDefinition.Sort.NON_GENERIC))).isEmpty()) { for (TypeDescription.Generic exceptionType : exceptionTypes) { exceptionType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(signatureWriter.visitExceptionType())); generic = generic || !exceptionType.getSort().isNonGeneric(); } } return generic ? signatureWriter.toString() : NON_GENERIC_SIGNATURE; } catch (GenericSignatureFormatError ignored) { return NON_GENERIC_SIGNATURE; } }
{@inheritDoc}
/** * {@inheritDoc} */
public int getActualModifiers() { return getModifiers() | (getDeclaredAnnotations().isAnnotationPresent(Deprecated.class) ? Opcodes.ACC_DEPRECATED : EMPTY_MASK); }
{@inheritDoc}
/** * {@inheritDoc} */
public int getActualModifiers(boolean manifest) { return manifest ? getActualModifiers() & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE) : getActualModifiers() & ~Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT; }
{@inheritDoc}
/** * {@inheritDoc} */
public int getActualModifiers(boolean manifest, Visibility visibility) { return ModifierContributor.Resolver.of(Collections.singleton(getVisibility().expandTo(visibility))).resolve(getActualModifiers(manifest)); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isVisibleTo(TypeDescription typeDescription) { return (isVirtual() || getDeclaringType().asErasure().isVisibleTo(typeDescription)) && (isPublic() || typeDescription.equals(getDeclaringType().asErasure()) || isProtected() && getDeclaringType().asErasure().isAssignableFrom(typeDescription) || !isPrivate() && typeDescription.isSamePackage(getDeclaringType().asErasure()) || isPrivate() && typeDescription.isNestMateOf(getDeclaringType().asErasure())); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isAccessibleTo(TypeDescription typeDescription) { return (isVirtual() || getDeclaringType().asErasure().isVisibleTo(typeDescription)) && (isPublic() || typeDescription.equals(getDeclaringType().asErasure()) || !isPrivate() && typeDescription.isSamePackage(getDeclaringType().asErasure())) || isPrivate() && typeDescription.isNestMateOf(getDeclaringType().asErasure()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isVirtual() { return !(isConstructor() || isPrivate() || isStatic() || isTypeInitializer()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isDefaultMethod() { return !isAbstract() && !isBridge() && getDeclaringType().isInterface(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isSpecializableFor(TypeDescription targetType) { if (isStatic()) { // Static private methods are never specializable, check static property first return false; } else if (isPrivate() || isConstructor()) { return getDeclaringType().equals(targetType); } else { return !isAbstract() && getDeclaringType().asErasure().isAssignableFrom(targetType); } }
{@inheritDoc}
/** * {@inheritDoc} */
public <T> T getDefaultValue(Class<T> type) { return type.cast(getDefaultValue()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isInvokableOn(TypeDescription typeDescription) { return !isStatic() && !isTypeInitializer() && isVisibleTo(typeDescription) && (isVirtual() ? getDeclaringType().asErasure().isAssignableFrom(typeDescription) : getDeclaringType().asErasure().equals(typeDescription)); }
Checks if this method is a bootstrap method while expecting the supplied type as a type representation.
Params:
  • typeType – The type of the bootstrap method's type representation.
Returns:true if this method is a bootstrap method assuming the supplied type representation.
/** * Checks if this method is a bootstrap method while expecting the supplied type as a type representation. * * @param typeType The type of the bootstrap method's type representation. * @return {@code true} if this method is a bootstrap method assuming the supplied type representation. */
private boolean isBootstrap(TypeDescription typeType) { TypeList parameterTypes = getParameters().asTypeList().asErasures(); switch (parameterTypes.size()) { case 0: return false; case 1: return parameterTypes.getOnly().represents(Object[].class); case 2: return JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isAssignableTo(parameterTypes.get(0)) && parameterTypes.get(1).represents(Object[].class); case 3: return JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isAssignableTo(parameterTypes.get(0)) && (parameterTypes.get(1).represents(Object.class) || parameterTypes.get(1).represents(String.class)) && (parameterTypes.get(2).represents(Object[].class) || parameterTypes.get(2).isAssignableFrom(typeType)); default: return JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isAssignableTo(parameterTypes.get(0)) && (parameterTypes.get(1).represents(Object.class) || parameterTypes.get(1).represents(String.class)) && parameterTypes.get(2).isAssignableFrom(typeType); } }
Checks if this method is a bootstrap method given the supplied arguments. This method does not implement a full check but assumes that isBootstrap(TypeDescription) is invoked, as well.
Params:
  • arguments – The arguments to the bootstrap method.
Returns:true if this method is a bootstrap method for the supplied arguments..
/** * Checks if this method is a bootstrap method given the supplied arguments. This method does not implement a full check but assumes that * {@link MethodDescription.AbstractBase#isBootstrap(TypeDescription)} is invoked, as well. * * @param arguments The arguments to the bootstrap method. * @return {@code true} if this method is a bootstrap method for the supplied arguments.. */
private boolean isBootstrap(List<?> arguments) { for (Object argument : arguments) { if (argument == null) { throw new IllegalArgumentException("The null value is not a bootstrap constant"); } Class<?> argumentType = argument.getClass(); if (!(argumentType == String.class || argumentType == Integer.class || argumentType == Long.class || argumentType == Float.class || argumentType == Double.class || TypeDescription.class.isAssignableFrom(argumentType) || JavaConstant.class.isAssignableFrom(argumentType))) { throw new IllegalArgumentException("Not a Java constant representation: " + argument); } } TypeList parameterTypes = getParameters().asTypeList().asErasures(); if (parameterTypes.size() < 4) { return arguments.isEmpty() || parameterTypes.get(parameterTypes.size() - 1).represents(Object[].class); } else { int index = 4; Iterator<?> argumentIterator = arguments.iterator(); for (TypeDescription parameterType : parameterTypes.subList(3, parameterTypes.size())) { boolean finalParameterCheck = !argumentIterator.hasNext(); if (!finalParameterCheck) { Object argument = argumentIterator.next(); finalParameterCheck = !((argument instanceof JavaConstant) && ((JavaConstant) argument).getType().isAssignableTo(parameterType)) && !(parameterType.represents(Class.class) && argument instanceof TypeDescription && !((TypeDescription) argument).isPrimitive()) && !(parameterType.represents(String.class) && argument.getClass() == String.class) && !(parameterType.represents(int.class) && argument.getClass() == Integer.class) && !(parameterType.represents(long.class) && argument.getClass() == Long.class) && !(parameterType.represents(float.class) && argument.getClass() == Float.class) && !(parameterType.represents(double.class) && argument.getClass() == Double.class); } if (finalParameterCheck) { return index == parameterTypes.size() && parameterType.represents(Object[].class); } index++; } return true; } }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isInvokeBootstrap() { TypeDescription returnType = getReturnType().asErasure(); if ((isMethod() && (!isStatic() || !(JavaType.CALL_SITE.getTypeStub().isAssignableFrom(returnType) || JavaType.CALL_SITE.getTypeStub().isAssignableTo(returnType)))) || (isConstructor() && !JavaType.CALL_SITE.getTypeStub().isAssignableFrom(getDeclaringType().asErasure()))) { return false; } return isBootstrap(JavaType.METHOD_TYPE.getTypeStub()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isInvokeBootstrap(List<?> arguments) { return isInvokeBootstrap() && isBootstrap(arguments); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isConstantBootstrap() { ParameterList<?> parameters = getParameters(); return !parameters.isEmpty() && getParameters().get(0).getType().asErasure().equals(JavaType.METHOD_HANDLES_LOOKUP.getTypeStub()) && isBootstrap(TypeDescription.CLASS); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isConstantBootstrap(List<?> arguments) { return isConstantBootstrap() && isBootstrap(arguments); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isDefaultValue() { return !isConstructor() && !isStatic() && getReturnType().asErasure().isAnnotationReturnType() && getParameters().isEmpty(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isDefaultValue(AnnotationValue<?, ?> annotationValue) { if (!isDefaultValue()) { return false; } TypeDescription returnType = getReturnType().asErasure(); Object value = annotationValue.resolve(); return (returnType.represents(boolean.class) && value instanceof Boolean) || (returnType.represents(byte.class) && value instanceof Byte) || (returnType.represents(char.class) && value instanceof Character) || (returnType.represents(short.class) && value instanceof Short) || (returnType.represents(int.class) && value instanceof Integer) || (returnType.represents(long.class) && value instanceof Long) || (returnType.represents(float.class) && value instanceof Float) || (returnType.represents(double.class) && value instanceof Double) || (returnType.represents(String.class) && value instanceof String) || (returnType.isAssignableTo(Enum.class) && value instanceof EnumerationDescription && isEnumerationType(returnType, (EnumerationDescription) value)) || (returnType.isAssignableTo(Annotation.class) && value instanceof AnnotationDescription && isAnnotationType(returnType, (AnnotationDescription) value)) || (returnType.represents(Class.class) && value instanceof TypeDescription) || (returnType.represents(boolean[].class) && value instanceof boolean[]) || (returnType.represents(byte[].class) && value instanceof byte[]) || (returnType.represents(char[].class) && value instanceof char[]) || (returnType.represents(short[].class) && value instanceof short[]) || (returnType.represents(int[].class) && value instanceof int[]) || (returnType.represents(long[].class) && value instanceof long[]) || (returnType.represents(float[].class) && value instanceof float[]) || (returnType.represents(double[].class) && value instanceof double[]) || (returnType.represents(String[].class) && value instanceof String[]) || (returnType.isAssignableTo(Enum[].class) && value instanceof EnumerationDescription[] && isEnumerationType(returnType.getComponentType(), (EnumerationDescription[]) value)) || (returnType.isAssignableTo(Annotation[].class) && value instanceof AnnotationDescription[] && isAnnotationType(returnType.getComponentType(), (AnnotationDescription[]) value)) || (returnType.represents(Class[].class) && value instanceof TypeDescription[]); }
Checks if the supplied enumeration descriptions describe the correct enumeration type.
Params:
  • enumerationType – The enumeration type to check for.
  • enumerationDescription – The enumeration descriptions to check.
Returns:true if all enumeration descriptions represent the enumeration type in question.
/** * Checks if the supplied enumeration descriptions describe the correct enumeration type. * * @param enumerationType The enumeration type to check for. * @param enumerationDescription The enumeration descriptions to check. * @return {@code true} if all enumeration descriptions represent the enumeration type in question. */
private static boolean isEnumerationType(TypeDescription enumerationType, EnumerationDescription... enumerationDescription) { for (EnumerationDescription anEnumerationDescription : enumerationDescription) { if (!anEnumerationDescription.getEnumerationType().equals(enumerationType)) { return false; } } return true; }
Checks if the supplied enumeration descriptions describe the correct annotation type.
Params:
  • annotationType – The annotation type to check for.
  • annotationDescription – The annotation descriptions to check.
Returns:true if all annotation descriptions represent the annotation type in question.
/** * Checks if the supplied enumeration descriptions describe the correct annotation type. * * @param annotationType The annotation type to check for. * @param annotationDescription The annotation descriptions to check. * @return {@code true} if all annotation descriptions represent the annotation type in question. */
private static boolean isAnnotationType(TypeDescription annotationType, AnnotationDescription... annotationDescription) { for (AnnotationDescription anAnnotationDescription : annotationDescription) { if (!anAnnotationDescription.getAnnotationType().equals(annotationType)) { return false; } } return true; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeVariableSource getEnclosingSource() { return isStatic() ? TypeVariableSource.UNDEFINED : getDeclaringType().asErasure(); }
{@inheritDoc}
/** * {@inheritDoc} */
public <T> T accept(TypeVariableSource.Visitor<T> visitor) { return visitor.onMethod(this.asDefined()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isGenerified() { return !getTypeVariables().isEmpty(); }
{@inheritDoc}
/** * {@inheritDoc} */
public MethodDescription.Token asToken(ElementMatcher<? super TypeDescription> matcher) { TypeDescription.Generic receiverType = getReceiverType(); return new MethodDescription.Token(getInternalName(), getModifiers(), getTypeVariables().asTokenList(matcher), getReturnType().accept(new TypeDescription.Generic.Visitor.Substitutor.ForDetachment(matcher)), getParameters().asTokenList(matcher), getExceptionTypes().accept(new TypeDescription.Generic.Visitor.Substitutor.ForDetachment(matcher)), getDeclaredAnnotations(), getDefaultValue(), receiverType == null ? TypeDescription.Generic.UNDEFINED : receiverType.accept(new TypeDescription.Generic.Visitor.Substitutor.ForDetachment(matcher))); }
{@inheritDoc}
/** * {@inheritDoc} */
public SignatureToken asSignatureToken() { return new SignatureToken(getInternalName(), getReturnType().asErasure(), getParameters().asTypeList().asErasures()); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeToken asTypeToken() { return new TypeToken(getReturnType().asErasure(), getParameters().asTypeList().asErasures()); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isBridgeCompatible(TypeToken typeToken) { List<TypeDescription> types = getParameters().asTypeList().asErasures(), bridgeTypes = typeToken.getParameterTypes(); if (types.size() != bridgeTypes.size()) { return false; } for (int index = 0; index < types.size(); index++) { if (!types.get(index).equals(bridgeTypes.get(index)) && (types.get(index).isPrimitive() || bridgeTypes.get(index).isPrimitive())) { return false; } } TypeDescription returnType = getReturnType().asErasure(), bridgeReturnType = typeToken.getReturnType(); return returnType.equals(bridgeReturnType) || (!returnType.isPrimitive() && !bridgeReturnType.isPrimitive()); } @Override public int hashCode() { int hashCode = 17 + getDeclaringType().hashCode(); hashCode = 31 * hashCode + getInternalName().hashCode(); hashCode = 31 * hashCode + getReturnType().asErasure().hashCode(); return 31 * hashCode + getParameters().asTypeList().asErasures().hashCode(); } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof MethodDescription)) { return false; } MethodDescription methodDescription = (MethodDescription) other; return getInternalName().equals(methodDescription.getInternalName()) && getDeclaringType().equals(methodDescription.getDeclaringType()) && getReturnType().asErasure().equals(methodDescription.getReturnType().asErasure()) && getParameters().asTypeList().asErasures().equals(methodDescription.getParameters().asTypeList().asErasures()); }
{@inheritDoc}
/** * {@inheritDoc} */
public String toGenericString() { StringBuilder stringBuilder = new StringBuilder(); int modifiers = getModifiers() & SOURCE_MODIFIERS; if (modifiers != EMPTY_MASK) { stringBuilder.append(Modifier.toString(modifiers)).append(' '); } if (isMethod()) { stringBuilder.append(getReturnType().getActualName()).append(' '); stringBuilder.append(getDeclaringType().asErasure().getActualName()).append('.'); } stringBuilder.append(getName()).append('('); boolean first = true; for (TypeDescription.Generic typeDescription : getParameters().asTypeList()) { if (!first) { stringBuilder.append(','); } else { first = false; } stringBuilder.append(typeDescription.getActualName()); } stringBuilder.append(')'); TypeList.Generic exceptionTypes = getExceptionTypes(); if (!exceptionTypes.isEmpty()) { stringBuilder.append(" throws "); first = true; for (TypeDescription.Generic typeDescription : exceptionTypes) { if (!first) { stringBuilder.append(','); } else { first = false; } stringBuilder.append(typeDescription.getActualName()); } } return stringBuilder.toString(); } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder(); int modifiers = getModifiers() & SOURCE_MODIFIERS; if (modifiers != EMPTY_MASK) { stringBuilder.append(Modifier.toString(modifiers)).append(' '); } if (isMethod()) { stringBuilder.append(getReturnType().asErasure().getActualName()).append(' '); stringBuilder.append(getDeclaringType().asErasure().getActualName()).append('.'); } stringBuilder.append(getName()).append('('); boolean first = true; for (TypeDescription typeDescription : getParameters().asTypeList().asErasures()) { if (!first) { stringBuilder.append(','); } else { first = false; } stringBuilder.append(typeDescription.getActualName()); } stringBuilder.append(')'); TypeList exceptionTypes = getExceptionTypes().asErasures(); if (!exceptionTypes.isEmpty()) { stringBuilder.append(" throws "); first = true; for (TypeDescription typeDescription : exceptionTypes) { if (!first) { stringBuilder.append(','); } else { first = false; } stringBuilder.append(typeDescription.getActualName()); } } return stringBuilder.toString(); } }
An implementation of a method description for a loaded constructor.
/** * An implementation of a method description for a loaded constructor. */
class ForLoadedConstructor extends InDefinedShape.AbstractBase implements ParameterDescription.ForLoadedParameter.ParameterAnnotationSource {
The loaded constructor that is represented by this instance.
/** * The loaded constructor that is represented by this instance. */
private final Constructor<?> constructor;
Creates a new immutable method description for a loaded constructor.
Params:
  • constructor – The loaded constructor to be represented by this method description.
/** * Creates a new immutable method description for a loaded constructor. * * @param constructor The loaded constructor to be represented by this method description. */
public ForLoadedConstructor(Constructor<?> constructor) { this.constructor = constructor; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getDeclaringType() { return TypeDescription.ForLoadedType.of(constructor.getDeclaringClass()); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReturnType() { return TypeDescription.Generic.VOID; }
{@inheritDoc}
/** * {@inheritDoc} */
@CachedReturnPlugin.Enhance("parameters") public ParameterList<ParameterDescription.InDefinedShape> getParameters() { return ParameterList.ForLoadedExecutable.of(constructor, this); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getExceptionTypes() { return new TypeList.Generic.OfConstructorExceptionTypes(constructor); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isConstructor() { return true; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isTypeInitializer() { return false; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Method method) { return false; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Constructor<?> constructor) { return this.constructor.equals(constructor) || equals(new MethodDescription.ForLoadedConstructor(constructor)); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getName() { return constructor.getName(); }
{@inheritDoc}
/** * {@inheritDoc} */
public int getModifiers() { return constructor.getModifiers(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isSynthetic() { return constructor.isSynthetic(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getInternalName() { return CONSTRUCTOR_INTERNAL_NAME; }
{@inheritDoc}
/** * {@inheritDoc} */
public String getDescriptor() { return Type.getConstructorDescriptor(constructor); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<?, ?> getDefaultValue() { return AnnotationValue.UNDEFINED; }
{@inheritDoc}
/** * {@inheritDoc} */
@CachedReturnPlugin.Enhance("declaredAnnotations") public AnnotationList getDeclaredAnnotations() { return new AnnotationList.ForLoadedAnnotations(constructor.getDeclaredAnnotations()); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getTypeVariables() { return TypeList.Generic.ForLoadedTypes.OfTypeVariables.of(constructor); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReceiverType() { TypeDescription.Generic receiverType = TypeDescription.Generic.AnnotationReader.DISPATCHER.resolveReceiverType(constructor); return receiverType == null ? super.getReceiverType() : receiverType; }
{@inheritDoc}
/** * {@inheritDoc} */
@CachedReturnPlugin.Enhance("parameterAnnotations") public Annotation[][] getParameterAnnotations() { return constructor.getParameterAnnotations(); } }
An implementation of a method description for a loaded method.
/** * An implementation of a method description for a loaded method. */
class ForLoadedMethod extends InDefinedShape.AbstractBase implements ParameterDescription.ForLoadedParameter.ParameterAnnotationSource {
The loaded method that is represented by this instance.
/** * The loaded method that is represented by this instance. */
private final Method method;
Creates a new immutable method description for a loaded method.
Params:
  • method – The loaded method to be represented by this method description.
/** * Creates a new immutable method description for a loaded method. * * @param method The loaded method to be represented by this method description. */
public ForLoadedMethod(Method method) { this.method = method; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getDeclaringType() { return TypeDescription.ForLoadedType.of(method.getDeclaringClass()); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReturnType() { if (TypeDescription.AbstractBase.RAW_TYPES) { return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(method.getReturnType()); } return new TypeDescription.Generic.LazyProjection.ForLoadedReturnType(method); }
{@inheritDoc}
/** * {@inheritDoc} */
@CachedReturnPlugin.Enhance("parameters") public ParameterList<ParameterDescription.InDefinedShape> getParameters() { return ParameterList.ForLoadedExecutable.of(method, this); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getExceptionTypes() { if (TypeDescription.AbstractBase.RAW_TYPES) { return new TypeList.Generic.ForLoadedTypes(method.getExceptionTypes()); } return new TypeList.Generic.OfMethodExceptionTypes(method); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isConstructor() { return false; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isTypeInitializer() { return false; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isBridge() { return method.isBridge(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Method method) { return this.method.equals(method) || equals(new MethodDescription.ForLoadedMethod(method)); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean represents(Constructor<?> constructor) { return false; }
{@inheritDoc}
/** * {@inheritDoc} */
public String getName() { return method.getName(); }
{@inheritDoc}
/** * {@inheritDoc} */
public int getModifiers() { return method.getModifiers(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isSynthetic() { return method.isSynthetic(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getInternalName() { return method.getName(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getDescriptor() { return Type.getMethodDescriptor(method); }
Returns the loaded method that is represented by this method description.
Returns:The loaded method that is represented by this method description.
/** * Returns the loaded method that is represented by this method description. * * @return The loaded method that is represented by this method description. */
public Method getLoadedMethod() { return method; }
{@inheritDoc}
/** * {@inheritDoc} */
@CachedReturnPlugin.Enhance("declaredAnnotations") public AnnotationList getDeclaredAnnotations() { return new AnnotationList.ForLoadedAnnotations(method.getDeclaredAnnotations()); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<?, ?> getDefaultValue() { Object value = method.getDefaultValue(); return value == null ? AnnotationValue.UNDEFINED : AnnotationDescription.ForLoadedAnnotation.asValue(value, method.getReturnType()); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getTypeVariables() { if (TypeDescription.AbstractBase.RAW_TYPES) { return new TypeList.Generic.Empty(); } return TypeList.Generic.ForLoadedTypes.OfTypeVariables.of(method); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReceiverType() { if (TypeDescription.AbstractBase.RAW_TYPES) { return super.getReceiverType(); } TypeDescription.Generic receiverType = TypeDescription.Generic.AnnotationReader.DISPATCHER.resolveReceiverType(method); return receiverType == null ? super.getReceiverType() : receiverType; }
{@inheritDoc}
/** * {@inheritDoc} */
@CachedReturnPlugin.Enhance("parameterAnnotations") public Annotation[][] getParameterAnnotations() { return method.getParameterAnnotations(); } }
A latent method description describes a method that is not attached to a declaring TypeDescription.
/** * A latent method description describes a method that is not attached to a declaring * {@link TypeDescription}. */
class Latent extends InDefinedShape.AbstractBase {
The type that is declaring this method.
/** * The type that is declaring this method. */
private final TypeDescription declaringType;
The internal name of this method.
/** * The internal name of this method. */
private final String internalName;
The modifiers of this method.
/** * The modifiers of this method. */
private final int modifiers;
A tokenized list representing the method's type variables.
/** * A tokenized list representing the method's type variables. */
private final List<? extends TypeVariableToken> typeVariables;
The return type of this method.
/** * The return type of this method. */
private final TypeDescription.Generic returnType;
The parameter tokens describing this method.
/** * The parameter tokens describing this method. */
private final List<? extends ParameterDescription.Token> parameterTokens;
This method's exception types.
/** * This method's exception types. */
private final List<? extends TypeDescription.Generic> exceptionTypes;
The annotations of this method.
/** * The annotations of this method. */
private final List<? extends AnnotationDescription> declaredAnnotations;
The default value of this method or null if no default annotation value is defined.
/** * The default value of this method or {@code null} if no default annotation value is defined. */
private final AnnotationValue<?, ?> defaultValue;
The receiver type of this method or null if the receiver type is defined implicitly.
/** * The receiver type of this method or {@code null} if the receiver type is defined implicitly. */
private final TypeDescription.Generic receiverType;
Creates a new latent method description. All provided types are attached to this instance before they are returned.
Params:
  • declaringType – The declaring type of the method.
  • token – A token representing the method's shape.
/** * Creates a new latent method description. All provided types are attached to this instance before they are returned. * * @param declaringType The declaring type of the method. * @param token A token representing the method's shape. */
public Latent(TypeDescription declaringType, MethodDescription.Token token) { this(declaringType, token.getName(), token.getModifiers(), token.getTypeVariableTokens(), token.getReturnType(), token.getParameterTokens(), token.getExceptionTypes(), token.getAnnotations(), token.getDefaultValue(), token.getReceiverType()); }
Creates a new latent method description. All provided types are attached to this instance before they are returned.
Params:
  • declaringType – The type that is declaring this method.
  • internalName – The internal name of this method.
  • modifiers – The modifiers of this method.
  • typeVariables – The type variables of the described method.
  • returnType – The return type of this method.
  • parameterTokens – The parameter tokens describing this method.
  • exceptionTypes – This method's exception types.
  • declaredAnnotations – The annotations of this method.
  • defaultValue – The default value of this method or null if no default annotation value is defined.
  • receiverType – The receiver type of this method or null if the receiver type is defined implicitly.
/** * Creates a new latent method description. All provided types are attached to this instance before they are returned. * * @param declaringType The type that is declaring this method. * @param internalName The internal name of this method. * @param modifiers The modifiers of this method. * @param typeVariables The type variables of the described method. * @param returnType The return type of this method. * @param parameterTokens The parameter tokens describing this method. * @param exceptionTypes This method's exception types. * @param declaredAnnotations The annotations of this method. * @param defaultValue The default value of this method or {@code null} if no default annotation value is defined. * @param receiverType The receiver type of this method or {@code null} if the receiver type is defined implicitly. */
public Latent(TypeDescription declaringType, String internalName, int modifiers, List<? extends TypeVariableToken> typeVariables, TypeDescription.Generic returnType, List<? extends ParameterDescription.Token> parameterTokens, List<? extends TypeDescription.Generic> exceptionTypes, List<? extends AnnotationDescription> declaredAnnotations, AnnotationValue<?, ?> defaultValue, TypeDescription.Generic receiverType) { this.declaringType = declaringType; this.internalName = internalName; this.modifiers = modifiers; this.typeVariables = typeVariables; this.returnType = returnType; this.parameterTokens = parameterTokens; this.exceptionTypes = exceptionTypes; this.declaredAnnotations = declaredAnnotations; this.defaultValue = defaultValue; this.receiverType = receiverType; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getTypeVariables() { return TypeList.Generic.ForDetachedTypes.attachVariables(this, typeVariables); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReturnType() { return returnType.accept(TypeDescription.Generic.Visitor.Substitutor.ForAttachment.of(this)); }
{@inheritDoc}
/** * {@inheritDoc} */
public ParameterList<ParameterDescription.InDefinedShape> getParameters() { return new ParameterList.ForTokens(this, parameterTokens); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getExceptionTypes() { return TypeList.Generic.ForDetachedTypes.attach(this, exceptionTypes); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationList getDeclaredAnnotations() { return new AnnotationList.Explicit(declaredAnnotations); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getInternalName() { return internalName; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getDeclaringType() { return declaringType; }
{@inheritDoc}
/** * {@inheritDoc} */
public int getModifiers() { return modifiers; }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<?, ?> getDefaultValue() { return defaultValue; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReceiverType() { return receiverType == null ? super.getReceiverType() : receiverType.accept(TypeDescription.Generic.Visitor.Substitutor.ForAttachment.of(this)); }
A method description that represents the type initializer.
/** * A method description that represents the type initializer. */
public static class TypeInitializer extends InDefinedShape.AbstractBase {
The type for which the type initializer should be represented.
/** * The type for which the type initializer should be represented. */
private final TypeDescription typeDescription;
Creates a new method description representing the type initializer.
Params:
  • typeDescription – The type for which the type initializer should be represented.
/** * Creates a new method description representing the type initializer. * * @param typeDescription The type for which the type initializer should be represented. */
public TypeInitializer(TypeDescription typeDescription) { this.typeDescription = typeDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReturnType() { return TypeDescription.Generic.VOID; }
{@inheritDoc}
/** * {@inheritDoc} */
public ParameterList<ParameterDescription.InDefinedShape> getParameters() { return new ParameterList.Empty<ParameterDescription.InDefinedShape>(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getExceptionTypes() { return new TypeList.Generic.Empty(); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<?, ?> getDefaultValue() { return AnnotationValue.UNDEFINED; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getTypeVariables() { return new TypeList.Generic.Empty(); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationList getDeclaredAnnotations() { return new AnnotationList.Empty(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription getDeclaringType() { return typeDescription; }
{@inheritDoc}
/** * {@inheritDoc} */
public int getModifiers() { return TYPE_INITIALIZER_MODIFIER; }
{@inheritDoc}
/** * {@inheritDoc} */
public String getInternalName() { return MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME; } } }
A method description that represents a given method but with substituted method types.
/** * A method description that represents a given method but with substituted method types. */
class TypeSubstituting extends AbstractBase implements InGenericShape {
The type that declares this type-substituted method.
/** * The type that declares this type-substituted method. */
private final TypeDescription.Generic declaringType;
The represented method description.
/** * The represented method description. */
private final MethodDescription methodDescription;
A visitor that is applied to the method type.
/** * A visitor that is applied to the method type. */
private final TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor;
Creates a method description with substituted method types.
Params:
  • declaringType – The type that is declaring the substituted method.
  • methodDescription – The represented method description.
  • visitor – A visitor that is applied to the method type.
/** * Creates a method description with substituted method types. * * @param declaringType The type that is declaring the substituted method. * @param methodDescription The represented method description. * @param visitor A visitor that is applied to the method type. */
public TypeSubstituting(TypeDescription.Generic declaringType, MethodDescription methodDescription, TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor) { this.declaringType = declaringType; this.methodDescription = methodDescription; this.visitor = visitor; }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReturnType() { return methodDescription.getReturnType().accept(visitor); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getTypeVariables() { return methodDescription.getTypeVariables().accept(visitor).filter(ElementMatchers.ofSort(TypeDefinition.Sort.VARIABLE)); }
{@inheritDoc}
/** * {@inheritDoc} */
public ParameterList<ParameterDescription.InGenericShape> getParameters() { return new ParameterList.TypeSubstituting(this, methodDescription.getParameters(), visitor); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeList.Generic getExceptionTypes() { return new TypeList.Generic.ForDetachedTypes(methodDescription.getExceptionTypes(), visitor); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationValue<?, ?> getDefaultValue() { return methodDescription.getDefaultValue(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getReceiverType() { TypeDescription.Generic receiverType = methodDescription.getReceiverType(); return receiverType == null ? TypeDescription.Generic.UNDEFINED : receiverType.accept(visitor); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationList getDeclaredAnnotations() { return methodDescription.getDeclaredAnnotations(); }
{@inheritDoc}
/** * {@inheritDoc} */
public TypeDescription.Generic getDeclaringType() { return declaringType; }
{@inheritDoc}
/** * {@inheritDoc} */
public int getModifiers() { return methodDescription.getModifiers(); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getInternalName() { return methodDescription.getInternalName(); }
{@inheritDoc}
/** * {@inheritDoc} */
public InDefinedShape asDefined() { return methodDescription.asDefined(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isConstructor() { return methodDescription.isConstructor(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isMethod() { return methodDescription.isMethod(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isTypeInitializer() { return methodDescription.isTypeInitializer(); } }
A token representing a method's properties detached from a type.
/** * A token representing a method's properties detached from a type. */
class Token implements ByteCodeElement.Token<Token> {
The internal name of the represented method.
/** * The internal name of the represented method. */
private final String name;
The modifiers of the represented method.
/** * The modifiers of the represented method. */
private final int modifiers;
A list of tokens representing the method's type variables.
/** * A list of tokens representing the method's type variables. */
private final List<? extends TypeVariableToken> typeVariableTokens;
The return type of the represented method.
/** * The return type of the represented method. */
private final TypeDescription.Generic returnType;
The parameter tokens of the represented method.
/** * The parameter tokens of the represented method. */
private final List<? extends ParameterDescription.Token> parameterTokens;
The exception types of the represented method.
/** * The exception types of the represented method. */
private final List<? extends TypeDescription.Generic> exceptionTypes;
The annotations of the represented method.
/** * The annotations of the represented method. */
private final List<? extends AnnotationDescription> annotations;
The default value of the represented method or null if no such value exists.
/** * The default value of the represented method or {@code null} if no such value exists. */
private final AnnotationValue<?, ?> defaultValue;
The receiver type of the represented method or null if the receiver type is implicit.
/** * The receiver type of the represented method or {@code null} if the receiver type is implicit. */
private final TypeDescription.Generic receiverType;
Creates a new method token representing a constructor without any parameters, exception types, type variables or annotations. All types must be represented in an detached format.
Params:
  • modifiers – The constructor's modifiers.
/** * Creates a new method token representing a constructor without any parameters, exception types, type variables or annotations. * All types must be represented in an detached format. * * @param modifiers The constructor's modifiers. */
public Token(int modifiers) { this(MethodDescription.CONSTRUCTOR_INTERNAL_NAME, modifiers, TypeDescription.Generic.VOID); }
Creates a new method token representing a method without any parameters, exception types, type variables or annotations. All types must be represented in an detached format.
Params:
  • name – The name of the method.
  • modifiers – The modifiers of the method.
  • returnType – The return type of the method.
/** * Creates a new method token representing a method without any parameters, exception types, type variables or annotations. * All types must be represented in an detached format. * * @param name The name of the method. * @param modifiers The modifiers of the method. * @param returnType The return type of the method. */
public Token(String name, int modifiers, TypeDescription.Generic returnType) { this(name, modifiers, returnType, Collections.<TypeDescription.Generic>emptyList()); }
Creates a new method token with simple values. All types must be represented in an detached format.
Params:
  • name – The internal name of the represented method.
  • modifiers – The modifiers of the represented method.
  • returnType – The return type of the represented method.
  • parameterTypes – The parameter types of this method.
/** * Creates a new method token with simple values. All types must be represented in an detached format. * * @param name The internal name of the represented method. * @param modifiers The modifiers of the represented method. * @param returnType The return type of the represented method. * @param parameterTypes The parameter types of this method. */
public Token(String name, int modifiers, TypeDescription.Generic returnType, List<? extends TypeDescription.Generic> parameterTypes) { this(name, modifiers, Collections.<TypeVariableToken>emptyList(), returnType, new ParameterDescription.Token.TypeList(parameterTypes), Collections.<TypeDescription.Generic>emptyList(), Collections.<AnnotationDescription>emptyList(), AnnotationValue.UNDEFINED, TypeDescription.Generic.UNDEFINED); }
Creates a new token for a method description. All types must be represented in an detached format.
Params:
  • name – The internal name of the represented method.
  • modifiers – The modifiers of the represented method.
  • typeVariableTokens – The type variables of the the represented method.
  • returnType – The return type of the represented method.
  • parameterTokens – The parameter tokens of the represented method.
  • exceptionTypes – The exception types of the represented method.
  • annotations – The annotations of the represented method.
  • defaultValue – The default value of the represented method or null if no such value exists.
  • receiverType – The receiver type of the represented method or null if the receiver type is implicit.
/** * Creates a new token for a method description. All types must be represented in an detached format. * * @param name The internal name of the represented method. * @param modifiers The modifiers of the represented method. * @param typeVariableTokens The type variables of the the represented method. * @param returnType The return type of the represented method. * @param parameterTokens The parameter tokens of the represented method. * @param exceptionTypes The exception types of the represented method. * @param annotations The annotations of the represented method. * @param defaultValue The default value of the represented method or {@code null} if no such value exists. * @param receiverType The receiver type of the represented method or {@code null} if the receiver type is implicit. */
public Token(String name, int modifiers, List<? extends TypeVariableToken> typeVariableTokens, TypeDescription.Generic returnType, List<? extends ParameterDescription.Token> parameterTokens, List<? extends TypeDescription.Generic> exceptionTypes, List<? extends AnnotationDescription> annotations, AnnotationValue<?, ?> defaultValue, TypeDescription.Generic receiverType) { this.name = name; this.modifiers = modifiers; this.typeVariableTokens = typeVariableTokens; this.returnType = returnType; this.parameterTokens = parameterTokens; this.exceptionTypes = exceptionTypes; this.annotations = annotations; this.defaultValue = defaultValue; this.receiverType = receiverType; }
Returns the internal name of the represented method.
Returns:The internal name of the represented method.
/** * Returns the internal name of the represented method. * * @return The internal name of the represented method. */
public String getName() { return name; }
Returns the modifiers of the represented method.
Returns:The modifiers of the represented method.
/** * Returns the modifiers of the represented method. * * @return The modifiers of the represented method. */
public int getModifiers() { return modifiers; }
Returns the type variables of this method token.
Returns:A a list of tokens representing the method's type variables.
/** * Returns the type variables of this method token. * * @return A a list of tokens representing the method's type variables. */
public TokenList<TypeVariableToken> getTypeVariableTokens() { return new TokenList<TypeVariableToken>(typeVariableTokens); }
Returns the return type of the represented method.
Returns:The return type of the represented method.
/** * Returns the return type of the represented method. * * @return The return type of the represented method. */
public TypeDescription.Generic getReturnType() { return returnType; }
Returns the parameter tokens of the represented method.
Returns:The parameter tokens of the represented method.
/** * Returns the parameter tokens of the represented method. * * @return The parameter tokens of the represented method. */
public TokenList<ParameterDescription.Token> getParameterTokens() { return new TokenList<ParameterDescription.Token>(parameterTokens); }
Returns the exception types of the represented method.
Returns:The exception types of the represented method.
/** * Returns the exception types of the represented method. * * @return The exception types of the represented method. */
public TypeList.Generic getExceptionTypes() { return new TypeList.Generic.Explicit(exceptionTypes); }
Returns the annotations of the represented method.
Returns:The annotations of the represented method.
/** * Returns the annotations of the represented method. * * @return The annotations of the represented method. */
public AnnotationList getAnnotations() { return new AnnotationList.Explicit(annotations); }
Returns the default value of the represented method.
Returns:The default value of the represented method or null if no such value exists.
/** * Returns the default value of the represented method. * * @return The default value of the represented method or {@code null} if no such value exists. */
public AnnotationValue<?, ?> getDefaultValue() { return defaultValue; }
Returns the receiver type of this token or null if the receiver type is implicit.
Returns:The receiver type of this token or null if the receiver type is implicit.
/** * Returns the receiver type of this token or {@code null} if the receiver type is implicit. * * @return The receiver type of this token or {@code null} if the receiver type is implicit. */
public TypeDescription.Generic getReceiverType() { return receiverType; }
{@inheritDoc}
/** * {@inheritDoc} */
public Token accept(TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor) { return new Token(name, modifiers, getTypeVariableTokens().accept(visitor), returnType.accept(visitor), getParameterTokens().accept(visitor), getExceptionTypes().accept(visitor), annotations, defaultValue, receiverType == null ? TypeDescription.Generic.UNDEFINED : receiverType.accept(visitor)); }
Creates a signature token that represents the method that is represented by this token.
Params:
  • declaringType – The declaring type of the method that this token represents.
Returns:A signature token representing this token.
/** * Creates a signature token that represents the method that is represented by this token. * * @param declaringType The declaring type of the method that this token represents. * @return A signature token representing this token. */
public SignatureToken asSignatureToken(TypeDescription declaringType) { TypeDescription.Generic.Visitor<TypeDescription> visitor = new TypeDescription.Generic.Visitor.Reducing(declaringType, typeVariableTokens); List<TypeDescription> parameters = new ArrayList<TypeDescription>(parameterTokens.size()); for (ParameterDescription.Token parameter : parameterTokens) { parameters.add(parameter.getType().accept(visitor)); } return new SignatureToken(name, returnType.accept(visitor), parameters); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + modifiers; result = 31 * result + typeVariableTokens.hashCode(); result = 31 * result + returnType.hashCode(); result = 31 * result + parameterTokens.hashCode(); result = 31 * result + exceptionTypes.hashCode(); result = 31 * result + annotations.hashCode(); result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0); result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0); return result; } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (other == null || getClass() != other.getClass()) { return false; } Token token = (Token) other; return modifiers == token.modifiers && name.equals(token.name) && typeVariableTokens.equals(token.typeVariableTokens) && returnType.equals(token.returnType) && parameterTokens.equals(token.parameterTokens) && exceptionTypes.equals(token.exceptionTypes) && annotations.equals(token.annotations) && (defaultValue != null ? defaultValue.equals(token.defaultValue) : token.defaultValue == null) && (receiverType != null ? receiverType.equals(token.receiverType) : token.receiverType == null); } @Override public String toString() { return "MethodDescription.Token{" + "name='" + name + '\'' + ", modifiers=" + modifiers + ", typeVariableTokens=" + typeVariableTokens + ", returnType=" + returnType + ", parameterTokens=" + parameterTokens + ", exceptionTypes=" + exceptionTypes + ", annotations=" + annotations + ", defaultValue=" + defaultValue + ", receiverType=" + receiverType + '}'; } }
A token representing a method's name and raw return and parameter types.
/** * A token representing a method's name and raw return and parameter types. */
class SignatureToken {
The internal name of the represented method.
/** * The internal name of the represented method. */
private final String name;
The represented method's raw return type.
/** * The represented method's raw return type. */
private final TypeDescription returnType;
The represented method's raw parameter types.
/** * The represented method's raw parameter types. */
private final List<? extends TypeDescription> parameterTypes;
Creates a new type token.
Params:
  • name – The internal name of the represented method.
  • returnType – The represented method's raw return type.
  • parameterTypes – The represented method's raw parameter types.
/** * Creates a new type token. * * @param name The internal name of the represented method. * @param returnType The represented method's raw return type. * @param parameterTypes The represented method's raw parameter types. */
public SignatureToken(String name, TypeDescription returnType, List<? extends TypeDescription> parameterTypes) { this.name = name; this.returnType = returnType; this.parameterTypes = parameterTypes; }
Returns the internal name of the represented method.
Returns:The internal name of the represented method.
/** * Returns the internal name of the represented method. * * @return The internal name of the represented method. */
public String getName() { return name; }
Returns this token's return type.
Returns:This token's return type.
/** * Returns this token's return type. * * @return This token's return type. */
public TypeDescription getReturnType() { return returnType; }
Returns this token's parameter types.
Returns:This token's parameter types.
/** * Returns this token's parameter types. * * @return This token's parameter types. */
@SuppressWarnings("unchecked") public List<TypeDescription> getParameterTypes() { return (List<TypeDescription>) parameterTypes; }
Returns this signature token as a type token.
Returns:This signature token as a type token.
/** * Returns this signature token as a type token. * * @return This signature token as a type token. */
public TypeToken asTypeToken() { return new TypeToken(returnType, parameterTypes); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + returnType.hashCode(); result = 31 * result + parameterTypes.hashCode(); return result; } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof SignatureToken)) { return false; } SignatureToken signatureToken = (SignatureToken) other; return name.equals(signatureToken.name) && returnType.equals(signatureToken.returnType) && parameterTypes.equals(signatureToken.parameterTypes); } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder().append(returnType).append(' ').append(name).append('('); boolean first = true; for (TypeDescription parameterType : parameterTypes) { if (first) { first = false; } else { stringBuilder.append(','); } stringBuilder.append(parameterType); } return stringBuilder.append(')').toString(); } }
A token representing a method's erased return and parameter types.
/** * A token representing a method's erased return and parameter types. */
class TypeToken {
The represented method's raw return type.
/** * The represented method's raw return type. */
private final TypeDescription returnType;
The represented method's raw parameter types.
/** * The represented method's raw parameter types. */
private final List<? extends TypeDescription> parameterTypes;
Creates a new type token.
Params:
  • returnType – The represented method's raw return type.
  • parameterTypes – The represented method's raw parameter types.
/** * Creates a new type token. * * @param returnType The represented method's raw return type. * @param parameterTypes The represented method's raw parameter types. */
public TypeToken(TypeDescription returnType, List<? extends TypeDescription> parameterTypes) { this.returnType = returnType; this.parameterTypes = parameterTypes; }
Returns this token's return type.
Returns:This token's return type.
/** * Returns this token's return type. * * @return This token's return type. */
public TypeDescription getReturnType() { return returnType; }
Returns this token's parameter types.
Returns:This token's parameter types.
/** * Returns this token's parameter types. * * @return This token's parameter types. */
@SuppressWarnings("unchecked") public List<TypeDescription> getParameterTypes() { return (List<TypeDescription>) parameterTypes; } @Override public int hashCode() { int result = returnType.hashCode(); result = 31 * result + parameterTypes.hashCode(); return result; } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof TypeToken)) { return false; } TypeToken typeToken = (TypeToken) other; return returnType.equals(typeToken.returnType) && parameterTypes.equals(typeToken.parameterTypes); } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder().append('('); for (TypeDescription parameterType : parameterTypes) { stringBuilder.append(parameterType.getDescriptor()); } return stringBuilder.append(')').append(returnType.getDescriptor()).toString(); } } }