1 /*
2  * Copyright 2014 - 2020 Rafael Winterhalter
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.bytebuddy.description.type;
17
18 import net.bytebuddy.description.ModifierReviewable;
19 import net.bytebuddy.description.NamedElement;
20 import net.bytebuddy.description.field.FieldList;
21 import net.bytebuddy.description.method.MethodList;
22 import net.bytebuddy.implementation.bytecode.StackSize;
23
24 import java.lang.reflect.*;
25 import java.util.Iterator;
26 import java.util.NoSuchElementException;
27
28 /**
29  * Implementations define a type, either as a {@link TypeDescription} or as a {@link TypeDescription.Generic}.
30  */

31 public interface TypeDefinition extends NamedElement, ModifierReviewable.ForTypeDefinition, Iterable<TypeDefinition> {
32
33     /**
34      * <p>
35      * If this property is set to {@code true}, non-generic {@link TypeDefinition}s do no longer resolve their referenced
36      * generic types when traversing type hierarchies. Setting this property can cause unexpected side effects such as
37      * {@link ClassCastException}s from overridden methods as type variables are resolved to their erasures where a method
38      * might return that is unexpected by the callee. Setting this property also makes type annotations unavailable using
39      * such type navigation.
40      * </p>
41      * <p>
42      * Setting this property can be useful if generic type information is not required in order to avoid bugs in
43      * implementations of the JVM where processing generic types can cause segmentation faults. Byte Buddy will undertake
44      * a best effort to retain the generic type information and information about type annotations within the redefined
45      * types' class files. Typically, this property can be meaningful in combination with a Java agent that only changes
46      * byte code without changing a class type's structure.
47      * </p>
48      */

49     String RAW_TYPES_PROPERTY = "net.bytebuddy.raw";
50
51     /**
52      * Returns this type definition as a generic type.
53      *
54      * @return This type definition represented as a generic type.
55      */

56     TypeDescription.Generic asGenericType();
57
58     /**
59      * Returns the erasure of this type. Wildcard types ({@link TypeDescription.Generic.Sort#WILDCARD})
60      * do not have a well-defined erasure and cause an {@link IllegalStateException} to be thrown.
61      *
62      * @return The erasure of this type.
63      */

64     TypeDescription asErasure();
65
66     /**
67      * Returns the super class of this type. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
68      * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Interface types
69      * and the {@link Object} class do not define a super class where {@code null} is returned. Array types define {@link Object}
70      * as their direct super class.
71      *
72      * @return The super class of this type or {@code nullif no super class exists for this type.
73      */

74     TypeDescription.Generic getSuperClass();
75
76     /**
77      * Returns the interfaces that this type implements. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
78      * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types.
79      *
80      * @return The interfaces that this type implements.
81      */

82     TypeList.Generic getInterfaces();
83
84     /**
85      * Returns the fields that this type declares. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
86      * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Generic array
87      * types never define fields and the returned list is always empty for such types.
88      *
89      * @return The fields that this type declares. A super type is only defined for non-generic types ({@link Sort#NON_GENERIC}),
90      * parameterized types ({@link Sort#PARAMETERIZED}) or generic array types ({@link Sort#GENERIC_ARRAY}) types. Generic array
91      * types never define methods and the returned list is always empty for such types.
92      */

93     FieldList<?> getDeclaredFields();
94
95     /**
96      * Returns the methods that this type declares.
97      *
98      * @return The methods that this type declares.
99      */

100     MethodList<?> getDeclaredMethods();
101
102     /**
103      * <p>
104      * Returns the component type of this type.
105      * </p>
106      * <p>
107      * Only non-generic types ({@link TypeDescription.Generic.Sort#NON_GENERIC}) and generic array types
108      * {@link TypeDescription.Generic.Sort#GENERIC_ARRAY}) define a component type. For other
109      * types, an {@link IllegalStateException} is thrown.
110      * </p>
111      *
112      * @return The component type of this type or {@code nullif this type does not represent an array type.
113      */

114     TypeDefinition getComponentType();
115
116     /**
117      * Returns the list of record components that are declared by this type. If this type is not
118      * a record, the returned list is empty.
119      *
120      * @return A list of record components that this type declares.
121      */

122     RecordComponentList<?> getRecordComponents();
123
124     /**
125      * Returns the sort of the generic type this instance represents.
126      *
127      * @return The sort of the generic type.
128      */

129     Sort getSort();
130
131     /**
132      * Returns the name of the type. For generic types, this name is their {@link Object#toString()} representations. For a non-generic
133      * type, it is the fully qualified binary name of the type.
134      *
135      * @return The name of this type.
136      */

137     String getTypeName();
138
139     /**
140      * Returns the size of the type described by this instance. Wildcard types
141      * ({@link TypeDescription.Generic.Sort#WILDCARD} do not have a well-defined a stack size and
142      * cause an {@link IllegalStateException} to be thrown.
143      *
144      * @return The size of the type described by this instance.
145      */

146     StackSize getStackSize();
147
148     /**
149      * Checks if the type described by this entity is an array.
150      *
151      * @return {@code trueif this type description represents an array.
152      */

153     boolean isArray();
154
155     /**
156      * Checks if this type is a Java record.
157      *
158      * @return {@code trueif this type is a Java record.
159      */

160     boolean isRecord();
161
162     /**
163      * Checks if the type described by this entity is a primitive type.
164      *
165      * @return {@code trueif this type description represents a primitive type.
166      */

167     boolean isPrimitive();
168
169     /**
170      * Checks if the type described by this instance represents {@code type}.
171      *
172      * @param type The type of interest.
173      * @return {@code trueif the type described by this instance represents {@code type}.
174      */

175     boolean represents(Type type);
176
177     /**
178      * Represents a {@link TypeDescription.Generic}'s form.
179      */

180     enum Sort {
181
182         /**
183          * Represents a non-generic type.
184          */

185         NON_GENERIC,
186
187         /**
188          * Represents a generic array type.
189          */

190         GENERIC_ARRAY,
191
192         /**
193          * Represents a parameterized type.
194          */

195         PARAMETERIZED,
196
197         /**
198          * Represents a wildcard type.
199          */

200         WILDCARD,
201
202         /**
203          * Represents a type variable that is attached to a {@link net.bytebuddy.description.TypeVariableSource}.
204          */

205         VARIABLE,
206
207         /**
208          * Represents a type variable that is merely symbolic and is not attached to a {@link net.bytebuddy.description.TypeVariableSource}
209          * and does not defined bounds.
210          */

211         VARIABLE_SYMBOLIC;
212
213         /**
214          * Describes a loaded generic type as a {@link TypeDescription.Generic}.
215          *
216          * @param type The type to describe.
217          * @return A description of the provided generic type.
218          */

219         public static TypeDescription.Generic describe(Type type) {
220             return describe(type, TypeDescription.Generic.AnnotationReader.NoOp.INSTANCE);
221         }
222
223         /**
224          * Describes the generic type while using the supplied annotation reader for resolving type annotations if this
225          * language feature is available on the current JVM.
226          *
227          * @param type             The type to describe.
228          * @param annotationReader The annotation reader for extracting type annotations.
229          * @return A description of the provided generic annotated type.
230          */

231         protected static TypeDescription.Generic describe(Type type, TypeDescription.Generic.AnnotationReader annotationReader) {
232             if (type instanceof Class<?>) {
233                 return new TypeDescription.Generic.OfNonGenericType.ForLoadedType((Class<?>) type, annotationReader);
234             } else if (type instanceof GenericArrayType) {
235                 return new TypeDescription.Generic.OfGenericArray.ForLoadedType((GenericArrayType) type, annotationReader);
236             } else if (type instanceof ParameterizedType) {
237                 return new TypeDescription.Generic.OfParameterizedType.ForLoadedType((ParameterizedType) type, annotationReader);
238             } else if (type instanceof TypeVariable) {
239                 return new TypeDescription.Generic.OfTypeVariable.ForLoadedType((TypeVariable<?>) type, annotationReader);
240             } else if (type instanceof WildcardType) {
241                 return new TypeDescription.Generic.OfWildcardType.ForLoadedType((WildcardType) type, annotationReader);
242             } else {
243                 throw new IllegalArgumentException("Unknown type: " + type);
244             }
245         }
246
247         /**
248          * Checks if this type sort represents a non-generic type.
249          *
250          * @return {@code trueif this sort form represents a non-generic.
251          */

252         public boolean isNonGeneric() {
253             return this == NON_GENERIC;
254         }
255
256         /**
257          * Checks if this type sort represents a parameterized type.
258          *
259          * @return {@code trueif this sort form represents a parameterized type.
260          */

261         public boolean isParameterized() {
262             return this == PARAMETERIZED;
263         }
264
265         /**
266          * Checks if this type sort represents a generic array.
267          *
268          * @return {@code trueif this type sort represents a generic array.
269          */

270         public boolean isGenericArray() {
271             return this == GENERIC_ARRAY;
272         }
273
274         /**
275          * Checks if this type sort represents a wildcard.
276          *
277          * @return {@code trueif this type sort represents a wildcard.
278          */

279         public boolean isWildcard() {
280             return this == WILDCARD;
281         }
282
283         /**
284          * Checks if this type sort represents a type variable of any form.
285          *
286          * @return {@code trueif this type sort represents an attached type variable.
287          */

288         public boolean isTypeVariable() {
289             return this == VARIABLE || this == VARIABLE_SYMBOLIC;
290         }
291     }
292
293     /**
294      * An iterator that iterates over a type's class hierarchy.
295      */

296     class SuperClassIterator implements Iterator<TypeDefinition> {
297
298         /**
299          * The next class to represent.
300          */

301         private TypeDefinition nextClass;
302
303         /**
304          * Creates a new iterator.
305          *
306          * @param initialType The initial type of this iterator.
307          */

308         public SuperClassIterator(TypeDefinition initialType) {
309             nextClass = initialType;
310         }
311
312         /**
313          * {@inheritDoc}
314          */

315         public boolean hasNext() {
316             return nextClass != null;
317         }
318
319         /**
320          * {@inheritDoc}
321          */

322         public TypeDefinition next() {
323             if (!hasNext()) {
324                 throw new NoSuchElementException("End of type hierarchy");
325             }
326             try {
327                 return nextClass;
328             } finally {
329                 nextClass = nextClass.getSuperClass();
330             }
331         }
332
333         /**
334          * {@inheritDoc}
335          */

336         public void remove() {
337             throw new UnsupportedOperationException("remove");
338         }
339     }
340 }
341