// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.pool;
import scouter.bytebuddy.description.TypeVariableSource;
import scouter.bytebuddy.description.annotation.AnnotationDescription;
import scouter.bytebuddy.description.annotation.AnnotationList;
import scouter.bytebuddy.description.annotation.AnnotationValue;
import scouter.bytebuddy.description.enumeration.EnumerationDescription;
import scouter.bytebuddy.description.field.FieldDescription;
import scouter.bytebuddy.description.field.FieldList;
import scouter.bytebuddy.description.method.MethodDescription;
import scouter.bytebuddy.description.method.MethodList;
import scouter.bytebuddy.description.method.ParameterDescription;
import scouter.bytebuddy.description.method.ParameterList;
import scouter.bytebuddy.description.type.PackageDescription;
import scouter.bytebuddy.description.type.TypeDescription;
import scouter.bytebuddy.description.type.TypeList;
import scouter.bytebuddy.dynamic.ClassFileLocator;
import scouter.bytebuddy.implementation.bytecode.StackSize;
import scouter.bytebuddy.jar.asm.signature.SignatureReader;
import scouter.bytebuddy.jar.asm.signature.SignatureVisitor;
import scouter.bytebuddy.description.ByteCodeElement;
import scouter.bytebuddy.jar.asm.*;
import scouter.bytebuddy.matcher.ElementMatchers;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.GenericSignatureFormatError;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* A type pool allows the retrieval of {@link TypeDescription} by its name.
*/
public interface TypePool {
/**
* Locates and describes the given type by its name.
*
* @param name The name of the type to describe. The name is to be written as when calling {@link Object#toString()}
* on a loaded {@link java.lang.Class}.
* @return A resolution of the type to describe. If the type to be described was found, the returned
* {@link TypePool.Resolution} represents this type. Otherwise, an illegal resolution is returned.
*/
Resolution describe(String name);
/**
* Clears this type pool's cache.
*/
void clear();
/**
* A resolution of a {@link TypePool} which was queried for a description.
*/
interface Resolution {
/**
* Determines if this resolution represents a fully-resolved {@link TypeDescription}.
*
* @return {@code true} if the queried type could be resolved.
*/
boolean isResolved();
/**
* Resolves this resolution to a {@link TypeDescription}. If this resolution is unresolved, this
* method throws an exception either upon invoking this method or upon invoking at least one method
* of the returned type description.
*
* @return The type description that is represented by this resolution.
*/
TypeDescription resolve();
/**
* A simple resolution that represents a given {@link TypeDescription}.
*/
class Simple implements Resolution {
/**
* The represented type description.
*/
private final TypeDescription typeDescription;
/**
* Creates a new successful resolution of a given type description.
*
* @param typeDescription The represented type description.
*/
public Simple(TypeDescription typeDescription) {
this.typeDescription = typeDescription;
}
@Override
public boolean isResolved() {
return true;
}
@Override
public TypeDescription resolve() {
return typeDescription;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Resolution.Simple)) return false;
final TypePool.Resolution.Simple other = (TypePool.Resolution.Simple) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$typeDescription = this.typeDescription;
final java.lang.Object other$typeDescription = other.typeDescription;
if (this$typeDescription == null ? other$typeDescription != null : !this$typeDescription.equals(other$typeDescription)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Resolution.Simple;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $typeDescription = this.typeDescription;
result = result * PRIME + ($typeDescription == null ? 43 : $typeDescription.hashCode());
return result;
}
}
/**
* A canonical representation of a non-successful resolution of a {@link TypePool}.
*/
class Illegal implements Resolution {
/**
* The name of the unresolved type.
*/
private final String name;
/**
* Creates a new illegal resolution.
*
* @param name The name of the unresolved type.
*/
public Illegal(String name) {
this.name = name;
}
@Override
public boolean isResolved() {
return false;
}
@Override
public TypeDescription resolve() {
throw new IllegalStateException("Cannot resolve type description for " + name);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Resolution.Illegal)) return false;
final TypePool.Resolution.Illegal other = (TypePool.Resolution.Illegal) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Resolution.Illegal;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
}
}
/**
* A cache provider for a {@link TypePool}.
*/
interface CacheProvider {
/**
* The value that is returned on a cache-miss.
*/
Resolution UNRESOLVED = null;
/**
* Attempts to find a resolution in this cache.
*
* @param name The name of the type to describe.
* @return A resolution of the type or {@code null} if no such resolution can be found in the cache..
*/
Resolution find(String name);
/**
* Registers a resolution in this cache. If a resolution to the given name already exists in the
* cache, it should be discarded.
*
* @param name The name of the type that is to be registered.
* @param resolution The resolution to register.
* @return The oldest version of a resolution that is currently registered in the cache which might
* be the given resolution or another resolution that was previously registered.
*/
Resolution register(String name, Resolution resolution);
/**
* Clears this cache.
*/
void clear();
/**
* A non-operational cache that does not store any type descriptions.
*/
enum NoOp implements CacheProvider {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Resolution find(String name) {
return UNRESOLVED;
}
@Override
public Resolution register(String name, Resolution resolution) {
return resolution;
}
@Override
public void clear() {
/* do nothing */
}
}
/**
* A simple, thread-safe type cache based on a {@link java.util.concurrent.ConcurrentHashMap}.
*/
class Simple implements CacheProvider {
/**
* A map containing all cached resolutions by their names.
*/
private final ConcurrentMap<String, Resolution> cache;
/**
* Creates a new simple cache.
*/
public Simple() {
cache = new ConcurrentHashMap<String, Resolution>();
}
/**
* Returns a simple cache provider that is prepopulated with the {@link Object} type.
*
* @return A simple cache provider that is prepopulated with the {@link Object} type.
*/
public static CacheProvider withObjectType() {
CacheProvider cacheProvider = new Simple();
cacheProvider.register(Object.class.getName(), new Resolution.Simple(TypeDescription.OBJECT));
return cacheProvider;
}
@Override
public Resolution find(String name) {
return cache.get(name);
}
@Override
public Resolution register(String name, Resolution resolution) {
Resolution cached = cache.putIfAbsent(name, resolution);
return cached == null ? resolution : cached;
}
@Override
public void clear() {
cache.clear();
}
}
}
/**
* An empty type pool that cannot describe any type.
*/
enum Empty implements TypePool {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Resolution describe(String name) {
return new Resolution.Illegal(name);
}
@Override
public void clear() {
/* do nothing */
}
}
/**
* A base implementation of a {@link TypePool} that is managing a cache provider and
* that handles the description of array and primitive types.
*/
abstract class AbstractBase implements TypePool {
/**
* A map of primitive types by their name.
*/
protected static final Map<String, TypeDescription> PRIMITIVE_TYPES;
/**
* A map of primitive types by their descriptor.
*/
protected static final Map<String, String> PRIMITIVE_DESCRIPTORS;
/**
* The array symbol as used by Java descriptors.
*/
private static final String ARRAY_SYMBOL = "[";
/*
* Initializes the maps of primitive type names and descriptors.
*/
static {
Map<String, TypeDescription> primitiveTypes = new HashMap<String, TypeDescription>();
Map<String, String> primitiveDescriptors = new HashMap<String, String>();
for (Class<?> primitiveType : new Class<?>[] {boolean.class, byte.class, short.class, char.class, int.class, long.class, float.class, double.class, void.class}) {
primitiveTypes.put(primitiveType.getName(), new TypeDescription.ForLoadedType(primitiveType));
primitiveDescriptors.put(Type.getDescriptor(primitiveType), primitiveType.getName());
}
PRIMITIVE_TYPES = Collections.unmodifiableMap(primitiveTypes);
PRIMITIVE_DESCRIPTORS = Collections.unmodifiableMap(primitiveDescriptors);
}
/**
* The cache provider of this instance.
*/
protected final CacheProvider cacheProvider;
/**
* Creates a new instance.
*
* @param cacheProvider The cache provider to be used.
*/
protected AbstractBase(CacheProvider cacheProvider) {
this.cacheProvider = cacheProvider;
}
@Override
public Resolution describe(String name) {
if (name.contains("/")) {
throw new IllegalArgumentException(name + " contains the illegal character \'/\'");
}
int arity = 0;
while (name.startsWith(ARRAY_SYMBOL)) {
arity++;
name = name.substring(1);
}
if (arity > 0) {
String primitiveName = PRIMITIVE_DESCRIPTORS.get(name);
name = primitiveName == null ? name.substring(1, name.length() - 1) : primitiveName;
}
TypeDescription typeDescription = PRIMITIVE_TYPES.get(name);
Resolution resolution = typeDescription == null ? cacheProvider.find(name) : new Resolution.Simple(typeDescription);
if (resolution == null) {
resolution = doCache(name, doDescribe(name));
}
return ArrayTypeResolution.of(resolution, arity);
}
/**
* Writes the resolution to the cache. This method should be overridden if the directly
* resolved instance should not be added to the cache.
*
* @param name The name of the type.
* @param resolution The resolution for this type.
* @return The actual resolution for the type of this name that is stored in the cache.
*/
protected Resolution doCache(String name, Resolution resolution) {
return cacheProvider.register(name, resolution);
}
@Override
public void clear() {
cacheProvider.clear();
}
/**
* Determines a resolution to a non-primitive, non-array type.
*
* @param name The name of the type to describe.
* @return A resolution to the type to describe.
*/
protected abstract Resolution doDescribe(String name);
/**
* Implements a hierarchical view of type pools, similarly to class loader hierarchies. For every lookup, the parent type pool
* is asked first if it can resolve a type. Only if the parent (and potentially its parents) are unable to resolve a type,
* this instance is queried for a type description.
*/
public static abstract class Hierarchical extends AbstractBase {
/**
* The parent type pool.
*/
private final TypePool parent;
/**
* Creates a hierarchical type pool.
*
* @param cacheProvider The cache provider to be used.
* @param parent The parent type pool to be used.
*/
protected Hierarchical(CacheProvider cacheProvider, TypePool parent) {
super(cacheProvider);
this.parent = parent;
}
@Override
public Resolution describe(String name) {
Resolution resolution = parent.describe(name);
return resolution.isResolved() ? resolution : super.describe(name);
}
@Override
public void clear() {
try {
parent.clear();
} finally {
super.clear();
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.AbstractBase.Hierarchical)) return false;
final TypePool.AbstractBase.Hierarchical other = (TypePool.AbstractBase.Hierarchical) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (!super.equals(o)) return false;
final java.lang.Object this$parent = this.parent;
final java.lang.Object other$parent = other.parent;
if (this$parent == null ? other$parent != null : !this$parent.equals(other$parent)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.AbstractBase.Hierarchical;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + super.hashCode();
final java.lang.Object $parent = this.parent;
result = result * PRIME + ($parent == null ? 43 : $parent.hashCode());
return result;
}
}
/**
* A resolution for a type that, if resolved, represents an array type.
*/
protected static class ArrayTypeResolution implements Resolution {
/**
* The underlying resolution that is represented by this instance.
*/
private final Resolution resolution;
/**
* The arity of the represented array.
*/
private final int arity;
/**
* Creates a wrapper for another resolution that, if resolved, represents an array type.
*
* @param resolution The underlying resolution that is represented by this instance.
* @param arity The arity of the represented array.
*/
protected ArrayTypeResolution(Resolution resolution, int arity) {
this.resolution = resolution;
this.arity = arity;
}
/**
* Creates a wrapper for another resolution that, if resolved, represents an array type. The wrapper
* is only created if the arity is not zero. If the arity is zero, the given resolution is simply
* returned instead.
*
* @param resolution The underlying resolution that is represented by this instance.
* @param arity The arity of the represented array.
* @return A wrapper for another resolution that, if resolved, represents an array type or the
* given resolution if the given arity is zero.
*/
protected static Resolution of(Resolution resolution, int arity) {
return arity == 0 ? resolution : new ArrayTypeResolution(resolution, arity);
}
@Override
public boolean isResolved() {
return resolution.isResolved();
}
@Override
public TypeDescription resolve() {
return TypeDescription.ArrayProjection.of(resolution.resolve(), arity);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.AbstractBase.ArrayTypeResolution)) return false;
final TypePool.AbstractBase.ArrayTypeResolution other = (TypePool.AbstractBase.ArrayTypeResolution) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$resolution = this.resolution;
final java.lang.Object other$resolution = other.resolution;
if (this$resolution == null ? other$resolution != null : !this$resolution.equals(other$resolution)) return false;
if (this.arity != other.arity) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.AbstractBase.ArrayTypeResolution;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $resolution = this.resolution;
result = result * PRIME + ($resolution == null ? 43 : $resolution.hashCode());
result = result * PRIME + this.arity;
return result;
}
}
/**
* Represents a nested annotation value.
*/
protected static class RawAnnotationValue extends AnnotationValue.AbstractBase<AnnotationDescription, Annotation> {
/**
* The type pool to use for looking up types.
*/
private final TypePool typePool;
/**
* The annotation token that represents the nested invocation.
*/
private final Default.LazyTypeDescription.AnnotationToken annotationToken;
/**
* Creates a new annotation value for a nested annotation.
*
* @param typePool The type pool to use for looking up types.
* @param annotationToken The token that represents the annotation.
*/
public RawAnnotationValue(TypePool typePool, Default.LazyTypeDescription.AnnotationToken annotationToken) {
this.typePool = typePool;
this.annotationToken = annotationToken;
}
@Override
public AnnotationDescription resolve() {
return annotationToken.toAnnotationDescription(typePool).resolve();
}
@Override
@SuppressWarnings("unchecked")
public Loaded<Annotation> load(ClassLoader classLoader) throws ClassNotFoundException {
Class<?> type = Class.forName(annotationToken.getBinaryName(), false, classLoader);
if (type.isAnnotation()) {
return new ForAnnotationDescription.Loaded<Annotation>(AnnotationDescription.AnnotationInvocationHandler.of(classLoader, (Class<? extends Annotation>) type, annotationToken.getValues()));
} else {
return new ForAnnotationDescription.IncompatibleRuntimeType(type);
}
}
@Override
public boolean equals(Object other) {
return this == other || (other instanceof AnnotationValue<?, ?> && resolve().equals(((AnnotationValue<?, ?>) other).resolve()));
}
@Override
public int hashCode() {
return resolve().hashCode();
}
@Override
public String toString() {
return resolve().toString();
}
}
/**
* Represents an enumeration value of an annotation.
*/
protected static class RawEnumerationValue extends AnnotationValue.AbstractBase<EnumerationDescription, Enum<?>> {
/**
* The type pool to use for looking up types.
*/
private final TypePool typePool;
/**
* The descriptor of the enumeration type.
*/
private final String descriptor;
/**
* The name of the enumeration.
*/
private final String value;
/**
* Creates a new enumeration value representation.
*
* @param typePool The type pool to use for looking up types.
* @param descriptor The descriptor of the enumeration type.
* @param value The name of the enumeration.
*/
public RawEnumerationValue(TypePool typePool, String descriptor, String value) {
this.typePool = typePool;
this.descriptor = descriptor;
this.value = value;
}
@Override
public EnumerationDescription resolve() {
return new LazyEnumerationDescription();
}
@Override
@SuppressWarnings("unchecked")
public Loaded<Enum<?>> load(ClassLoader classLoader) throws ClassNotFoundException {
Class<?> type = Class.forName(descriptor.substring(1, descriptor.length() - 1).replace('/', '.'), false, classLoader);
try {
return type.isEnum() ? new ForEnumerationDescription.Loaded(Enum.valueOf((Class) type, value)) : new ForEnumerationDescription.IncompatibleRuntimeType(type);
} catch (IllegalArgumentException ignored) {
return new ForEnumerationDescription.UnknownRuntimeEnumeration((Class) type, value);
}
}
@Override
public boolean equals(Object other) {
return this == other || (other instanceof AnnotationValue<?, ?> && resolve().equals(((AnnotationValue<?, ?>) other).resolve()));
}
@Override
public int hashCode() {
return resolve().hashCode();
}
@Override
public String toString() {
return resolve().toString();
}
/**
* An enumeration description where any type references are only resolved on demand.
*/
protected class LazyEnumerationDescription extends EnumerationDescription.AbstractBase {
@Override
public String getValue() {
return value;
}
@Override
public TypeDescription getEnumerationType() {
return typePool.describe(descriptor.substring(1, descriptor.length() - 1).replace('/', '.')).resolve();
}
@Override
public <T extends Enum<T>> T load(Class<T> type) {
return Enum.valueOf(type, value);
}
}
}
/**
* Represents a type value of an annotation.
*/
protected static class RawTypeValue extends AnnotationValue.AbstractBase<TypeDescription, Class<?>> {
/**
* A convenience reference indicating that a loaded type should not be initialized.
*/
private static final boolean NO_INITIALIZATION = false;
/**
* The type pool to use for looking up types.
*/
private final TypePool typePool;
/**
* The binary name of the type.
*/
private final String name;
/**
* Represents a type value of an annotation.
*
* @param typePool The type pool to use for looking up types.
* @param type A type representation of the type that is referenced by the annotation..
*/
protected RawTypeValue(TypePool typePool, Type type) {
this.typePool = typePool;
name = type.getSort() == Type.ARRAY ? type.getInternalName().replace('/', '.') : type.getClassName();
}
@Override
public TypeDescription resolve() {
return typePool.describe(name).resolve();
}
@Override
public AnnotationValue.Loaded<Class<?>> load(ClassLoader classLoader) throws ClassNotFoundException {
return new Loaded(Class.forName(name, NO_INITIALIZATION, classLoader));
}
@Override
public boolean equals(Object other) {
return this == other || (other instanceof AnnotationValue<?, ?> && resolve().equals(((AnnotationValue<?, ?>) other).resolve()));
}
@Override
public int hashCode() {
return resolve().hashCode();
}
@Override
public String toString() {
return RenderingDispatcher.CURRENT.toSourceString(resolve());
}
/**
* Represents a loaded annotation property that represents a type.
*/
protected static class Loaded extends AnnotationValue.Loaded.AbstractBase<Class<?>> {
/**
* The type that is represented by an annotation property.
*/
private final Class<?> type;
/**
* Creates a new representation for an annotation property referencing a type.
*
* @param type The type that is represented by an annotation property.
*/
public Loaded(Class<?> type) {
this.type = type;
}
@Override
public State getState() {
return State.RESOLVED;
}
@Override
public Class<?> resolve() {
return type;
}
@Override
public boolean represents(Object value) {
return type.equals(value);
}
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof AnnotationValue.Loaded<?>)) return false;
AnnotationValue.Loaded<?> loadedOther = (AnnotationValue.Loaded<?>) other;
return loadedOther.getState().isResolved() && type.equals(loadedOther.resolve());
}
@Override
public int hashCode() {
return type.hashCode();
}
@Override
public String toString() {
return RenderingDispatcher.CURRENT.toSourceString(new TypeDescription.ForLoadedType(type));
}
}
}
/**
* Represents an array that is referenced by an annotation which does not contain primitive values or {@link String}s.
*/
protected static class RawDescriptionArray extends AnnotationValue.AbstractBase<Object[], Object[]> {
/**
* The type pool to use for looking up types.
*/
private final TypePool typePool;
/**
* A reference to the component type.
*/
private final ComponentTypeReference componentTypeReference;
/**
* A list of all values of this array value in their order.
*/
private List<AnnotationValue<?, ?>> values;
public RawDescriptionArray(TypePool typePool, ComponentTypeReference componentTypeReference, List<AnnotationValue<?, ?>> values) {
this.typePool = typePool;
this.values = values;
this.componentTypeReference = componentTypeReference;
}
@Override
public Object[] resolve() {
TypeDescription componentTypeDescription = typePool.describe(componentTypeReference.lookup()).resolve();
Class<?> componentType;
if (componentTypeDescription.represents(Class.class)) {
componentType = TypeDescription.class;
} else if (componentTypeDescription.isAssignableTo(Enum.class)) {
// Enums can implement annotation interfaces, check this first.
/**
* Creates a new array value representation of a complex array.
*
* @param typePool The type pool to use for looking up types.
* @param componentTypeReference A lazy reference to the component type of this array.
* @param values A list of all values of this annotation.
*/
componentType = EnumerationDescription.class;
} else if (componentTypeDescription.isAssignableTo(Annotation.class)) {
componentType = AnnotationDescription.class;
} else if (componentTypeDescription.represents(String.class)) {
componentType = String.class;
} else {
throw new IllegalStateException("Unexpected complex array component type " + componentTypeDescription);
}
Object[] array = (Object[]) Array.newInstance(componentType, values.size());
int index = 0;
for (AnnotationValue<?, ?> annotationValue : values) {
Array.set(array, index++, annotationValue.resolve());
}
return array;
}
@Override
public AnnotationValue.Loaded<Object[]> load(ClassLoader classLoader) throws ClassNotFoundException {
List<AnnotationValue.Loaded<?>> loadedValues = new ArrayList<AnnotationValue.Loaded<?>>(values.size());
for (AnnotationValue<?, ?> value : values) {
loadedValues.add(value.load(classLoader));
}
return new Loaded(Class.forName(componentTypeReference.lookup(), false, classLoader), loadedValues);
}
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof AnnotationValue<?, ?>)) return false;
Object value = ((AnnotationValue<?, ?>) other).resolve();
return value instanceof Object[] && Arrays.equals(resolve(), (Object[]) value);
}
@Override
public int hashCode() {
return Arrays.hashCode(resolve());
}
@Override
public String toString() {
return RenderingDispatcher.CURRENT.toSourceString(values);
}
/**
* A lazy representation of the component type of an array.
*/
public interface ComponentTypeReference {
/**
* Lazily returns the binary name of the array component type of an annotation value.
*
* @return The binary name of the component type.
*/
String lookup();
}
/**
* Represents a loaded annotation property representing a complex array.
*/
protected static class Loaded extends AnnotationValue.Loaded.AbstractBase<Object[]> {
/**
* The array's loaded component type.
*/
private final Class<?> componentType;
/**
* A list of loaded values of the represented complex array.
*/
private final List<AnnotationValue.Loaded<?>> values;
/**
* Creates a new representation of an annotation property representing an array of
* non-trivial values.
*
* @param componentType The array's loaded component type.
* @param values A list of loaded values of the represented complex array.
*/
public Loaded(Class<?> componentType, List<AnnotationValue.Loaded<?>> values) {
this.componentType = componentType;
this.values = values;
}
@Override
public State getState() {
for (AnnotationValue.Loaded<?> value : values) {
if (!value.getState().isResolved()) {
return State.UNRESOLVED;
}
}
return State.RESOLVED;
}
@Override
public Object[] resolve() {
Object[] array = (Object[]) Array.newInstance(componentType, values.size());
int index = 0;
for (AnnotationValue.Loaded<?> annotationValue : values) {
Array.set(array, index++, annotationValue.resolve());
}
return array;
}
@Override
public boolean represents(Object value) {
if (!(value instanceof Object[])) return false;
if (value.getClass().getComponentType() != componentType) return false;
Object[] array = (Object[]) value;
if (values.size() != array.length) return false;
Iterator<AnnotationValue.Loaded<?>> iterator = values.iterator();
for (Object aValue : array) {
AnnotationValue.Loaded<?> self = iterator.next();
if (!self.getState().isResolved() || !self.represents(aValue)) {
return false;
}
}
return true;
}
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof AnnotationValue.Loaded<?>)) return false;
AnnotationValue.Loaded<?> loadedOther = (AnnotationValue.Loaded<?>) other;
if (!loadedOther.getState().isResolved()) return false;
Object otherValue = loadedOther.resolve();
if (!(otherValue instanceof Object[])) return false;
Object[] otherArrayValue = (Object[]) otherValue;
if (values.size() != otherArrayValue.length) return false;
Iterator<AnnotationValue.Loaded<?>> iterator = values.iterator();
for (Object value : otherArrayValue) {
AnnotationValue.Loaded<?> self = iterator.next();
if (!self.resolve().equals(value)) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
int result = 1;
for (AnnotationValue.Loaded<?> value : values) {
result = 31 * result + value.hashCode();
}
return result;
}
@Override
public String toString() {
return RenderingDispatcher.CURRENT.toSourceString(values);
}
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.AbstractBase)) return false;
final TypePool.AbstractBase other = (TypePool.AbstractBase) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$cacheProvider = this.cacheProvider;
final java.lang.Object other$cacheProvider = other.cacheProvider;
if (this$cacheProvider == null ? other$cacheProvider != null : !this$cacheProvider.equals(other$cacheProvider)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.AbstractBase;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $cacheProvider = this.cacheProvider;
result = result * PRIME + ($cacheProvider == null ? 43 : $cacheProvider.hashCode());
return result;
}
}
/**
* <p>
* A default implementation of a {@link TypePool} that models binary data in the Java byte code format
* into a {@link TypeDescription}. The data lookup is delegated to a {@link ClassFileLocator}.
* </p>
* <p>
* {@link Resolution}s that are produced by this type pool are either fully resolved or not resolved at all.
* </p>
*/
class Default extends AbstractBase.Hierarchical {
/**
* Indicates that a visited method should be ignored.
*/
private static final MethodVisitor IGNORE_METHOD = null;
/**
* The locator to query for finding binary data of a type.
*/
protected final ClassFileLocator classFileLocator;
/**
* The reader mode to apply by this default type pool.
*/
protected final ReaderMode readerMode;
/**
* Creates a new default type pool without a parent pool.
*
* @param cacheProvider The cache provider to be used.
* @param classFileLocator The class file locator to be used.
* @param readerMode The reader mode to apply by this default type pool.
*/
public Default(CacheProvider cacheProvider, ClassFileLocator classFileLocator, ReaderMode readerMode) {
this(cacheProvider, classFileLocator, readerMode, Empty.INSTANCE);
}
/**
* Creates a new default type pool.
*
* @param cacheProvider The cache provider to be used.
* @param classFileLocator The class file locator to be used.
* @param readerMode The reader mode to apply by this default type pool.
* @param parentPool The parent type pool.
*/
public Default(CacheProvider cacheProvider, ClassFileLocator classFileLocator, ReaderMode readerMode, TypePool parentPool) {
super(cacheProvider, parentPool);
this.classFileLocator = classFileLocator;
this.readerMode = readerMode;
}
/**
* Creates a default {@link TypePool} that looks up data by querying the system class
* loader. The returned instance is configured to use a fast reading mode and a simple cache.
*
* @return A type pool that reads its data from the system class path.
*/
public static TypePool ofClassPath() {
return of(ClassFileLocator.ForClassLoader.ofClassPath());
}
/**
* Returns a type pool for the provided class loader.
*
* @param classLoader The class loader for which this class pool is representing types.
* @return An appropriate type pool.
*/
public static TypePool of(ClassLoader classLoader) {
return of(ClassFileLocator.ForClassLoader.of(classLoader));
}
/**
* Creates a default {@link TypePool} that looks up data by querying the supplied class
* file locator. The returned instance is configured to use a fast reading mode and a simple cache.
*
* @param classFileLocator The class file locator to use.
* @return A type pool that reads its data from the system class path.
*/
public static TypePool of(ClassFileLocator classFileLocator) {
return new Default(new CacheProvider.Simple(), classFileLocator, ReaderMode.FAST);
}
@Override
protected Resolution doDescribe(String name) {
try {
ClassFileLocator.Resolution resolution = classFileLocator.locate(name);
return resolution.isResolved() ? new Resolution.Simple(parse(resolution.resolve())) : new Resolution.Illegal(name);
} catch (IOException exception) {
throw new IllegalStateException("Error while reading class file", exception);
}
}
/**
* Parses a binary representation and transforms it into a type description.
*
* @param binaryRepresentation The binary data to be parsed.
* @return A type description of the binary data.
*/
private TypeDescription parse(byte[] binaryRepresentation) {
ClassReader classReader = new ClassReader(binaryRepresentation);
TypeExtractor typeExtractor = new TypeExtractor();
classReader.accept(typeExtractor, readerMode.getFlags());
return typeExtractor.toTypeDescription();
}
/**
* Determines the granularity of the class file parsing that is conducted by a {@link TypePool.Default}.
*/
public enum ReaderMode {
/**
* The extended reader mode parses the code segment of each method in order to detect parameter names
* that are only stored in a method's debugging information but are not explicitly included.
*/
EXTENDED(ClassReader.SKIP_FRAMES), /**
* The fast reader mode skips the code segment of each method and cannot detect parameter names that are
* only contained within the debugging information. This mode still detects explicitly included method
* parameter names.
*/
FAST(ClassReader.SKIP_CODE);
/**
* The flags to provide to a {@link ClassReader} for parsing a file.
*/
private final int flags;
/**
* Creates a new reader mode constant.
*
* @param flags The flags to provide to a {@link ClassReader} for parsing a file.
*/
ReaderMode(int flags) {
this.flags = flags;
}
/**
* Returns the flags to provide to a {@link ClassReader} for parsing a file.
*
* @return The flags to provide to a {@link ClassReader} for parsing a file.
*/
protected int getFlags() {
return flags;
}
/**
* Determines if this reader mode represents extended reading.
*
* @return {@code true} if this reader mode represents extended reading.
*/
public boolean isExtended() {
return this == EXTENDED;
}
}
/**
* <p>
* A variant of {@link TypePool.Default} that resolves type descriptions lazily. A lazy resolution respects this type
* pool's {@link CacheProvider} but requeries this cache pool for every access of a property of a {@link TypeDescription}.
* </p>
* <p>
* {@link Resolution}s of this type pool are only fully resolved if a property that is not the type's name is required.
* </p>
*/
public static class WithLazyResolution extends Default {
/**
* Creates a new default type pool with lazy resolution and without a parent pool.
*
* @param cacheProvider The cache provider to be used.
* @param classFileLocator The class file locator to be used.
* @param readerMode The reader mode to apply by this default type pool.
*/
public WithLazyResolution(CacheProvider cacheProvider, ClassFileLocator classFileLocator, ReaderMode readerMode) {
this(cacheProvider, classFileLocator, readerMode, Empty.INSTANCE);
}
/**
* Creates a new default type pool with lazy resolution.
*
* @param cacheProvider The cache provider to be used.
* @param classFileLocator The class file locator to be used.
* @param readerMode The reader mode to apply by this default type pool.
* @param parentPool The parent type pool.
*/
public WithLazyResolution(CacheProvider cacheProvider, ClassFileLocator classFileLocator, ReaderMode readerMode, TypePool parentPool) {
super(cacheProvider, classFileLocator, readerMode, parentPool);
}
/**
* Creates a default {@link TypePool} with lazy resolution that looks up data by querying the system class
* loader. The returned instance is configured to use a fast reading mode and a simple cache.
*
* @return A type pool that reads its data from the system class path.
*/
public static TypePool ofClassPath() {
return of(ClassFileLocator.ForClassLoader.ofClassPath());
}
/**
* Returns a default {@link TypePool} with lazy resolution for the provided class loader.
*
* @param classLoader The class loader for which this class pool is representing types.
* @return An appropriate type pool.
*/
public static TypePool of(ClassLoader classLoader) {
return of(ClassFileLocator.ForClassLoader.of(classLoader));
}
/**
* Creates a default {@link TypePool} with lazy resolution that looks up data by querying the supplied class
* file locator. The returned instance is configured to use a fast reading mode and a simple cache.
*
* @param classFileLocator The class file locator to use.
* @return A type pool that reads its data from the system class path.
*/
public static TypePool of(ClassFileLocator classFileLocator) {
return new WithLazyResolution(new CacheProvider.Simple(), classFileLocator, ReaderMode.FAST);
}
@Override
protected Resolution doDescribe(String name) {
return new LazyResolution(name);
}
@Override
protected Resolution doCache(String name, Resolution resolution) {
return resolution;
}
/**
* Non-lazily resolves a type name.
*
* @param name The name of the type to resolve.
* @return The resolution for the type of this name.
*/
protected Resolution doResolve(String name) {
Resolution resolution = cacheProvider.find(name);
if (resolution == null) {
resolution = cacheProvider.register(name, WithLazyResolution.super.doDescribe(name));
}
return resolution;
}
/**
* A lazy resolution of a type that the enclosing type pool attempts to resolve.
*/
protected class LazyResolution implements Resolution {
/**
* The type's name.
*/
private final String name;
/**
* Creates a new lazy resolution.
*
* @param name The type's name.
*/
protected LazyResolution(String name) {
this.name = name;
}
@Override
public boolean isResolved() {
return doResolve(name).isResolved();
}
@Override
public TypeDescription resolve() {
return new LazyTypeDescription(name);
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private WithLazyResolution getOuter() {
return WithLazyResolution.this;
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
LazyResolution that = (LazyResolution) object;
return name.equals(that.name) && getOuter().equals(that.getOuter());
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return name.hashCode() + 31 * getOuter().hashCode();
}
}
/**
* A lazy type description that resolves any property that is not the name only when requested.
*/
protected class LazyTypeDescription extends TypeDescription.AbstractBase.OfSimpleType.WithDelegation {
/**
* The type's name.
*/
private final String name;
/**
* Creates a new lazy type description.
*
* @param name The type's name.
*/
protected LazyTypeDescription(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
protected TypeDescription delegate() {
return doResolve(name).resolve();
}
}
}
/**
* An annotation registrant implements a visitor pattern for reading an unknown amount of values of annotations.
*/
protected interface AnnotationRegistrant {
/**
* Registers an annotation value.
*
* @param name The name of the annotation value.
* @param annotationValue The value of the annotation.
*/
void register(String name, AnnotationValue<?, ?> annotationValue);
/**
* Called once all annotation values are visited.
*/
void onComplete();
/**
* An abstract base implementation of an annotation registrant.
*/
abstract class AbstractBase implements AnnotationRegistrant {
/**
* The annotation descriptor.
*/
private final String descriptor;
/**
* The values that were collected so far.
*/
private final Map<String, AnnotationValue<?, ?>> values;
/**
* Creates a new annotation registrant.
*
* @param descriptor The annotation descriptor.
*/
protected AbstractBase(String descriptor) {
this.descriptor = descriptor;
values = new HashMap<String, AnnotationValue<?, ?>>();
}
@Override
public void register(String name, AnnotationValue<?, ?> annotationValue) {
values.put(name, annotationValue);
}
@Override
public void onComplete() {
getTokens().add(new LazyTypeDescription.AnnotationToken(descriptor, values));
}
/**
* Returns the token list for this collector.
*
* @return The token list for this collector.
*/
protected abstract List<LazyTypeDescription.AnnotationToken> getTokens();
/**
* A base implementation for a collector for a type variable.
*/
protected static abstract class ForTypeVariable extends AbstractBase {
/**
* The type variable's type path.
*/
private final String typePath;
/**
* Creates a new annotation collector.
*
* @param descriptor The annotation descriptor.
* @param typePath The type variable's type path.
*/
protected ForTypeVariable(String descriptor, TypePath typePath) {
super(descriptor);
this.typePath = typePath == null ? LazyTypeDescription.GenericTypeToken.EMPTY_TYPE_PATH : typePath.toString();
}
@Override
protected List<LazyTypeDescription.AnnotationToken> getTokens() {
Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap = getPathMap();
List<LazyTypeDescription.AnnotationToken> tokens = pathMap.get(typePath);
if (tokens == null) {
tokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
pathMap.put(typePath, tokens);
}
return tokens;
}
/**
* Returns this collector's path map.
*
* @return This collector's path map.
*/
protected abstract Map<String, List<LazyTypeDescription.AnnotationToken>> getPathMap();
/**
* A base implementation for a collector for a type variable with an index.
*/
protected static abstract class WithIndex extends AbstractBase.ForTypeVariable {
/**
* The type variable's index.
*/
private final int index;
/**
* Creates a new annotation collector.
*
* @param descriptor The annotation descriptor.
* @param typePath The type variable's type path.
* @param index The type variable's index.
*/
protected WithIndex(String descriptor, TypePath typePath, int index) {
super(descriptor, typePath);
this.index = index;
}
@Override
protected Map<String, List<LazyTypeDescription.AnnotationToken>> getPathMap() {
Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap = getIndexedPathMap();
Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap = indexedPathMap.get(index);
if (pathMap == null) {
pathMap = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
indexedPathMap.put(index, pathMap);
}
return pathMap;
}
/**
* Returns this collector's indexed path map.
*
* @return This collector's indexed path map.
*/
protected abstract Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> getIndexedPathMap();
/**
* A base implementation for a collector for a type variable with two indices.
*/
protected static abstract class DoubleIndexed extends WithIndex {
/**
* The type variable's first index.
*/
private final int preIndex;
/**
* Creates a new annotation collector.
*
* @param descriptor The annotation descriptor.
* @param typePath The type variable's type path.
* @param index The type variable's index.
* @param preIndex The type variable's first index.
*/
protected DoubleIndexed(String descriptor, TypePath typePath, int index, int preIndex) {
super(descriptor, typePath, index);
this.preIndex = preIndex;
}
@Override
protected Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> getIndexedPathMap() {
Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> doubleIndexPathMap = getDoubleIndexedPathMap();
Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap = doubleIndexPathMap.get(preIndex);
if (indexedPathMap == null) {
indexedPathMap = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
doubleIndexPathMap.put(preIndex, indexedPathMap);
}
return indexedPathMap;
}
/**
* Returns this collector's double indexed path map.
*
* @return This collector's double indexed path map.
*/
protected abstract Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> getDoubleIndexedPathMap();
}
}
}
}
/**
* An annotation collector for a byte code element.
*/
class ForByteCodeElement extends AbstractBase {
/**
* The target collection.
*/
private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
/**
* Creates a new annotation collector for a byte code element.
*
* @param descriptor The annotation descriptor.
* @param annotationTokens The target collection.
*/
protected ForByteCodeElement(String descriptor, List<LazyTypeDescription.AnnotationToken> annotationTokens) {
super(descriptor);
this.annotationTokens = annotationTokens;
}
@Override
protected List<LazyTypeDescription.AnnotationToken> getTokens() {
return annotationTokens;
}
/**
* An annotation collector for a byte code element with an index.
*/
public static class WithIndex extends AbstractBase {
/**
* The byte code element's index.
*/
private final int index;
/**
* The target collection.
*/
private final Map<Integer, List<LazyTypeDescription.AnnotationToken>> annotationTokens;
/**
* Creates a new annotation collector for a byte code element with an index.
*
* @param descriptor The annotation descriptor.
* @param index The byte code element's index.
* @param annotationTokens The target collection.
*/
protected WithIndex(String descriptor, int index, Map<Integer, List<LazyTypeDescription.AnnotationToken>> annotationTokens) {
super(descriptor);
this.index = index;
this.annotationTokens = annotationTokens;
}
@Override
protected List<LazyTypeDescription.AnnotationToken> getTokens() {
List<LazyTypeDescription.AnnotationToken> annotationTokens = this.annotationTokens.get(index);
if (annotationTokens == null) {
annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
this.annotationTokens.put(index, annotationTokens);
}
return annotationTokens;
}
}
}
/**
* An annotation collector for a type variable.
*/
class ForTypeVariable extends AbstractBase.ForTypeVariable {
/**
* The target collection.
*/
private final Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap;
/**
* Creates a new annotation collector.
*
* @param descriptor The annotation descriptor.
* @param typePath The type variable's type path.
* @param pathMap The target collection.
*/
protected ForTypeVariable(String descriptor, TypePath typePath, Map<String, List<LazyTypeDescription.AnnotationToken>> pathMap) {
super(descriptor, typePath);
this.pathMap = pathMap;
}
@Override
protected Map<String, List<LazyTypeDescription.AnnotationToken>> getPathMap() {
return pathMap;
}
/**
* An annotation collector for a type variable with an index.
*/
public static class WithIndex extends AbstractBase.ForTypeVariable.WithIndex {
/**
* The target collection.
*/
private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap;
/**
* Creates a new annotation collector.
*
* @param descriptor The annotation descriptor.
* @param typePath The type variable's type path.
* @param index The target index.
* @param indexedPathMap The target collection.
*/
protected WithIndex(String descriptor, TypePath typePath, int index, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> indexedPathMap) {
super(descriptor, typePath, index);
this.indexedPathMap = indexedPathMap;
}
@Override
protected Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> getIndexedPathMap() {
return indexedPathMap;
}
/**
* An annotation collector for a type variable with two indices.
*/
public static class DoubleIndexed extends AbstractBase.ForTypeVariable.WithIndex.DoubleIndexed {
/**
* The target collection.
*/
private final Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> doubleIndexedPathMap;
/**
* Creates a new annotation collector.
*
* @param descriptor The annotation descriptor.
* @param typePath The type variable's type path.
* @param index The target index.
* @param preIndex The initial target index.
* @param doubleIndexedPathMap The target collection.
*/
protected DoubleIndexed(String descriptor, TypePath typePath, int index, int preIndex, Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> doubleIndexedPathMap) {
super(descriptor, typePath, index, preIndex);
this.doubleIndexedPathMap = doubleIndexedPathMap;
}
@Override
protected Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> getDoubleIndexedPathMap() {
return doubleIndexedPathMap;
}
}
}
}
}
/**
* A component type locator allows for the lazy location of an array's component type.
*/
protected interface ComponentTypeLocator {
/**
* Binds this component type to a given property name of an annotation.
*
* @param name The name of an annotation property which the returned component type reference should
* query for resolving an array's component type.
* @return A component type reference to an annotation value's component type.
*/
RawDescriptionArray.ComponentTypeReference bind(String name);
/**
* A component type locator which cannot legally resolve an array's component type.
*/
enum Illegal implements ComponentTypeLocator {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public RawDescriptionArray.ComponentTypeReference bind(String name) {
throw new IllegalStateException("Unexpected lookup of component type for " + name);
}
}
/**
* A component type locator that lazily analyses an annotation for resolving an annotation property's
* array value's component type.
*/
class ForAnnotationProperty implements ComponentTypeLocator {
/**
* The type pool to query for type descriptions.
*/
private final TypePool typePool;
/**
* The name of the annotation to analyze.
*/
private final String annotationName;
/**
* Creates a new component type locator for an array value.
*
* @param typePool The type pool to be used for looking up linked types.
* @param annotationDescriptor A descriptor of the annotation to analyze.
*/
public ForAnnotationProperty(TypePool typePool, String annotationDescriptor) {
this.typePool = typePool;
annotationName = annotationDescriptor.substring(1, annotationDescriptor.length() - 1).replace('/', '.');
}
@Override
public RawDescriptionArray.ComponentTypeReference bind(String name) {
return new Bound(name);
}
/**
* A bound representation of a
* {@link TypePool.Default.ComponentTypeLocator.ForAnnotationProperty}.
*/
protected class Bound implements RawDescriptionArray.ComponentTypeReference {
/**
* The name of the annotation property.
*/
private final String name;
protected Bound(String name) {
this.name = name;
}
@Override
public String lookup() {
return typePool.describe(annotationName).resolve().getDeclaredMethods().filter(ElementMatchers.named(name)).getOnly().getReturnType().asErasure().getComponentType().getName();
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public boolean equals(Object other) {
return this == other || !(other == null || getClass() != other.getClass()) && name.equals(((Bound) other).name) && ForAnnotationProperty.this.equals(((Bound) other).getOuter());
}
// HE: Remove when Lombok support for getOuter is added.
/**
* Creates a new bound component type locator for an annotation property.
*
* @param name The name of the annotation property.
*/
@Override
public int hashCode() {
return name.hashCode() + 31 * ForAnnotationProperty.this.hashCode();
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private ForAnnotationProperty getOuter() {
return ForAnnotationProperty.this;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.ComponentTypeLocator.ForAnnotationProperty)) return false;
final TypePool.Default.ComponentTypeLocator.ForAnnotationProperty other = (TypePool.Default.ComponentTypeLocator.ForAnnotationProperty) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$typePool = this.typePool;
final java.lang.Object other$typePool = other.typePool;
if (this$typePool == null ? other$typePool != null : !this$typePool.equals(other$typePool)) return false;
final java.lang.Object this$annotationName = this.annotationName;
final java.lang.Object other$annotationName = other.annotationName;
if (this$annotationName == null ? other$annotationName != null : !this$annotationName.equals(other$annotationName)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.ComponentTypeLocator.ForAnnotationProperty;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $typePool = this.typePool;
result = result * PRIME + ($typePool == null ? 43 : $typePool.hashCode());
final java.lang.Object $annotationName = this.annotationName;
result = result * PRIME + ($annotationName == null ? 43 : $annotationName.hashCode());
return result;
}
}
/**
* A component type locator that locates an array type by a method's return value from its method descriptor.
*/
class ForArrayType implements ComponentTypeLocator, RawDescriptionArray.ComponentTypeReference {
/**
* The resolved component type's binary name.
*/
private final String componentType;
/**
* Creates a new component type locator for an array type.
*
* @param methodDescriptor The method descriptor to resolve.
*/
public ForArrayType(String methodDescriptor) {
String arrayType = Type.getMethodType(methodDescriptor).getReturnType().getClassName();
componentType = arrayType.substring(0, arrayType.length() - 2);
}
@Override
public RawDescriptionArray.ComponentTypeReference bind(String name) {
return this;
}
@Override
public String lookup() {
return componentType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.ComponentTypeLocator.ForArrayType)) return false;
final TypePool.Default.ComponentTypeLocator.ForArrayType other = (TypePool.Default.ComponentTypeLocator.ForArrayType) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$componentType = this.componentType;
final java.lang.Object other$componentType = other.componentType;
if (this$componentType == null ? other$componentType != null : !this$componentType.equals(other$componentType)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.ComponentTypeLocator.ForArrayType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $componentType = this.componentType;
result = result * PRIME + ($componentType == null ? 43 : $componentType.hashCode());
return result;
}
}
}
/**
* A type registrant allows to register a generic type token.
*/
protected interface GenericTypeRegistrant {
/**
* Registers a discovered generic type token.
*
* @param token The token to be registered.
*/
void register(LazyTypeDescription.GenericTypeToken token);
/**
* A signature visitor that rejects any discovered generic type.
*/
class RejectingSignatureVisitor extends SignatureVisitor {
/**
* The message of the error message.
*/
private static final String MESSAGE = "Unexpected token in generic signature";
/**
* Creates a new rejecting signature visitor.
*/
public RejectingSignatureVisitor() {
super(Opcodes.ASM5);
}
@Override
public void visitFormalTypeParameter(String name) {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitClassBound() {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitInterfaceBound() {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitSuperclass() {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitInterface() {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitParameterType() {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitReturnType() {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitExceptionType() {
throw new IllegalStateException(MESSAGE);
}
@Override
public void visitBaseType(char descriptor) {
throw new IllegalStateException(MESSAGE);
}
@Override
public void visitTypeVariable(String name) {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitArrayType() {
throw new IllegalStateException(MESSAGE);
}
@Override
public void visitClassType(String name) {
throw new IllegalStateException(MESSAGE);
}
@Override
public void visitInnerClassType(String name) {
throw new IllegalStateException(MESSAGE);
}
@Override
public void visitTypeArgument() {
throw new IllegalStateException(MESSAGE);
}
@Override
public SignatureVisitor visitTypeArgument(char wildcard) {
throw new IllegalStateException(MESSAGE);
}
@Override
public void visitEnd() {
throw new IllegalStateException(MESSAGE);
}
}
}
/**
* A bag for collecting parameter meta information that is stored as debug information for implemented
* methods.
*/
protected static class ParameterBag {
/**
* An array of the method's parameter types.
*/
private final Type[] parameterType;
/**
* A map containing the tokens that were collected until now.
*/
private final Map<Integer, String> parameterRegistry;
/**
* Creates a new bag.
*
* @param parameterType An array of parameter types for the method on which this parameter bag
* is used.
*/
protected ParameterBag(Type[] parameterType) {
this.parameterType = parameterType;
parameterRegistry = new HashMap<Integer, String>();
}
/**
* Registers a new parameter.
*
* @param offset The offset of the registered entry on the local variable array of the method.
* @param name The name of the parameter.
*/
protected void register(int offset, String name) {
parameterRegistry.put(offset, name);
}
/**
* Resolves the collected parameters as a list of parameter tokens.
*
* @param isStatic {@code true} if the analyzed method is static.
* @return A list of parameter tokens based on the collected information.
*/
protected List<LazyTypeDescription.MethodToken.ParameterToken> resolve(boolean isStatic) {
List<LazyTypeDescription.MethodToken.ParameterToken> parameterTokens = new ArrayList<LazyTypeDescription.MethodToken.ParameterToken>(parameterType.length);
int offset = isStatic ? StackSize.ZERO.getSize() : StackSize.SINGLE.getSize();
for (Type aParameterType : parameterType) {
String name = this.parameterRegistry.get(offset);
parameterTokens.add(name == null ? new LazyTypeDescription.MethodToken.ParameterToken() : new LazyTypeDescription.MethodToken.ParameterToken(name));
offset += aParameterType.getSize();
}
return parameterTokens;
}
}
/**
* A generic type extractor allows for an iterative extraction of generic type information.
*/
protected static class GenericTypeExtractor extends GenericTypeRegistrant.RejectingSignatureVisitor implements GenericTypeRegistrant {
/**
* A registrant that receives any discovered type.
*/
private final GenericTypeRegistrant genericTypeRegistrant;
/**
* The current token that is in the process of creation.
*/
private IncompleteToken incompleteToken;
/**
* Creates a new generic type extractor.
*
* @param genericTypeRegistrant The target to receive the complete type.
*/
protected GenericTypeExtractor(GenericTypeRegistrant genericTypeRegistrant) {
this.genericTypeRegistrant = genericTypeRegistrant;
}
@Override
public void visitBaseType(char descriptor) {
genericTypeRegistrant.register(LazyTypeDescription.GenericTypeToken.ForPrimitiveType.of(descriptor));
}
@Override
public void visitTypeVariable(String name) {
genericTypeRegistrant.register(new LazyTypeDescription.GenericTypeToken.ForTypeVariable(name));
}
@Override
public SignatureVisitor visitArrayType() {
return new GenericTypeExtractor(this);
}
@Override
public void register(LazyTypeDescription.GenericTypeToken componentTypeToken) {
genericTypeRegistrant.register(new LazyTypeDescription.GenericTypeToken.ForGenericArray(componentTypeToken));
}
@Override
public void visitClassType(String name) {
incompleteToken = new IncompleteToken.ForTopLevelType(name);
}
@Override
public void visitInnerClassType(String name) {
incompleteToken = new IncompleteToken.ForInnerClass(name, incompleteToken);
}
@Override
public void visitTypeArgument() {
incompleteToken.appendPlaceholder();
}
@Override
public SignatureVisitor visitTypeArgument(char wildcard) {
switch (wildcard) {
case SignatureVisitor.SUPER:
return incompleteToken.appendLowerBound();
case SignatureVisitor.EXTENDS:
return incompleteToken.appendUpperBound();
case SignatureVisitor.INSTANCEOF:
return incompleteToken.appendDirectBound();
default:
throw new IllegalArgumentException("Unknown wildcard: " + wildcard);
}
}
@Override
public void visitEnd() {
genericTypeRegistrant.register(incompleteToken.toToken());
}
/**
* An incomplete {@link LazyTypeDescription.GenericTypeToken}.
*/
protected interface IncompleteToken {
/**
* Appends a lower bound to this token.
*
* @return A signature visitor for visiting the lower bound's type.
*/
SignatureVisitor appendLowerBound();
/**
* Appends an upper bound to this token.
*
* @return A signature visitor for visiting the upper bound's type.
*/
SignatureVisitor appendUpperBound();
/**
* Appends a direct bound to this token.
*
* @return A signature visitor for visiting the direct bound's type.
*/
SignatureVisitor appendDirectBound();
/**
* Appends a placeholder to this token.
*/
void appendPlaceholder();
/**
* Returns {@code true} if this token describes a type with parameters.
*
* @return {@code true} if this token describes a type with parameters.
*/
boolean isParameterized();
/**
* Returns the name of this token.
*
* @return The name of this token.
*/
String getName();
/**
* Converts this incomplete token to a completed token.
*
* @return The finalized token.
*/
LazyTypeDescription.GenericTypeToken toToken();
/**
* An abstract base implementation of an incomplete token.
*/
abstract class AbstractBase implements IncompleteToken {
/**
* The parameters of this token.
*/
protected final List<LazyTypeDescription.GenericTypeToken> parameters;
/**
* Creates a new base implementation of an incomplete token.
*/
public AbstractBase() {
parameters = new ArrayList<LazyTypeDescription.GenericTypeToken>();
}
@Override
public SignatureVisitor appendDirectBound() {
return new GenericTypeExtractor(new ForDirectBound());
}
@Override
public SignatureVisitor appendUpperBound() {
return new GenericTypeExtractor(new ForUpperBound());
}
@Override
public SignatureVisitor appendLowerBound() {
return new GenericTypeExtractor(new ForLowerBound());
}
@Override
public void appendPlaceholder() {
parameters.add(LazyTypeDescription.GenericTypeToken.ForUnboundWildcard.INSTANCE);
}
/**
* A token for registering a direct bound.
*/
protected class ForDirectBound implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
parameters.add(token);
}
}
/**
* A token for registering a wildcard with an upper bound.
*/
protected class ForUpperBound implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
parameters.add(new LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard(token));
}
}
/**
* A token for registering a wildcard with a lower bound.
*/
protected class ForLowerBound implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
parameters.add(new LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard(token));
}
}
}
/**
* An incomplete token representing a generic type without an outer type.
*/
class ForTopLevelType extends AbstractBase {
/**
* The internal name of the type.
*/
private final String internalName;
/**
* Creates a new incomplete token representing a type without an outer type.
*
* @param internalName The internal name of the type.
*/
public ForTopLevelType(String internalName) {
this.internalName = internalName;
}
@Override
public LazyTypeDescription.GenericTypeToken toToken() {
return isParameterized() ? new LazyTypeDescription.GenericTypeToken.ForParameterizedType(getName(), parameters) : new LazyTypeDescription.GenericTypeToken.ForRawType(getName());
}
@Override
public boolean isParameterized() {
return !parameters.isEmpty();
}
@Override
public String getName() {
return internalName.replace('/', '.');
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.GenericTypeExtractor.IncompleteToken.ForTopLevelType)) return false;
final TypePool.Default.GenericTypeExtractor.IncompleteToken.ForTopLevelType other = (TypePool.Default.GenericTypeExtractor.IncompleteToken.ForTopLevelType) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$internalName = this.internalName;
final java.lang.Object other$internalName = other.internalName;
if (this$internalName == null ? other$internalName != null : !this$internalName.equals(other$internalName)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.GenericTypeExtractor.IncompleteToken.ForTopLevelType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $internalName = this.internalName;
result = result * PRIME + ($internalName == null ? 43 : $internalName.hashCode());
return result;
}
}
/**
* An incomplete generic type token representing a type with an outer type.
*/
class ForInnerClass extends AbstractBase {
/**
* The separator that indicates an inner type.
*/
private static final char INNER_CLASS_SEPARATOR = '$';
/**
* The internal name of the type.
*/
private final String internalName;
/**
* The token representing the outer type.
*/
private final IncompleteToken outerTypeToken;
/**
* Creates a new incomplete token representing a type without an outer type.
*
* @param internalName The internal name of the type.
* @param outerTypeToken The incomplete token representing the outer type.
*/
public ForInnerClass(String internalName, IncompleteToken outerTypeToken) {
this.internalName = internalName;
this.outerTypeToken = outerTypeToken;
}
@Override
public LazyTypeDescription.GenericTypeToken toToken() {
return isParameterized() || outerTypeToken.isParameterized() ? new LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested(getName(), parameters, outerTypeToken.toToken()) : new LazyTypeDescription.GenericTypeToken.ForRawType(getName());
}
@Override
public boolean isParameterized() {
return !parameters.isEmpty() || !outerTypeToken.isParameterized();
}
@Override
public String getName() {
return outerTypeToken.getName() + INNER_CLASS_SEPARATOR + internalName.replace('/', '.');
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.GenericTypeExtractor.IncompleteToken.ForInnerClass)) return false;
final TypePool.Default.GenericTypeExtractor.IncompleteToken.ForInnerClass other = (TypePool.Default.GenericTypeExtractor.IncompleteToken.ForInnerClass) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$internalName = this.internalName;
final java.lang.Object other$internalName = other.internalName;
if (this$internalName == null ? other$internalName != null : !this$internalName.equals(other$internalName)) return false;
final java.lang.Object this$outerTypeToken = this.outerTypeToken;
final java.lang.Object other$outerTypeToken = other.outerTypeToken;
if (this$outerTypeToken == null ? other$outerTypeToken != null : !this$outerTypeToken.equals(other$outerTypeToken)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.GenericTypeExtractor.IncompleteToken.ForInnerClass;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $internalName = this.internalName;
result = result * PRIME + ($internalName == null ? 43 : $internalName.hashCode());
final java.lang.Object $outerTypeToken = this.outerTypeToken;
result = result * PRIME + ($outerTypeToken == null ? 43 : $outerTypeToken.hashCode());
return result;
}
}
}
/**
* A signature visitor for extracting a generic type resolution.
*
* @param <T> The type of the resolution this visitor extracts.
*/
protected static abstract class ForSignature<T extends LazyTypeDescription.GenericTypeToken.Resolution> extends RejectingSignatureVisitor implements GenericTypeRegistrant {
/**
* The resolved type variable tokens.
*/
protected final List<LazyTypeDescription.GenericTypeToken.OfFormalTypeVariable> typeVariableTokens;
/**
* The name of the currently constructed type.
*/
protected String currentTypeParameter;
/**
* The bounds of the currently constructed type.
*/
protected List<LazyTypeDescription.GenericTypeToken> currentBounds;
/**
* Creates a new signature visitor.
*/
public ForSignature() {
typeVariableTokens = new ArrayList<LazyTypeDescription.GenericTypeToken.OfFormalTypeVariable>();
}
/**
* Applies an extraction of a generic signature given the supplied visitor.
*
* @param genericSignature The generic signature to interpret.
* @param visitor The visitor to apply.
* @param <S> The type of the generated resolution.
* @return The resolution of the supplied signature.
*/
protected static <S extends LazyTypeDescription.GenericTypeToken.Resolution> S extract(String genericSignature, ForSignature<S> visitor) {
SignatureReader signatureReader = new SignatureReader(genericSignature);
signatureReader.accept(visitor);
return visitor.resolve();
}
@Override
public void visitFormalTypeParameter(String name) {
collectTypeParameter();
currentTypeParameter = name;
currentBounds = new ArrayList<LazyTypeDescription.GenericTypeToken>();
}
@Override
public SignatureVisitor visitClassBound() {
return new GenericTypeExtractor(this);
}
@Override
public SignatureVisitor visitInterfaceBound() {
return new GenericTypeExtractor(this);
}
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
if (currentBounds == null) {
throw new IllegalStateException("Did not expect " + token + " before finding formal parameter");
}
currentBounds.add(token);
}
/**
* Collects the currently constructed type.
*/
protected void collectTypeParameter() {
if (currentTypeParameter != null) {
typeVariableTokens.add(new LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal(currentTypeParameter, currentBounds));
}
}
/**
* Completes the current resolution.
*
* @return The resolved generic signature.
*/
public abstract T resolve();
/**
* A parser for a generic type signature.
*/
protected static class OfType extends ForSignature<LazyTypeDescription.GenericTypeToken.Resolution.ForType> {
/**
* The interface type's generic signatures.
*/
private final List<LazyTypeDescription.GenericTypeToken> interfaceTypeTokens;
/**
* The super type's generic signature.
*/
private LazyTypeDescription.GenericTypeToken superClassToken;
/**
* Creates a new parser for a type signature.
*/
protected OfType() {
interfaceTypeTokens = new ArrayList<LazyTypeDescription.GenericTypeToken>();
}
/**
* Extracts a generic type resolution of a type signature.
*
* @param genericSignature The signature to interpret.
* @return The interpreted type signature.
*/
public static LazyTypeDescription.GenericTypeToken.Resolution.ForType extract(String genericSignature) {
try {
return genericSignature == null ? LazyTypeDescription.GenericTypeToken.Resolution.Raw.INSTANCE : ForSignature.extract(genericSignature, new OfType());
} catch (RuntimeException ignored) {
return LazyTypeDescription.GenericTypeToken.Resolution.Malformed.INSTANCE;
}
}
@Override
public SignatureVisitor visitSuperclass() {
collectTypeParameter();
return new GenericTypeExtractor(new SuperClassRegistrant());
}
@Override
public SignatureVisitor visitInterface() {
return new GenericTypeExtractor(new InterfaceTypeRegistrant());
}
@Override
public LazyTypeDescription.GenericTypeToken.Resolution.ForType resolve() {
return new LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized(superClassToken, interfaceTypeTokens, typeVariableTokens);
}
protected class SuperClassRegistrant implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
superClassToken = token;
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return OfType.this.hashCode();
}
// HE: Remove when Lombok support for getOuter is added.
/**
* A registrant for the super type.
*/
@Override
public boolean equals(Object other) {
return other != null && getClass() == other.getClass() && OfType.this.equals(((SuperClassRegistrant) other).getOuter());
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private OfType getOuter() {
return OfType.this;
}
}
protected class InterfaceTypeRegistrant implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
interfaceTypeTokens.add(token);
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return OfType.this.hashCode();
}
// HE: Remove when Lombok support for getOuter is added.
/**
* A registrant for the interface types.
*/
@Override
public boolean equals(Object other) {
return other != null && getClass() == other.getClass() && OfType.this.equals(((InterfaceTypeRegistrant) other).getOuter());
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private OfType getOuter() {
return OfType.this;
}
}
}
/**
* A parser for a generic method signature.
*/
protected static class OfMethod extends ForSignature<LazyTypeDescription.GenericTypeToken.Resolution.ForMethod> {
/**
* The generic parameter types.
*/
private final List<LazyTypeDescription.GenericTypeToken> parameterTypeTokens;
/**
* The generic exception types.
*/
private final List<LazyTypeDescription.GenericTypeToken> exceptionTypeTokens;
/**
* The generic return type.
*/
private LazyTypeDescription.GenericTypeToken returnTypeToken;
/**
* Creates a parser for a generic method signature.
*/
public OfMethod() {
parameterTypeTokens = new ArrayList<LazyTypeDescription.GenericTypeToken>();
exceptionTypeTokens = new ArrayList<LazyTypeDescription.GenericTypeToken>();
}
/**
* Extracts a generic method resolution of a method signature.
*
* @param genericSignature The signature to interpret.
* @return The interpreted method signature.
*/
public static LazyTypeDescription.GenericTypeToken.Resolution.ForMethod extract(String genericSignature) {
try {
return genericSignature == null ? LazyTypeDescription.GenericTypeToken.Resolution.Raw.INSTANCE : ForSignature.extract(genericSignature, new OfMethod());
} catch (RuntimeException ignored) {
return LazyTypeDescription.GenericTypeToken.Resolution.Malformed.INSTANCE;
}
}
@Override
public SignatureVisitor visitParameterType() {
return new GenericTypeExtractor(new ParameterTypeRegistrant());
}
@Override
public SignatureVisitor visitReturnType() {
collectTypeParameter();
return new GenericTypeExtractor(new ReturnTypeTypeRegistrant());
}
@Override
public SignatureVisitor visitExceptionType() {
return new GenericTypeExtractor(new ExceptionTypeRegistrant());
}
@Override
public LazyTypeDescription.GenericTypeToken.Resolution.ForMethod resolve() {
return new LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized(returnTypeToken, parameterTypeTokens, exceptionTypeTokens, typeVariableTokens);
}
protected class ParameterTypeRegistrant implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
parameterTypeTokens.add(token);
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return OfMethod.this.hashCode();
}
// HE: Remove when Lombok support for getOuter is added.
/**
* A registrant for a parameter type.
*/
@Override
public boolean equals(Object other) {
return other != null && getClass() == other.getClass() && OfMethod.this.equals(((ParameterTypeRegistrant) other).getOuter());
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private OfMethod getOuter() {
return OfMethod.this;
}
}
protected class ReturnTypeTypeRegistrant implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
returnTypeToken = token;
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return OfMethod.this.hashCode();
}
// HE: Remove when Lombok support for getOuter is added.
/**
* A registrant for a return type.
*/
@Override
public boolean equals(Object other) {
return other != null && getClass() == other.getClass() && OfMethod.this.equals(((ReturnTypeTypeRegistrant) other).getOuter());
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private OfMethod getOuter() {
return OfMethod.this;
}
}
protected class ExceptionTypeRegistrant implements GenericTypeRegistrant {
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
exceptionTypeTokens.add(token);
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return OfMethod.this.hashCode();
}
// HE: Remove when Lombok support for getOuter is added.
/**
* A registrant for an exception type.
*/
@Override
public boolean equals(Object other) {
return other != null && getClass() == other.getClass() && OfMethod.this.equals(((ExceptionTypeRegistrant) other).getOuter());
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private OfMethod getOuter() {
return OfMethod.this;
}
}
}
/**
* A parser for a generic field signature.
*/
protected static class OfField implements GenericTypeRegistrant {
/**
* The generic field type.
*/
private LazyTypeDescription.GenericTypeToken fieldTypeToken;
/**
* Extracts a generic field resolution of a field signature.
*
* @param genericSignature The signature to interpret.
* @return The interpreted field signature.
*/
public static LazyTypeDescription.GenericTypeToken.Resolution.ForField extract(String genericSignature) {
if (genericSignature == null) {
return LazyTypeDescription.GenericTypeToken.Resolution.Raw.INSTANCE;
} else {
SignatureReader signatureReader = new SignatureReader(genericSignature);
OfField visitor = new OfField();
try {
signatureReader.acceptType(new GenericTypeExtractor(visitor));
return visitor.resolve();
} catch (RuntimeException ignored) {
return LazyTypeDescription.GenericTypeToken.Resolution.Malformed.INSTANCE;
}
}
}
@Override
public void register(LazyTypeDescription.GenericTypeToken token) {
fieldTypeToken = token;
}
/**
* Completes the current resolution.
*
* @return The resolved generic signature.
*/
protected LazyTypeDescription.GenericTypeToken.Resolution.ForField resolve() {
return new LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized(fieldTypeToken);
}
}
}
}
/**
* A type description that looks up any referenced {@link ByteCodeElement} or
* {@link AnnotationDescription} by querying a type pool at lookup time.
*/
protected static class LazyTypeDescription extends TypeDescription.AbstractBase.OfSimpleType {
/**
* The index of a super class's type annotations.
*/
private static final int SUPER_CLASS_INDEX = -1;
/**
* Indicates that a type does not exist and does therefore not have a name.
*/
private static final String NO_TYPE = null;
/**
* The type pool to be used for looking up linked types.
*/
private final TypePool typePool;
/**
* The actual modifiers of this type.
*/
private final int actualModifiers;
/**
* The modifiers of this type.
*/
private final int modifiers;
/**
* The binary name of this type.
*/
private final String name;
/**
* The type's super type's descriptor or {@code null} if this type does not define a super type.
*/
private final String superClassDescriptor;
/**
* The type's generic signature as found in the class file or {@code null} if the type is not generic.
*/
private final String genericSignature;
/**
* The resolution of this type's generic type.
*/
private final GenericTypeToken.Resolution.ForType signatureResolution;
/**
* The descriptor of this type's interfaces.
*/
private final List<String> interfaceTypeDescriptors;
/**
* A definition of this type's containment within another type or method.
*/
private final TypeContainment typeContainment;
/**
* The binary name of this type's declaring type or {@code null} if no such type exists.
*/
private final String declaringTypeName;
/**
* A list of descriptors representing the types that are declared by this type.
*/
private final List<String> declaredTypes;
/**
* {@code true} if this type is an anonymous type.
*/
private final boolean anonymousType;
/**
* A mapping of type annotations for this type's super type and interface types by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> superTypeAnnotationTokens;
/**
* A mapping of type annotations of the type variables' type annotations by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens;
/**
* A mapping of type annotations of the type variables' bounds' type annotations by their indices and each variable's index.
*/
private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundsAnnotationTokens;
/**
* A list of tokens that represent the annotations of this type.
*/
private final List<AnnotationToken> annotationTokens;
/**
* A list of field tokens describing the field's of this type.
*/
private final List<FieldToken> fieldTokens;
/**
* A list of method tokens describing the method's of this type.
*/
private final List<MethodToken> methodTokens;
/**
* Creates a new lazy type description.
*
* @param typePool The type pool to be used for looking up linked types.
* @param actualModifiers The actual modifiers of this type.
* @param modifiers The modifiers of this type.
* @param name The binary name of this type.
* @param superClassInternalName The internal name of this type's super type or {@code null} if no such super type is defined.
* @param interfaceInternalName An array of this type's interfaces or {@code null} if this type does not define any interfaces.
* @param genericSignature The type's generic signature as found in the class file or {@code null} if the type is not generic.
* @param typeContainment A definition of this type's containment within another type or method.
* @param declaringTypeInternalName The internal name of this type's declaring type or {@code null} if no such type exists.
* @param declaredTypes A list of descriptors representing the types that are declared by this type.
* @param anonymousType {@code true} if this type is an anonymous type.
* @param superTypeAnnotationTokens A mapping of type annotations for this type's super type and interface types by their indices.
* @param typeVariableAnnotationTokens A mapping of type annotations of the type variables' type annotations by their indices.
* @param typeVariableBoundsAnnotationTokens A mapping of type annotations of the type variables' bounds' type annotations by their indices
* and each variable's index.
* @param annotationTokens A list of tokens that represent the annotations of this type.
* @param fieldTokens A list of field tokens describing the field's of this type.
* @param methodTokens A list of method tokens describing the method's of this type.
*/
protected LazyTypeDescription(TypePool typePool, int actualModifiers, int modifiers, String name, String superClassInternalName, String[] interfaceInternalName, String genericSignature, TypeContainment typeContainment, String declaringTypeInternalName, List<String> declaredTypes, boolean anonymousType, Map<Integer, Map<String, List<AnnotationToken>>> superTypeAnnotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundsAnnotationTokens, List<AnnotationToken> annotationTokens, List<FieldToken> fieldTokens, List<MethodToken> methodTokens) {
this.typePool = typePool;
this.actualModifiers = actualModifiers & ~Opcodes.ACC_SUPER;
this.modifiers = modifiers & ~(Opcodes.ACC_SUPER | Opcodes.ACC_DEPRECATED);
this.name = Type.getObjectType(name).getClassName();
this.superClassDescriptor = superClassInternalName == null ? NO_TYPE : Type.getObjectType(superClassInternalName).getDescriptor();
this.genericSignature = genericSignature;
signatureResolution = GenericTypeExtractor.ForSignature.OfType.extract(genericSignature);
if (interfaceInternalName == null) {
interfaceTypeDescriptors = Collections.emptyList();
} else {
interfaceTypeDescriptors = new ArrayList<String>(interfaceInternalName.length);
for (String internalName : interfaceInternalName) {
interfaceTypeDescriptors.add(Type.getObjectType(internalName).getDescriptor());
}
}
this.typeContainment = typeContainment;
declaringTypeName = declaringTypeInternalName == null ? NO_TYPE : declaringTypeInternalName.replace('/', '.');
this.declaredTypes = declaredTypes;
this.anonymousType = anonymousType;
this.superTypeAnnotationTokens = superTypeAnnotationTokens;
this.typeVariableAnnotationTokens = typeVariableAnnotationTokens;
this.typeVariableBoundsAnnotationTokens = typeVariableBoundsAnnotationTokens;
this.annotationTokens = annotationTokens;
this.fieldTokens = fieldTokens;
this.methodTokens = methodTokens;
}
@Override
public Generic getSuperClass() {
return superClassDescriptor == null || isInterface() ? Generic.UNDEFINED : signatureResolution.resolveSuperClass(superClassDescriptor, typePool, superTypeAnnotationTokens.get(SUPER_CLASS_INDEX), this);
}
@Override
public TypeList.Generic getInterfaces() {
return signatureResolution.resolveInterfaceTypes(interfaceTypeDescriptors, typePool, superTypeAnnotationTokens, this);
}
@Override
public MethodDescription getEnclosingMethod() {
return typeContainment.getEnclosingMethod(typePool);
}
@Override
public TypeDescription getEnclosingType() {
return typeContainment.getEnclosingType(typePool);
}
@Override
public TypeList getDeclaredTypes() {
return new LazyTypeList(typePool, declaredTypes);
}
@Override
public boolean isAnonymousClass() {
return anonymousType;
}
@Override
public boolean isLocalClass() {
return !anonymousType && typeContainment.isLocalType();
}
@Override
public boolean isMemberClass() {
return typeContainment.isMemberClass();
}
@Override
public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
return new FieldTokenList();
}
@Override
public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
return new MethodTokenList();
}
@Override
public PackageDescription getPackage() {
String name = getName();
int index = name.lastIndexOf('.');
return index == -1 ? PackageDescription.UNDEFINED : new LazyPackageDescription(typePool, name.substring(0, index));
}
@Override
public String getName() {
return name;
}
@Override
public TypeDescription getDeclaringType() {
return declaringTypeName == null ? TypeDescription.UNDEFINED : typePool.describe(declaringTypeName).resolve();
}
@Override
public int getModifiers() {
return modifiers;
}
@Override
public int getActualModifiers(boolean superFlag) {
return superFlag ? (actualModifiers | Opcodes.ACC_SUPER) : actualModifiers;
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asList(typePool, annotationTokens);
}
@Override
public TypeList.Generic getTypeVariables() {
return signatureResolution.resolveTypeVariables(typePool, this, typeVariableAnnotationTokens, typeVariableBoundsAnnotationTokens);
}
@Override
public String getGenericSignature() {
return genericSignature;
}
/**
* A list of field tokens representing each entry as a field description.
*/
protected class FieldTokenList extends FieldList.AbstractBase<FieldDescription.InDefinedShape> {
@Override
public FieldDescription.InDefinedShape get(int index) {
return fieldTokens.get(index).toFieldDescription(LazyTypeDescription.this);
}
@Override
public int size() {
return fieldTokens.size();
}
}
/**
* A list of method tokens representing each entry as a method description.
*/
protected class MethodTokenList extends MethodList.AbstractBase<MethodDescription.InDefinedShape> {
@Override
public MethodDescription.InDefinedShape get(int index) {
return methodTokens.get(index).toMethodDescription(LazyTypeDescription.this);
}
@Override
public int size() {
return methodTokens.size();
}
}
/**
* A declaration context encapsulates information about whether a type was declared within another type
* or within a method of another type.
*/
protected interface TypeContainment {
/**
* Returns the enclosing method or {@code null} if no such method exists.
*
* @param typePool The type pool to be used for looking up linked types.
* @return A method description describing the linked type or {@code null}.
*/
MethodDescription getEnclosingMethod(TypePool typePool);
/**
* Returns the enclosing type or {@code null} if no such type exists.
*
* @param typePool The type pool to be used for looking up linked types.
* @return A type description describing the linked type or {@code null}.
*/
TypeDescription getEnclosingType(TypePool typePool);
/**
* Returns {@code true} if the type is self-contained.
*
* @return {@code true} if the type is self-contained.
*/
boolean isSelfContained();
/**
* Returns {@code true} if the type is a member type.
*
* @return {@code true} if the type is a member type.
*/
boolean isMemberClass();
/**
* Returns {@code true} if the type is a local type unless it is an anonymous type.
*
* @return {@code true} if the type is a local type unless it is an anonymous type
*/
boolean isLocalType();
/**
* Describes a type that is not contained within another type, a method or a constructor.
*/
enum SelfContained implements TypeContainment {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public MethodDescription getEnclosingMethod(TypePool typePool) {
return MethodDescription.UNDEFINED;
}
@Override
public TypeDescription getEnclosingType(TypePool typePool) {
return TypeDescription.UNDEFINED;
}
@Override
public boolean isSelfContained() {
return true;
}
@Override
public boolean isMemberClass() {
return false;
}
@Override
public boolean isLocalType() {
return false;
}
}
/**
* Describes a type that is contained within another type.
*/
class WithinType implements TypeContainment {
/**
* The type's binary name.
*/
private final String name;
/**
* {@code true} if the type is a local type unless it is an anonymous type.
*/
private final boolean localType;
/**
* Creates a new type containment for a type that is declared within another type.
*
* @param internalName The type's internal name.
* @param localType {@code true} if the type is a local type unless it is an anonymous type.
*/
public WithinType(String internalName, boolean localType) {
name = internalName.replace('/', '.');
this.localType = localType;
}
@Override
public MethodDescription getEnclosingMethod(TypePool typePool) {
return MethodDescription.UNDEFINED;
}
@Override
public TypeDescription getEnclosingType(TypePool typePool) {
return typePool.describe(name).resolve();
}
@Override
public boolean isSelfContained() {
return false;
}
@Override
public boolean isMemberClass() {
return !localType;
}
@Override
public boolean isLocalType() {
return localType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.TypeContainment.WithinType)) return false;
final TypePool.Default.LazyTypeDescription.TypeContainment.WithinType other = (TypePool.Default.LazyTypeDescription.TypeContainment.WithinType) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
if (this.isLocalType() != other.isLocalType()) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.TypeContainment.WithinType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
result = result * PRIME + (this.isLocalType() ? 79 : 97);
return result;
}
}
/**
* Describes a type that is contained within a method or constructor.
*/
class WithinMethod implements TypeContainment {
/**
* The method's declaring type's internal name.
*/
private final String name;
/**
* The method's internal name.
*/
private final String methodName;
/**
* The method's descriptor.
*/
private final String methodDescriptor;
/**
* Creates a new type containment for a type that is declared within a method.
*
* @param internalName The method's declaring type's internal name.
* @param methodName The method's internal name.
* @param methodDescriptor The method's descriptor.
*/
public WithinMethod(String internalName, String methodName, String methodDescriptor) {
name = internalName.replace('/', '.');
this.methodName = methodName;
this.methodDescriptor = methodDescriptor;
}
@Override
public MethodDescription getEnclosingMethod(TypePool typePool) {
return getEnclosingType(typePool).getDeclaredMethods().filter(ElementMatchers.hasMethodName(methodName).and(ElementMatchers.hasDescriptor(methodDescriptor))).getOnly();
}
@Override
public TypeDescription getEnclosingType(TypePool typePool) {
return typePool.describe(name).resolve();
}
@Override
public boolean isSelfContained() {
return false;
}
@Override
public boolean isMemberClass() {
return false;
}
@Override
public boolean isLocalType() {
return true;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.TypeContainment.WithinMethod)) return false;
final TypePool.Default.LazyTypeDescription.TypeContainment.WithinMethod other = (TypePool.Default.LazyTypeDescription.TypeContainment.WithinMethod) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
final java.lang.Object this$methodName = this.methodName;
final java.lang.Object other$methodName = other.methodName;
if (this$methodName == null ? other$methodName != null : !this$methodName.equals(other$methodName)) return false;
final java.lang.Object this$methodDescriptor = this.methodDescriptor;
final java.lang.Object other$methodDescriptor = other.methodDescriptor;
if (this$methodDescriptor == null ? other$methodDescriptor != null : !this$methodDescriptor.equals(other$methodDescriptor)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.TypeContainment.WithinMethod;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
final java.lang.Object $methodName = this.methodName;
result = result * PRIME + ($methodName == null ? 43 : $methodName.hashCode());
final java.lang.Object $methodDescriptor = this.methodDescriptor;
result = result * PRIME + ($methodDescriptor == null ? 43 : $methodDescriptor.hashCode());
return result;
}
}
}
/**
* A token that represents a generic Java type.
*/
protected interface GenericTypeToken {
/**
* Represents an empty type path.
*/
String EMPTY_TYPE_PATH = "";
/**
* Represents a step to a component type within a type path.
*/
char COMPONENT_TYPE_PATH = '[';
/**
* Represents a wildcard type step within a type path.
*/
char WILDCARD_TYPE_PATH = '*';
/**
* Represents a (reversed) step to an inner class within a type path.
*/
char INNER_CLASS_PATH = '.';
/**
* Represents an index type delimiter within a type path.
*/
char INDEXED_TYPE_DELIMITER = ';';
/**
* Transforms this token into a generic type representation.
*
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param typeVariableSource The type variable source.
* @param typePath The type path of the resolved generic type.
* @param annotationTokens A mapping of the type's annotation tokens by their type path.
* @return A description of the represented generic type.
*/
Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens);
/**
* Determines if a generic type tokens represents a primary bound of a type variable. This method must only be invoked on types
* that represent a {@link Sort#NON_GENERIC},
* {@link Sort#PARAMETERIZED} or {@link Sort#VARIABLE}.
*
* @param typePool The type pool to use.
* @return {@code true} if this token represents a primary bound.
*/
boolean isPrimaryBound(TypePool typePool);
/**
* Returns the type path prefix that needs to be appended to the existing type path before any further navigation on the parameterized
* type. This method must only be called on type tokens that represent parameterized type
*
* @return A type path segment that needs to be appended to the base type path before any further navigation on the parameterized type.
*/
String getTypePathPrefix();
/**
* Represents a generic type token for a formal type variable.
*/
interface OfFormalTypeVariable {
/**
* Transforms this token into a generic type representation.
*
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param typeVariableSource The type variable source.
* @param annotationTokens A mapping of the type variables' type annotations.
* @param boundaryAnnotationTokens A mapping of the type variables' bounds' type annotation by their bound index.
* @return A generic type representation of this formal type variable.
*/
Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, Map<String, List<AnnotationToken>> annotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens);
}
/**
* A generic type token that represents a primitive type.
*/
enum ForPrimitiveType implements GenericTypeToken {
/**
* The generic type token describing the {@code boolean} type.
*/
BOOLEAN(boolean.class), /**
* The generic type token describing the {@code byte} type.
*/
BYTE(byte.class), /**
* The generic type token describing the {@code short} type.
*/
SHORT(short.class), /**
* The generic type token describing the {@code char} type.
*/
CHAR(char.class), /**
* The generic type token describing the {@code int} type.
*/
INTEGER(int.class), /**
* The generic type token describing the {@code long} type.
*/
LONG(long.class), /**
* The generic type token describing the {@code float} type.
*/
FLOAT(float.class), /**
* The generic type token describing the {@code double} type.
*/
DOUBLE(double.class), /**
* The generic type token describing the {@code void} type.
*/
VOID(void.class);
/**
* A description of this primitive type token.
*/
private final TypeDescription typeDescription;
/**
* Creates a new primitive type token.
*
* @param type The loaded type representing this primitive.
*/
ForPrimitiveType(Class<?> type) {
typeDescription = new ForLoadedType(type);
}
/**
* Resolves a generic type token of a primitive type.
*
* @param descriptor The descriptor of the primitive type.
* @return The corresponding generic type token.
*/
public static GenericTypeToken of(char descriptor) {
switch (descriptor) {
case 'V':
return VOID;
case 'Z':
return BOOLEAN;
case 'B':
return BYTE;
case 'S':
return SHORT;
case 'C':
return CHAR;
case 'I':
return INTEGER;
case 'J':
return LONG;
case 'F':
return FLOAT;
case 'D':
return DOUBLE;
default:
throw new IllegalArgumentException("Not a valid primitive type descriptor: " + descriptor);
}
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new LazyPrimitiveType(typePool, typePath, annotationTokens == null ? Collections.<String, List<AnnotationToken>>emptyMap() : annotationTokens, typeDescription);
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
throw new IllegalStateException("A primitive type cannot be a type variable bound: " + this);
}
@Override
public String getTypePathPrefix() {
throw new IllegalStateException("A primitive type cannot be the owner of a nested type: " + this);
}
/**
* A representation of a lazy primitive type.
*/
protected static class LazyPrimitiveType extends Generic.OfNonGenericType {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* This type's type path.
*/
private final String typePath;
/**
* This type's type annotation tokens.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* The represented type's description.
*/
private final TypeDescription typeDescription;
/**
* Creates a new lazy primitive type.
*
* @param typePool The type pool to use.
* @param typePath This type's type path.
* @param annotationTokens This type's type annotation tokens.
* @param typeDescription The represented type's description.
*/
protected LazyPrimitiveType(TypePool typePool, String typePath, Map<String, List<AnnotationToken>> annotationTokens, TypeDescription typeDescription) {
this.typePool = typePool;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.typeDescription = typeDescription;
}
@Override
public TypeDescription asErasure() {
return typeDescription;
}
@Override
public Generic getOwnerType() {
return Generic.UNDEFINED;
}
@Override
public Generic getComponentType() {
return Generic.UNDEFINED;
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
}
}
}
/**
* A generic type token that represents an unbound wildcard.
*/
enum ForUnboundWildcard implements GenericTypeToken {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new LazyUnboundWildcard(typePool, typePath, annotationTokens == null ? Collections.<String, List<AnnotationToken>>emptyMap() : annotationTokens);
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
throw new IllegalStateException("A wildcard type cannot be a type variable bound: " + this);
}
@Override
public String getTypePathPrefix() {
throw new IllegalStateException("An unbound wildcard cannot be the owner of a nested type: " + this);
}
/**
* A generic type representation of a generic unbound wildcard.
*/
protected static class LazyUnboundWildcard extends Generic.OfWildcardType {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* This type's type path.
*/
private final String typePath;
/**
* The type's type annotations.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* Creates a new lazy unbound wildcard.
*
* @param typePool The type pool to use.
* @param typePath This type's type path.
* @param annotationTokens The type's type annotations.
*/
protected LazyUnboundWildcard(TypePool typePool, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
this.typePool = typePool;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
}
@Override
public TypeList.Generic getUpperBounds() {
return new TypeList.Generic.Explicit(Generic.OBJECT);
}
@Override
public TypeList.Generic getLowerBounds() {
return new TypeList.Generic.Empty();
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
}
}
}
/**
* A resolution of a type's, method's or field's generic types.
*/
interface Resolution {
/**
* Resolves the type variables of the represented element.
*
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param typeVariableSource The type variable source to use for resolving type variables.
* @param annotationTokens A mapping of the type variables' type annotation tokens by their indices.
* @param boundAnnotationTokens A mapping of the type variables' bounds' type annotation tokens by their indices
* and each type variable's index.
* @return A list describing the resolved generic types.
*/
TypeList.Generic resolveTypeVariables(TypePool typePool, TypeVariableSource typeVariableSource, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens);
/**
* A resolution of a type's, method's or field's generic types if all of the represented element's are raw.
*/
enum Raw implements ForType, ForMethod, ForField {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Generic resolveFieldType(String fieldTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, FieldDescription.InDefinedShape definingField) {
return RawAnnotatedType.of(typePool, annotationTokens, fieldTypeDescriptor);
}
@Override
public Generic resolveReturnType(String returnTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return RawAnnotatedType.of(typePool, annotationTokens, returnTypeDescriptor);
}
@Override
public TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return RawAnnotatedType.LazyRawAnnotatedTypeList.of(typePool, annotationTokens, parameterTypeDescriptors);
}
@Override
public TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return RawAnnotatedType.LazyRawAnnotatedTypeList.of(typePool, annotationTokens, exceptionTypeDescriptors);
}
@Override
public Generic resolveSuperClass(String superClassDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, TypeDescription definingType) {
return RawAnnotatedType.of(typePool, annotationTokens, superClassDescriptor);
}
@Override
public TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, TypeDescription definingType) {
return RawAnnotatedType.LazyRawAnnotatedTypeList.of(typePool, annotationTokens, interfaceTypeDescriptors);
}
@Override
public TypeList.Generic resolveTypeVariables(TypePool typePool, TypeVariableSource typeVariableSource, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
return new TypeList.Generic.Empty();
}
/**
* Represents a non-generic type that defines type annotations.
*/
protected static class RawAnnotatedType extends Generic.OfNonGenericType {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* The type's type path.
*/
private final String typePath;
/**
* A mapping of this type's type annotations.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* The represented non-generic type.
*/
private final TypeDescription typeDescription;
/**
* Creates a new raw annotated type.
*
* @param typePool The type pool to use.
* @param typePath The type's type path.
* @param annotationTokens A mapping of this type's type annotations.
* @param typeDescription The represented non-generic type.
*/
protected RawAnnotatedType(TypePool typePool, String typePath, Map<String, List<AnnotationToken>> annotationTokens, TypeDescription typeDescription) {
this.typePool = typePool;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.typeDescription = typeDescription;
}
/**
* Creates a new raw annotated type.
*
* @param typePool The type pool to use.
* @param annotationTokens A mapping of this type's type annotations.
* @param descriptor The descriptor of the represented non-generic type.
* @return An annotated non-generic type.
*/
protected static Generic of(TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, String descriptor) {
return new RawAnnotatedType(typePool, EMPTY_TYPE_PATH, annotationTokens == null ? Collections.<String, List<AnnotationToken>>emptyMap() : annotationTokens, TokenizedGenericType.toErasure(typePool, descriptor));
}
@Override
public TypeDescription asErasure() {
return typeDescription;
}
@Override
public Generic getOwnerType() {
TypeDescription declaringType = typeDescription.getDeclaringType();
return declaringType == null ? Generic.UNDEFINED : new RawAnnotatedType(typePool, typePath, annotationTokens, declaringType);
}
@Override
public Generic getComponentType() {
TypeDescription componentType = typeDescription.getComponentType();
return componentType == null ? Generic.UNDEFINED : new RawAnnotatedType(typePool, typePath + COMPONENT_TYPE_PATH, annotationTokens, componentType);
}
@Override
public AnnotationList getDeclaredAnnotations() {
StringBuilder typePath = new StringBuilder(this.typePath);
for (int index = 0; index < typeDescription.getSegmentCount(); index++) {
typePath = typePath.append(INNER_CLASS_PATH);
}
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath.toString()));
}
/**
* A generic type list representing raw types.
*/
protected static class LazyRawAnnotatedTypeList extends TypeList.Generic.AbstractBase {
/**
* The type pool to use for locating types.
*/
private final TypePool typePool;
/**
* A mapping of the represented types' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
/**
* A list of type descriptors that this list represents.
*/
private final List<String> descriptors;
/**
* Creates a generic type list only representing raw types.
*
* @param typePool The type pool to use for locating types.
* @param annotationTokens A mapping of the represented types' type annotation tokens by their indices.
* @param descriptors A list of type descriptors that this list represents.
*/
protected LazyRawAnnotatedTypeList(TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, List<String> descriptors) {
this.typePool = typePool;
this.annotationTokens = annotationTokens;
this.descriptors = descriptors;
}
/**
* Creates generic type list only representing raw types.
*
* @param typePool The type pool to use for locating types.
* @param annotationTokens A mapping of the represented types' type annotation tokens by their indices or
* {@code null} if no type annotations are defined for any type.
* @param descriptors A list of type descriptors that this list represents.
* @return A generic type list representing the raw types this list represents.
*/
protected static TypeList.Generic of(TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, List<String> descriptors) {
return new LazyRawAnnotatedTypeList(typePool, annotationTokens == null ? Collections.<Integer, Map<String, List<AnnotationToken>>>emptyMap() : annotationTokens, descriptors);
}
@Override
public Generic get(int index) {
return RawAnnotatedType.of(typePool, annotationTokens.get(index), descriptors.get(index));
}
@Override
public int size() {
return descriptors.size();
}
@Override
public TypeList asErasures() {
return new LazyTypeList(typePool, descriptors);
}
@Override
public TypeList.Generic asRawTypes() {
return this;
}
@Override
public int getStackSize() {
int stackSize = 0;
for (String descriptor : descriptors) {
stackSize += Type.getType(descriptor).getSize();
}
return stackSize;
}
}
}
}
/**
* A resolution of a type's, method's or field's generic types if its generic signature is malformed.
*/
enum Malformed implements ForType, ForMethod, ForField {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Generic resolveFieldType(String fieldTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, FieldDescription.InDefinedShape definingField) {
return new TokenizedGenericType.Malformed(typePool, fieldTypeDescriptor);
}
@Override
public Generic resolveReturnType(String returnTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return new TokenizedGenericType.Malformed(typePool, returnTypeDescriptor);
}
@Override
public TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return new TokenizedGenericType.Malformed.TokenList(typePool, parameterTypeDescriptors);
}
@Override
public TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return new TokenizedGenericType.Malformed.TokenList(typePool, exceptionTypeDescriptors);
}
@Override
public Generic resolveSuperClass(String superClassDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, TypeDescription definingType) {
return new TokenizedGenericType.Malformed(typePool, superClassDescriptor);
}
@Override
public TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, TypeDescription definingType) {
return new TokenizedGenericType.Malformed.TokenList(typePool, interfaceTypeDescriptors);
}
@Override
public TypeList.Generic resolveTypeVariables(TypePool typePool, TypeVariableSource typeVariableSource, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
throw new GenericSignatureFormatError();
}
}
/**
* A resolution of the generic types of a {@link TypeDescription}.
*/
interface ForType extends Resolution {
/**
* Resolves the generic super type of the represented type.
*
* @param superClassDescriptor The descriptor of the raw super type.
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param annotationTokens A mapping of the super type's type annotation tokens.
* @param definingType The type that defines this super type.
* @return A description of this type's generic super type.
*/
Generic resolveSuperClass(String superClassDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, TypeDescription definingType);
/**
* Resolves the generic interface types of the represented type.
*
* @param interfaceTypeDescriptors The descriptor of the raw interface types.
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param annotationTokens A mapping of the interface types' type annotation tokens by their indices.
* @param definingType The type that defines these interface type.
* @return A description of this type's generic interface types.
*/
TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, TypeDescription definingType);
/**
* An implementation of a tokenized resolution of generic types of a {@link TypeDescription}.
*/
class Tokenized implements ForType {
/**
* The super type's generic type token.
*/
private final GenericTypeToken superClassToken;
/**
* The interface type's generic type tokens.
*/
private final List<GenericTypeToken> interfaceTypeTokens;
/**
* The type variables generic type tokens.
*/
private final List<OfFormalTypeVariable> typeVariableTokens;
/**
* Creates a new tokenized resolution of a {@link TypeDescription}'s generic signatures.
*
* @param superClassToken The super class's generic type token.
* @param interfaceTypeTokens The interface type's generic type tokens.
* @param typeVariableTokens The type variables generic type tokens.
*/
public Tokenized(GenericTypeToken superClassToken, List<GenericTypeToken> interfaceTypeTokens, List<OfFormalTypeVariable> typeVariableTokens) {
this.superClassToken = superClassToken;
this.interfaceTypeTokens = interfaceTypeTokens;
this.typeVariableTokens = typeVariableTokens;
}
@Override
public Generic resolveSuperClass(String superClassDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, TypeDescription definingType) {
return TokenizedGenericType.of(typePool, superClassToken, superClassDescriptor, annotationTokens, definingType);
}
@Override
public TypeList.Generic resolveInterfaceTypes(List<String> interfaceTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, TypeDescription definingType) {
return new TokenizedGenericType.TokenList(typePool, interfaceTypeTokens, annotationTokens, interfaceTypeDescriptors, definingType);
}
@Override
public TypeList.Generic resolveTypeVariables(TypePool typePool, TypeVariableSource typeVariableSource, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
return new TokenizedGenericType.TypeVariableList(typePool, typeVariableTokens, typeVariableSource, annotationTokens, boundAnnotationTokens);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$superClassToken = this.superClassToken;
final java.lang.Object other$superClassToken = other.superClassToken;
if (this$superClassToken == null ? other$superClassToken != null : !this$superClassToken.equals(other$superClassToken)) return false;
final java.lang.Object this$interfaceTypeTokens = this.interfaceTypeTokens;
final java.lang.Object other$interfaceTypeTokens = other.interfaceTypeTokens;
if (this$interfaceTypeTokens == null ? other$interfaceTypeTokens != null : !this$interfaceTypeTokens.equals(other$interfaceTypeTokens)) return false;
final java.lang.Object this$typeVariableTokens = this.typeVariableTokens;
final java.lang.Object other$typeVariableTokens = other.typeVariableTokens;
if (this$typeVariableTokens == null ? other$typeVariableTokens != null : !this$typeVariableTokens.equals(other$typeVariableTokens)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForType.Tokenized;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $superClassToken = this.superClassToken;
result = result * PRIME + ($superClassToken == null ? 43 : $superClassToken.hashCode());
final java.lang.Object $interfaceTypeTokens = this.interfaceTypeTokens;
result = result * PRIME + ($interfaceTypeTokens == null ? 43 : $interfaceTypeTokens.hashCode());
final java.lang.Object $typeVariableTokens = this.typeVariableTokens;
result = result * PRIME + ($typeVariableTokens == null ? 43 : $typeVariableTokens.hashCode());
return result;
}
}
}
/**
* A resolution of the generic types of a {@link MethodDescription}.
*/
interface ForMethod extends Resolution {
/**
* Resolves the return type of the represented method.
*
* @param returnTypeDescriptor The descriptor of the raw return type.
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param annotationTokens A mapping of the return type's type annotation tokens.
* @param definingMethod The method that defines this return type.
* @return A description of this type's generic return type.
*/
Generic resolveReturnType(String returnTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, MethodDescription.InDefinedShape definingMethod);
/**
* Resolves the generic parameter types of the represented method.
*
* @param parameterTypeDescriptors The descriptor of the raw parameter types.
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param annotationTokens A mapping of the parameter types' type annotation tokens by their indices.
* @param definingMethod The method that defines these parameter types.
* @return A description of this type's generic interface types.
*/
TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod);
/**
* Resolves the generic parameter types of the represented method.
*
* @param exceptionTypeDescriptors The descriptor of the raw exception types.
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param annotationTokens A mapping of the exception types' type annotation tokens by their indices.
* @param definingMethod The method that defines these exception types.
* @return A description of this type's generic interface types.
*/
TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod);
/**
* An implementation of a tokenized resolution of generic types of a {@link MethodDescription}.
*/
class Tokenized implements ForMethod {
/**
* A token describing the represented method's return type.
*/
private final GenericTypeToken returnTypeToken;
/**
* A token describing the represented method's parameter types.
*/
private final List<GenericTypeToken> parameterTypeTokens;
/**
* A token describing the represented method's exception types.
*/
private final List<GenericTypeToken> exceptionTypeTokens;
/**
* A token describing the represented method's type variables.
*/
private final List<OfFormalTypeVariable> typeVariableTokens;
public Tokenized(GenericTypeToken returnTypeToken, List<GenericTypeToken> parameterTypeTokens, List<GenericTypeToken> exceptionTypeTokens, List<OfFormalTypeVariable> typeVariableTokens) {
this.returnTypeToken = returnTypeToken;
this.parameterTypeTokens = parameterTypeTokens;
this.exceptionTypeTokens = exceptionTypeTokens;
this.typeVariableTokens = typeVariableTokens;
}
@Override
public Generic resolveReturnType(String returnTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return TokenizedGenericType.of(typePool, returnTypeToken, returnTypeDescriptor, annotationTokens, definingMethod);
}
@Override
public TypeList.Generic resolveParameterTypes(List<String> parameterTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
return new TokenizedGenericType.TokenList(typePool, parameterTypeTokens, annotationTokens, parameterTypeDescriptors, definingMethod);
}
@Override
public TypeList.Generic resolveExceptionTypes(List<String> exceptionTypeDescriptors, TypePool typePool, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, MethodDescription.InDefinedShape definingMethod) {
// Generic signatures of methods are optional.
/**
* Creates a new tokenized resolution of a {@link MethodDescription}'s generic signatures.
*
* @param returnTypeToken A token describing the represented method's return type.
* @param parameterTypeTokens A token describing the represented method's parameter types.
* @param exceptionTypeTokens A token describing the represented method's exception types.
* @param typeVariableTokens A token describing the represented method's type variables.
*/
return exceptionTypeTokens.isEmpty() ? Raw.INSTANCE.resolveExceptionTypes(exceptionTypeDescriptors, typePool, annotationTokens, definingMethod) : new TokenizedGenericType.TokenList(typePool, exceptionTypeTokens, annotationTokens, exceptionTypeDescriptors, definingMethod);
}
@Override
public TypeList.Generic resolveTypeVariables(TypePool typePool, TypeVariableSource typeVariableSource, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
return new TokenizedGenericType.TypeVariableList(typePool, typeVariableTokens, typeVariableSource, annotationTokens, boundAnnotationTokens);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$returnTypeToken = this.returnTypeToken;
final java.lang.Object other$returnTypeToken = other.returnTypeToken;
if (this$returnTypeToken == null ? other$returnTypeToken != null : !this$returnTypeToken.equals(other$returnTypeToken)) return false;
final java.lang.Object this$parameterTypeTokens = this.parameterTypeTokens;
final java.lang.Object other$parameterTypeTokens = other.parameterTypeTokens;
if (this$parameterTypeTokens == null ? other$parameterTypeTokens != null : !this$parameterTypeTokens.equals(other$parameterTypeTokens)) return false;
final java.lang.Object this$exceptionTypeTokens = this.exceptionTypeTokens;
final java.lang.Object other$exceptionTypeTokens = other.exceptionTypeTokens;
if (this$exceptionTypeTokens == null ? other$exceptionTypeTokens != null : !this$exceptionTypeTokens.equals(other$exceptionTypeTokens)) return false;
final java.lang.Object this$typeVariableTokens = this.typeVariableTokens;
final java.lang.Object other$typeVariableTokens = other.typeVariableTokens;
if (this$typeVariableTokens == null ? other$typeVariableTokens != null : !this$typeVariableTokens.equals(other$typeVariableTokens)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForMethod.Tokenized;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $returnTypeToken = this.returnTypeToken;
result = result * PRIME + ($returnTypeToken == null ? 43 : $returnTypeToken.hashCode());
final java.lang.Object $parameterTypeTokens = this.parameterTypeTokens;
result = result * PRIME + ($parameterTypeTokens == null ? 43 : $parameterTypeTokens.hashCode());
final java.lang.Object $exceptionTypeTokens = this.exceptionTypeTokens;
result = result * PRIME + ($exceptionTypeTokens == null ? 43 : $exceptionTypeTokens.hashCode());
final java.lang.Object $typeVariableTokens = this.typeVariableTokens;
result = result * PRIME + ($typeVariableTokens == null ? 43 : $typeVariableTokens.hashCode());
return result;
}
}
}
/**
* A resolution of the generic types of a {@link FieldDescription}.
*/
interface ForField {
/**
* Resolves the field type of the represented field.
*
* @param fieldTypeDescriptor The descriptor of the raw field type.
* @param annotationTokens A mapping of the represented types' type annotation tokens.
* @param typePool The type pool to be used for locating non-generic type descriptions.
* @param definingField The field that defines this type. @return A description of this field's type.
* @return A generic type representation of the field's type.
*/
Generic resolveFieldType(String fieldTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, FieldDescription.InDefinedShape definingField);
/**
* An implementation of a tokenized resolution of the generic type of a {@link FieldDescription}.
*/
class Tokenized implements ForField {
/**
* The token of the represented field's type.
*/
private final GenericTypeToken fieldTypeToken;
/**
* Creates a new tokenized resolution of a {@link FieldDescription}'s type.
*
* @param fieldTypeToken The token of the represented field's type.
*/
public Tokenized(GenericTypeToken fieldTypeToken) {
this.fieldTypeToken = fieldTypeToken;
}
@Override
public Generic resolveFieldType(String fieldTypeDescriptor, TypePool typePool, Map<String, List<AnnotationToken>> annotationTokens, FieldDescription.InDefinedShape definingField) {
return TokenizedGenericType.of(typePool, fieldTypeToken, fieldTypeDescriptor, annotationTokens, definingField.getDeclaringType());
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$fieldTypeToken = this.fieldTypeToken;
final java.lang.Object other$fieldTypeToken = other.fieldTypeToken;
if (this$fieldTypeToken == null ? other$fieldTypeToken != null : !this$fieldTypeToken.equals(other$fieldTypeToken)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.Resolution.ForField.Tokenized;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $fieldTypeToken = this.fieldTypeToken;
result = result * PRIME + ($fieldTypeToken == null ? 43 : $fieldTypeToken.hashCode());
return result;
}
}
}
}
/**
* A generic type token that represents a non-generic type.
*/
class ForRawType implements GenericTypeToken {
/**
* The name of the represented type.
*/
private final String name;
/**
* Creates a new type token that represents a non-generic type.
*
* @param name The name of the represented type.
*/
protected ForRawType(String name) {
this.name = name;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new Resolution.Raw.RawAnnotatedType(typePool, typePath, annotationTokens == null ? Collections.<String, List<AnnotationToken>>emptyMap() : annotationTokens, typePool.describe(name).resolve());
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
return !typePool.describe(name).resolve().isInterface();
}
@Override
public String getTypePathPrefix() {
throw new IllegalStateException("A non-generic type cannot be the owner of a nested type: " + this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForRawType)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForRawType other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForRawType) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForRawType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
}
/**
* A generic type token that represents a type variable.
*/
class ForTypeVariable implements GenericTypeToken {
/**
* This type variable's nominal symbol.
*/
private final String symbol;
/**
* Creates a generic type token that represents a type variable.
*
* @param symbol This type variable's nominal symbol.
*/
protected ForTypeVariable(String symbol) {
this.symbol = symbol;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
Generic typeVariable = typeVariableSource.findVariable(symbol);
return typeVariable == null ? new UnresolvedTypeVariable(typeVariableSource, typePool, symbol, annotationTokens.get(typePath)) : new AnnotatedTypeVariable(typePool, annotationTokens.get(typePath), typeVariable);
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
return true;
}
@Override
public String getTypePathPrefix() {
throw new IllegalStateException("A type variable cannot be the owner of a nested type: " + this);
}
/**
* An annotated representation of a formal type variable.
*/
protected static class AnnotatedTypeVariable extends Generic.OfTypeVariable {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* The represented annotation tokens.
*/
private final List<AnnotationToken> annotationTokens;
/**
* The represented type variable.
*/
private final Generic typeVariable;
/**
* Creates a new annotated type variable.
*
* @param typePool The type pool to use.
* @param annotationTokens The represented annotation tokens.
* @param typeVariable The represented type variable.
*/
protected AnnotatedTypeVariable(TypePool typePool, List<AnnotationToken> annotationTokens, Generic typeVariable) {
this.typePool = typePool;
this.annotationTokens = annotationTokens;
this.typeVariable = typeVariable;
}
@Override
public TypeList.Generic getUpperBounds() {
return typeVariable.getUpperBounds();
}
@Override
public TypeVariableSource getTypeVariableSource() {
return typeVariable.getTypeVariableSource();
}
@Override
public String getSymbol() {
return typeVariable.getSymbol();
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens);
}
}
/**
* Represents a type variable that a type references but that does not exist. Such type variables are only emitted by wrongful
* compilation either due to the isolated recompilation of outer classes or due to bugs in compilers.
*/
protected static class UnresolvedTypeVariable extends Generic.OfTypeVariable {
/**
* The undeclared type variable's source.
*/
private final TypeVariableSource typeVariableSource;
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* The type variable's symbol.
*/
private final String symbol;
/**
* The type variable's annotation tokens.
*/
private final List<AnnotationToken> annotationTokens;
/**
* Creates an unresolved type variable.
*
* @param typeVariableSource The undeclared type variable's source.
* @param typePool The type pool to use.
* @param symbol The type variable's symbol.
* @param annotationTokens The type variable's annotation tokens.
*/
protected UnresolvedTypeVariable(TypeVariableSource typeVariableSource, TypePool typePool, String symbol, List<AnnotationToken> annotationTokens) {
this.typeVariableSource = typeVariableSource;
this.typePool = typePool;
this.symbol = symbol;
this.annotationTokens = annotationTokens;
}
@Override
public TypeList.Generic getUpperBounds() {
throw new IllegalStateException("Cannot resolve bounds of unresolved type variable " + this + " by " + typeVariableSource);
}
@Override
public TypeVariableSource getTypeVariableSource() {
return typeVariableSource;
}
@Override
public String getSymbol() {
return symbol;
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens);
}
}
/**
* A generic type token that represent a formal type variable, i.e. a type variable including its upper bounds.
*/
protected static class Formal implements GenericTypeToken.OfFormalTypeVariable {
/**
* This type variable's nominal symbol.
*/
private final String symbol;
/**
* A list of tokens that represent this type variable's upper bounds.
*/
private final List<GenericTypeToken> boundTypeTokens;
/**
* Creates generic type token that represent a formal type variable.
*
* @param symbol This type variable's nominal symbol.
* @param boundTypeTokens A list of tokens that represent this type variable's upper bounds.
*/
protected Formal(String symbol, List<GenericTypeToken> boundTypeTokens) {
this.symbol = symbol;
this.boundTypeTokens = boundTypeTokens;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, Map<String, List<AnnotationToken>> annotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens) {
return new LazyTypeVariable(typePool, typeVariableSource, annotationTokens == null ? Collections.<String, List<AnnotationToken>>emptyMap() : annotationTokens, boundaryAnnotationTokens == null ? Collections.<Integer, Map<String, List<AnnotationToken>>>emptyMap() : boundaryAnnotationTokens, symbol, boundTypeTokens);
}
/**
* A type description that represents a type variable with bounds that are resolved lazily.
*/
protected static class LazyTypeVariable extends Generic.OfTypeVariable {
/**
* The type pool to use for locating type descriptions.
*/
private final TypePool typePool;
/**
* The type variable source to use for locating type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* The type variable's type annotation tokens.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* A mapping of the type variable bounds' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens;
/**
* The type variable's symbol.
*/
private final String symbol;
/**
* Tokenized representations of the type variables bound types.
*/
private final List<GenericTypeToken> boundTypeTokens;
/**
* Creates a lazy type description of a type variables.
*
* @param typePool The type pool to use for locating type descriptions.
* @param typeVariableSource The type variable source to use for locating type variables.
* @param annotationTokens The type variable's type annotation tokens.
* @param boundaryAnnotationTokens A mapping of the type variable bounds' type annotation tokens by their indices.
* @param symbol The type variable's symbol.
* @param boundTypeTokens Tokenized representations of the type variables bound types.
*/
protected LazyTypeVariable(TypePool typePool, TypeVariableSource typeVariableSource, Map<String, List<AnnotationToken>> annotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> boundaryAnnotationTokens, String symbol, List<GenericTypeToken> boundTypeTokens) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.annotationTokens = annotationTokens;
this.boundaryAnnotationTokens = boundaryAnnotationTokens;
this.symbol = symbol;
this.boundTypeTokens = boundTypeTokens;
}
@Override
public TypeList.Generic getUpperBounds() {
return new LazyBoundTokenList(typePool, typeVariableSource, boundaryAnnotationTokens, boundTypeTokens);
}
@Override
public TypeVariableSource getTypeVariableSource() {
return typeVariableSource;
}
@Override
public String getSymbol() {
return symbol;
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(EMPTY_TYPE_PATH));
}
/**
* A list representing a formal type variable's bounds.
*/
protected static class LazyBoundTokenList extends TypeList.Generic.AbstractBase {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* The type variable source for locating type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* A mapping of the bound type's type annotations by their bound index.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
/**
* The bound types in their tokenized form.
*/
private final List<GenericTypeToken> boundTypeTokens;
protected LazyBoundTokenList(TypePool typePool, TypeVariableSource typeVariableSource, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, List<GenericTypeToken> boundTypeTokens) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.annotationTokens = annotationTokens;
this.boundTypeTokens = boundTypeTokens;
}
@Override
public Generic get(int index) {
// Avoid resolution of interface bound type unless a type annotation can be possibly resolved.
/**
* Creates a new lazy bound token list for a type variable.
*
* @param typePool The type pool to use.
* @param typeVariableSource The type variable source for locating type variables.
* @param annotationTokens A mapping of the bound type's type annotations by their bound index.
* @param boundTypeTokens The bound types in their tokenized form.
*/
Map<String, List<AnnotationToken>> annotationTokens = !this.annotationTokens.containsKey(index) && !this.annotationTokens.containsKey(index + 1) ? Collections.<String, List<AnnotationToken>>emptyMap() : this.annotationTokens.get(index + (boundTypeTokens.get(0).isPrimaryBound(typePool) ? 0 : 1));
return boundTypeTokens.get(index).toGenericType(typePool, typeVariableSource, EMPTY_TYPE_PATH, annotationTokens == null ? Collections.<String, List<AnnotationToken>>emptyMap() : annotationTokens);
}
@Override
public int size() {
return boundTypeTokens.size();
}
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$symbol = this.symbol;
final java.lang.Object other$symbol = other.symbol;
if (this$symbol == null ? other$symbol != null : !this$symbol.equals(other$symbol)) return false;
final java.lang.Object this$boundTypeTokens = this.boundTypeTokens;
final java.lang.Object other$boundTypeTokens = other.boundTypeTokens;
if (this$boundTypeTokens == null ? other$boundTypeTokens != null : !this$boundTypeTokens.equals(other$boundTypeTokens)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable.Formal;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $symbol = this.symbol;
result = result * PRIME + ($symbol == null ? 43 : $symbol.hashCode());
final java.lang.Object $boundTypeTokens = this.boundTypeTokens;
result = result * PRIME + ($boundTypeTokens == null ? 43 : $boundTypeTokens.hashCode());
return result;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$symbol = this.symbol;
final java.lang.Object other$symbol = other.symbol;
if (this$symbol == null ? other$symbol != null : !this$symbol.equals(other$symbol)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForTypeVariable;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $symbol = this.symbol;
result = result * PRIME + ($symbol == null ? 43 : $symbol.hashCode());
return result;
}
}
/**
* A generic type token that represents a generic array.
*/
class ForGenericArray implements GenericTypeToken {
/**
* The array's component type.
*/
private final GenericTypeToken componentTypeToken;
/**
* Creates a generic type token that represents a generic array.
*
* @param componentTypeToken The array's component type.
*/
protected ForGenericArray(GenericTypeToken componentTypeToken) {
this.componentTypeToken = componentTypeToken;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new LazyGenericArray(typePool, typeVariableSource, typePath, annotationTokens, componentTypeToken);
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
throw new IllegalStateException("A generic array type cannot be a type variable bound: " + this);
}
@Override
public String getTypePathPrefix() {
throw new IllegalStateException("A generic array type cannot be the owner of a nested type: " + this);
}
/**
* A generic type representation of a generic array.
*/
protected static class LazyGenericArray extends Generic.OfGenericArray {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* The type variable source for locating type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* This type's type path.
*/
private final String typePath;
/**
* This type's type annotations.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* A tokenized representation of this generic arrays's component type.
*/
private final GenericTypeToken componentTypeToken;
/**
* Creates a new lazy generic array.
*
* @param typePool The type pool to use.
* @param typeVariableSource The type variable source for locating type variables.
* @param typePath This type's type path.
* @param annotationTokens This type's type annotations.
* @param componentTypeToken A tokenized representation of this generic arrays's component type.
*/
protected LazyGenericArray(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens, GenericTypeToken componentTypeToken) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.componentTypeToken = componentTypeToken;
}
@Override
public Generic getComponentType() {
return componentTypeToken.toGenericType(typePool, typeVariableSource, typePath + COMPONENT_TYPE_PATH, annotationTokens);
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForGenericArray)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForGenericArray other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForGenericArray) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$componentTypeToken = this.componentTypeToken;
final java.lang.Object other$componentTypeToken = other.componentTypeToken;
if (this$componentTypeToken == null ? other$componentTypeToken != null : !this$componentTypeToken.equals(other$componentTypeToken)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForGenericArray;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $componentTypeToken = this.componentTypeToken;
result = result * PRIME + ($componentTypeToken == null ? 43 : $componentTypeToken.hashCode());
return result;
}
}
/**
* A generic type token for a wildcard that is bound below.
*/
class ForLowerBoundWildcard implements GenericTypeToken {
/**
* A token that represents the wildcard's lower bound.
*/
private final GenericTypeToken boundTypeToken;
/**
* Creates a generic type token for a wildcard that is bound below.
*
* @param boundTypeToken A token that represents the wildcard's lower bound.
*/
protected ForLowerBoundWildcard(GenericTypeToken boundTypeToken) {
this.boundTypeToken = boundTypeToken;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new LazyLowerBoundWildcard(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
throw new IllegalStateException("A wildcard type cannot be a type variable bound: " + this);
}
@Override
public String getTypePathPrefix() {
throw new IllegalStateException("A lower bound wildcard cannot be the owner of a nested type: " + this);
}
/**
* A generic type representation of a lower bound wildcard.
*/
protected static class LazyLowerBoundWildcard extends Generic.OfWildcardType {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* The type variable source for locating type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* This type's type path.
*/
private final String typePath;
/**
* This type's type annotations.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* A tokenized representation of this wildcard's bound.
*/
private final GenericTypeToken boundTypeToken;
/**
* Creates a new lazy lower bound wildcard.
*
* @param typePool The type pool to use.
* @param typeVariableSource The type variable source for locating type variables.
* @param typePath This type's type path.
* @param annotationTokens This type's type annotations.
* @param boundTypeToken A tokenized representation of this wildcard's bound.
*/
protected LazyLowerBoundWildcard(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens, GenericTypeToken boundTypeToken) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.boundTypeToken = boundTypeToken;
}
@Override
public TypeList.Generic getUpperBounds() {
return new TypeList.Generic.Explicit(Generic.OBJECT);
}
@Override
public TypeList.Generic getLowerBounds() {
return new LazyTokenList.ForWildcardBound(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$boundTypeToken = this.boundTypeToken;
final java.lang.Object other$boundTypeToken = other.boundTypeToken;
if (this$boundTypeToken == null ? other$boundTypeToken != null : !this$boundTypeToken.equals(other$boundTypeToken)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForLowerBoundWildcard;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $boundTypeToken = this.boundTypeToken;
result = result * PRIME + ($boundTypeToken == null ? 43 : $boundTypeToken.hashCode());
return result;
}
}
/**
* A generic type token for a wildcard that is bound above.
*/
class ForUpperBoundWildcard implements GenericTypeToken {
/**
* A token that represents the wildcard's upper bound.
*/
private final GenericTypeToken boundTypeToken;
/**
* Creates a generic type token for a wildcard that is bound above.
*
* @param boundTypeToken A token that represents the wildcard's upper bound.
*/
protected ForUpperBoundWildcard(GenericTypeToken boundTypeToken) {
this.boundTypeToken = boundTypeToken;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new LazyUpperBoundWildcard(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
throw new IllegalStateException("A wildcard type cannot be a type variable bound: " + this);
}
@Override
public String getTypePathPrefix() {
throw new IllegalStateException("An upper bound wildcard cannot be the owner of a nested type: " + this);
}
/**
* A generic type representation of a tokenized wildcard with an upper bound.
*/
protected static class LazyUpperBoundWildcard extends Generic.OfWildcardType {
/**
* The type pool to use.
*/
private final TypePool typePool;
/**
* The type variable source for locating type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* This type's type path.
*/
private final String typePath;
/**
* This type's type annotations.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* A tokenized representation of this wildcard's bound.
*/
private final GenericTypeToken boundTypeToken;
/**
* Creates a new lazy upper bound wildcard.
*
* @param typePool The type pool to use.
* @param typeVariableSource The type variable source for locating type variables.
* @param typePath This type's type path.
* @param annotationTokens This type's type annotations.
* @param boundTypeToken A tokenized representation of this wildcard's bound.
*/
protected LazyUpperBoundWildcard(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens, GenericTypeToken boundTypeToken) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.boundTypeToken = boundTypeToken;
}
@Override
public TypeList.Generic getUpperBounds() {
return new LazyTokenList.ForWildcardBound(typePool, typeVariableSource, typePath, annotationTokens, boundTypeToken);
}
@Override
public TypeList.Generic getLowerBounds() {
return new TypeList.Generic.Empty();
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$boundTypeToken = this.boundTypeToken;
final java.lang.Object other$boundTypeToken = other.boundTypeToken;
if (this$boundTypeToken == null ? other$boundTypeToken != null : !this$boundTypeToken.equals(other$boundTypeToken)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForUpperBoundWildcard;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $boundTypeToken = this.boundTypeToken;
result = result * PRIME + ($boundTypeToken == null ? 43 : $boundTypeToken.hashCode());
return result;
}
}
/**
* A generic type token that represents a parameterized type.
*/
class ForParameterizedType implements GenericTypeToken {
/**
* The name of the parameterized type's erasure.
*/
private final String name;
/**
* A list of tokens that represent the parameters of the represented type.
*/
private final List<GenericTypeToken> parameterTypeTokens;
/**
* Creates a type token that represents a parameterized type.
*
* @param name The name of the parameterized type's erasure.
* @param parameterTypeTokens A list of tokens that represent the parameters of the represented type.
*/
protected ForParameterizedType(String name, List<GenericTypeToken> parameterTypeTokens) {
this.name = name;
this.parameterTypeTokens = parameterTypeTokens;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new LazyParameterizedType(typePool, typeVariableSource, typePath, annotationTokens, name, parameterTypeTokens);
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
return !typePool.describe(name).resolve().isInterface();
}
@Override
public String getTypePathPrefix() {
return String.valueOf(INNER_CLASS_PATH);
}
/**
* A generic type token to describe a parameterized type description with a generic owner type.
*/
public static class Nested implements GenericTypeToken {
/**
* The name of the parameterized type's erasure.
*/
private final String name;
/**
* A list of tokens that represent the parameters of the represented type.
*/
private final List<GenericTypeToken> parameterTypeTokens;
/**
* A token that describes the described parameterized type's owner type.
*/
private final GenericTypeToken ownerTypeToken;
/**
* Creates a type token that represents a parameterized type.
*
* @param name The name of the parameterized type's erasure.
* @param parameterTypeTokens A list of tokens that represent the parameters of the represented type.
* @param ownerTypeToken A token that describes the described parameterized type's owner type.
*/
protected Nested(String name, List<GenericTypeToken> parameterTypeTokens, GenericTypeToken ownerTypeToken) {
this.name = name;
this.parameterTypeTokens = parameterTypeTokens;
this.ownerTypeToken = ownerTypeToken;
}
@Override
public Generic toGenericType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens) {
return new LazyParameterizedType(typePool, typeVariableSource, typePath, annotationTokens, name, parameterTypeTokens, ownerTypeToken);
}
@Override
public String getTypePathPrefix() {
return ownerTypeToken.getTypePathPrefix() + INNER_CLASS_PATH;
}
@Override
public boolean isPrimaryBound(TypePool typePool) {
return !typePool.describe(name).resolve().isInterface();
}
/**
* A lazy description of a parameterized type with an owner type.
*/
protected static class LazyParameterizedType extends Generic.OfParameterizedType {
/**
* The type pool that is used for locating a generic type.
*/
private final TypePool typePool;
/**
* The type variable source to use for resolving type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* This type's type path.
*/
private final String typePath;
/**
* A mapping of type annotations for this type.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* The binary name of this parameterized type's raw type.
*/
private final String name;
/**
* Tokens that represent this parameterized type's parameters.
*/
private final List<GenericTypeToken> parameterTypeTokens;
/**
* A token that represents this type's owner type.
*/
private final GenericTypeToken ownerTypeToken;
/**
* Creates a new lazy parameterized type.
*
* @param typePool The type pool that is used for locating a generic type.
* @param typeVariableSource The type variable source to use for resolving type variables.
* @param typePath This type's type path.
* @param annotationTokens A mapping of type annotations for this type.
* @param name The binary name of this parameterized type's raw type.
* @param parameterTypeTokens Tokens that represent this parameterized type's parameters.
* @param ownerTypeToken A token that represents this type's owner type.
*/
protected LazyParameterizedType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens, String name, List<GenericTypeToken> parameterTypeTokens, GenericTypeToken ownerTypeToken) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.name = name;
this.parameterTypeTokens = parameterTypeTokens;
this.ownerTypeToken = ownerTypeToken;
}
@Override
public TypeDescription asErasure() {
return typePool.describe(name).resolve();
}
@Override
public TypeList.Generic getTypeArguments() {
return new LazyTokenList(typePool, typeVariableSource, typePath + ownerTypeToken.getTypePathPrefix(), annotationTokens, parameterTypeTokens);
}
@Override
public Generic getOwnerType() {
return ownerTypeToken.toGenericType(typePool, typeVariableSource, typePath, annotationTokens);
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath + ownerTypeToken.getTypePathPrefix()));
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
final java.lang.Object this$parameterTypeTokens = this.parameterTypeTokens;
final java.lang.Object other$parameterTypeTokens = other.parameterTypeTokens;
if (this$parameterTypeTokens == null ? other$parameterTypeTokens != null : !this$parameterTypeTokens.equals(other$parameterTypeTokens)) return false;
final java.lang.Object this$ownerTypeToken = this.ownerTypeToken;
final java.lang.Object other$ownerTypeToken = other.ownerTypeToken;
if (this$ownerTypeToken == null ? other$ownerTypeToken != null : !this$ownerTypeToken.equals(other$ownerTypeToken)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType.Nested;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
final java.lang.Object $parameterTypeTokens = this.parameterTypeTokens;
result = result * PRIME + ($parameterTypeTokens == null ? 43 : $parameterTypeTokens.hashCode());
final java.lang.Object $ownerTypeToken = this.ownerTypeToken;
result = result * PRIME + ($ownerTypeToken == null ? 43 : $ownerTypeToken.hashCode());
return result;
}
}
/**
* A generic type description that represents a parameterized type <b>without</b> an enclosing generic owner type.
*/
protected static class LazyParameterizedType extends Generic.OfParameterizedType {
/**
* The type pool that is used for locating a generic type.
*/
private final TypePool typePool;
/**
* The type variable source to use for resolving type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* This type's type path.
*/
private final String typePath;
/**
* A mapping of the represent type's annotation tokens.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* The binary name of the raw type.
*/
private final String name;
/**
* A list of type tokens representing this type's bounds.
*/
private final List<GenericTypeToken> parameterTypeTokens;
/**
* Creates a new description of a parameterized type.
*
* @param typePool The type pool that is used for locating a generic type.
* @param typeVariableSource The type variable source to use for resolving type variables.
* @param typePath This type's type path.
* @param annotationTokens A mapping of the represent type's annotation tokens,
* @param name The binary name of the raw type.
* @param parameterTypeTokens A list of type tokens representing this type's bounds.
*/
protected LazyParameterizedType(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens, String name, List<GenericTypeToken> parameterTypeTokens) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.name = name;
this.parameterTypeTokens = parameterTypeTokens;
}
@Override
public TypeDescription asErasure() {
return typePool.describe(name).resolve();
}
@Override
public TypeList.Generic getTypeArguments() {
return new LazyTokenList(typePool, typeVariableSource, typePath, annotationTokens, parameterTypeTokens);
}
@Override
public Generic getOwnerType() {
TypeDescription ownerType = typePool.describe(name).resolve().getEnclosingType();
return ownerType == null ? Generic.UNDEFINED : ownerType.asGenericType();
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens.get(typePath));
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType)) return false;
final TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType other = (TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
final java.lang.Object this$parameterTypeTokens = this.parameterTypeTokens;
final java.lang.Object other$parameterTypeTokens = other.parameterTypeTokens;
if (this$parameterTypeTokens == null ? other$parameterTypeTokens != null : !this$parameterTypeTokens.equals(other$parameterTypeTokens)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.GenericTypeToken.ForParameterizedType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
final java.lang.Object $parameterTypeTokens = this.parameterTypeTokens;
result = result * PRIME + ($parameterTypeTokens == null ? 43 : $parameterTypeTokens.hashCode());
return result;
}
}
/**
* A lazy list of type tokens.
*/
class LazyTokenList extends TypeList.Generic.AbstractBase {
/**
* The type pool that is used for locating a generic type.
*/
private final TypePool typePool;
/**
* The type variable source to use for resolving type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* The represented types' type path to which an index step is added upon resolution.
*/
private final String typePath;
/**
* A mapping of the represent types' annotation tokens.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* A list of type tokens this list represents.
*/
private final List<GenericTypeToken> genericTypeTokens;
/**
* Creates a new type list that represents a list of tokenized types.
*
* @param typePool The type pool that is used for locating a generic type.
* @param typeVariableSource The type variable source to use for resolving type variables.
* @param typePath The represented types' type path to which an index step is added upon resolution.
* @param annotationTokens A mapping of the represent types' annotation tokens,
* @param genericTypeTokens A list of type tokens this list represents.
*/
protected LazyTokenList(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens, List<GenericTypeToken> genericTypeTokens) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.genericTypeTokens = genericTypeTokens;
}
@Override
public Generic get(int index) {
return genericTypeTokens.get(index).toGenericType(typePool, typeVariableSource, typePath + index + INDEXED_TYPE_DELIMITER, annotationTokens);
}
@Override
public int size() {
return genericTypeTokens.size();
}
/**
* A generic type description representing a tokenized wildcard bound.
*/
protected static class ForWildcardBound extends TypeList.Generic.AbstractBase {
/**
* The type pool that is used for locating a generic type.
*/
private final TypePool typePool;
/**
* The type variable source to use for resolving type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* The represented types' type path to which a wildcard step is added upon resolution.
*/
private final String typePath;
/**
* A mapping of the represent types' annotation tokens.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* A token representing the wildcard's bound.
*/
private final GenericTypeToken genericTypeToken;
/**
* @param typePool The type pool that is used for locating a generic type.
* @param typeVariableSource The type variable source to use for resolving type variables.
* @param typePath The represented types' type path to which a wildcard step is added upon resolution.
* @param annotationTokens A mapping of the represent types' annotation tokens,
* @param genericTypeToken A token representing the wildcard's bound.
*/
protected ForWildcardBound(TypePool typePool, TypeVariableSource typeVariableSource, String typePath, Map<String, List<AnnotationToken>> annotationTokens, GenericTypeToken genericTypeToken) {
this.typePool = typePool;
this.typeVariableSource = typeVariableSource;
this.typePath = typePath;
this.annotationTokens = annotationTokens;
this.genericTypeToken = genericTypeToken;
}
@Override
public Generic get(int index) {
if (index == 0) {
return genericTypeToken.toGenericType(typePool, typeVariableSource, typePath + WILDCARD_TYPE_PATH, annotationTokens);
} else {
throw new IndexOutOfBoundsException("index = " + index);
}
}
@Override
public int size() {
return 1;
}
}
}
}
/**
* A token for representing collected data on an annotation.
*/
protected static class AnnotationToken {
/**
* The descriptor of the represented annotation.
*/
private final String descriptor;
/**
* A map of annotation value names to their value representations.
*/
private final Map<String, AnnotationValue<?, ?>> values;
/**
* Creates a new annotation token.
*
* @param descriptor The descriptor of the represented annotation.
* @param values A map of annotation value names to their value representations.
*/
protected AnnotationToken(String descriptor, Map<String, AnnotationValue<?, ?>> values) {
this.descriptor = descriptor;
this.values = values;
}
/**
* Returns a map of annotation value names to their value representations.
*
* @return A map of annotation value names to their value representations.
*/
protected Map<String, AnnotationValue<?, ?>> getValues() {
return values;
}
/**
* Returns the annotation type's binary name.
*
* @return The annotation type's binary name.
*/
protected String getBinaryName() {
return descriptor.substring(1, descriptor.length() - 1).replace('/', '.');
}
/**
* Transforms this token into an annotation description.
*
* @param typePool The type pool to be used for looking up linked types.
* @return An optional description of this annotation's token.
*/
private Resolution toAnnotationDescription(TypePool typePool) {
TypePool.Resolution resolution = typePool.describe(getBinaryName());
return resolution.isResolved() ? new Resolution.Simple(new LazyAnnotationDescription(typePool, resolution.resolve(), values)) : new Resolution.Illegal(getBinaryName());
}
/**
* A resolution for an annotation tokens. Any annotation is suppressed if its type is not available.
* This conforms to the handling of the Java reflection API.
*/
protected interface Resolution {
/**
* Returns {@code true} if the represented annotation could be resolved.
*
* @return {@code true} if the represented annotation could be resolved.
*/
boolean isResolved();
/**
* Returns the resolved annotation. This method throws an exception if this instance is not resolved.
*
* @return The resolved annotation. This method throws an exception if this instance is not resolved.
*/
AnnotationDescription resolve();
/**
* A simple resolved annotation.
*/
class Simple implements Resolution {
/**
* The represented annotation description.
*/
private final AnnotationDescription annotationDescription;
/**
* Creates a new simple resolution.
*
* @param annotationDescription The represented annotation description.
*/
protected Simple(AnnotationDescription annotationDescription) {
this.annotationDescription = annotationDescription;
}
@Override
public boolean isResolved() {
return true;
}
@Override
public AnnotationDescription resolve() {
return annotationDescription;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Simple)) return false;
final TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Simple other = (TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Simple) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$annotationDescription = this.annotationDescription;
final java.lang.Object other$annotationDescription = other.annotationDescription;
if (this$annotationDescription == null ? other$annotationDescription != null : !this$annotationDescription.equals(other$annotationDescription)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Simple;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $annotationDescription = this.annotationDescription;
result = result * PRIME + ($annotationDescription == null ? 43 : $annotationDescription.hashCode());
return result;
}
}
/**
* An illegal resolution.
*/
class Illegal implements Resolution {
/**
* The annotation's binary type name.
*/
private final String annotationType;
/**
* Creates a new illegal resolution.
*
* @param annotationType The annotation's binary type name.
*/
public Illegal(String annotationType) {
this.annotationType = annotationType;
}
@Override
public boolean isResolved() {
return false;
}
@Override
public AnnotationDescription resolve() {
throw new IllegalStateException("Annotation type is not available: " + annotationType);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Illegal)) return false;
final TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Illegal other = (TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Illegal) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$annotationType = this.annotationType;
final java.lang.Object other$annotationType = other.annotationType;
if (this$annotationType == null ? other$annotationType != null : !this$annotationType.equals(other$annotationType)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.AnnotationToken.Resolution.Illegal;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $annotationType = this.annotationType;
result = result * PRIME + ($annotationType == null ? 43 : $annotationType.hashCode());
return result;
}
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.AnnotationToken)) return false;
final TypePool.Default.LazyTypeDescription.AnnotationToken other = (TypePool.Default.LazyTypeDescription.AnnotationToken) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$descriptor = this.descriptor;
final java.lang.Object other$descriptor = other.descriptor;
if (this$descriptor == null ? other$descriptor != null : !this$descriptor.equals(other$descriptor)) return false;
final java.lang.Object this$values = this.getValues();
final java.lang.Object other$values = other.getValues();
if (this$values == null ? other$values != null : !this$values.equals(other$values)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.AnnotationToken;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $descriptor = this.descriptor;
result = result * PRIME + ($descriptor == null ? 43 : $descriptor.hashCode());
final java.lang.Object $values = this.getValues();
result = result * PRIME + ($values == null ? 43 : $values.hashCode());
return result;
}
}
/**
* A token for representing collected data on a field.
*/
protected static class FieldToken {
/**
* The name of the field.
*/
private final String name;
/**
* The modifiers of the represented field.
*/
private final int modifiers;
/**
* The descriptor of the field.
*/
private final String descriptor;
/**
* The field's generic signature as found in the class file or {@code null} if the field is not generic.
*/
private final String genericSignature;
/**
* The resolution of this field's generic type.
*/
private final GenericTypeToken.Resolution.ForField signatureResolution;
/**
* A mapping of the field type's type annotation tokens.
*/
private final Map<String, List<AnnotationToken>> typeAnnotationTokens;
/**
* A list of annotation tokens representing the annotations of the represented field.
*/
private final List<AnnotationToken> annotationTokens;
/**
* Creates a new field token.
*
* @param name The name of the field.
* @param modifiers The modifiers of the represented field.
* @param descriptor The descriptor of the field.
* @param genericSignature The field's generic signature as found in the class file or {@code null} if the field is not generic.
* @param typeAnnotationTokens A mapping of the field type's type annotation tokens.
* @param annotationTokens A list of annotation tokens representing the annotations of the represented field.
*/
protected FieldToken(String name, int modifiers, String descriptor, String genericSignature, Map<String, List<AnnotationToken>> typeAnnotationTokens, List<AnnotationToken> annotationTokens) {
this.modifiers = modifiers & ~Opcodes.ACC_DEPRECATED;
this.name = name;
this.descriptor = descriptor;
this.genericSignature = genericSignature;
signatureResolution = GenericTypeExtractor.ForSignature.OfField.extract(genericSignature);
this.typeAnnotationTokens = typeAnnotationTokens;
this.annotationTokens = annotationTokens;
}
/**
* Transforms this token into a lazy field description.
*
* @param lazyTypeDescription The lazy type description to attach this field description to.
* @return A field description resembling this field token.
*/
private LazyFieldDescription toFieldDescription(LazyTypeDescription lazyTypeDescription) {
return lazyTypeDescription.new LazyFieldDescription(name, modifiers, descriptor, genericSignature, signatureResolution, typeAnnotationTokens, annotationTokens);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.FieldToken)) return false;
final TypePool.Default.LazyTypeDescription.FieldToken other = (TypePool.Default.LazyTypeDescription.FieldToken) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
if (this.modifiers != other.modifiers) return false;
final java.lang.Object this$descriptor = this.descriptor;
final java.lang.Object other$descriptor = other.descriptor;
if (this$descriptor == null ? other$descriptor != null : !this$descriptor.equals(other$descriptor)) return false;
final java.lang.Object this$genericSignature = this.genericSignature;
final java.lang.Object other$genericSignature = other.genericSignature;
if (this$genericSignature == null ? other$genericSignature != null : !this$genericSignature.equals(other$genericSignature)) return false;
final java.lang.Object this$signatureResolution = this.signatureResolution;
final java.lang.Object other$signatureResolution = other.signatureResolution;
if (this$signatureResolution == null ? other$signatureResolution != null : !this$signatureResolution.equals(other$signatureResolution)) return false;
final java.lang.Object this$typeAnnotationTokens = this.typeAnnotationTokens;
final java.lang.Object other$typeAnnotationTokens = other.typeAnnotationTokens;
if (this$typeAnnotationTokens == null ? other$typeAnnotationTokens != null : !this$typeAnnotationTokens.equals(other$typeAnnotationTokens)) return false;
final java.lang.Object this$annotationTokens = this.annotationTokens;
final java.lang.Object other$annotationTokens = other.annotationTokens;
if (this$annotationTokens == null ? other$annotationTokens != null : !this$annotationTokens.equals(other$annotationTokens)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.FieldToken;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
result = result * PRIME + this.modifiers;
final java.lang.Object $descriptor = this.descriptor;
result = result * PRIME + ($descriptor == null ? 43 : $descriptor.hashCode());
final java.lang.Object $genericSignature = this.genericSignature;
result = result * PRIME + ($genericSignature == null ? 43 : $genericSignature.hashCode());
final java.lang.Object $signatureResolution = this.signatureResolution;
result = result * PRIME + ($signatureResolution == null ? 43 : $signatureResolution.hashCode());
final java.lang.Object $typeAnnotationTokens = this.typeAnnotationTokens;
result = result * PRIME + ($typeAnnotationTokens == null ? 43 : $typeAnnotationTokens.hashCode());
final java.lang.Object $annotationTokens = this.annotationTokens;
result = result * PRIME + ($annotationTokens == null ? 43 : $annotationTokens.hashCode());
return result;
}
}
/**
* A token for representing collected data on a method.
*/
protected static class MethodToken {
/**
* The internal name of the represented method.
*/
private final String name;
/**
* The modifiers of the represented method.
*/
private final int modifiers;
/**
* The descriptor of the represented method.
*/
private final String descriptor;
/**
* The methods's generic signature as found in the class file or {@code null} if the method is not generic.
*/
private final String genericSignature;
/**
* The generic type resolution of this method.
*/
private final GenericTypeToken.Resolution.ForMethod signatureResolution;
/**
* An array of internal names of the exceptions of the represented method or {@code null} if there
* are no such exceptions.
*/
private final String[] exceptionName;
/**
* A mapping of the type variables' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens;
/**
* A mapping of the type variables' type bounds' type annotation tokens by their indices and each variable's index.
*/
private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens;
/**
* A mapping of the return type's type variable tokens.
*/
private final Map<String, List<AnnotationToken>> returnTypeAnnotationTokens;
/**
* A mapping of the parameter types' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens;
/**
* A mapping of the exception types' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens;
/**
* A mapping of the receiver type's annotation tokens.
*/
private final Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens;
/**
* A list of annotation tokens that are present on the represented method.
*/
private final List<AnnotationToken> annotationTokens;
/**
* A map of parameter indices to tokens that represent their annotations.
*/
private final Map<Integer, List<AnnotationToken>> parameterAnnotationTokens;
/**
* A list of tokens describing meta data of the method's parameters.
*/
private final List<ParameterToken> parameterTokens;
/**
* The default value of this method or {@code null} if there is no such value.
*/
private final AnnotationValue<?, ?> defaultValue;
/**
* Creates a new method token.
*
* @param name The name of the method.
* @param modifiers The modifiers of the represented method.
* @param descriptor The descriptor of the represented method.
* @param genericSignature The methods's generic signature as found in the class file or {@code null} if the method is not generic.
* @param exceptionName An array of internal names of the exceptions of the represented method or {@code null} if
* there are no such exceptions.
* @param typeVariableAnnotationTokens A mapping of the type variables' type annotation tokens by their indices.
* @param typeVariableBoundAnnotationTokens A mapping of the type variables' type bounds' type annotation tokens by their
* index and each variable's index.
* @param returnTypeAnnotationTokens A mapping of the return type's type variable tokens.
* @param parameterTypeAnnotationTokens A mapping of the parameter types' type annotation tokens by their indices.
* @param exceptionTypeAnnotationTokens A mapping of the exception types' type annotation tokens by their indices.
* @param receiverTypeAnnotationTokens A mapping of the receiver type's annotation tokens.
* @param annotationTokens A list of annotation tokens that are present on the represented method.
* @param parameterAnnotationTokens A map of parameter indices to tokens that represent their annotations.
* @param parameterTokens A list of tokens describing meta data of the method's parameters.
* @param defaultValue The default value of this method or {@code null} if there is no such value.
*/
protected MethodToken(String name, int modifiers, String descriptor, String genericSignature, String[] exceptionName, Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens, Map<String, List<AnnotationToken>> returnTypeAnnotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens, Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens, List<AnnotationToken> annotationTokens, Map<Integer, List<AnnotationToken>> parameterAnnotationTokens, List<ParameterToken> parameterTokens, AnnotationValue<?, ?> defaultValue) {
this.modifiers = modifiers & ~Opcodes.ACC_DEPRECATED;
this.name = name;
this.descriptor = descriptor;
this.genericSignature = genericSignature;
signatureResolution = GenericTypeExtractor.ForSignature.OfMethod.extract(genericSignature);
this.exceptionName = exceptionName;
this.typeVariableAnnotationTokens = typeVariableAnnotationTokens;
this.typeVariableBoundAnnotationTokens = typeVariableBoundAnnotationTokens;
this.returnTypeAnnotationTokens = returnTypeAnnotationTokens;
this.parameterTypeAnnotationTokens = parameterTypeAnnotationTokens;
this.exceptionTypeAnnotationTokens = exceptionTypeAnnotationTokens;
this.receiverTypeAnnotationTokens = receiverTypeAnnotationTokens;
this.annotationTokens = annotationTokens;
this.parameterAnnotationTokens = parameterAnnotationTokens;
this.parameterTokens = parameterTokens;
this.defaultValue = defaultValue;
}
/**
* Transforms this method token to a method description that is attached to a lazy type description.
*
* @param lazyTypeDescription The lazy type description to attach this method description to.
* @return A method description representing this field token.
*/
private MethodDescription.InDefinedShape toMethodDescription(LazyTypeDescription lazyTypeDescription) {
return lazyTypeDescription.new LazyMethodDescription(name, modifiers, descriptor, genericSignature, signatureResolution, exceptionName, typeVariableAnnotationTokens, typeVariableBoundAnnotationTokens, returnTypeAnnotationTokens, parameterTypeAnnotationTokens, exceptionTypeAnnotationTokens, receiverTypeAnnotationTokens, annotationTokens, parameterAnnotationTokens, parameterTokens, defaultValue);
}
/**
* A token representing a method's parameter.
*/
protected static class ParameterToken {
/**
* Donates an unknown name of a parameter.
*/
protected static final String NO_NAME = null;
/**
* Donates an unknown modifier of a parameter.
*/
protected static final Integer NO_MODIFIERS = null;
/**
* The name of the parameter or {@code null} if no explicit name for this parameter is known.
*/
private final String name;
/**
* The modifiers of the parameter or {@code null} if no modifiers are known for this parameter.
*/
private final Integer modifiers;
/**
* Creates a parameter token for a parameter without an explicit name and without specific modifiers.
*/
protected ParameterToken() {
this(NO_NAME);
}
/**
* Creates a parameter token for a parameter with an explicit name and without specific modifiers.
*
* @param name The name of the parameter.
*/
protected ParameterToken(String name) {
this(name, NO_MODIFIERS);
}
/**
* Creates a parameter token for a parameter with an explicit name and with specific modifiers.
*
* @param name The name of the parameter.
* @param modifiers The modifiers of the parameter.
*/
protected ParameterToken(String name, Integer modifiers) {
this.name = name;
this.modifiers = modifiers;
}
/**
* Returns the name of the parameter or {@code null} if there is no such name.
*
* @return The name of the parameter or {@code null} if there is no such name.
*/
protected String getName() {
return name;
}
/**
* Returns the modifiers of the parameter or {@code null} if no modifiers are known.
*
* @return The modifiers of the parameter or {@code null} if no modifiers are known.
*/
protected Integer getModifiers() {
return modifiers;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.MethodToken.ParameterToken)) return false;
final TypePool.Default.LazyTypeDescription.MethodToken.ParameterToken other = (TypePool.Default.LazyTypeDescription.MethodToken.ParameterToken) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.getName();
final java.lang.Object other$name = other.getName();
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
final java.lang.Object this$modifiers = this.getModifiers();
final java.lang.Object other$modifiers = other.getModifiers();
if (this$modifiers == null ? other$modifiers != null : !this$modifiers.equals(other$modifiers)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.MethodToken.ParameterToken;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.getName();
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
final java.lang.Object $modifiers = this.getModifiers();
result = result * PRIME + ($modifiers == null ? 43 : $modifiers.hashCode());
return result;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default.LazyTypeDescription.MethodToken)) return false;
final TypePool.Default.LazyTypeDescription.MethodToken other = (TypePool.Default.LazyTypeDescription.MethodToken) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
if (this.modifiers != other.modifiers) return false;
final java.lang.Object this$descriptor = this.descriptor;
final java.lang.Object other$descriptor = other.descriptor;
if (this$descriptor == null ? other$descriptor != null : !this$descriptor.equals(other$descriptor)) return false;
final java.lang.Object this$genericSignature = this.genericSignature;
final java.lang.Object other$genericSignature = other.genericSignature;
if (this$genericSignature == null ? other$genericSignature != null : !this$genericSignature.equals(other$genericSignature)) return false;
final java.lang.Object this$signatureResolution = this.signatureResolution;
final java.lang.Object other$signatureResolution = other.signatureResolution;
if (this$signatureResolution == null ? other$signatureResolution != null : !this$signatureResolution.equals(other$signatureResolution)) return false;
if (!java.util.Arrays.deepEquals(this.exceptionName, other.exceptionName)) return false;
final java.lang.Object this$typeVariableAnnotationTokens = this.typeVariableAnnotationTokens;
final java.lang.Object other$typeVariableAnnotationTokens = other.typeVariableAnnotationTokens;
if (this$typeVariableAnnotationTokens == null ? other$typeVariableAnnotationTokens != null : !this$typeVariableAnnotationTokens.equals(other$typeVariableAnnotationTokens)) return false;
final java.lang.Object this$typeVariableBoundAnnotationTokens = this.typeVariableBoundAnnotationTokens;
final java.lang.Object other$typeVariableBoundAnnotationTokens = other.typeVariableBoundAnnotationTokens;
if (this$typeVariableBoundAnnotationTokens == null ? other$typeVariableBoundAnnotationTokens != null : !this$typeVariableBoundAnnotationTokens.equals(other$typeVariableBoundAnnotationTokens)) return false;
final java.lang.Object this$returnTypeAnnotationTokens = this.returnTypeAnnotationTokens;
final java.lang.Object other$returnTypeAnnotationTokens = other.returnTypeAnnotationTokens;
if (this$returnTypeAnnotationTokens == null ? other$returnTypeAnnotationTokens != null : !this$returnTypeAnnotationTokens.equals(other$returnTypeAnnotationTokens)) return false;
final java.lang.Object this$parameterTypeAnnotationTokens = this.parameterTypeAnnotationTokens;
final java.lang.Object other$parameterTypeAnnotationTokens = other.parameterTypeAnnotationTokens;
if (this$parameterTypeAnnotationTokens == null ? other$parameterTypeAnnotationTokens != null : !this$parameterTypeAnnotationTokens.equals(other$parameterTypeAnnotationTokens)) return false;
final java.lang.Object this$exceptionTypeAnnotationTokens = this.exceptionTypeAnnotationTokens;
final java.lang.Object other$exceptionTypeAnnotationTokens = other.exceptionTypeAnnotationTokens;
if (this$exceptionTypeAnnotationTokens == null ? other$exceptionTypeAnnotationTokens != null : !this$exceptionTypeAnnotationTokens.equals(other$exceptionTypeAnnotationTokens)) return false;
final java.lang.Object this$receiverTypeAnnotationTokens = this.receiverTypeAnnotationTokens;
final java.lang.Object other$receiverTypeAnnotationTokens = other.receiverTypeAnnotationTokens;
if (this$receiverTypeAnnotationTokens == null ? other$receiverTypeAnnotationTokens != null : !this$receiverTypeAnnotationTokens.equals(other$receiverTypeAnnotationTokens)) return false;
final java.lang.Object this$annotationTokens = this.annotationTokens;
final java.lang.Object other$annotationTokens = other.annotationTokens;
if (this$annotationTokens == null ? other$annotationTokens != null : !this$annotationTokens.equals(other$annotationTokens)) return false;
final java.lang.Object this$parameterAnnotationTokens = this.parameterAnnotationTokens;
final java.lang.Object other$parameterAnnotationTokens = other.parameterAnnotationTokens;
if (this$parameterAnnotationTokens == null ? other$parameterAnnotationTokens != null : !this$parameterAnnotationTokens.equals(other$parameterAnnotationTokens)) return false;
final java.lang.Object this$parameterTokens = this.parameterTokens;
final java.lang.Object other$parameterTokens = other.parameterTokens;
if (this$parameterTokens == null ? other$parameterTokens != null : !this$parameterTokens.equals(other$parameterTokens)) return false;
final java.lang.Object this$defaultValue = this.defaultValue;
final java.lang.Object other$defaultValue = other.defaultValue;
if (this$defaultValue == null ? other$defaultValue != null : !this$defaultValue.equals(other$defaultValue)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default.LazyTypeDescription.MethodToken;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
result = result * PRIME + this.modifiers;
final java.lang.Object $descriptor = this.descriptor;
result = result * PRIME + ($descriptor == null ? 43 : $descriptor.hashCode());
final java.lang.Object $genericSignature = this.genericSignature;
result = result * PRIME + ($genericSignature == null ? 43 : $genericSignature.hashCode());
final java.lang.Object $signatureResolution = this.signatureResolution;
result = result * PRIME + ($signatureResolution == null ? 43 : $signatureResolution.hashCode());
result = result * PRIME + java.util.Arrays.deepHashCode(this.exceptionName);
final java.lang.Object $typeVariableAnnotationTokens = this.typeVariableAnnotationTokens;
result = result * PRIME + ($typeVariableAnnotationTokens == null ? 43 : $typeVariableAnnotationTokens.hashCode());
final java.lang.Object $typeVariableBoundAnnotationTokens = this.typeVariableBoundAnnotationTokens;
result = result * PRIME + ($typeVariableBoundAnnotationTokens == null ? 43 : $typeVariableBoundAnnotationTokens.hashCode());
final java.lang.Object $returnTypeAnnotationTokens = this.returnTypeAnnotationTokens;
result = result * PRIME + ($returnTypeAnnotationTokens == null ? 43 : $returnTypeAnnotationTokens.hashCode());
final java.lang.Object $parameterTypeAnnotationTokens = this.parameterTypeAnnotationTokens;
result = result * PRIME + ($parameterTypeAnnotationTokens == null ? 43 : $parameterTypeAnnotationTokens.hashCode());
final java.lang.Object $exceptionTypeAnnotationTokens = this.exceptionTypeAnnotationTokens;
result = result * PRIME + ($exceptionTypeAnnotationTokens == null ? 43 : $exceptionTypeAnnotationTokens.hashCode());
final java.lang.Object $receiverTypeAnnotationTokens = this.receiverTypeAnnotationTokens;
result = result * PRIME + ($receiverTypeAnnotationTokens == null ? 43 : $receiverTypeAnnotationTokens.hashCode());
final java.lang.Object $annotationTokens = this.annotationTokens;
result = result * PRIME + ($annotationTokens == null ? 43 : $annotationTokens.hashCode());
final java.lang.Object $parameterAnnotationTokens = this.parameterAnnotationTokens;
result = result * PRIME + ($parameterAnnotationTokens == null ? 43 : $parameterAnnotationTokens.hashCode());
final java.lang.Object $parameterTokens = this.parameterTokens;
result = result * PRIME + ($parameterTokens == null ? 43 : $parameterTokens.hashCode());
final java.lang.Object $defaultValue = this.defaultValue;
result = result * PRIME + ($defaultValue == null ? 43 : $defaultValue.hashCode());
return result;
}
}
/**
* A lazy description of an annotation that looks up types from a type pool when required.
*/
private static class LazyAnnotationDescription extends AnnotationDescription.AbstractBase {
/**
* The type pool for looking up type references.
*/
protected final TypePool typePool;
/**
* The type of this annotation.
*/
private final TypeDescription annotationType;
/**
* A map of annotation values by their property name.
*/
protected final Map<String, AnnotationValue<?, ?>> values;
/**
* Creates a new lazy annotation description.
*
* @param typePool The type pool to be used for looking up linked types.
* @param annotationType The annotation's type.
* @param values A map of annotation value names to their value representations.
*/
private LazyAnnotationDescription(TypePool typePool, TypeDescription annotationType, Map<String, AnnotationValue<?, ?>> values) {
this.typePool = typePool;
this.annotationType = annotationType;
this.values = values;
}
/**
* Represents a list of annotation tokens in form of a list of lazy type annotations. Any annotation with
* a type that cannot be loaded from the type pool is ignored and not included in the list. If the provided
* {@code tokens} are {@code null}, an empty list is returned.
*
* @param typePool The type pool to be used for looking up linked types.
* @param tokens The tokens to represent in the list.
* @return A list of the loadable annotations.
*/
protected static AnnotationList asListOfNullable(TypePool typePool, List<? extends AnnotationToken> tokens) {
return tokens == null ? new AnnotationList.Empty() : asList(typePool, tokens);
}
/**
* Represents a list of annotation tokens in form of a list of lazy type annotations. Any annotation with
* a type that cannot be loaded from the type pool is ignored and not included in the list.
*
* @param typePool The type pool to be used for looking up linked types.
* @param tokens The tokens to represent in the list.
* @return A list of the loadable annotations.
*/
protected static AnnotationList asList(TypePool typePool, List<? extends AnnotationToken> tokens) {
List<AnnotationDescription> annotationDescriptions = new ArrayList<AnnotationDescription>(tokens.size());
for (AnnotationToken token : tokens) {
AnnotationToken.Resolution resolution = token.toAnnotationDescription(typePool);
if (resolution.isResolved()) {
annotationDescriptions.add(resolution.resolve());
}
}
return new AnnotationList.Explicit(annotationDescriptions);
}
@Override
public AnnotationValue<?, ?> getValue(MethodDescription.InDefinedShape property) {
if (!property.getDeclaringType().asErasure().equals(annotationType)) {
throw new IllegalArgumentException(property + " is not declared by " + getAnnotationType());
}
AnnotationValue<?, ?> annotationValue = values.get(property.getName());
if (annotationValue == null) {
annotationValue = getAnnotationType().getDeclaredMethods().filter(ElementMatchers.is(property)).getOnly().getDefaultValue();
}
if (annotationValue != null) {
return annotationValue;
}
throw new IllegalStateException(property + " is not defined on annotation");
}
@Override
public TypeDescription getAnnotationType() {
return annotationType;
}
@Override
public <T extends Annotation> Loadable<T> prepare(Class<T> annotationType) {
if (!this.annotationType.represents(annotationType)) {
throw new IllegalArgumentException(annotationType + " does not represent " + this.annotationType);
}
return new Loadable<T>(typePool, annotationType, values);
}
/**
* A loadable version of a lazy annotation description.
*
* @param <S> The annotation type.
*/
private static class Loadable<S extends Annotation> extends LazyAnnotationDescription implements AnnotationDescription.Loadable<S> {
/**
* The loaded annotation type.
*/
private final Class<S> annotationType;
/**
* Creates a new loadable version of a lazy annotation.
*
* @param typePool The type pool to be used for looking up linked types.
* @param annotationType The annotation's loaded type.
* @param values A map of annotation value names to their value representations.
*/
private Loadable(TypePool typePool, Class<S> annotationType, Map<String, AnnotationValue<?, ?>> values) {
super(typePool, new ForLoadedType(annotationType), values);
this.annotationType = annotationType;
}
@Override
public S load() throws ClassNotFoundException {
return AnnotationInvocationHandler.of(annotationType.getClassLoader(), annotationType, values);
}
@Override
public S loadSilent() {
try {
return load();
} catch (ClassNotFoundException exception) {
throw new IllegalStateException("Could not load annotation type or referenced type", exception);
}
}
}
}
/**
* An implementation of a {@link PackageDescription} that only
* loads its annotations on requirement.
*/
private static class LazyPackageDescription extends PackageDescription.AbstractBase {
/**
* The type pool to use for look-ups.
*/
private final TypePool typePool;
/**
* The name of the package.
*/
private final String name;
/**
* Creates a new lazy package description.
*
* @param typePool The type pool to use for look-ups.
* @param name The name of the package.
*/
private LazyPackageDescription(TypePool typePool, String name) {
this.typePool = typePool;
this.name = name;
}
@Override
public AnnotationList getDeclaredAnnotations() {
Resolution resolution = typePool.describe(name + "." + PackageDescription.PACKAGE_CLASS_NAME);
return resolution.isResolved() ? resolution.resolve().getDeclaredAnnotations() : new AnnotationList.Empty();
}
@Override
public String getName() {
return name;
}
}
/**
* A list that is constructing {@link LazyTypeDescription}s.
*/
private static class LazyTypeList extends TypeList.AbstractBase {
/**
* The type pool to use for locating types.
*/
private final TypePool typePool;
/**
* A list of type descriptors that this list represents.
*/
private final List<String> descriptors;
/**
* Creates a list of lazy type descriptions.
*
* @param typePool The type pool to use for locating types.
* @param descriptors A list of type descriptors that this list represents.
*/
private LazyTypeList(TypePool typePool, List<String> descriptors) {
this.typePool = typePool;
this.descriptors = descriptors;
}
@Override
public TypeDescription get(int index) {
return TokenizedGenericType.toErasure(typePool, descriptors.get(index));
}
@Override
public int size() {
return descriptors.size();
}
@Override
public String[] toInternalNames() {
String[] internalName = new String[descriptors.size()];
int index = 0;
for (String descriptor : descriptors) {
internalName[index++] = Type.getType(descriptor).getInternalName();
}
return internalName.length == 0 ? NO_INTERFACES : internalName;
}
@Override
public int getStackSize() {
int stackSize = 0;
for (String descriptor : descriptors) {
stackSize += Type.getType(descriptor).getSize();
}
return stackSize;
}
}
/**
* A representation of a generic type that is described by a {@link GenericTypeToken}.
*/
private static class TokenizedGenericType extends Generic.LazyProjection.WithEagerNavigation {
/**
* The type pool to use for locating referenced types.
*/
private final TypePool typePool;
/**
* The token that describes the represented generic type.
*/
private final GenericTypeToken genericTypeToken;
/**
* A descriptor of the generic type's raw type.
*/
private final String rawTypeDescriptor;
/**
* The tokenized type's type annotation tokens.
*/
private final Map<String, List<AnnotationToken>> annotationTokens;
/**
* The closest type variable source of this generic type's declaration context.
*/
private final TypeVariableSource typeVariableSource;
/**
* Creates a new tokenized generic type.
*
* @param typePool The type pool to use for locating referenced types.
* @param genericTypeToken The token that describes the represented generic type.
* @param rawTypeDescriptor A descriptor of the generic type's erasure.
* @param annotationTokens The tokenized type's type annotation tokens.
* @param typeVariableSource The closest type variable source of this generic type's declaration context.
*/
protected TokenizedGenericType(TypePool typePool, GenericTypeToken genericTypeToken, String rawTypeDescriptor, Map<String, List<AnnotationToken>> annotationTokens, TypeVariableSource typeVariableSource) {
this.typePool = typePool;
this.genericTypeToken = genericTypeToken;
this.rawTypeDescriptor = rawTypeDescriptor;
this.annotationTokens = annotationTokens;
this.typeVariableSource = typeVariableSource;
}
/**
* Creates a new generic type description for a tokenized generic type.
*
* @param typePool The type pool to use for locating referenced types.
* @param genericTypeToken The token that describes the represented generic type.
* @param rawTypeDescriptor A descriptor of the generic type's erasure.
* @param annotationTokens The tokenized type's type annotation tokens or {@code null} if no such annotations are defined.
* @param typeVariableSource The closest type variable source of this generic type's declaration context.
* @return A suitable generic type.
*/
protected static Generic of(TypePool typePool, GenericTypeToken genericTypeToken, String rawTypeDescriptor, Map<String, List<AnnotationToken>> annotationTokens, TypeVariableSource typeVariableSource) {
return new TokenizedGenericType(typePool, genericTypeToken, rawTypeDescriptor, annotationTokens == null ? Collections.<String, List<AnnotationToken>>emptyMap() : annotationTokens, typeVariableSource);
}
/**
* Creates a type description from a descriptor by looking up the corresponding type.
*
* @param typePool The type pool to use for locating a type.
* @param descriptor The descriptor to interpret.
* @return A description of the type represented by the descriptor.
*/
protected static TypeDescription toErasure(TypePool typePool, String descriptor) {
Type type = Type.getType(descriptor);
return typePool.describe(type.getSort() == Type.ARRAY ? type.getInternalName().replace('/', '.') : type.getClassName()).resolve();
}
@Override
protected Generic resolve() {
return genericTypeToken.toGenericType(typePool, typeVariableSource, GenericTypeToken.EMPTY_TYPE_PATH, annotationTokens);
}
@Override
public TypeDescription asErasure() {
return toErasure(typePool, rawTypeDescriptor);
}
@Override
public AnnotationList getDeclaredAnnotations() {
return resolve().getDeclaredAnnotations();
}
/**
* A tokenized list of generic types.
*/
protected static class TokenList extends TypeList.Generic.AbstractBase {
/**
* The type pool to use for locating types.
*/
private final TypePool typePool;
/**
* Type tokens that describe the represented generic types.
*/
private final List<GenericTypeToken> genericTypeTokens;
/**
* A list of the generic types' erasures.
*/
private final List<String> rawTypeDescriptors;
/**
* The closest type variable source of this generic type's declaration context.
*/
private final TypeVariableSource typeVariableSource;
/**
* A mapping of each type's type annotation tokens by its index.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
/**
* Creates a list of tokenized generic types.
*
* @param typePool The type pool to use for locating type descriptions.
* @param genericTypeTokens A list of tokens describing the represented generic types.
* @param annotationTokens A mapping of each type's type annotation tokens by its index.
* @param rawTypeDescriptors A list of the generic types' erasures.
* @param typeVariableSource The closest type variable source of this generic type's declaration context.
*/
private TokenList(TypePool typePool, List<GenericTypeToken> genericTypeTokens, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, List<String> rawTypeDescriptors, TypeVariableSource typeVariableSource) {
this.typePool = typePool;
this.genericTypeTokens = genericTypeTokens;
this.annotationTokens = annotationTokens;
this.rawTypeDescriptors = rawTypeDescriptors;
this.typeVariableSource = typeVariableSource;
}
@Override
public Generic get(int index) {
return rawTypeDescriptors.size() == genericTypeTokens.size() ? TokenizedGenericType.of(typePool, genericTypeTokens.get(index), rawTypeDescriptors.get(index), annotationTokens.get(index), typeVariableSource) : TokenizedGenericType.toErasure(typePool, rawTypeDescriptors.get(index)).asGenericType();
}
@Override
public int size() {
return rawTypeDescriptors.size();
}
@Override
public TypeList asErasures() {
return new LazyTypeList(typePool, rawTypeDescriptors);
}
}
/**
* A list of tokenized type variables.
*/
protected static class TypeVariableList extends TypeList.Generic.AbstractBase {
/**
* The type pool to use for locating types.
*/
private final TypePool typePool;
/**
* Type tokens that describe the represented type variables.
*/
private final List<GenericTypeToken.OfFormalTypeVariable> typeVariables;
/**
* The type variable source of the represented type variables.
*/
private final TypeVariableSource typeVariableSource;
/**
* A mapping of the type variables' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens;
/**
* A mapping of the type variables' bound types' annotation tokens by their indices and each type variable's index..
*/
private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens;
/**
* Creates a list of type variables.
*
* @param typePool The type pool to use for locating types.
* @param typeVariables Type tokens that describe the represented generic types.
* @param typeVariableSource The type variable source of the represented type variables.
* @param annotationTokens A mapping of the type variables' type annotation tokens by their indices.
* @param boundAnnotationTokens A mapping of the type variables' bound types' annotation tokens by their indices
* and each type variable's index.
*/
protected TypeVariableList(TypePool typePool, List<GenericTypeToken.OfFormalTypeVariable> typeVariables, TypeVariableSource typeVariableSource, Map<Integer, Map<String, List<AnnotationToken>>> annotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> boundAnnotationTokens) {
this.typePool = typePool;
this.typeVariables = typeVariables;
this.typeVariableSource = typeVariableSource;
this.annotationTokens = annotationTokens;
this.boundAnnotationTokens = boundAnnotationTokens;
}
@Override
public Generic get(int index) {
return typeVariables.get(index).toGenericType(typePool, typeVariableSource, annotationTokens.get(index), boundAnnotationTokens.get(index));
}
@Override
public int size() {
return typeVariables.size();
}
}
/**
* A lazy description of a non-well-defined described generic type.
*/
protected static class Malformed extends LazyProjection.WithEagerNavigation {
/**
* The type pool to use for locating types.
*/
private final TypePool typePool;
/**
* The descriptor of the type erasure.
*/
private final String rawTypeDescriptor;
/**
* Creates a lazy description of a non-well-defined described generic type.
*
* @param typePool The type pool to use for locating types.
* @param rawTypeDescriptor The descriptor of the type erasure.
*/
protected Malformed(TypePool typePool, String rawTypeDescriptor) {
this.typePool = typePool;
this.rawTypeDescriptor = rawTypeDescriptor;
}
@Override
protected Generic resolve() {
throw new GenericSignatureFormatError();
}
@Override
public TypeDescription asErasure() {
return toErasure(typePool, rawTypeDescriptor);
}
@Override
public AnnotationList getDeclaredAnnotations() {
throw new GenericSignatureFormatError();
}
/**
* A tokenized list of non-well-defined generic types.
*/
protected static class TokenList extends TypeList.Generic.AbstractBase {
/**
* The type pool to use for locating types.
*/
private final TypePool typePool;
/**
* A list of descriptors of the list's types' erasures.
*/
private final List<String> rawTypeDescriptors;
/**
* Creates a new tokenized list of generic types.
*
* @param typePool The type pool to use for locating types.
* @param rawTypeDescriptors A list of descriptors of the list's types' erasures.
*/
protected TokenList(TypePool typePool, List<String> rawTypeDescriptors) {
this.typePool = typePool;
this.rawTypeDescriptors = rawTypeDescriptors;
}
@Override
public Generic get(int index) {
return new Malformed(typePool, rawTypeDescriptors.get(index));
}
@Override
public int size() {
return rawTypeDescriptors.size();
}
@Override
public TypeList asErasures() {
return new LazyTypeList(typePool, rawTypeDescriptors);
}
}
}
}
/**
* A lazy field description that only resolved type references when required.
*/
private class LazyFieldDescription extends FieldDescription.InDefinedShape.AbstractBase {
/**
* The name of the field.
*/
private final String name;
/**
* The modifiers of the field.
*/
private final int modifiers;
/**
* The descriptor of this field's type.
*/
private final String descriptor;
/**
* The field's generic signature as found in the class file or {@code null} if the field is not generic.
*/
private final String genericSignature;
/**
* A resolution of this field's generic type.
*/
private final GenericTypeToken.Resolution.ForField signatureResolution;
/**
* A mapping of the field type's type annotation tokens.
*/
private final Map<String, List<AnnotationToken>> typeAnnotationTokens;
/**
* A list of annotation descriptions of this field.
*/
private final List<AnnotationToken> annotationTokens;
/**
* Creates a new lazy field description.
*
* @param name The name of the field.
* @param modifiers The modifiers of the field.
* @param descriptor The descriptor of this field's type.
* @param genericSignature The field's generic signature as found in the class file or {@code null} if the field is not generic.
* @param signatureResolution A resolution of this field's generic type.
* @param typeAnnotationTokens A mapping of the field type's type annotation tokens.
* @param annotationTokens A list of annotation descriptions of this field.
*/
private LazyFieldDescription(String name, int modifiers, String descriptor, String genericSignature, GenericTypeToken.Resolution.ForField signatureResolution, Map<String, List<AnnotationToken>> typeAnnotationTokens, List<AnnotationToken> annotationTokens) {
this.modifiers = modifiers;
this.name = name;
this.descriptor = descriptor;
this.genericSignature = genericSignature;
this.signatureResolution = signatureResolution;
this.typeAnnotationTokens = typeAnnotationTokens;
this.annotationTokens = annotationTokens;
}
@Override
public Generic getType() {
return signatureResolution.resolveFieldType(descriptor, typePool, typeAnnotationTokens, this);
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, annotationTokens);
}
@Override
public String getName() {
return name;
}
@Override
public TypeDescription getDeclaringType() {
return LazyTypeDescription.this;
}
@Override
public int getModifiers() {
return modifiers;
}
@Override
public String getGenericSignature() {
return genericSignature;
}
}
/**
* A lazy representation of a method that resolves references to types only on demand.
*/
private class LazyMethodDescription extends MethodDescription.InDefinedShape.AbstractBase {
/**
* The internal name of this method.
*/
private final String internalName;
/**
* The modifiers of this method.
*/
private final int modifiers;
/**
* The descriptor of the return type.
*/
private final String returnTypeDescriptor;
/**
* The method's generic signature as found in the class file or {@code null} if the method is not generic.
*/
private final String genericSignature;
/**
* The generic type token of this method.
*/
private final GenericTypeToken.Resolution.ForMethod signatureResolution;
/**
* A list of type descriptions of this method's parameters.
*/
private final List<String> parameterTypeDescriptors;
/**
* A list of type descriptions of this method's exception types.
*/
private final List<String> exceptionTypeDescriptors;
/**
* A mapping of the type variables' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens;
/**
* A mapping of the type variables' type bounds' type annotation tokens by their indices and each variable's index.
*/
private final Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens;
/**
* A mapping of the return type's type variable tokens.
*/
private final Map<String, List<AnnotationToken>> returnTypeAnnotationTokens;
/**
* A mapping of the parameter types' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens;
/**
* A mapping of the exception types' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens;
/**
* A mapping of the receiver type's type annotation tokens.
*/
private final Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens;
/**
* The annotation tokens representing the method's annotations.
*/
private final List<AnnotationToken> annotationTokens;
/**
* The annotation tokens representing the parameter's annotation. Every index can
* contain {@code null} if a parameter does not define any annotations.
*/
private final Map<Integer, List<AnnotationToken>> parameterAnnotationTokens;
/**
* An array of parameter names which may be {@code null} if no explicit name is known for a parameter.
*/
private final String[] parameterNames;
/**
* An array of parameter modifiers which may be {@code null} if no modifiers is known.
*/
private final Integer[] parameterModifiers;
/**
* The default value of this method or {@code null} if no such value exists.
*/
private final AnnotationValue<?, ?> defaultValue;
/**
* Creates a new lazy method description.
*
* @param internalName The internal name of this method.
* @param modifiers The modifiers of the represented method.
* @param descriptor The method descriptor of this method.
* @param genericSignature The method's generic signature as found in the class file or {@code null} if the method is not generic.
* @param signatureResolution The generic type token of this method.
* @param exceptionTypeInternalName The internal names of the exceptions that are declared by this
* method or {@code null} if no exceptions are declared by this
* method.
* @param typeVariableAnnotationTokens A mapping of the type variables' type annotation tokens by their indices.
* @param typeVariableBoundAnnotationTokens A mapping of the type variables' type bounds' type annotation tokens by their
* index and each variable's index.
* @param returnTypeAnnotationTokens A mapping of the return type's type variable tokens.
* @param parameterTypeAnnotationTokens A mapping of the parameter types' type annotation tokens by their indices.
* @param exceptionTypeAnnotationTokens A mapping of the exception types' type annotation tokens by their indices.
* @param receiverTypeAnnotationTokens A mapping of the receiver type's type annotation tokens.
* @param annotationTokens The annotation tokens representing the method's annotations.
* @param parameterAnnotationTokens The annotation tokens representing the parameter's annotation. Every
* index can contain {@code null} if a parameter does not define any annotations.
* @param parameterTokens A list of parameter tokens which might be empty or even out of sync
* with the actual parameters if the debugging information found in a
* class was corrupt.
* @param defaultValue The default value of this method or {@code null} if there is no
*/
private LazyMethodDescription(String internalName, int modifiers, String descriptor, String genericSignature, GenericTypeToken.Resolution.ForMethod signatureResolution, String[] exceptionTypeInternalName, Map<Integer, Map<String, List<AnnotationToken>>> typeVariableAnnotationTokens, Map<Integer, Map<Integer, Map<String, List<AnnotationToken>>>> typeVariableBoundAnnotationTokens, Map<String, List<AnnotationToken>> returnTypeAnnotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> parameterTypeAnnotationTokens, Map<Integer, Map<String, List<AnnotationToken>>> exceptionTypeAnnotationTokens, Map<String, List<AnnotationToken>> receiverTypeAnnotationTokens, List<AnnotationToken> annotationTokens, Map<Integer, List<AnnotationToken>> parameterAnnotationTokens, List<MethodToken.ParameterToken> parameterTokens, AnnotationValue<?, ?> defaultValue) {
this.modifiers = modifiers;
this.internalName = internalName;
Type methodType = Type.getMethodType(descriptor);
Type returnType = methodType.getReturnType();
Type[] parameterType = methodType.getArgumentTypes();
returnTypeDescriptor = returnType.getDescriptor();
parameterTypeDescriptors = new ArrayList<String>(parameterType.length);
for (Type type : parameterType) {
parameterTypeDescriptors.add(type.getDescriptor());
}
this.genericSignature = genericSignature;
this.signatureResolution = signatureResolution;
if (exceptionTypeInternalName == null) {
exceptionTypeDescriptors = Collections.emptyList();
} else {
exceptionTypeDescriptors = new ArrayList<String>(exceptionTypeInternalName.length);
for (String anExceptionTypeInternalName : exceptionTypeInternalName) {
exceptionTypeDescriptors.add(Type.getObjectType(anExceptionTypeInternalName).getDescriptor());
}
}
this.typeVariableAnnotationTokens = typeVariableAnnotationTokens;
this.typeVariableBoundAnnotationTokens = typeVariableBoundAnnotationTokens;
this.returnTypeAnnotationTokens = returnTypeAnnotationTokens;
this.parameterTypeAnnotationTokens = parameterTypeAnnotationTokens;
this.exceptionTypeAnnotationTokens = exceptionTypeAnnotationTokens;
this.receiverTypeAnnotationTokens = receiverTypeAnnotationTokens;
this.annotationTokens = annotationTokens;
this.parameterAnnotationTokens = parameterAnnotationTokens;
parameterNames = new String[parameterType.length];
parameterModifiers = new Integer[parameterType.length];
if (parameterTokens.size() == parameterType.length) {
int index = 0;
for (MethodToken.ParameterToken parameterToken : parameterTokens) {
parameterNames[index] = parameterToken.getName();
parameterModifiers[index] = parameterToken.getModifiers();
index++;
}
}
this.defaultValue = defaultValue;
}
@Override
public Generic getReturnType() {
return signatureResolution.resolveReturnType(returnTypeDescriptor, typePool, returnTypeAnnotationTokens, this);
}
@Override
public TypeList.Generic getExceptionTypes() {
return signatureResolution.resolveExceptionTypes(exceptionTypeDescriptors, typePool, exceptionTypeAnnotationTokens, this);
}
@Override
public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
return new LazyParameterList();
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asList(typePool, annotationTokens);
}
@Override
public String getInternalName() {
return internalName;
}
@Override
public TypeDescription getDeclaringType() {
return LazyTypeDescription.this;
}
@Override
public int getModifiers() {
return modifiers;
}
@Override
public TypeList.Generic getTypeVariables() {
return signatureResolution.resolveTypeVariables(typePool, this, typeVariableAnnotationTokens, typeVariableBoundAnnotationTokens);
}
@Override
public AnnotationValue<?, ?> getDefaultValue() {
return defaultValue;
}
@Override
public Generic getReceiverType() {
if (isStatic()) {
return Generic.UNDEFINED;
} else if (isConstructor()) {
TypeDescription declaringType = getDeclaringType();
TypeDescription enclosingDeclaringType = declaringType.getEnclosingType();
if (enclosingDeclaringType == null) {
return declaringType.isGenerified() ? new LazyParameterizedReceiverType(declaringType) : new LazyNonGenericReceiverType(declaringType);
} else {
return !declaringType.isStatic() && declaringType.isGenerified() ? new LazyParameterizedReceiverType(enclosingDeclaringType) : new LazyNonGenericReceiverType(enclosingDeclaringType);
}
} else {
return LazyTypeDescription.this.isGenerified() ? new LazyParameterizedReceiverType() : new LazyNonGenericReceiverType();
}
}
@Override
public String getGenericSignature() {
return genericSignature;
}
/**
* A lazy list of parameter descriptions for the enclosing method description.
*/
private class LazyParameterList extends ParameterList.AbstractBase<ParameterDescription.InDefinedShape> {
@Override
public ParameterDescription.InDefinedShape get(int index) {
return new LazyParameterDescription(index);
}
@Override
public boolean hasExplicitMetaData() {
for (int i = 0; i < size(); i++) {
if (parameterNames[i] == null || parameterModifiers[i] == null) {
return false;
}
}
return true;
}
@Override
public int size() {
return parameterTypeDescriptors.size();
}
@Override
public TypeList.Generic asTypeList() {
return signatureResolution.resolveParameterTypes(parameterTypeDescriptors, typePool, parameterTypeAnnotationTokens, LazyMethodDescription.this);
}
}
/**
* A lazy description of a parameters of the enclosing method.
*/
private class LazyParameterDescription extends ParameterDescription.InDefinedShape.AbstractBase {
/**
* The index of the described parameter.
*/
private final int index;
/**
* Creates a new description for a given parameter of the enclosing method.
*
* @param index The index of the described parameter.
*/
protected LazyParameterDescription(int index) {
this.index = index;
}
@Override
public MethodDescription.InDefinedShape getDeclaringMethod() {
return LazyMethodDescription.this;
}
@Override
public int getIndex() {
return index;
}
@Override
public boolean isNamed() {
return parameterNames[index] != null;
}
@Override
public boolean hasModifiers() {
return parameterModifiers[index] != null;
}
@Override
public String getName() {
return isNamed() ? parameterNames[index] : super.getName();
}
@Override
public int getModifiers() {
return hasModifiers() ? parameterModifiers[index] : super.getModifiers();
}
@Override
public Generic getType() {
return signatureResolution.resolveParameterTypes(parameterTypeDescriptors, typePool, parameterTypeAnnotationTokens, LazyMethodDescription.this).get(index);
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, parameterAnnotationTokens.get(index));
}
}
/**
* A lazy description of a parameterized receiver type.
*/
private class LazyParameterizedReceiverType extends Generic.OfParameterizedType {
/**
* The erasure of the type to be represented as a parameterized receiver type.
*/
private final TypeDescription typeDescription;
/**
* Creates a new lazy parameterized receiver type of the method's declaring type.
*/
protected LazyParameterizedReceiverType() {
this(LazyTypeDescription.this);
}
/**
* Creates a new lazy parameterized receiver type of the supplied receiver type.
*
* @param typeDescription The erasure of the type to be represented as a parameterized receiver type.
*/
protected LazyParameterizedReceiverType(TypeDescription typeDescription) {
this.typeDescription = typeDescription;
}
@Override
public TypeList.Generic getTypeArguments() {
return new TypeArgumentList(typeDescription.getTypeVariables());
}
@Override
public Generic getOwnerType() {
TypeDescription declaringType = typeDescription.getDeclaringType();
if (declaringType == null) {
return Generic.UNDEFINED;
} else {
return !typeDescription.isStatic() && declaringType.isGenerified() ? new LazyParameterizedReceiverType(declaringType) : new LazyNonGenericReceiverType(declaringType);
}
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, receiverTypeAnnotationTokens.get(getTypePath()));
}
/**
* Returns the type path for this type.
*
* @return This type's type path.
*/
private String getTypePath() {
StringBuilder typePath = new StringBuilder();
for (int index = 0; index < typeDescription.getSegmentCount(); index++) {
typePath = typePath.append(GenericTypeToken.INNER_CLASS_PATH);
}
return typePath.toString();
}
@Override
public TypeDescription asErasure() {
return typeDescription;
}
/**
* A list of generic types representing the receiver type's type arguments.
*/
protected class TypeArgumentList extends TypeList.Generic.AbstractBase {
/**
* The type variables of the represented receiver type.
*/
private final List<? extends Generic> typeVariables;
/**
* Creates a new type argument list.
*
* @param typeVariables The type variables of the represented receiver type.
*/
protected TypeArgumentList(List<? extends Generic> typeVariables) {
this.typeVariables = typeVariables;
}
@Override
public Generic get(int index) {
return new AnnotatedTypeVariable(typeVariables.get(index), index);
}
@Override
public int size() {
return typeVariables.size();
}
/**
* Represents a type variable as a type argument with type annotations.
*/
protected class AnnotatedTypeVariable extends OfTypeVariable {
/**
* The type variable's description.
*/
private final Generic typeVariable;
/**
* The type variable's index.
*/
private final int index;
/**
* Creates a new description of an annotated type variable as a type argument.
*
* @param typeVariable The type variable's description.
* @param index The type variable's index.
*/
protected AnnotatedTypeVariable(Generic typeVariable, int index) {
this.typeVariable = typeVariable;
this.index = index;
}
@Override
public TypeList.Generic getUpperBounds() {
return typeVariable.getUpperBounds();
}
@Override
public TypeVariableSource getTypeVariableSource() {
return typeVariable.getTypeVariableSource();
}
@Override
public String getSymbol() {
return typeVariable.getSymbol();
}
@Override
public AnnotationList getDeclaredAnnotations() {
return LazyAnnotationDescription.asListOfNullable(typePool, receiverTypeAnnotationTokens.get(getTypePath() + index + GenericTypeToken.INDEXED_TYPE_DELIMITER));
}
}
}
}
/**
* A lazy description of a non-generic receiver type.
*/
protected class LazyNonGenericReceiverType extends Generic.OfNonGenericType {
/**
* The type description of the non-generic receiver type.
*/
private final TypeDescription typeDescription;
/**
* Creates a new non-generic receiver type of the method's declaring type.
*/
protected LazyNonGenericReceiverType() {
this(LazyTypeDescription.this);
}
/**
* Creates a new non-generic receiver type of the supplied type.
*
* @param typeDescription The type to represent as a non-generic receiver type.
*/
protected LazyNonGenericReceiverType(TypeDescription typeDescription) {
this.typeDescription = typeDescription;
}
@Override
public Generic getOwnerType() {
TypeDescription declaringType = typeDescription.getDeclaringType();
return declaringType == null ? Generic.UNDEFINED : new LazyNonGenericReceiverType(declaringType);
}
@Override
public Generic getComponentType() {
return Generic.UNDEFINED;
}
@Override
public AnnotationList getDeclaredAnnotations() {
StringBuilder typePath = new StringBuilder();
for (int index = 0; index < typeDescription.getSegmentCount(); index++) {
typePath = typePath.append(GenericTypeToken.INNER_CLASS_PATH);
}
return LazyAnnotationDescription.asListOfNullable(typePool, receiverTypeAnnotationTokens.get(typePath.toString()));
}
@Override
public TypeDescription asErasure() {
return typeDescription;
}
}
}
}
/**
* A type extractor reads a class file and collects data that is relevant to create a type description.
*/
protected class TypeExtractor extends ClassVisitor {
/**
* A mask that cuts off pseudo flags beyond the second byte that are inserted by ASM.
*/
private static final int REAL_MODIFIER_MASK = 65535;
/**
* A mapping of the super types' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> superTypeAnnotationTokens;
/**
* A mapping of the type variables' type annotation tokens by their indices.
*/
private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> typeVariableAnnotationTokens;
/**
* A mapping of the type variables' bounds' type annotation tokens by their indices and each variables index.
*/
private final Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> typeVariableBoundsAnnotationTokens;
/**
* A list of annotation tokens describing annotations that are found on the visited type.
*/
private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
/**
* A list of field tokens describing fields that are found on the visited type.
*/
private final List<LazyTypeDescription.FieldToken> fieldTokens;
/**
* A list of method tokens describing annotations that are found on the visited type.
*/
private final List<LazyTypeDescription.MethodToken> methodTokens;
/**
* The actual modifiers found for this type.
*/
private int actualModifiers;
/**
* The modifiers found for this type.
*/
private int modifiers;
/**
* The internal name found for this type.
*/
private String internalName;
/**
* The internal name of the super type found for this type or {@code null} if no such type exists.
*/
private String superClassName;
/**
* The generic signature of the type or {@code null} if it is not generic.
*/
private String genericSignature;
/**
* A list of internal names of interfaces implemented by this type or {@code null} if no interfaces
* are implemented.
*/
private String[] interfaceName;
/**
* {@code true} if this type was found to represent an anonymous type.
*/
private boolean anonymousType;
/**
* The declaration context found for this type.
*/
private LazyTypeDescription.TypeContainment typeContainment;
/**
* The binary name of this type's declaring type or {@code null} if no such type exists.
*/
private String declaringTypeName;
/**
* A list of descriptors representing the types that are declared by the parsed type.
*/
private final List<String> declaredTypes;
/**
* Creates a new type extractor.
*/
protected TypeExtractor() {
super(Opcodes.ASM5);
superTypeAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
typeVariableAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
typeVariableBoundsAnnotationTokens = new HashMap<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>>();
annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
fieldTokens = new ArrayList<LazyTypeDescription.FieldToken>();
methodTokens = new ArrayList<LazyTypeDescription.MethodToken>();
anonymousType = false;
typeContainment = LazyTypeDescription.TypeContainment.SelfContained.INSTANCE;
declaredTypes = new ArrayList<String>();
}
@Override
public void visit(int classFileVersion, int modifiers, String internalName, String genericSignature, String superClassName, String[] interfaceName) {
this.modifiers = modifiers & REAL_MODIFIER_MASK;
actualModifiers = modifiers;
this.internalName = internalName;
this.genericSignature = genericSignature;
this.superClassName = superClassName;
this.interfaceName = interfaceName;
}
@Override
public void visitOuterClass(String typeName, String methodName, String methodDescriptor) {
if (methodName != null) {
typeContainment = new LazyTypeDescription.TypeContainment.WithinMethod(typeName, methodName, methodDescriptor);
} else if (typeName != null) {
typeContainment = new LazyTypeDescription.TypeContainment.WithinType(typeName, true);
}
}
@Override
public void visitInnerClass(String internalName, String outerName, String innerName, int modifiers) {
if (internalName.equals(this.internalName)) {
this.modifiers = modifiers & REAL_MODIFIER_MASK;
if (innerName == null) {
anonymousType = true;
}
if (outerName != null) {
declaringTypeName = outerName;
if (typeContainment.isSelfContained()) {
typeContainment = new LazyTypeDescription.TypeContainment.WithinType(outerName, false);
}
}
} else if (outerName != null && innerName != null && internalName.equals(this.internalName + "$" + innerName)) {
declaredTypes.add("L" + internalName + ";");
}
}
@Override
public AnnotationVisitor visitTypeAnnotation(int rawTypeReference, TypePath typePath, String descriptor, boolean visible) {
AnnotationRegistrant annotationRegistrant;
TypeReference typeReference = new TypeReference(rawTypeReference);
switch (typeReference.getSort()) {
case TypeReference.CLASS_EXTENDS:
annotationRegistrant = new AnnotationRegistrant.ForTypeVariable.WithIndex(descriptor, typePath, typeReference.getSuperTypeIndex(), superTypeAnnotationTokens);
break;
case TypeReference.CLASS_TYPE_PARAMETER:
annotationRegistrant = new AnnotationRegistrant.ForTypeVariable.WithIndex(descriptor, typePath, typeReference.getTypeParameterIndex(), typeVariableAnnotationTokens);
break;
case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
annotationRegistrant = new AnnotationRegistrant.ForTypeVariable.WithIndex.DoubleIndexed(descriptor, typePath, typeReference.getTypeParameterBoundIndex(), typeReference.getTypeParameterIndex(), typeVariableBoundsAnnotationTokens);
break;
default:
throw new IllegalArgumentException("Unexpected type reference: " + typeReference.getSort());
}
return new AnnotationExtractor(annotationRegistrant, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
}
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new AnnotationExtractor(descriptor, annotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
}
@Override
public FieldVisitor visitField(int modifiers, String internalName, String descriptor, String genericSignature, Object defaultValue) {
return new FieldExtractor(modifiers & REAL_MODIFIER_MASK, internalName, descriptor, genericSignature);
}
@Override
public MethodVisitor visitMethod(int modifiers, String internalName, String descriptor, String genericSignature, String[] exceptionName) {
return internalName.equals(MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME) ? IGNORE_METHOD : new MethodExtractor(modifiers & REAL_MODIFIER_MASK, internalName, descriptor, genericSignature, exceptionName);
}
/**
* Creates a type description from all data that is currently collected. This method should only be invoked
* after a class file was parsed fully.
*
* @return A type description reflecting the data that was collected by this instance.
*/
protected TypeDescription toTypeDescription() {
return new LazyTypeDescription(Default.this, actualModifiers, modifiers, internalName, superClassName, interfaceName, genericSignature, typeContainment, declaringTypeName, declaredTypes, anonymousType, superTypeAnnotationTokens, typeVariableAnnotationTokens, typeVariableBoundsAnnotationTokens, annotationTokens, fieldTokens, methodTokens);
}
/**
* An annotation extractor reads an annotation found in a class field an collects data that
* is relevant to creating a related annotation description.
*/
protected class AnnotationExtractor extends AnnotationVisitor {
/**
* The annotation registrant to register found annotation values on.
*/
private final AnnotationRegistrant annotationRegistrant;
/**
* A locator for the component type of any found annotation value.
*/
private final ComponentTypeLocator componentTypeLocator;
/**
* Creates a new annotation extractor for a byte code element without an index.
*
* @param descriptor The annotation descriptor.
* @param annotationTokens The collection for storing any discovered annotation tokens.
* @param componentTypeLocator The component type locator to use.
*/
protected AnnotationExtractor(String descriptor, List<LazyTypeDescription.AnnotationToken> annotationTokens, ComponentTypeLocator componentTypeLocator) {
this(new AnnotationRegistrant.ForByteCodeElement(descriptor, annotationTokens), componentTypeLocator);
}
/**
* Creates a new annotation extractor for a byte code element with an index.
*
* @param descriptor The annotation descriptor.
* @param index The index of the element for which the annotations are collected.
* @param annotationTokens The collection for storing any discovered annotation tokens.
* @param componentTypeLocator The component type locator to use.
*/
protected AnnotationExtractor(String descriptor, int index, Map<Integer, List<LazyTypeDescription.AnnotationToken>> annotationTokens, ComponentTypeLocator componentTypeLocator) {
this(new AnnotationRegistrant.ForByteCodeElement.WithIndex(descriptor, index, annotationTokens), componentTypeLocator);
}
/**
* Creates a new annotation extractor.
*
* @param annotationRegistrant The annotation registrant to register found annotation values on.
* @param componentTypeLocator A locator for the component type of any found annotation value.
*/
protected AnnotationExtractor(AnnotationRegistrant annotationRegistrant, ComponentTypeLocator componentTypeLocator) {
super(Opcodes.ASM5);
this.annotationRegistrant = annotationRegistrant;
this.componentTypeLocator = componentTypeLocator;
}
@Override
public void visit(String name, Object value) {
annotationRegistrant.register(name, value instanceof Type ? new RawTypeValue(Default.this, (Type) value) : AnnotationValue.ForConstant.of(value));
}
@Override
public void visitEnum(String name, String descriptor, String value) {
annotationRegistrant.register(name, new RawEnumerationValue(Default.this, descriptor, value));
}
@Override
public AnnotationVisitor visitAnnotation(String name, String descriptor) {
return new AnnotationExtractor(new AnnotationLookup(descriptor, name), new ComponentTypeLocator.ForAnnotationProperty(TypePool.Default.this, descriptor));
}
@Override
public AnnotationVisitor visitArray(String name) {
return new AnnotationExtractor(new ArrayLookup(name, componentTypeLocator.bind(name)), ComponentTypeLocator.Illegal.INSTANCE);
}
@Override
public void visitEnd() {
annotationRegistrant.onComplete();
}
/**
* An annotation registrant for registering values of an array.
*/
protected class ArrayLookup implements AnnotationRegistrant {
/**
* The name of the annotation property the collected array is representing.
*/
private final String name;
/**
* A lazy reference to resolve the component type of the collected array.
*/
private final RawDescriptionArray.ComponentTypeReference componentTypeReference;
/**
* A list of all annotation values that are found on this array.
*/
private final List<AnnotationValue<?, ?>> values;
/**
* Creates a new annotation registrant for an array lookup.
*
* @param name The name of the annotation property the collected array is representing.
* @param componentTypeReference A lazy reference to resolve the component type of the collected array.
*/
protected ArrayLookup(String name, RawDescriptionArray.ComponentTypeReference componentTypeReference) {
this.name = name;
this.componentTypeReference = componentTypeReference;
values = new ArrayList<AnnotationValue<?, ?>>();
}
@Override
public void register(String ignored, AnnotationValue<?, ?> annotationValue) {
values.add(annotationValue);
}
@Override
public void onComplete() {
annotationRegistrant.register(name, new RawDescriptionArray(Default.this, componentTypeReference, values));
}
}
/**
* An annotation registrant for registering the values on an array that is itself an annotation property.
*/
protected class AnnotationLookup implements AnnotationRegistrant {
/**
* The descriptor of the original annotation for which the annotation values are looked up.
*/
private final String descriptor;
/**
* The name of the original annotation for which the annotation values are looked up.
*/
private final String name;
/**
* This annotation's values mapped by their attribute name.
*/
private final Map<String, AnnotationValue<?, ?>> values;
/**
* Creates a new annotation registrant for a recursive annotation lookup.
*
* @param name The name of the original annotation for which the annotation values are looked up.
* @param descriptor The descriptor of the original annotation for which the annotation values are looked up.
*/
protected AnnotationLookup(String descriptor, String name) {
this.descriptor = descriptor;
this.name = name;
values = new HashMap<String, AnnotationValue<?, ?>>();
}
@Override
public void register(String name, AnnotationValue<?, ?> annotationValue) {
values.put(name, annotationValue);
}
@Override
public void onComplete() {
annotationRegistrant.register(name, new RawAnnotationValue(Default.this, new LazyTypeDescription.AnnotationToken(descriptor, values)));
}
}
}
/**
* A field extractor reads a field within a class file and collects data that is relevant
* to creating a related field description.
*/
protected class FieldExtractor extends FieldVisitor {
/**
* The modifiers found on the field.
*/
private final int modifiers;
/**
* The name of the field.
*/
private final String internalName;
/**
* The descriptor of the field type.
*/
private final String descriptor;
/**
* The generic signature of the field or {@code null} if it is not generic.
*/
private final String genericSignature;
/**
* A mapping of the field type's type annotations.
*/
private final Map<String, List<LazyTypeDescription.AnnotationToken>> typeAnnotationTokens;
/**
* A list of annotation tokens found for this field.
*/
private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
/**
* Creates a new field extractor.
*
* @param modifiers The modifiers found for this field.
* @param internalName The name of the field.
* @param descriptor The descriptor of the field type.
* @param genericSignature The generic signature of the field or {@code null} if it is not generic.
*/
protected FieldExtractor(int modifiers, String internalName, String descriptor, String genericSignature) {
super(Opcodes.ASM5);
this.modifiers = modifiers;
this.internalName = internalName;
this.descriptor = descriptor;
this.genericSignature = genericSignature;
typeAnnotationTokens = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
}
@Override
public AnnotationVisitor visitTypeAnnotation(int rawTypeReference, TypePath typePath, String descriptor, boolean visible) {
AnnotationRegistrant annotationRegistrant;
TypeReference typeReference = new TypeReference(rawTypeReference);
switch (typeReference.getSort()) {
case TypeReference.FIELD:
annotationRegistrant = new AnnotationRegistrant.ForTypeVariable(descriptor, typePath, typeAnnotationTokens);
break;
default:
throw new IllegalStateException("Unexpected type reference on field: " + typeReference.getSort());
}
return new AnnotationExtractor(annotationRegistrant, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
}
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new AnnotationExtractor(descriptor, annotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
}
@Override
public void visitEnd() {
fieldTokens.add(new LazyTypeDescription.FieldToken(internalName, modifiers, descriptor, genericSignature, typeAnnotationTokens, annotationTokens));
}
}
/**
* A method extractor reads a method within a class file and collects data that is relevant
* to creating a related method description.
*/
protected class MethodExtractor extends MethodVisitor implements AnnotationRegistrant {
/**
* The modifiers found for this method.
*/
private final int modifiers;
/**
* The internal name found for this method.
*/
private final String internalName;
/**
* The descriptor found for this method.
*/
private final String descriptor;
/**
* The generic signature of the method or {@code null} if it is not generic.
*/
private final String genericSignature;
/**
* An array of internal names of the exceptions of the found method
* or {@code null} if there are no such exceptions.
*/
private final String[] exceptionName;
/**
* A mapping of the method's type variables' type annotations by their indices.
*/
private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> typeVariableAnnotationTokens;
/**
* A mapping of the method's type variables' bounds' type annotations by their indices and each variable's index.
*/
private final Map<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>> typeVariableBoundAnnotationTokens;
/**
* A mapping of the method's return type's type annotations.
*/
private final Map<String, List<LazyTypeDescription.AnnotationToken>> returnTypeAnnotationTokens;
/**
* A mapping of the parameters' type annotations by their indices.
*/
private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> parameterTypeAnnotationTokens;
/**
* A mapping of the exception types' type annotations by their indices.
*/
private final Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>> exceptionTypeAnnotationTokens;
/**
* A mapping of the receiver type's type annotations.
*/
private final Map<String, List<LazyTypeDescription.AnnotationToken>> receiverTypeAnnotationTokens;
/**
* A list of annotation tokens declared on the found method.
*/
private final List<LazyTypeDescription.AnnotationToken> annotationTokens;
/**
* A mapping of parameter indices to annotation tokens found for the parameters at these indices.
*/
private final Map<Integer, List<LazyTypeDescription.AnnotationToken>> parameterAnnotationTokens;
/**
* A list of tokens representing meta information of a parameter as it is available for method's
* that are compiled in the Java 8 version format.
*/
private final List<LazyTypeDescription.MethodToken.ParameterToken> parameterTokens;
/**
* A bag of parameter meta information representing debugging information which allows to extract
* a method's parameter names.
*/
private final ParameterBag legacyParameterBag;
/**
* The first label that is found in the method's body, if any, denoting the start of the method.
* This label can be used to identify names of local variables that describe the method's parameters.
*/
private Label firstLabel;
/**
* The default value of the found method or {@code null} if no such value exists.
*/
private AnnotationValue<?, ?> defaultValue;
protected MethodExtractor(int modifiers, String internalName, String descriptor, String genericSignature, String[] exceptionName) {
super(Opcodes.ASM5);
this.modifiers = modifiers;
this.internalName = internalName;
this.descriptor = descriptor;
this.genericSignature = genericSignature;
this.exceptionName = exceptionName;
typeVariableAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
typeVariableBoundAnnotationTokens = new HashMap<Integer, Map<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>>();
returnTypeAnnotationTokens = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
parameterTypeAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
exceptionTypeAnnotationTokens = new HashMap<Integer, Map<String, List<LazyTypeDescription.AnnotationToken>>>();
receiverTypeAnnotationTokens = new HashMap<String, List<LazyTypeDescription.AnnotationToken>>();
annotationTokens = new ArrayList<LazyTypeDescription.AnnotationToken>();
parameterAnnotationTokens = new HashMap<Integer, List<LazyTypeDescription.AnnotationToken>>();
parameterTokens = new ArrayList<LazyTypeDescription.MethodToken.ParameterToken>();
legacyParameterBag = new ParameterBag(Type.getMethodType(descriptor).getArgumentTypes());
}
@Override
public AnnotationVisitor visitTypeAnnotation(int rawTypeReference, TypePath typePath, String descriptor, boolean visible) {
AnnotationRegistrant annotationRegistrant;
TypeReference typeReference = new TypeReference(rawTypeReference);
switch (typeReference.getSort()) {
case TypeReference.METHOD_TYPE_PARAMETER:
annotationRegistrant = new ForTypeVariable.WithIndex(descriptor, typePath, typeReference.getTypeParameterIndex(), typeVariableAnnotationTokens);
break;
case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
annotationRegistrant = new ForTypeVariable.WithIndex.DoubleIndexed(descriptor, typePath, typeReference.getTypeParameterBoundIndex(), typeReference.getTypeParameterIndex(), typeVariableBoundAnnotationTokens);
break;
case TypeReference.METHOD_RETURN:
annotationRegistrant = new ForTypeVariable(descriptor, typePath, returnTypeAnnotationTokens);
break;
case TypeReference.METHOD_FORMAL_PARAMETER:
annotationRegistrant = new ForTypeVariable.WithIndex(descriptor, typePath, typeReference.getFormalParameterIndex(), parameterTypeAnnotationTokens);
break;
case TypeReference.THROWS:
annotationRegistrant = new ForTypeVariable.WithIndex(descriptor, typePath, typeReference.getExceptionIndex(), exceptionTypeAnnotationTokens);
break;
case TypeReference.METHOD_RECEIVER:
annotationRegistrant = new ForTypeVariable(descriptor, typePath, receiverTypeAnnotationTokens);
break;
default:
throw new IllegalStateException("Unexpected type reference on method: " + typeReference.getSort());
}
return new AnnotationExtractor(annotationRegistrant, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
}
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new AnnotationExtractor(descriptor, annotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
}
@Override
public AnnotationVisitor visitParameterAnnotation(int index, String descriptor, boolean visible) {
return new AnnotationExtractor(descriptor, index, parameterAnnotationTokens, new ComponentTypeLocator.ForAnnotationProperty(Default.this, descriptor));
}
@Override
public void visitLabel(Label label) {
if (readerMode.isExtended() && firstLabel == null) {
firstLabel = label;
}
}
@Override
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
if (readerMode.isExtended() && start == firstLabel) {
legacyParameterBag.register(index, name);
}
}
@Override
public void visitParameter(String name, int modifiers) {
parameterTokens.add(new LazyTypeDescription.MethodToken.ParameterToken(name, modifiers));
}
@Override
public AnnotationVisitor visitAnnotationDefault() {
return new AnnotationExtractor(this, new ComponentTypeLocator.ForArrayType(descriptor));
}
@Override
public void register(String ignored, AnnotationValue<?, ?> annotationValue) {
defaultValue = annotationValue;
}
@Override
public void onComplete() {
/* do nothing, as the register method is called at most once for default values */
/**
* Creates a method extractor.
*
* @param modifiers The modifiers found for this method.
* @param internalName The internal name found for this method.
* @param descriptor The descriptor found for this method.
* @param genericSignature The generic signature of the method or {@code null} if it is not generic.
* @param exceptionName An array of internal names of the exceptions of the found method
* or {@code null} if there are no such exceptions.
*/
}
@Override
public void visitEnd() {
methodTokens.add(new LazyTypeDescription.MethodToken(internalName, modifiers, descriptor, genericSignature, exceptionName, typeVariableAnnotationTokens, typeVariableBoundAnnotationTokens, returnTypeAnnotationTokens, parameterTypeAnnotationTokens, exceptionTypeAnnotationTokens, receiverTypeAnnotationTokens, annotationTokens, parameterAnnotationTokens, parameterTokens.isEmpty() ? legacyParameterBag.resolve((modifiers & Opcodes.ACC_STATIC) != 0) : parameterTokens, defaultValue));
}
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Default)) return false;
final TypePool.Default other = (TypePool.Default) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (!super.equals(o)) return false;
final java.lang.Object this$classFileLocator = this.classFileLocator;
final java.lang.Object other$classFileLocator = other.classFileLocator;
if (this$classFileLocator == null ? other$classFileLocator != null : !this$classFileLocator.equals(other$classFileLocator)) return false;
final java.lang.Object this$readerMode = this.readerMode;
final java.lang.Object other$readerMode = other.readerMode;
if (this$readerMode == null ? other$readerMode != null : !this$readerMode.equals(other$readerMode)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Default;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + super.hashCode();
final java.lang.Object $classFileLocator = this.classFileLocator;
result = result * PRIME + ($classFileLocator == null ? 43 : $classFileLocator.hashCode());
final java.lang.Object $readerMode = this.readerMode;
result = result * PRIME + ($readerMode == null ? 43 : $readerMode.hashCode());
return result;
}
}
/**
* A lazy facade of a type pool that delegates any lookups to another type pool only if another value than the type's name is looked up.
*/
class LazyFacade extends AbstractBase {
/**
* The type pool to delegate to.
*/
private final TypePool typePool;
/**
* Creates a lazy facade for a type pool.
*
* @param typePool The type pool to delegate to.
*/
public LazyFacade(TypePool typePool) {
super(CacheProvider.NoOp.INSTANCE);
this.typePool = typePool;
}
@Override
protected Resolution doDescribe(String name) {
return new LazyResolution(typePool, name);
}
@Override
public void clear() {
typePool.clear();
}
/**
* The lazy resolution for a lazy facade for a type pool.
*/
protected static class LazyResolution implements Resolution {
/**
* The type pool to delegate to.
*/
private final TypePool typePool;
/**
* The name of the type that is represented by this resolution.
*/
private final String name;
/**
* Creates a lazy resolution for a lazy facade for a type pool.
*
* @param typePool The type pool to delegate to.
* @param name The name of the type that is represented by this resolution.
*/
protected LazyResolution(TypePool typePool, String name) {
this.typePool = typePool;
this.name = name;
}
@Override
public boolean isResolved() {
return typePool.describe(name).isResolved();
}
@Override
public TypeDescription resolve() {
return new LazyTypeDescription(typePool, name);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.LazyFacade.LazyResolution)) return false;
final TypePool.LazyFacade.LazyResolution other = (TypePool.LazyFacade.LazyResolution) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$typePool = this.typePool;
final java.lang.Object other$typePool = other.typePool;
if (this$typePool == null ? other$typePool != null : !this$typePool.equals(other$typePool)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.LazyFacade.LazyResolution;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $typePool = this.typePool;
result = result * PRIME + ($typePool == null ? 43 : $typePool.hashCode());
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
return result;
}
}
/**
* A description of a type that delegates to another type pool once a property that is not the name is resolved.
*/
protected static class LazyTypeDescription extends TypeDescription.AbstractBase.OfSimpleType.WithDelegation {
/**
* The type pool to delegate to.
*/
private final TypePool typePool;
/**
* The name of the type that is represented by this resolution.
*/
private final String name;
/**
* Creates a new lazy type resolution.
*
* @param typePool The type pool to delegate to.
* @param name The name of the type.
*/
protected LazyTypeDescription(TypePool typePool, String name) {
this.typePool = typePool;
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
protected TypeDescription delegate() {
return typePool.describe(name).resolve();
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.LazyFacade)) return false;
final TypePool.LazyFacade other = (TypePool.LazyFacade) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$typePool = this.typePool;
final java.lang.Object other$typePool = other.typePool;
if (this$typePool == null ? other$typePool != null : !this$typePool.equals(other$typePool)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.LazyFacade;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $typePool = this.typePool;
result = result * PRIME + ($typePool == null ? 43 : $typePool.hashCode());
return result;
}
}
/**
* A type pool that attempts to load a class.
*/
class ClassLoading extends AbstractBase.Hierarchical {
/**
* Type-safe representation of the bootstrap class loader which is {@code null}.
*/
private static final ClassLoader BOOTSTRAP_CLASS_LOADER = null;
/**
* The class loader to query.
*/
private final ClassLoader classLoader;
/**
* Creates a class loadings type pool.
*
* @param cacheProvider The cache provider to use.
* @param parent The parent type pool.
* @param classLoader The class loader to use for locating files.
*/
public ClassLoading(CacheProvider cacheProvider, TypePool parent, ClassLoader classLoader) {
super(cacheProvider, parent);
this.classLoader = classLoader;
}
/**
* Returns a type pool that attempts type descriptions by loadings types from the given class loader.
*
* @param classLoader The class loader to use.
* @return An class loading type pool.
*/
public static TypePool of(ClassLoader classLoader) {
return of(classLoader, Empty.INSTANCE);
}
/**
* Returns a type pool that attempts type descriptions by loadings types from the given class loader.
*
* @param classLoader The class loader to use.
* @param parent The parent type pool to use.
* @return An class loading type pool.
*/
public static TypePool of(ClassLoader classLoader, TypePool parent) {
return new ClassLoading(CacheProvider.NoOp.INSTANCE, parent, classLoader);
}
/**
* Returns a type pool that attempts type descriptions by loadings types from the bootstrap class loader.
*
* @return An class loading type pool for the bootstrap class loader.
*/
public static TypePool ofBootPath() {
return of(BOOTSTRAP_CLASS_LOADER);
}
/**
* Returns a type pool that attempts type descriptions by loadings types from the system class loader.
*
* @return An class loading type pool for the system class loader.
*/
public static TypePool ofClassPath() {
return of(ClassLoader.getSystemClassLoader());
}
@Override
public Resolution doDescribe(String name) {
try {
return new Resolution.Simple(new TypeDescription.ForLoadedType(Class.forName(name, false, classLoader)));
} catch (ClassNotFoundException ignored) {
return new Resolution.Illegal(name);
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.ClassLoading)) return false;
final TypePool.ClassLoading other = (TypePool.ClassLoading) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (!super.equals(o)) return false;
final java.lang.Object this$classLoader = this.classLoader;
final java.lang.Object other$classLoader = other.classLoader;
if (this$classLoader == null ? other$classLoader != null : !this$classLoader.equals(other$classLoader)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.ClassLoading;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + super.hashCode();
final java.lang.Object $classLoader = this.classLoader;
result = result * PRIME + ($classLoader == null ? 43 : $classLoader.hashCode());
return result;
}
}
/**
* A type pool that supplies explicitly known type descriptions.
*/
class Explicit extends AbstractBase.Hierarchical {
/**
* A mapping from type names to type descriptions of that name.
*/
private final Map<String, TypeDescription> types;
/**
* Creates a new explicit type pool without a parent.
*
* @param types A mapping from type names to type descriptions of that name.
*/
public Explicit(Map<String, TypeDescription> types) {
this(Empty.INSTANCE, types);
}
/**
* Creates a new explicit type pool.
*
* @param parent The parent type pool.
* @param types A mapping from type names to type descriptions of that name.
*/
public Explicit(TypePool parent, Map<String, TypeDescription> types) {
super(CacheProvider.NoOp.INSTANCE, parent);
this.types = types;
}
@Override
protected Resolution doDescribe(String name) {
TypeDescription typeDescription = types.get(name);
return typeDescription == null ? new Resolution.Illegal(name) : new Resolution.Simple(typeDescription);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof TypePool.Explicit)) return false;
final TypePool.Explicit other = (TypePool.Explicit) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (!super.equals(o)) return false;
final java.lang.Object this$types = this.types;
final java.lang.Object other$types = other.types;
if (this$types == null ? other$types != null : !this$types.equals(other$types)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof TypePool.Explicit;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + super.hashCode();
final java.lang.Object $types = this.types;
result = result * PRIME + ($types == null ? 43 : $types.hashCode());
return result;
}
}
}