All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.bytebuddy.description.type.TypeDefinition Maven / Gradle / Ivy

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

import net.bytebuddy.build.AccessControllerPlugin;
import net.bytebuddy.description.ModifierReviewable;
import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.implementation.bytecode.StackSize;
import net.bytebuddy.utility.dispatcher.JavaDispatcher;
import net.bytebuddy.utility.nullability.MaybeNull;
import net.bytebuddy.utility.nullability.UnknownNull;

import java.lang.reflect.*;
import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Implementations define a type, either as a {@link TypeDescription} or as a {@link TypeDescription.Generic}.
 */
public interface TypeDefinition extends NamedElement, ModifierReviewable.ForTypeDefinition, Iterable {

    /**
     * 

* If this property is set to {@code true}, non-generic {@link TypeDefinition}s do no longer resolve their referenced * generic types when traversing type hierarchies. Setting this property can cause unexpected side effects such as * {@link ClassCastException}s from overridden methods as type variables are resolved to their erasures where a method * might return that is unexpected by the callee. Setting this property also makes type annotations unavailable using * such type navigation. *

*

* Setting this property can be useful if generic type information is not required in order to avoid bugs in * implementations of the JVM where processing generic types can cause segmentation faults. Byte Buddy will undertake * a best effort to retain the generic type information and information about type annotations within the redefined * types' class files. Typically, this property can be meaningful in combination with a Java agent that only changes * byte code without changing a class type's structure. *

*/ String RAW_TYPES_PROPERTY = "net.bytebuddy.raw"; /** * Returns this type definition as a generic type. * * @return This type definition represented as a generic type. */ TypeDescription.Generic asGenericType(); /** * Returns the erasure of this type. Wildcard types ({@link TypeDescription.Generic.Sort#WILDCARD}) * do not have a well-defined erasure and cause an {@link IllegalStateException} to be thrown. * * @return The erasure of this type. */ TypeDescription asErasure(); /** * Returns the super class of this type. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}), * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Interface types * and the {@link Object} class do not define a super class where {@code null} is returned. Array types define {@link Object} * as their direct super class. * * @return The super class of this type or {@code null} if no super class exists for this type. */ @MaybeNull TypeDescription.Generic getSuperClass(); /** * Returns the interfaces that this type implements. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}), * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. * * @return The interfaces that this type implements. */ TypeList.Generic getInterfaces(); /** * Returns the fields that this type declares. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}), * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Generic array * types never define fields and the returned list is always empty for such types. * * @return The fields that this type declares. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}), * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Generic array * types never define methods and the returned list is always empty for such types. */ FieldList getDeclaredFields(); /** * Returns the methods that this type declares. * * @return The methods that this type declares. */ MethodList getDeclaredMethods(); /** *

* Returns the component type of this type. *

*

* Only non-generic types ({@link TypeDescription.Generic.Sort#NON_GENERIC}) and generic array types * {@link TypeDescription.Generic.Sort#GENERIC_ARRAY}) define a component type. For other * types, an {@link IllegalStateException} is thrown. *

* * @return The component type of this type or {@code null} if this type does not represent an array type. */ @MaybeNull TypeDefinition getComponentType(); /** * Returns the list of record components that are declared by this type. If this type is not * a record, the returned list is empty. * * @return A list of record components that this type declares. */ RecordComponentList getRecordComponents(); /** * Returns the sort of the generic type this instance represents. * * @return The sort of the generic type. */ Sort getSort(); /** * Returns the name of the type. For generic types, this name is their {@link Object#toString()} representations. For a non-generic * type, it is the fully qualified binary name of the type. * * @return The name of this type. */ String getTypeName(); /** * Returns the size of the type described by this instance. Wildcard types * ({@link TypeDescription.Generic.Sort#WILDCARD} do not have a well-defined a stack size and * cause an {@link IllegalStateException} to be thrown. * * @return The size of the type described by this instance. */ StackSize getStackSize(); /** * Checks if the type described by this entity is an array. * * @return {@code true} if this type description represents an array. */ boolean isArray(); /** * Checks if this type is a Java record. * * @return {@code true} if this type is a Java record. */ boolean isRecord(); /** * Checks if the type described by this entity is a primitive type. * * @return {@code true} if this type description represents a primitive type. */ boolean isPrimitive(); /** * Checks if the type described by this instance represents {@code type}. * * @param type The type of interest. * @return {@code true} if the type described by this instance represents {@code type}. */ boolean represents(Type type); /** * Represents a {@link TypeDescription.Generic}'s form. */ enum Sort { /** * Represents a non-generic type. */ NON_GENERIC, /** * Represents a generic array type. */ GENERIC_ARRAY, /** * Represents a parameterized type. */ PARAMETERIZED, /** * Represents a wildcard type. */ WILDCARD, /** * Represents a type variable that is attached to a {@link net.bytebuddy.description.TypeVariableSource}. */ VARIABLE, /** * Represents a type variable that is merely symbolic and is not attached to a {@link net.bytebuddy.description.TypeVariableSource} * and does not defined bounds. */ VARIABLE_SYMBOLIC; /** * A dispatcher for interacting with {@code java.lang.reflect.AnnotatedType}. */ private static final AnnotatedType ANNOTATED_TYPE = doPrivileged(JavaDispatcher.of(AnnotatedType.class)); /** * A proxy for {@code java.security.AccessController#doPrivileged} that is activated if available. * * @param action The action to execute from a privileged context. * @param The type of the action's resolved value. * @return The action's resolved value. */ @AccessControllerPlugin.Enhance private static T doPrivileged(PrivilegedAction action) { return action.run(); } /** * Describes a loaded generic type as a {@link TypeDescription.Generic}. * * @param type The type to describe. * @return A description of the provided generic type. */ public static TypeDescription.Generic describe(Type type) { return describe(type, TypeDescription.Generic.AnnotationReader.NoOp.INSTANCE); } /** * Describes a loaded {@code java.lang.reflect.AnnotatedType} as a {@link TypeDescription.Generic}. * * @param annotatedType The {@code java.lang.reflect.AnnotatedType} to describe. * @return A description of the provided generic type. */ public static TypeDescription.Generic describeAnnotated(AnnotatedElement annotatedType) { if (!ANNOTATED_TYPE.isInstance(annotatedType)) { throw new IllegalArgumentException("Not an instance of AnnotatedType: " + annotatedType); } return describe(ANNOTATED_TYPE.getType(annotatedType), new TypeDescription.Generic.AnnotationReader.Delegator.Simple(annotatedType)); } /** * Describes the generic type while using the supplied annotation reader for resolving type annotations if this * language feature is available on the current JVM. * * @param type The type to describe. * @param annotationReader The annotation reader for extracting type annotations. * @return A description of the provided generic annotated type. */ protected static TypeDescription.Generic describe(Type type, TypeDescription.Generic.AnnotationReader annotationReader) { if (type instanceof Class) { return new TypeDescription.Generic.OfNonGenericType.ForLoadedType((Class) type, annotationReader); } else if (type instanceof GenericArrayType) { return new TypeDescription.Generic.OfGenericArray.ForLoadedType((GenericArrayType) type, annotationReader); } else if (type instanceof ParameterizedType) { return new TypeDescription.Generic.OfParameterizedType.ForLoadedType((ParameterizedType) type, annotationReader); } else if (type instanceof TypeVariable) { return new TypeDescription.Generic.OfTypeVariable.ForLoadedType((TypeVariable) type, annotationReader); } else if (type instanceof WildcardType) { return new TypeDescription.Generic.OfWildcardType.ForLoadedType((WildcardType) type, annotationReader); } else { throw new IllegalArgumentException("Unknown type: " + type); } } /** * Checks if this type sort represents a non-generic type. * * @return {@code true} if this sort form represents a non-generic. */ public boolean isNonGeneric() { return this == NON_GENERIC; } /** * Checks if this type sort represents a parameterized type. * * @return {@code true} if this sort form represents a parameterized type. */ public boolean isParameterized() { return this == PARAMETERIZED; } /** * Checks if this type sort represents a generic array. * * @return {@code true} if this type sort represents a generic array. */ public boolean isGenericArray() { return this == GENERIC_ARRAY; } /** * Checks if this type sort represents a wildcard. * * @return {@code true} if this type sort represents a wildcard. */ public boolean isWildcard() { return this == WILDCARD; } /** * Checks if this type sort represents a type variable of any form. * * @return {@code true} if this type sort represents an attached type variable. */ public boolean isTypeVariable() { return this == VARIABLE || this == VARIABLE_SYMBOLIC; } /** * A proxy for interacting with {@code java.lang.reflect.AnnotatedType}. */ @JavaDispatcher.Proxied("java.lang.reflect.AnnotatedType") protected interface AnnotatedType { /** * Returns {@code true} if the supplied value is an instance of {@code java.lang.reflect.AnnotatedType}. * * @param value The instance to consider. * @return {@code true} if the supplied instance is of type {@code java.lang.reflect.AnnotatedType}. */ @JavaDispatcher.Instance boolean isInstance(AnnotatedElement value); /** * Resolves the supplied {@code java.lang.reflect.AnnotatedType}'s type. * * @param value The {@code java.lang.reflect.AnnotatedType} to resolve. * @return The annotated type's type. */ Type getType(AnnotatedElement value); } } /** * An iterator that iterates over a type's class hierarchy. */ class SuperClassIterator implements Iterator { /** * The next class to represent. */ @UnknownNull private TypeDefinition nextClass; /** * Creates a new iterator. * * @param initialType The initial type of this iterator. */ public SuperClassIterator(TypeDefinition initialType) { nextClass = initialType; } /** * {@inheritDoc} */ public boolean hasNext() { return nextClass != null; } /** * {@inheritDoc} */ public TypeDefinition next() { if (!hasNext()) { throw new NoSuchElementException("End of type hierarchy"); } try { return nextClass; } finally { nextClass = nextClass.getSuperClass(); } } /** * {@inheritDoc} */ public void remove() { throw new UnsupportedOperationException("remove"); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy