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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import net.bytebuddy.ClassFileVersion;
20 import net.bytebuddy.build.CachedReturnPlugin;
21 import net.bytebuddy.build.HashCodeAndEqualsPlugin;
22 import net.bytebuddy.description.ByteCodeElement;
23 import net.bytebuddy.description.ModifierReviewable;
24 import net.bytebuddy.description.TypeVariableSource;
25 import net.bytebuddy.description.annotation.AnnotationDescription;
26 import net.bytebuddy.description.annotation.AnnotationList;
27 import net.bytebuddy.description.annotation.AnnotationSource;
28 import net.bytebuddy.description.enumeration.EnumerationDescription;
29 import net.bytebuddy.description.field.FieldDescription;
30 import net.bytebuddy.description.field.FieldList;
31 import net.bytebuddy.description.method.MethodDescription;
32 import net.bytebuddy.description.method.MethodList;
33 import net.bytebuddy.description.method.ParameterDescription;
34 import net.bytebuddy.dynamic.TargetType;
35 import net.bytebuddy.implementation.bytecode.StackSize;
36 import net.bytebuddy.matcher.ElementMatcher;
37 import net.bytebuddy.utility.CompoundList;
38 import net.bytebuddy.utility.JavaType;
39 import net.bytebuddy.utility.privilege.GetSystemPropertyAction;
40 import net.bytebuddy.jar.asm.Opcodes;
41 import net.bytebuddy.jar.asm.Type;
42 import net.bytebuddy.jar.asm.signature.SignatureVisitor;
43 import net.bytebuddy.jar.asm.signature.SignatureWriter;
44
45 import java.io.Serializable;
46 import java.lang.annotation.Annotation;
47 import java.lang.annotation.ElementType;
48 import java.lang.reflect.*;
49 import java.security.AccessController;
50 import java.security.PrivilegedAction;
51 import java.util.*;
52
53 import static net.bytebuddy.matcher.ElementMatchers.is;
54
55 /**
56 * Implementations of this interface represent a Java type, i.e. a class or interface. Instances of this interface always
57 * represent non-generic types of sort {@link Generic.Sort#NON_GENERIC}.
58 */
59 public interface TypeDescription extends TypeDefinition, ByteCodeElement, TypeVariableSource {
60
61 /**
62 * A representation of the {@link java.lang.Object} type.
63 */
64 TypeDescription OBJECT = new ForLoadedType(Object.class);
65
66 /**
67 * A representation of the {@link java.lang.String} type.
68 */
69 TypeDescription STRING = new ForLoadedType(String.class);
70
71 /**
72 * A representation of the {@link java.lang.Class} type.
73 */
74 TypeDescription CLASS = new ForLoadedType(Class.class);
75
76 /**
77 * A representation of the {@link java.lang.Throwable} type.
78 */
79 TypeDescription THROWABLE = new ForLoadedType(Throwable.class);
80
81 /**
82 * A representation of the {@code void} non-type.
83 */
84 TypeDescription VOID = new ForLoadedType(void.class);
85
86 /**
87 * A list of interfaces that are implicitly implemented by any array type.
88 */
89 TypeList.Generic ARRAY_INTERFACES = new TypeList.Generic.ForLoadedTypes(Cloneable.class, Serializable.class);
90
91 /**
92 * Represents any undefined property representing a type description that is instead represented as {@code null} in order
93 * to resemble the Java reflection API which returns {@code null} and is intuitive to many Java developers.
94 */
95 TypeDescription UNDEFINED = null;
96
97 /**
98 * {@inheritDoc}
99 */
100 FieldList<FieldDescription.InDefinedShape> getDeclaredFields();
101
102 /**
103 * {@inheritDoc}
104 */
105 MethodList<MethodDescription.InDefinedShape> getDeclaredMethods();
106
107 /**
108 * {@inheritDoc}
109 */
110 RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents();
111
112 /**
113 * Checks if {@code value} is an instance of the type represented by this instance.
114 *
115 * @param value The object of interest.
116 * @return {@code true} if the object is an instance of the type described by this instance.
117 */
118 boolean isInstance(Object value);
119
120 /**
121 * Checks if this type is assignable from the type described by this instance, for example for
122 * {@code class Foo} and {@code class Bar extends Foo}, this method would return {@code true} for
123 * {@code Foo.class.isAssignableFrom(Bar.class)}.
124 *
125 * @param type The type of interest.
126 * @return {@code true} if this type is assignable from {@code type}.
127 */
128 boolean isAssignableFrom(Class<?> type);
129
130 /**
131 * Checks if this type is assignable from the type described by this instance, for example for
132 * {@code class Foo} and {@code class Bar extends Foo}, this method would return {@code true} for
133 * {@code Foo.class.isAssignableFrom(Bar.class)}.
134 * <p> </p>
135 * Implementations of this methods are allowed to delegate to
136 * {@link TypeDescription#isAssignableFrom(Class)}
137 *
138 * @param typeDescription The type of interest.
139 * @return {@code true} if this type is assignable from {@code type}.
140 */
141 boolean isAssignableFrom(TypeDescription typeDescription);
142
143 /**
144 * Checks if this type is assignable from the type described by this instance, for example for
145 * {@code class Foo} and {@code class Bar extends Foo}, this method would return {@code true} for
146 * {@code Bar.class.isAssignableTo(Foo.class)}.
147 *
148 * @param type The type of interest.
149 * @return {@code true} if this type is assignable to {@code type}.
150 */
151 boolean isAssignableTo(Class<?> type);
152
153 /**
154 * Checks if this type is assignable from the type described by this instance, for example for
155 * {@code class Foo} and {@code class Bar extends Foo}, this method would return {@code true} for
156 * {@code Bar.class.isAssignableFrom(Foo.class)}.
157 * <p> </p>
158 * Implementations of this methods are allowed to delegate to
159 * {@link TypeDescription#isAssignableTo(Class)}
160 *
161 * @param typeDescription The type of interest.
162 * @return {@code true} if this type is assignable to {@code type}.
163 */
164 boolean isAssignableTo(TypeDescription typeDescription);
165
166 /**
167 * Returns {@code true} if this type and the supplied type are in a type hierarchy with each other, i.e. if this type is assignable
168 * to the supplied type or the other way around.
169 *
170 * @param type The type of interest.
171 * @return {@code true} if this type and the supplied type are in a type hierarchy with each other.
172 */
173 boolean isInHierarchyWith(Class<?> type);
174
175 /**
176 * Returns {@code true} if this type and the supplied type are in a type hierarchy with each other, i.e. if this type is assignable
177 * to the supplied type or the other way around.
178 *
179 * @param typeDescription The type of interest.
180 * @return {@code true} if this type and the supplied type are in a type hierarchy with each other.
181 */
182 boolean isInHierarchyWith(TypeDescription typeDescription);
183
184 /**
185 * {@inheritDoc}
186 */
187 TypeDescription getComponentType();
188
189 /**
190 * {@inheritDoc}
191 */
192 TypeDescription getDeclaringType();
193
194 /**
195 * Returns a list of types that are declared by this type. This list does not normally include anonymous types but might
196 * include additional types if they are explicitly added to an instrumented type.
197 *
198 * @return A list of types that are declared within this type.
199 */
200 TypeList getDeclaredTypes();
201
202 /**
203 * Returns a description of the method that encloses this type. If this method is not enclosed by any type or is
204 * enclosed by the type initializer, {@code null} is returned by this method.
205 *
206 * @return A description of the enclosing method of this type or {@code null} if there is no such method.
207 */
208 MethodDescription.InDefinedShape getEnclosingMethod();
209
210 /**
211 * Returns a description of this type's enclosing type if any.
212 *
213 * @return A description of the enclosing type of this type or {@code null} if there is no such type.
214 */
215 TypeDescription getEnclosingType();
216
217 /**
218 * Returns the type's actual modifiers as present in the class file. For example, a type cannot be {@code private}.
219 * but it modifiers might reflect this property nevertheless if a class was defined as a private inner class. The
220 * returned modifiers take also into account if the type is marked as {@link Deprecated}. Anonymous classes that are
221 * enclosed in a static method or the type initializer are additionally marked as {@code final} as it is also done
222 * by the Java compiler.
223 *
224 * @param superFlag {@code true} if the modifier's super flag should be set.
225 * @return The type's actual modifiers.
226 */
227 int getActualModifiers(boolean superFlag);
228
229 /**
230 * Returns the simple internalName of this type.
231 *
232 * @return The simple internalName of this type.
233 */
234 String getSimpleName();
235
236 /**
237 * Returns the canonical name of this type if it exists.
238 *
239 * @return The canonical name of this type. Might be {@code null}.
240 */
241 String getCanonicalName();
242
243 /**
244 * Checks if this type description represents an anonymous type.
245 *
246 * @return {@code true} if this type description represents an anonymous type.
247 */
248 boolean isAnonymousType();
249
250 /**
251 * Checks if this type description represents a local type.
252 *
253 * @return {@code true} if this type description represents a local type.
254 */
255 boolean isLocalType();
256
257 /**
258 * Checks if this type description represents a member type.
259 *
260 * @return {@code true} if this type description represents a member type.
261 */
262 boolean isMemberType();
263
264 /**
265 * Returns the package of the type described by this instance or {@code null} if the described type does not imply a package.
266 *
267 * @return The package of the type described by this instance or {@code null} if the described type does not imply a package.
268 */
269 PackageDescription getPackage();
270
271 /**
272 * Returns the annotations that this type declares or inherits from super types.
273 *
274 * @return A list of all inherited annotations.
275 */
276 AnnotationList getInheritedAnnotations();
277
278 /**
279 * Checks if two types are defined in the same package.
280 *
281 * @param typeDescription The type of interest.
282 * @return {@code true} if this type and the given type are in the same package.
283 */
284 boolean isSamePackage(TypeDescription typeDescription);
285
286 /**
287 * Checks if this type represents a wrapper type for a primitive type. The {@link java.lang.Void} type is
288 * not considered to be a wrapper type.
289 *
290 * @return {@code true} if this type represents a wrapper type.
291 */
292 boolean isPrimitiveWrapper();
293
294 /**
295 * Checks if instances of this type can be returned from an annotation method.
296 *
297 * @return {@code true} if instances of this type can be returned from an annotation method.
298 */
299 boolean isAnnotationReturnType();
300
301 /**
302 * Checks if instances of this type can be used for describing an annotation value.
303 *
304 * @return {@code true} if instances of this type can be used for describing an annotation value.
305 */
306 boolean isAnnotationValue();
307
308 /**
309 * Checks if instances of this type can be used for describing the given annotation value.
310 *
311 * @param value The value that is supposed to describe the annotation value for this instance.
312 * @return {@code true} if instances of this type can be used for describing the given annotation value..
313 */
314 boolean isAnnotationValue(Object value);
315
316 /**
317 * Checks if this type represents a class that is a place holder for a package description.
318 *
319 * @return {@code true} if this type represents a package description.
320 */
321 boolean isPackageType();
322
323 /**
324 * Returns the amount of outer classes this type defines. If this type is not an inner type of another class, {@code 0} is returned.
325 *
326 * @return The number of outer classes relatively to this type.
327 */
328 int getInnerClassCount();
329
330 /**
331 * Indicates if this class is an inner class.
332 *
333 * @return {@code true} if this class is an inner class.
334 */
335 boolean isInnerClass();
336
337 /**
338 * Indicates if this class is a nested class.
339 *
340 * @return {@code true} if this class is a nested class.
341 */
342 boolean isNestedClass();
343
344 /**
345 * Returns a description of this type that represents this type as a boxed type for primitive types, unless its {@code void}.
346 *
347 * @return A description of this type in its boxed form.
348 */
349 TypeDescription asBoxed();
350
351 /**
352 * Returns a description of this type that represents this type as an unboxed type for boxing types, unless its {@link Void}.
353 *
354 * @return A description of this type in its unboxed form.
355 */
356 TypeDescription asUnboxed();
357
358 /**
359 * Returns the default value for this type, i.e. the zero value for a primitive type and {@code null} for a reference type.
360 * For {@code void}, {@code null} is returned.
361 *
362 * @return This types default value.
363 */
364 Object getDefaultValue();
365
366 /**
367 * Returns the nest host of this type. For types prior to Java 11, this type is returned which is the default nest host.
368 *
369 * @return The nest host of this type.
370 */
371 TypeDescription getNestHost();
372
373 /**
374 * Returns a list of members that are part of a nesting group. Prior to Java 11, a list that only contains this type is returned which is
375 * the default nest group.
376 *
377 * @return A list of members of this nest group.
378 */
379 TypeList getNestMembers();
380
381 /**
382 * Checks if this class is the host of a nest group.
383 *
384 * @return {@code true} if this class is a nest group's host.
385 */
386 boolean isNestHost();
387
388 /**
389 * Checks if this type and the supplied type are members of the same nest group.
390 *
391 * @param type The type for which to check if it is a member of the same nest group.
392 * @return {@code true} if this type and the supplied type are members of the same nest group.
393 */
394 boolean isNestMateOf(Class<?> type);
395
396 /**
397 * Checks if this type and the supplied type are members of the same nest group.
398 *
399 * @param typeDescription The type for which to check if it is a member of the same nest group.
400 * @return {@code true} if this type and the supplied type are members of the same nest group.
401 */
402 boolean isNestMateOf(TypeDescription typeDescription);
403
404 /**
405 * Indicates if this type represents a compile-time constant, i.e. {@code int}, {@code long}, {@code float}, {@code double},
406 * {@link String}, {@link Class} or {@code java.lang.invoke.MethodHandle} or {@code java.lang.invoke.MethodType}.
407 *
408 * @return {@code true} if this type represents a compile-time constant.
409 */
410 boolean isCompileTimeConstant();
411
412 /**
413 * Returns the list of permitted subclasses if this class is a sealed class or an empty list if this class is not sealed.
414 *
415 * @return The list of permitted subclasses if this class is a sealed class or an empty list if this class is not sealed.
416 */
417 TypeList getPermittedSubclasses();
418
419 /**
420 * Returns {@code true} if this class is a sealed class that only permitts a specified range of subclasses.
421 *
422 * @return {@code true} if this class is a sealed class that only permitts a specified range of subclasses.
423 */
424 boolean isSealed();
425
426 /**
427 * <p>
428 * Represents a generic type of the Java programming language. A non-generic {@link TypeDescription} is considered to be
429 * a specialization of a generic type.
430 * </p>
431 * <p>
432 * Note that annotations that are declared on an annotated type refer to any type annotations that are declared by this
433 * generic type. For reading annotations of the erasure type, {@link TypeDefinition#asErasure()} must be called before.
434 * </p>
435 */
436 interface Generic extends TypeDefinition, AnnotationSource {
437
438 /**
439 * A representation of the {@link Object} type.
440 */
441 Generic OBJECT = new OfNonGenericType.ForLoadedType(Object.class);
442
443 /**
444 * A representation of the {@link Class} non-type.
445 */
446 Generic CLASS = new OfNonGenericType.ForLoadedType(Class.class);
447
448 /**
449 * A representation of the {@code void} non-type.
450 */
451 Generic VOID = new OfNonGenericType.ForLoadedType(void.class);
452
453 /**
454 * A representation of the {@link Annotation} type.
455 */
456 Generic ANNOTATION = new OfNonGenericType.ForLoadedType(Annotation.class);
457
458 /**
459 * Represents any undefined property representing a generic type description that is instead represented as {@code null} in order
460 * to resemble the Java reflection API which returns {@code null} and is intuitive to many Java developers.
461 */
462 Generic UNDEFINED = null;
463
464 /**
465 * Returns this type as a raw type. This resembles calling {@code asErasure().asGenericType()}.
466 *
467 * @return This type as a raw type.
468 */
469 Generic asRawType();
470
471 /**
472 * <p>
473 * Returns the upper bounds of this type. Any type with a well-defined upper bound is bound by at least one type. If no such
474 * type is defined, the bound is implicitly {@link Object}.
475 * </p>
476 * <p>
477 * Only non-symbolic type variables ({@link net.bytebuddy.description.type.TypeDefinition.Sort#VARIABLE}, and wildcard types
478 * ({@link net.bytebuddy.description.type.TypeDefinition.Sort#WILDCARD}) have well-defined upper bounds. For other
479 * types, an {@link IllegalStateException} is thrown.
480 * </p>
481 *
482 * @return The upper bounds of this type.
483 */
484 TypeList.Generic getUpperBounds();
485
486 /**
487 * <p>
488 * Returns the lower bounds of this type.
489 * </p>
490 * <p>
491 * Only wildcard types ({@link Sort#WILDCARD}) define a lower bound. For other
492 * types, an {@link IllegalStateException} is thrown.
493 * </p>
494 *
495 * @return The lower bounds of this type.
496 */
497 TypeList.Generic getLowerBounds();
498
499 /**
500 * <p>
501 * Returns the type arguments of this type.
502 * </p>
503 * <p>
504 * Parameters are only well-defined for parameterized types ({@link Sort#PARAMETERIZED}).
505 * For all other types, this method throws an {@link IllegalStateException}.
506 * </p>
507 *
508 * @return A list of this type's type parameters.
509 */
510 TypeList.Generic getTypeArguments();
511
512 /**
513 * <p>
514 * Returns the owner type of this type. A type's owner type describes a nested type's declaring type.
515 * If it exists, the returned type can be a non-generic or parameterized type. If a class has no
516 * declaring type, {@code null} is returned.
517 * </p>
518 * <p>
519 * An owner type is only well-defined for parameterized types ({@link Sort#PARAMETERIZED}),
520 * for non-generic types ({@link Sort#NON_GENERIC}) and for generic arrays ({@link Sort#GENERIC_ARRAY}).
521 * For all other types, this method throws an {@link IllegalStateException}.
522 * </p>
523 *
524 * @return This type's owner type or {@code null} if no owner type exists.
525 */
526 Generic getOwnerType();
527
528 /**
529 * <p>
530 * Returns the parameter binding of the supplied type variable.
531 * </p>
532 * <p>
533 * This method must only be called for parameterized types ({@link Sort#PARAMETERIZED}). For all other types,
534 * this method throws an {@link IllegalStateException}.
535 * </p>
536 *
537 * @param typeVariable The type variable for which a value should be located.
538 * @return The value that is bound to the supplied type variable or {@code null} if the type variable
539 * is not bound by this parameterized type.
540 */
541 Generic findBindingOf(Generic typeVariable);
542
543 /**
544 * Returns the source of this type variable. A type variable source is only well-defined for an attached type variable
545 * ({@link Sort#VARIABLE}. For other types, this method
546 * throws an {@link IllegalStateException}.
547 *
548 * @return This type's type variable source.
549 */
550 TypeVariableSource getTypeVariableSource();
551
552 /**
553 * Returns the symbol of this type variable. A symbol is only well-defined for type variables
554 * ({@link Sort#VARIABLE}, {@link Sort#VARIABLE_SYMBOLIC}). For other types, this method
555 * throws an {@link IllegalStateException}.
556 *
557 * @return This type's type variable symbol.
558 */
559 String getSymbol();
560
561 /**
562 * {@inheritDoc}
563 */
564 Generic getComponentType();
565
566 /**
567 * {@inheritDoc}
568 */
569 FieldList<FieldDescription.InGenericShape> getDeclaredFields();
570
571 /**
572 * {@inheritDoc}
573 */
574 MethodList<MethodDescription.InGenericShape> getDeclaredMethods();
575
576 /**
577 * {@inheritDoc}
578 */
579 RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents();
580
581 /**
582 * Applies a visitor to this generic type description.
583 *
584 * @param visitor The visitor to apply.
585 * @param <T> The value that this visitor yields.
586 * @return The visitor's return value.
587 */
588 <T> T accept(Visitor<T> visitor);
589
590 /**
591 * A visitor that can be applied to a {@link Generic} for differentiating on the sort of the visited type.
592 *
593 * @param <T> The visitor's return value's type.
594 */
595 interface Visitor<T> {
596
597 /**
598 * Visits a generic array type ({@link Sort#GENERIC_ARRAY}).
599 *
600 * @param genericArray The generic array type.
601 * @return The visitor's return value.
602 */
603 T onGenericArray(Generic genericArray);
604
605 /**
606 * Visits a wildcard ({@link Sort#WILDCARD}).
607 *
608 * @param wildcard The wildcard.
609 * @return The visitor's return value.
610 */
611 T onWildcard(Generic wildcard);
612
613 /**
614 * Visits a parameterized type ({@link Sort#PARAMETERIZED}).
615 *
616 * @param parameterizedType The generic array type.
617 * @return The visitor's return value.
618 */
619 T onParameterizedType(Generic parameterizedType);
620
621 /**
622 * Visits a type variable ({@link Sort#VARIABLE}, {@link Sort#VARIABLE_SYMBOLIC}).
623 *
624 * @param typeVariable The generic array type.
625 * @return The visitor's return value.
626 */
627 T onTypeVariable(Generic typeVariable);
628
629 /**
630 * Visits a non-generic type ({@link Sort#NON_GENERIC}).
631 *
632 * @param typeDescription The non-generic type.
633 * @return The visitor's return value.
634 */
635 T onNonGenericType(Generic typeDescription);
636
637 /**
638 * A non-operational generic type visitor. Any visited type is returned in its existing form.
639 */
640 enum NoOp implements Visitor<Generic> {
641
642 /**
643 * The singleton instance.
644 */
645 INSTANCE;
646
647 /**
648 * {@inheritDoc}
649 */
650 public Generic onGenericArray(Generic genericArray) {
651 return genericArray;
652 }
653
654 /**
655 * {@inheritDoc}
656 */
657 public Generic onWildcard(Generic wildcard) {
658 return wildcard;
659 }
660
661 /**
662 * {@inheritDoc}
663 */
664 public Generic onParameterizedType(Generic parameterizedType) {
665 return parameterizedType;
666 }
667
668 /**
669 * {@inheritDoc}
670 */
671 public Generic onTypeVariable(Generic typeVariable) {
672 return typeVariable;
673 }
674
675 /**
676 * {@inheritDoc}
677 */
678 public Generic onNonGenericType(Generic typeDescription) {
679 return typeDescription;
680 }
681 }
682
683 /**
684 * A visitor that returns the erasure of any visited type. For wildcard types, an exception is thrown.
685 */
686 enum TypeErasing implements Visitor<Generic> {
687
688 /**
689 * The singleton instance.
690 */
691 INSTANCE;
692
693 /**
694 * {@inheritDoc}
695 */
696 public Generic onGenericArray(Generic genericArray) {
697 return genericArray.asRawType();
698 }
699
700 /**
701 * {@inheritDoc}
702 */
703 public Generic onWildcard(Generic wildcard) {
704 throw new IllegalArgumentException("Cannot erase a wildcard type: " + wildcard);
705 }
706
707 /**
708 * {@inheritDoc}
709 */
710 public Generic onParameterizedType(Generic parameterizedType) {
711 return parameterizedType.asRawType();
712 }
713
714 /**
715 * {@inheritDoc}
716 */
717 public Generic onTypeVariable(Generic typeVariable) {
718 return typeVariable.asRawType();
719 }
720
721 /**
722 * {@inheritDoc}
723 */
724 public Generic onNonGenericType(Generic typeDescription) {
725 return typeDescription.asRawType();
726 }
727 }
728
729 /**
730 * A visitor that strips all type annotations of all types.
731 */
732 enum AnnotationStripper implements Visitor<Generic> {
733
734 /**
735 * The singleton instance.
736 */
737 INSTANCE;
738
739 /**
740 * {@inheritDoc}
741 */
742 public Generic onGenericArray(Generic genericArray) {
743 return new OfGenericArray.Latent(genericArray.getComponentType().accept(this), Empty.INSTANCE);
744 }
745
746 /**
747 * {@inheritDoc}
748 */
749 public Generic onWildcard(Generic wildcard) {
750 return new OfWildcardType.Latent(wildcard.getUpperBounds().accept(this), wildcard.getLowerBounds().accept(this), Empty.INSTANCE);
751 }
752
753 /**
754 * {@inheritDoc}
755 */
756 public Generic onParameterizedType(Generic parameterizedType) {
757 Generic ownerType = parameterizedType.getOwnerType();
758 return new OfParameterizedType.Latent(parameterizedType.asErasure(),
759 ownerType == null
760 ? UNDEFINED
761 : ownerType.accept(this),
762 parameterizedType.getTypeArguments().accept(this),
763 Empty.INSTANCE);
764 }
765
766 /**
767 * {@inheritDoc}
768 */
769 public Generic onTypeVariable(Generic typeVariable) {
770 return new NonAnnotatedTypeVariable(typeVariable);
771 }
772
773 /**
774 * {@inheritDoc}
775 */
776 public Generic onNonGenericType(Generic typeDescription) {
777 return typeDescription.isArray()
778 ? new OfGenericArray.Latent(onNonGenericType(typeDescription.getComponentType()), Empty.INSTANCE)
779 : new OfNonGenericType.Latent(typeDescription.asErasure(), Empty.INSTANCE);
780 }
781
782 /**
783 * Representation of a type variable without annotations.
784 */
785 protected static class NonAnnotatedTypeVariable extends OfTypeVariable {
786
787 /**
788 * The represented type variable.
789 */
790 private final Generic typeVariable;
791
792 /**
793 * Creates a new non-annotated type variable.
794 *
795 * @param typeVariable The represented type variable.
796 */
797 protected NonAnnotatedTypeVariable(Generic typeVariable) {
798 this.typeVariable = typeVariable;
799 }
800
801 /**
802 * {@inheritDoc}
803 */
804 public TypeList.Generic getUpperBounds() {
805 return typeVariable.getUpperBounds();
806 }
807
808 /**
809 * {@inheritDoc}
810 */
811 public TypeVariableSource getTypeVariableSource() {
812 return typeVariable.getTypeVariableSource();
813 }
814
815 /**
816 * {@inheritDoc}
817 */
818 public String getSymbol() {
819 return typeVariable.getSymbol();
820 }
821
822 /**
823 * {@inheritDoc}
824 */
825 public AnnotationList getDeclaredAnnotations() {
826 return new AnnotationList.Empty();
827 }
828 }
829 }
830
831 /**
832 * A visitor that determines the direct assignability of a type to another generic type. This visitor only checks
833 * for strict assignability and does not perform any form of boxing or primitive type widening that are allowed
834 * in the Java language.
835 */
836 enum Assigner implements Visitor<Assigner.Dispatcher> {
837
838 /**
839 * The singleton instance.
840 */
841 INSTANCE;
842
843 /**
844 * {@inheritDoc}
845 */
846 public Dispatcher onGenericArray(Generic genericArray) {
847 return new Dispatcher.ForGenericArray(genericArray);
848 }
849
850 /**
851 * {@inheritDoc}
852 */
853 public Dispatcher onWildcard(Generic wildcard) {
854 throw new IllegalArgumentException("A wildcard is not a first level type: " + this);
855 }
856
857 /**
858 * {@inheritDoc}
859 */
860 public Dispatcher onParameterizedType(Generic parameterizedType) {
861 return new Dispatcher.ForParameterizedType(parameterizedType);
862 }
863
864 /**
865 * {@inheritDoc}
866 */
867 public Dispatcher onTypeVariable(Generic typeVariable) {
868 return new Dispatcher.ForTypeVariable(typeVariable);
869 }
870
871 /**
872 * {@inheritDoc}
873 */
874 public Dispatcher onNonGenericType(Generic typeDescription) {
875 return new Dispatcher.ForNonGenericType(typeDescription.asErasure());
876 }
877
878 /**
879 * A dispatcher that allows to check if the visited generic type is assignable to the supplied type.
880 */
881 public interface Dispatcher {
882
883 /**
884 * Checks if the represented type is a super type of the type that is supplied as an argument.
885 *
886 * @param typeDescription The type to check for being assignable to the represented type.
887 * @return {@code true} if the represented type is assignable to the supplied type.
888 */
889 boolean isAssignableFrom(Generic typeDescription);
890
891 /**
892 * An abstract base implementation of a dispatcher that forwards the decision to a visitor implementation.
893 */
894 abstract class AbstractBase implements Dispatcher, Visitor<Boolean> {
895
896 /**
897 * {@inheritDoc}
898 */
899 public boolean isAssignableFrom(Generic typeDescription) {
900 return typeDescription.accept(this);
901 }
902 }
903
904 /**
905 * A dispatcher for checking the assignability of a non-generic type.
906 */
907 @HashCodeAndEqualsPlugin.Enhance
908 class ForNonGenericType extends AbstractBase {
909
910 /**
911 * The description of the type to which another type is assigned.
912 */
913 private final TypeDescription typeDescription;
914
915 /**
916 * Creates a new dispatcher of a non-generic type.
917 *
918 * @param typeDescription The description of the type to which another type is assigned.
919 */
920 protected ForNonGenericType(TypeDescription typeDescription) {
921 this.typeDescription = typeDescription;
922 }
923
924 /**
925 * {@inheritDoc}
926 */
927 public Boolean onGenericArray(Generic genericArray) {
928 return typeDescription.isArray()
929 ? genericArray.getComponentType().accept(new ForNonGenericType(typeDescription.getComponentType()))
930 : typeDescription.represents(Object.class) || TypeDescription.ARRAY_INTERFACES.contains(typeDescription.asGenericType());
931 }
932
933 /**
934 * {@inheritDoc}
935 */
936 public Boolean onWildcard(Generic wildcard) {
937 throw new IllegalArgumentException("A wildcard is not a first-level type: " + wildcard);
938 }
939
940 /**
941 * {@inheritDoc}
942 */
943 public Boolean onParameterizedType(Generic parameterizedType) {
944 if (typeDescription.equals(parameterizedType.asErasure())) {
945 return true;
946 }
947 Generic superClass = parameterizedType.getSuperClass();
948 if (superClass != null && isAssignableFrom(superClass)) {
949 return true;
950 }
951 for (Generic interfaceType : parameterizedType.getInterfaces()) {
952 if (isAssignableFrom(interfaceType)) {
953 return true;
954 }
955 }
956 return typeDescription.represents(Object.class);
957 }
958
959 /**
960 * {@inheritDoc}
961 */
962 public Boolean onTypeVariable(Generic typeVariable) {
963 for (Generic upperBound : typeVariable.getUpperBounds()) {
964 if (isAssignableFrom(upperBound)) {
965 return true;
966 }
967 }
968 return false;
969 }
970
971 /**
972 * {@inheritDoc}
973 */
974 public Boolean onNonGenericType(Generic typeDescription) {
975 return this.typeDescription.isAssignableFrom(typeDescription.asErasure());
976 }
977 }
978
979 /**
980 * A dispatcher for checking the assignability of a type variable.
981 */
982 @HashCodeAndEqualsPlugin.Enhance
983 class ForTypeVariable extends AbstractBase {
984
985 /**
986 * The description of the type variable to which another type is assigned.
987 */
988 private final Generic typeVariable;
989
990 /**
991 * Creates a new dispatcher of a type variable.
992 *
993 * @param typeVariable The description of the type variable to which another type is assigned.
994 */
995 protected ForTypeVariable(Generic typeVariable) {
996 this.typeVariable = typeVariable;
997 }
998
999 /**
1000 * {@inheritDoc}
1001 */
1002 public Boolean onGenericArray(Generic genericArray) {
1003 return false;
1004 }
1005
1006 /**
1007 * {@inheritDoc}
1008 */
1009 public Boolean onWildcard(Generic wildcard) {
1010 throw new IllegalArgumentException("A wildcard is not a first-level type: " + wildcard);
1011 }
1012
1013 /**
1014 * {@inheritDoc}
1015 */
1016 public Boolean onParameterizedType(Generic parameterizedType) {
1017 return false;
1018 }
1019
1020 /**
1021 * {@inheritDoc}
1022 */
1023 public Boolean onTypeVariable(Generic typeVariable) {
1024 if (typeVariable.equals(this.typeVariable)) {
1025 return true;
1026 }
1027 for (Generic upperBound : typeVariable.getUpperBounds()) {
1028 if (isAssignableFrom(upperBound)) {
1029 return true;
1030 }
1031 }
1032 return false;
1033 }
1034
1035 /**
1036 * {@inheritDoc}
1037 */
1038 public Boolean onNonGenericType(Generic typeDescription) {
1039 return false;
1040 }
1041 }
1042
1043 /**
1044 * A dispatcher for checking the assignability of a parameterized type.
1045 */
1046 @HashCodeAndEqualsPlugin.Enhance
1047 class ForParameterizedType extends AbstractBase {
1048
1049 /**
1050 * The parameterized type to which another type is assigned.
1051 */
1052 private final Generic parameterizedType;
1053
1054 /**
1055 * Creates a new dispatcher for checking the assignability of a parameterized type.
1056 *
1057 * @param parameterizedType The parameterized type to which another type is assigned.
1058 */
1059 protected ForParameterizedType(Generic parameterizedType) {
1060 this.parameterizedType = parameterizedType;
1061 }
1062
1063 /**
1064 * {@inheritDoc}
1065 */
1066 public Boolean onGenericArray(Generic genericArray) {
1067 return false;
1068 }
1069
1070 /**
1071 * {@inheritDoc}
1072 */
1073 public Boolean onWildcard(Generic wildcard) {
1074 throw new IllegalArgumentException("A wildcard is not a first-level type: " + wildcard);
1075 }
1076
1077 /**
1078 * {@inheritDoc}
1079 */
1080 public Boolean onParameterizedType(Generic parameterizedType) {
1081 if (this.parameterizedType.asErasure().equals(parameterizedType.asErasure())) {
1082 Generic fromOwner = this.parameterizedType.getOwnerType(), toOwner = parameterizedType.getOwnerType();
1083 if (fromOwner != null && toOwner != null && !fromOwner.accept(Assigner.INSTANCE).isAssignableFrom(toOwner)) {
1084 return false;
1085 }
1086 TypeList.Generic fromArguments = this.parameterizedType.getTypeArguments(), toArguments = parameterizedType.getTypeArguments();
1087 if (fromArguments.size() == toArguments.size()) {
1088 for (int index = 0; index < fromArguments.size(); index++) {
1089 if (!fromArguments.get(index).accept(ParameterAssigner.INSTANCE).isAssignableFrom(toArguments.get(index))) {
1090 return false;
1091 }
1092 }
1093 return true;
1094 } else {
1095 throw new IllegalArgumentException("Incompatible generic types: " + parameterizedType + " and " + this.parameterizedType);
1096 }
1097 }
1098 Generic superClass = parameterizedType.getSuperClass();
1099 if (superClass != null && isAssignableFrom(superClass)) {
1100 return true;
1101 }
1102 for (Generic interfaceType : parameterizedType.getInterfaces()) {
1103 if (isAssignableFrom(interfaceType)) {
1104 return true;
1105 }
1106 }
1107 return false;
1108 }
1109
1110 /**
1111 * {@inheritDoc}
1112 */
1113 public Boolean onTypeVariable(Generic typeVariable) {
1114 for (Generic upperBound : typeVariable.getUpperBounds()) {
1115 if (isAssignableFrom(upperBound)) {
1116 return true;
1117 }
1118 }
1119 return false;
1120 }
1121
1122 /**
1123 * {@inheritDoc}
1124 */
1125 public Boolean onNonGenericType(Generic typeDescription) {
1126 if (parameterizedType.asErasure().equals(typeDescription.asErasure())) {
1127 return true;
1128 }
1129 Generic superClass = typeDescription.getSuperClass();
1130 if (superClass != null && isAssignableFrom(superClass)) {
1131 return true;
1132 }
1133 for (Generic interfaceType : typeDescription.getInterfaces()) {
1134 if (isAssignableFrom(interfaceType)) {
1135 return true;
1136 }
1137 }
1138 return false;
1139 }
1140
1141 /**
1142 * An assigner for a parameter of a parameterized type.
1143 */
1144 protected enum ParameterAssigner implements Visitor<Dispatcher> {
1145
1146 /**
1147 * The singleton instance.
1148 */
1149 INSTANCE;
1150
1151 /**
1152 * {@inheritDoc}
1153 */
1154 public Dispatcher onGenericArray(Generic genericArray) {
1155 return new InvariantBinding(genericArray);
1156 }
1157
1158 /**
1159 * {@inheritDoc}
1160 */
1161 public Dispatcher onWildcard(Generic wildcard) {
1162 TypeList.Generic lowerBounds = wildcard.getLowerBounds();
1163 return lowerBounds.isEmpty()
1164 ? new CovariantBinding(wildcard.getUpperBounds().getOnly())
1165 : new ContravariantBinding(lowerBounds.getOnly());
1166 }
1167
1168 /**
1169 * {@inheritDoc}
1170 */
1171 public Dispatcher onParameterizedType(Generic parameterizedType) {
1172 return new InvariantBinding(parameterizedType);
1173 }
1174
1175 /**
1176 * {@inheritDoc}
1177 */
1178 public Dispatcher onTypeVariable(Generic typeVariable) {
1179 return new InvariantBinding(typeVariable);
1180 }
1181
1182 /**
1183 * {@inheritDoc}
1184 */
1185 public Dispatcher onNonGenericType(Generic typeDescription) {
1186 return new InvariantBinding(typeDescription);
1187 }
1188
1189 /**
1190 * A dispatcher for an invariant parameter of a parameterized type, i.e. a type without a wildcard.
1191 */
1192 @HashCodeAndEqualsPlugin.Enhance
1193 protected static class InvariantBinding implements Dispatcher {
1194
1195 /**
1196 * The invariant type of the parameter.
1197 */
1198 private final Generic typeDescription;
1199
1200 /**
1201 * Creates a new dispatcher for an invariant parameter of a parameterized type.
1202 *
1203 * @param typeDescription The invariant type of the parameter.
1204 */
1205 protected InvariantBinding(Generic typeDescription) {
1206 this.typeDescription = typeDescription;
1207 }
1208
1209 /**
1210 * {@inheritDoc}
1211 */
1212 public boolean isAssignableFrom(Generic typeDescription) {
1213 return typeDescription.equals(this.typeDescription);
1214 }
1215 }
1216
1217 /**
1218 * A dispatcher for an covariant parameter of a parameterized type, i.e. a type that is the lower bound of a wildcard.
1219 */
1220 @HashCodeAndEqualsPlugin.Enhance
1221 protected static class CovariantBinding implements Dispatcher {
1222
1223 /**
1224 * The lower bound type of a covariant parameter.
1225 */
1226 private final Generic upperBound;
1227
1228 /**
1229 * Creates a new dispatcher for covariant parameter of a parameterized type.
1230 *
1231 * @param upperBound The upper bound type of a covariant parameter.
1232 */
1233 protected CovariantBinding(Generic upperBound) {
1234 this.upperBound = upperBound;
1235 }
1236
1237 /**
1238 * {@inheritDoc}
1239 */
1240 public boolean isAssignableFrom(Generic typeDescription) {
1241 if (typeDescription.getSort().isWildcard()) {
1242 return typeDescription.getLowerBounds().isEmpty() && upperBound.accept(Assigner.INSTANCE)
1243 .isAssignableFrom(typeDescription.getUpperBounds().getOnly());
1244 } else {
1245 return upperBound.accept(Assigner.INSTANCE).isAssignableFrom(typeDescription);
1246 }
1247 }
1248 }
1249
1250 /**
1251 * A dispatcher for an contravariant parameter of a parameterized type, i.e. a type that is the lower bound of a wildcard.
1252 */
1253 @HashCodeAndEqualsPlugin.Enhance
1254 protected static class ContravariantBinding implements Dispatcher {
1255
1256 /**
1257 * The lower bound type of a contravariant parameter.
1258 */
1259 private final Generic lowerBound;
1260
1261 /**
1262 * Creates a new dispatcher for contravariant parameter of a parameterized type.
1263 *
1264 * @param lowerBound The lower bound type of a contravariant parameter.
1265 */
1266 protected ContravariantBinding(Generic lowerBound) {
1267 this.lowerBound = lowerBound;
1268 }
1269
1270 /**
1271 * {@inheritDoc}
1272 */
1273 public boolean isAssignableFrom(Generic typeDescription) {
1274 if (typeDescription.getSort().isWildcard()) {
1275 TypeList.Generic lowerBounds = typeDescription.getLowerBounds();
1276 return !lowerBounds.isEmpty() && lowerBounds.getOnly().accept(Assigner.INSTANCE).isAssignableFrom(lowerBound);
1277 } else {
1278 return typeDescription.getSort().isWildcard() || typeDescription.accept(Assigner.INSTANCE).isAssignableFrom(lowerBound);
1279 }
1280 }
1281 }
1282 }
1283 }
1284
1285 /**
1286 * A dispatcher for checking the assignability of a generic array type.
1287 */
1288 @HashCodeAndEqualsPlugin.Enhance
1289 class ForGenericArray extends AbstractBase {
1290
1291 /**
1292 * The generic array type to which another type is assigned.
1293 */
1294 private final Generic genericArray;
1295
1296 /**
1297 * Creates a new dispatcher for checking the assignability of a generic array type.
1298 *
1299 * @param genericArray The generic array type to which another type is assigned.
1300 */
1301 protected ForGenericArray(Generic genericArray) {
1302 this.genericArray = genericArray;
1303 }
1304
1305 /**
1306 * {@inheritDoc}
1307 */
1308 public Boolean onGenericArray(Generic genericArray) {
1309 return this.genericArray.getComponentType().accept(Assigner.INSTANCE).isAssignableFrom(genericArray.getComponentType());
1310 }
1311
1312 /**
1313 * {@inheritDoc}
1314 */
1315 public Boolean onWildcard(Generic wildcard) {
1316 throw new IllegalArgumentException("A wildcard is not a first-level type: " + wildcard);
1317 }
1318
1319 /**
1320 * {@inheritDoc}
1321 */
1322 public Boolean onParameterizedType(Generic parameterizedType) {
1323 return false;
1324 }
1325
1326 /**
1327 * {@inheritDoc}
1328 */
1329 public Boolean onTypeVariable(Generic typeVariable) {
1330 return false;
1331 }
1332
1333 /**
1334 * {@inheritDoc}
1335 */
1336 public Boolean onNonGenericType(Generic typeDescription) {
1337 return typeDescription.isArray()
1338 && genericArray.getComponentType().accept(Assigner.INSTANCE).isAssignableFrom(typeDescription.getComponentType());
1339 }
1340 }
1341 }
1342 }
1343
1344 /**
1345 * A validator for Java types that are defined for a specified type use within a Java class file.
1346 */
1347 enum Validator implements Visitor<Boolean> {
1348
1349 /**
1350 * A validator for checking a type's non-null super class.
1351 */
1352 SUPER_CLASS(false, false, false, false) {
1353 /** {@inheritDoc} */
1354 public Boolean onNonGenericType(Generic typeDescription) {
1355 return super.onNonGenericType(typeDescription) && !typeDescription.isInterface();
1356 }
1357
1358 /** {@inheritDoc} */
1359 public Boolean onParameterizedType(Generic parameterizedType) {
1360 return !parameterizedType.isInterface();
1361 }
1362 },
1363
1364 /**
1365 * A validator for an interface type.
1366 */
1367 INTERFACE(false, false, false, false) {
1368 /** {@inheritDoc} */
1369 public Boolean onNonGenericType(Generic typeDescription) {
1370 return super.onNonGenericType(typeDescription) && typeDescription.isInterface();
1371 }
1372
1373 /** {@inheritDoc} */
1374 public Boolean onParameterizedType(Generic parameterizedType) {
1375 return parameterizedType.isInterface();
1376 }
1377 },
1378
1379 /**
1380 * A validator for a type variable.
1381 */
1382 TYPE_VARIABLE(false, false, true, false),
1383
1384 /**
1385 * A validator for a field type.
1386 */
1387 FIELD(true, true, true, false),
1388
1389 /**
1390 * A validator for a method return type.
1391 */
1392 METHOD_RETURN(true, true, true, true),
1393
1394 /**
1395 * A validator for a method parameter type.
1396 */
1397 METHOD_PARAMETER(true, true, true, false),
1398
1399 /**
1400 * A validator for a method exception type.
1401 */
1402 EXCEPTION(false, false, true, false) {
1403 /** {@inheritDoc} */
1404 public Boolean onParameterizedType(Generic parameterizedType) {
1405 return false;
1406 }
1407
1408 /** {@inheritDoc} */
1409 public Boolean onTypeVariable(Generic typeVariable) {
1410 for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) {
1411 if (bound.accept(this)) {
1412 return true;
1413 }
1414 }
1415 return false;
1416 }
1417
1418 /** {@inheritDoc} */
1419 public Boolean onNonGenericType(Generic typeDescription) {
1420 return typeDescription.asErasure().isAssignableTo(Throwable.class);
1421 }
1422 },
1423
1424 /**
1425 * A validator for a method receiver type.
1426 */
1427 RECEIVER(false, false, false, false);
1428
1429 /**
1430 * {@code true} if this validator accepts array types.
1431 */
1432 private final boolean acceptsArray;
1433
1434 /**
1435 * {@code true} if this validator accepts primitive types.
1436 */
1437 private final boolean acceptsPrimitive;
1438
1439 /**
1440 * {@code true} if this validator accepts type variables.
1441 */
1442 private final boolean acceptsVariable;
1443
1444 /**
1445 * {@code true} if this validator accepts the {@code void} type.
1446 */
1447 private final boolean acceptsVoid;
1448
1449 /**
1450 * Creates a new validator.
1451 *
1452 * @param acceptsArray {@code true} if this validator accepts array types.
1453 * @param acceptsPrimitive {@code true} if this validator accepts primitive types.
1454 * @param acceptsVariable {@code true} if this validator accepts type variables.
1455 * @param acceptsVoid {@code true} if this validator accepts the {@code void} type.
1456 */
1457 Validator(boolean acceptsArray, boolean acceptsPrimitive, boolean acceptsVariable, boolean acceptsVoid) {
1458 this.acceptsArray = acceptsArray;
1459 this.acceptsPrimitive = acceptsPrimitive;
1460 this.acceptsVariable = acceptsVariable;
1461 this.acceptsVoid = acceptsVoid;
1462 }
1463
1464 /**
1465 * {@inheritDoc}
1466 */
1467 public Boolean onGenericArray(Generic genericArray) {
1468 return acceptsArray;
1469 }
1470
1471 /**
1472 * {@inheritDoc}
1473 */
1474 public Boolean onWildcard(Generic wildcard) {
1475 return false;
1476 }
1477
1478 /**
1479 * {@inheritDoc}
1480 */
1481 public Boolean onParameterizedType(Generic parameterizedType) {
1482 return true;
1483 }
1484
1485 /**
1486 * {@inheritDoc}
1487 */
1488 public Boolean onTypeVariable(Generic typeVariable) {
1489 return acceptsVariable;
1490 }
1491
1492 /**
1493 * {@inheritDoc}
1494 */
1495 public Boolean onNonGenericType(Generic typeDescription) {
1496 return (acceptsArray || !typeDescription.isArray())
1497 && (acceptsPrimitive || !typeDescription.isPrimitive())
1498 && (acceptsVoid || !typeDescription.represents(void.class));
1499 }
1500
1501 /**
1502 * A type validator for checking type annotations.
1503 */
1504 public enum ForTypeAnnotations implements Visitor<Boolean> {
1505
1506 /**
1507 * The singleton instance.
1508 */
1509 INSTANCE;
1510
1511 /**
1512 * The {@link ElementType}'s {@code TYPE_USE} constant.
1513 */
1514 private final ElementType typeUse;
1515
1516 /**
1517 * The {@link ElementType}'s {@code TYPE_PARAMETER} constant.
1518 */
1519 private final ElementType typeParameter;
1520
1521 /**
1522 * Creates a new type annotation validator.
1523 */
1524 ForTypeAnnotations() {
1525 ElementType typeUse, typeParameter;
1526 try {
1527 typeUse = Enum.valueOf(ElementType.class, "TYPE_USE");
1528 typeParameter = Enum.valueOf(ElementType.class, "TYPE_PARAMETER");
1529 } catch (IllegalArgumentException ignored) {
1530 // Setting these values null results in this validator always failing for pre Java-8 VMs.
1531 typeUse = null;
1532 typeParameter = null;
1533 }
1534 this.typeUse = typeUse;
1535 this.typeParameter = typeParameter;
1536 }
1537
1538 /**
1539 * Validates the type annotations on a formal type variable but not on its bounds..
1540 *
1541 * @param typeVariable The type variable to validate.
1542 * @return {@code true} if the formal type variable declares invalid type annotations.
1543 */
1544 public static boolean ofFormalTypeVariable(Generic typeVariable) {
1545 Set<TypeDescription> annotationTypes = new HashSet<TypeDescription>();
1546 for (AnnotationDescription annotationDescription : typeVariable.getDeclaredAnnotations()) {
1547 if (!annotationDescription.getElementTypes().contains(INSTANCE.typeParameter) || !annotationTypes.add(annotationDescription.getAnnotationType())) {
1548 return false;
1549 }
1550 }
1551 return true;
1552 }
1553
1554 /**
1555 * {@inheritDoc}
1556 */
1557 public Boolean onGenericArray(Generic genericArray) {
1558 return isValid(genericArray) && genericArray.getComponentType().accept(this);
1559 }
1560
1561 /**
1562 * {@inheritDoc}
1563 */
1564 public Boolean onWildcard(Generic wildcard) {
1565 if (!isValid(wildcard)) {
1566 return false;
1567 }
1568 TypeList.Generic lowerBounds = wildcard.getLowerBounds();
1569 return (lowerBounds.isEmpty()
1570 ? wildcard.getUpperBounds()
1571 : lowerBounds).getOnly().accept(this);
1572 }
1573
1574 /**
1575 * {@inheritDoc}
1576 */
1577 public Boolean onParameterizedType(Generic parameterizedType) {
1578 if (!isValid(parameterizedType)) {
1579 return false;
1580 }
1581 Generic ownerType = parameterizedType.getOwnerType();
1582 if (ownerType != null && !ownerType.accept(this)) {
1583 return false;
1584 }
1585 for (Generic typeArgument : parameterizedType.getTypeArguments()) {
1586 if (!typeArgument.accept(this)) {
1587 return false;
1588 }
1589 }
1590 return true;
1591 }
1592
1593 /**
1594 * {@inheritDoc}
1595 */
1596 public Boolean onTypeVariable(Generic typeVariable) {
1597 return isValid(typeVariable);
1598 }
1599
1600 /**
1601 * {@inheritDoc}
1602 */
1603 public Boolean onNonGenericType(Generic typeDescription) {
1604 return isValid(typeDescription) && (!typeDescription.isArray() || typeDescription.getComponentType().accept(this));
1605 }
1606
1607 /**
1608 * Checks if the supplied type's type annotations are valid.
1609 *
1610 * @param typeDescription The type to validate.
1611 * @return {@code true} if the supplied type's type annotations are valid.
1612 */
1613 private boolean isValid(Generic typeDescription) {
1614 Set<TypeDescription> annotationTypes = new HashSet<TypeDescription>();
1615 for (AnnotationDescription annotationDescription : typeDescription.getDeclaredAnnotations()) {
1616 if (!annotationDescription.getElementTypes().contains(typeUse) || !annotationTypes.add(annotationDescription.getAnnotationType())) {
1617 return false;
1618 }
1619 }
1620 return true;
1621 }
1622 }
1623 }
1624
1625 /**
1626 * A visitor that reifies type descriptions if they represent raw types.
1627 */
1628 enum Reifying implements Visitor<Generic> {
1629
1630 /**
1631 * A visitor that reifies non-generic types if they represent raw types. This visitor should be applied when
1632 * visiting a potential raw type.
1633 */
1634 INITIATING {
1635 /** {@inheritDoc} */
1636 public Generic onParameterizedType(Generic parameterizedType) {
1637 return parameterizedType;
1638 }
1639 },
1640
1641 /**
1642 * A visitor that reifies non-generic types if they represent raw types or are parameterized types. This visitor
1643 * should only be applied when a type was inherited from a reified type.
1644 */
1645 INHERITING {
1646 /** {@inheritDoc} */
1647 public Generic onParameterizedType(Generic parameterizedType) {
1648 return new OfParameterizedType.ForReifiedType(parameterizedType);
1649 }
1650 };
1651
1652 /**
1653 * {@inheritDoc}
1654 */
1655 public Generic onGenericArray(Generic genericArray) {
1656 throw new IllegalArgumentException("Cannot reify a generic array: " + genericArray);
1657 }
1658
1659 /**
1660 * {@inheritDoc}
1661 */
1662 public Generic onWildcard(Generic wildcard) {
1663 throw new IllegalArgumentException("Cannot reify a wildcard: " + wildcard);
1664 }
1665
1666 /**
1667 * {@inheritDoc}
1668 */
1669 public Generic onTypeVariable(Generic typeVariable) {
1670 throw new IllegalArgumentException("Cannot reify a type variable: " + typeVariable);
1671 }
1672
1673 /**
1674 * {@inheritDoc}
1675 */
1676 public Generic onNonGenericType(Generic typeDescription) {
1677 TypeDescription erasure = typeDescription.asErasure();
1678 return erasure.isGenerified()
1679 ? new OfNonGenericType.ForReifiedErasure(erasure)
1680 : typeDescription;
1681 }
1682 }
1683
1684 /**
1685 * Visits a generic type and appends the discovered type to the supplied signature visitor.
1686 */
1687 @HashCodeAndEqualsPlugin.Enhance
1688 class ForSignatureVisitor implements Visitor<SignatureVisitor> {
1689
1690 /**
1691 * Index of a {@link String}'s only character to improve code readability.
1692 */
1693 private static final int ONLY_CHARACTER = 0;
1694
1695 /**
1696 * The signature visitor that receives the discovered generic type.
1697 */
1698 protected final SignatureVisitor signatureVisitor;
1699
1700 /**
1701 * Creates a new visitor for the given signature visitor.
1702 *
1703 * @param signatureVisitor The signature visitor that receives the discovered generic type.
1704 */
1705 public ForSignatureVisitor(SignatureVisitor signatureVisitor) {
1706 this.signatureVisitor = signatureVisitor;
1707 }
1708
1709 /**
1710 * {@inheritDoc}
1711 */
1712 public SignatureVisitor onGenericArray(Generic genericArray) {
1713 genericArray.getComponentType().accept(new ForSignatureVisitor(signatureVisitor.visitArrayType()));
1714 return signatureVisitor;
1715 }
1716
1717 /**
1718 * {@inheritDoc}
1719 */
1720 public SignatureVisitor onWildcard(Generic wildcard) {
1721 throw new IllegalStateException("Unexpected wildcard: " + wildcard);
1722 }
1723
1724 /**
1725 * {@inheritDoc}
1726 */
1727 public SignatureVisitor onParameterizedType(Generic parameterizedType) {
1728 onOwnableType(parameterizedType);
1729 signatureVisitor.visitEnd();
1730 return signatureVisitor;
1731 }
1732
1733 /**
1734 * Visits a type which might define an owner type.
1735 *
1736 * @param ownableType The visited generic type.
1737 */
1738 private void onOwnableType(Generic ownableType) {
1739 Generic ownerType = ownableType.getOwnerType();
1740 if (ownerType != null && ownerType.getSort().isParameterized()) {
1741 onOwnableType(ownerType);
1742 signatureVisitor.visitInnerClassType(ownableType.asErasure().getSimpleName());
1743 } else {
1744 signatureVisitor.visitClassType(ownableType.asErasure().getInternalName());
1745 }
1746 for (Generic typeArgument : ownableType.getTypeArguments()) {
1747 typeArgument.accept(new OfTypeArgument(signatureVisitor));
1748 }
1749 }
1750
1751 /**
1752 * {@inheritDoc}
1753 */
1754 public SignatureVisitor onTypeVariable(Generic typeVariable) {
1755 signatureVisitor.visitTypeVariable(typeVariable.getSymbol());
1756 return signatureVisitor;
1757 }
1758
1759 /**
1760 * {@inheritDoc}
1761 */
1762 public SignatureVisitor onNonGenericType(Generic typeDescription) {
1763 if (typeDescription.isArray()) {
1764 typeDescription.getComponentType().accept(new ForSignatureVisitor(signatureVisitor.visitArrayType()));
1765 } else if (typeDescription.isPrimitive()) {
1766 signatureVisitor.visitBaseType(typeDescription.asErasure().getDescriptor().charAt(ONLY_CHARACTER));
1767 } else {
1768 signatureVisitor.visitClassType(typeDescription.asErasure().getInternalName());
1769 signatureVisitor.visitEnd();
1770 }
1771 return signatureVisitor;
1772 }
1773
1774 /**
1775 * Visits a parameter while visiting a generic type for delegating discoveries to a signature visitor.
1776 */
1777 protected static class OfTypeArgument extends ForSignatureVisitor {
1778
1779 /**
1780 * Creates a new parameter visitor.
1781 *
1782 * @param signatureVisitor The signature visitor which is notified over visited types.
1783 */
1784 protected OfTypeArgument(SignatureVisitor signatureVisitor) {
1785 super(signatureVisitor);
1786 }
1787
1788 /**
1789 * {@inheritDoc}
1790 */
1791 public SignatureVisitor onWildcard(Generic wildcard) {
1792 TypeList.Generic upperBounds = wildcard.getUpperBounds(), lowerBounds = wildcard.getLowerBounds();
1793 if (lowerBounds.isEmpty() && upperBounds.getOnly().represents(Object.class)) {
1794 signatureVisitor.visitTypeArgument();
1795 } else if (!lowerBounds.isEmpty() /* && upperBounds.isEmpty() */) {
1796 lowerBounds.getOnly().accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.SUPER)));
1797 } else /* if (!upperBounds.isEmpty() && lowerBounds.isEmpty()) */ {
1798 upperBounds.getOnly().accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.EXTENDS)));
1799 }
1800 return signatureVisitor;
1801 }
1802
1803 /**
1804 * {@inheritDoc}
1805 */
1806 public SignatureVisitor onGenericArray(Generic genericArray) {
1807 genericArray.accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.INSTANCEOF)));
1808 return signatureVisitor;
1809 }
1810
1811 /**
1812 * {@inheritDoc}
1813 */
1814 public SignatureVisitor onParameterizedType(Generic parameterizedType) {
1815 parameterizedType.accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.INSTANCEOF)));
1816 return signatureVisitor;
1817 }
1818
1819 /**
1820 * {@inheritDoc}
1821 */
1822 public SignatureVisitor onTypeVariable(Generic typeVariable) {
1823 typeVariable.accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.INSTANCEOF)));
1824 return signatureVisitor;
1825 }
1826
1827 /**
1828 * {@inheritDoc}
1829 */
1830 public SignatureVisitor onNonGenericType(Generic typeDescription) {
1831 typeDescription.accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.INSTANCEOF)));
1832 return signatureVisitor;
1833 }
1834 }
1835 }
1836
1837 /**
1838 * An abstract implementation of a visitor that substitutes generic types by replacing (nested)
1839 * type variables and/or non-generic component types.
1840 */
1841 abstract class Substitutor implements Visitor<Generic> {
1842
1843 /**
1844 * {@inheritDoc}
1845 */
1846 public Generic onParameterizedType(Generic parameterizedType) {
1847 Generic ownerType = parameterizedType.getOwnerType();
1848 List<Generic> typeArguments = new ArrayList<Generic>(parameterizedType.getTypeArguments().size());
1849 for (Generic typeArgument : parameterizedType.getTypeArguments()) {
1850 typeArguments.add(typeArgument.accept(this));
1851 }
1852 return new OfParameterizedType.Latent(parameterizedType.asRawType().accept(this).asErasure(),
1853 ownerType == null
1854 ? UNDEFINED
1855 : ownerType.accept(this),
1856 typeArguments,
1857 parameterizedType);
1858 }
1859
1860 /**
1861 * {@inheritDoc}
1862 */
1863 public Generic onGenericArray(Generic genericArray) {
1864 return new OfGenericArray.Latent(genericArray.getComponentType().accept(this), genericArray);
1865 }
1866
1867 /**
1868 * {@inheritDoc}
1869 */
1870 public Generic onWildcard(Generic wildcard) {
1871 return new OfWildcardType.Latent(wildcard.getUpperBounds().accept(this), wildcard.getLowerBounds().accept(this), wildcard);
1872 }
1873
1874 /**
1875 * {@inheritDoc}
1876 */
1877 public Generic onNonGenericType(Generic typeDescription) {
1878 return typeDescription.isArray()
1879 ? new OfGenericArray.Latent(typeDescription.getComponentType().accept(this), typeDescription)
1880 : onSimpleType(typeDescription);
1881 }
1882
1883 /**
1884 * Visits a simple, non-generic type, i.e. either a component type of an array or a non-array type.
1885 *
1886 * @param typeDescription The type that is visited.
1887 * @return The substituted type.
1888 */
1889 protected abstract Generic onSimpleType(Generic typeDescription);
1890
1891 /**
1892 * A {@link Substitutor} that only substitutes type variables but fully preserves non-generic type definitions.
1893 */
1894 public abstract static class WithoutTypeSubstitution extends Substitutor {
1895
1896 /**
1897 * {@inheritDoc}
1898 */
1899 public Generic onNonGenericType(Generic typeDescription) {
1900 return typeDescription;
1901 }
1902
1903 @Override
1904 protected Generic onSimpleType(Generic typeDescription) {
1905 return typeDescription;
1906 }
1907 }
1908
1909 /**
1910 * A substitutor that attaches type variables to a type variable source and replaces representations of
1911 * {@link TargetType} with a given declaring type.
1912 */
1913 @HashCodeAndEqualsPlugin.Enhance
1914 public static class ForAttachment extends Substitutor {
1915
1916 /**
1917 * The declaring type which is filled in for {@link TargetType}.
1918 */
1919 private final TypeDescription declaringType;
1920
1921 /**
1922 * The source which is used for locating type variables.
1923 */
1924 private final TypeVariableSource typeVariableSource;
1925
1926 /**
1927 * Creates a visitor for attaching type variables.
1928 *
1929 * @param declaringType The declaring type which is filled in for {@link TargetType} in its erased form.
1930 * @param typeVariableSource The source which is used for locating type variables.
1931 */
1932 protected ForAttachment(TypeDefinition declaringType, TypeVariableSource typeVariableSource) {
1933 this(declaringType.asErasure(), typeVariableSource);
1934 }
1935
1936 /**
1937 * Creates a visitor for attaching type variables.
1938 *
1939 * @param declaringType The declaring type which is filled in for {@link TargetType}.
1940 * @param typeVariableSource The source which is used for locating type variables.
1941 */
1942 protected ForAttachment(TypeDescription declaringType, TypeVariableSource typeVariableSource) {
1943 this.declaringType = declaringType;
1944 this.typeVariableSource = typeVariableSource;
1945 }
1946
1947 /**
1948 * Attaches all types to the given type description.
1949 *
1950 * @param typeDescription The type description to which visited types should be attached to.
1951 * @return A substitutor that attaches visited types to the given type's type context.
1952 */
1953 public static ForAttachment of(TypeDescription typeDescription) {
1954 return new ForAttachment(typeDescription, typeDescription);
1955 }
1956
1957 /**
1958 * Attaches all types to the given field description.
1959 *
1960 * @param fieldDescription The field description to which visited types should be attached to.
1961 * @return A substitutor that attaches visited types to the given field's type context.
1962 */
1963 public static ForAttachment of(FieldDescription fieldDescription) {
1964 return new ForAttachment(fieldDescription.getDeclaringType(), fieldDescription.getDeclaringType().asErasure());
1965 }
1966
1967 /**
1968 * Attaches all types to the given method description.
1969 *
1970 * @param methodDescription The method description to which visited types should be attached to.
1971 * @return A substitutor that attaches visited types to the given method's type context.
1972 */
1973 public static ForAttachment of(MethodDescription methodDescription) {
1974 return new ForAttachment(methodDescription.getDeclaringType(), methodDescription);
1975 }
1976
1977 /**
1978 * Attaches all types to the given parameter description.
1979 *
1980 * @param parameterDescription The parameter description to which visited types should be attached to.
1981 * @return A substitutor that attaches visited types to the given parameter's type context.
1982 */
1983 public static ForAttachment of(ParameterDescription parameterDescription) {
1984 return new ForAttachment(parameterDescription.getDeclaringMethod().getDeclaringType(), parameterDescription.getDeclaringMethod());
1985 }
1986
1987 /**
1988 * Attaches all types to the given record component description.
1989 *
1990 * @param recordComponentDescription The record component description to which visited types should be attached to.
1991 * @return A substitutor that attaches visited types to the given record component's type context.
1992 */
1993 public static ForAttachment of(RecordComponentDescription recordComponentDescription) {
1994 return new ForAttachment(recordComponentDescription.getDeclaringType(), recordComponentDescription.getDeclaringType().asErasure());
1995 }
1996
1997 /**
1998 * {@inheritDoc}
1999 */
2000 public Generic onTypeVariable(Generic typeVariable) {
2001 Generic attachedVariable = typeVariableSource.findVariable(typeVariable.getSymbol());
2002 if (attachedVariable == null) {
2003 throw new IllegalArgumentException("Cannot attach undefined variable: " + typeVariable);
2004 } else {
2005 return new OfTypeVariable.WithAnnotationOverlay(attachedVariable, typeVariable);
2006 }
2007 }
2008
2009 @Override
2010 protected Generic onSimpleType(Generic typeDescription) {
2011 return typeDescription.represents(TargetType.class)
2012 ? new OfNonGenericType.Latent(declaringType, typeDescription)
2013 : typeDescription;
2014 }
2015 }
2016
2017 /**
2018 * A visitor for detaching a type from its declaration context by detaching type variables. This is achieved by
2019 * detaching type variables and by replacing the declaring type which is identified by a provided {@link ElementMatcher}
2020 * with {@link TargetType}.
2021 */
2022 @HashCodeAndEqualsPlugin.Enhance
2023 public static class ForDetachment extends Substitutor {
2024
2025 /**
2026 * A type matcher for identifying the declaring type.
2027 */
2028 private final ElementMatcher<? super TypeDescription> typeMatcher;
2029
2030 /**
2031 * Creates a visitor for detaching a type.
2032 *
2033 * @param typeMatcher A type matcher for identifying the declaring type.
2034 */
2035 public ForDetachment(ElementMatcher<? super TypeDescription> typeMatcher) {
2036 this.typeMatcher = typeMatcher;
2037 }
2038
2039 /**
2040 * Returns a new detachment visitor that detaches any type matching the supplied type description.
2041 *
2042 * @param typeDefinition The type to detach.
2043 * @return A detachment visitor for the supplied type description.
2044 */
2045 public static Visitor<Generic> of(TypeDefinition typeDefinition) {
2046 return new ForDetachment(is(typeDefinition));
2047 }
2048
2049 /**
2050 * {@inheritDoc}
2051 */
2052 public Generic onTypeVariable(Generic typeVariable) {
2053 return new OfTypeVariable.Symbolic(typeVariable.getSymbol(), typeVariable);
2054 }
2055
2056 @Override
2057 protected Generic onSimpleType(Generic typeDescription) {
2058 return typeMatcher.matches(typeDescription.asErasure())
2059 ? new OfNonGenericType.Latent(TargetType.DESCRIPTION, typeDescription.getOwnerType(), typeDescription)
2060 : typeDescription;
2061 }
2062 }
2063
2064 /**
2065 * A visitor for binding type variables to their values.
2066 */
2067 @HashCodeAndEqualsPlugin.Enhance
2068 public static class ForTypeVariableBinding extends WithoutTypeSubstitution {
2069
2070 /**
2071 * The parameterized type for which type variables are bound.
2072 */
2073 private final Generic parameterizedType;
2074
2075 /**
2076 * Creates a new visitor for binding a parameterized type's type arguments to its type variables.
2077 *
2078 * @param parameterizedType The parameterized type for which type variables are bound.
2079 */
2080 protected ForTypeVariableBinding(Generic parameterizedType) {
2081 this.parameterizedType = parameterizedType;
2082 }
2083
2084 /**
2085 * {@inheritDoc}
2086 */
2087 public Generic onTypeVariable(Generic typeVariable) {
2088 return typeVariable.getTypeVariableSource().accept(new TypeVariableSubstitutor(typeVariable));
2089 }
2090
2091 /**
2092 * Substitutes a type variable, either with a new binding if the variable is defined by a type or with a
2093 * retained type variable if the variable is defined by a method.
2094 */
2095 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
2096 protected class TypeVariableSubstitutor implements TypeVariableSource.Visitor<Generic> {
2097
2098 /**
2099 * The discovered type variable.
2100 */
2101 private final Generic typeVariable;
2102
2103 /**
2104 * Creates a new type variable substitutor.
2105 *
2106 * @param typeVariable The discovered type variable.
2107 */
2108 protected TypeVariableSubstitutor(Generic typeVariable) {
2109 this.typeVariable = typeVariable;
2110 }
2111
2112 /**
2113 * {@inheritDoc}
2114 */
2115 public Generic onType(TypeDescription typeDescription) {
2116 // A type variable might be undeclared due to breaking inner class semantics or due to incorrect scoping by a compiler.
2117 Generic typeArgument = parameterizedType.findBindingOf(typeVariable);
2118 return typeArgument == null
2119 ? typeVariable.asRawType()
2120 : typeArgument;
2121 }
2122
2123 /**
2124 * {@inheritDoc}
2125 */
2126 public Generic onMethod(MethodDescription.InDefinedShape methodDescription) {
2127 return new RetainedMethodTypeVariable(typeVariable);
2128 }
2129 }
2130
2131 /**
2132 * Implementation of a type variable on a method that is not substituted.
2133 */
2134 protected class RetainedMethodTypeVariable extends OfTypeVariable {
2135
2136 /**
2137 * The discovered type variable.
2138 */
2139 private final Generic typeVariable;
2140
2141 /**
2142 * Creates a new retained type variable.
2143 *
2144 * @param typeVariable The discovered type variable.
2145 */
2146 protected RetainedMethodTypeVariable(Generic typeVariable) {
2147 this.typeVariable = typeVariable;
2148 }
2149
2150 /**
2151 * {@inheritDoc}
2152 */
2153 public TypeList.Generic getUpperBounds() {
2154 return typeVariable.getUpperBounds().accept(ForTypeVariableBinding.this);
2155 }
2156
2157 /**
2158 * {@inheritDoc}
2159 */
2160 public TypeVariableSource getTypeVariableSource() {
2161 return typeVariable.getTypeVariableSource();
2162 }
2163
2164 /**
2165 * {@inheritDoc}
2166 */
2167 public String getSymbol() {
2168 return typeVariable.getSymbol();
2169 }
2170
2171 /**
2172 * {@inheritDoc}
2173 */
2174 public AnnotationList getDeclaredAnnotations() {
2175 return typeVariable.getDeclaredAnnotations();
2176 }
2177 }
2178 }
2179
2180 /**
2181 * A substitutor that normalizes a token to represent all {@link TargetType} by a given type and that symbolizes all type variables.
2182 */
2183 @HashCodeAndEqualsPlugin.Enhance
2184 public static class ForTokenNormalization extends Substitutor {
2185
2186 /**
2187 * The type description to substitute all {@link TargetType} representations with.
2188 */
2189 private final TypeDescription typeDescription;
2190
2191 /**
2192 * Creates a new token normalization visitor.
2193 *
2194 * @param typeDescription The type description to substitute all {@link TargetType}
2195 */
2196 public ForTokenNormalization(TypeDescription typeDescription) {
2197 this.typeDescription = typeDescription;
2198 }
2199
2200 @Override
2201 protected Generic onSimpleType(Generic typeDescription) {
2202 return typeDescription.represents(TargetType.class)
2203 ? new OfNonGenericType.Latent(this.typeDescription, typeDescription)
2204 : typeDescription;
2205 }
2206
2207 /**
2208 * {@inheritDoc}
2209 */
2210 public Generic onTypeVariable(Generic typeVariable) {
2211 return new OfTypeVariable.Symbolic(typeVariable.getSymbol(), typeVariable);
2212 }
2213 }
2214 }
2215
2216 /**
2217 * A visitor that transforms any type into a raw type if declaring type is generified. If the declaring type is
2218 * not generified, the original type description is returned.
2219 */
2220 class ForRawType implements Visitor<Generic> {
2221
2222 /**
2223 * The type description that is potentially a raw type.
2224 */
2225 private final TypeDescription declaringType;
2226
2227 /**
2228 * Creates a visitor for representing declared types of a potentially raw type.
2229 *
2230 * @param declaringType The type description that is potentially a raw type.
2231 */
2232 public ForRawType(TypeDescription declaringType) {
2233 this.declaringType = declaringType;
2234 }
2235
2236 /**
2237 * {@inheritDoc}
2238 */
2239 public Generic onGenericArray(Generic genericArray) {
2240 return declaringType.isGenerified()
2241 ? new Generic.OfNonGenericType.Latent(genericArray.asErasure(), genericArray)
2242 : genericArray;
2243 }
2244
2245 /**
2246 * {@inheritDoc}
2247 */
2248 public Generic onWildcard(Generic wildcard) {
2249 throw new IllegalStateException("Did not expect wildcard on top-level: " + wildcard);
2250 }
2251
2252 /**
2253 * {@inheritDoc}
2254 */
2255 public Generic onParameterizedType(Generic parameterizedType) {
2256 return declaringType.isGenerified()
2257 ? new Generic.OfNonGenericType.Latent(parameterizedType.asErasure(), parameterizedType)
2258 : parameterizedType;
2259 }
2260
2261 /**
2262 * {@inheritDoc}
2263 */
2264 public Generic onTypeVariable(Generic typeVariable) {
2265 return declaringType.isGenerified()
2266 ? new Generic.OfNonGenericType.Latent(typeVariable.asErasure(), typeVariable)
2267 : typeVariable;
2268 }
2269
2270 /**
2271 * {@inheritDoc}
2272 */
2273 public Generic onNonGenericType(Generic typeDescription) {
2274 return typeDescription;
2275 }
2276 }
2277
2278 /**
2279 * A visitor that reduces a detached generic type to its erasure.
2280 */
2281 @HashCodeAndEqualsPlugin.Enhance
2282 class Reducing implements Visitor<TypeDescription> {
2283
2284 /**
2285 * The generic type's declaring type.
2286 */
2287 private final TypeDescription declaringType;
2288
2289 /**
2290 * Any type variables that are directly declared by the member that declares the type being reduced.
2291 */
2292 private final List<? extends TypeVariableToken> typeVariableTokens;
2293
2294 /**
2295 * Creates a new reducing type visitor.
2296 *
2297 * @param declaringType The generic type's declaring type.
2298 * @param typeVariableToken Any type variables that are directly declared by the member that declares the type being reduced.
2299 */
2300 public Reducing(TypeDescription declaringType, TypeVariableToken... typeVariableToken) {
2301 this(declaringType, Arrays.asList(typeVariableToken));
2302 }
2303
2304 /**
2305 * Creates a new reducing type visitor.
2306 *
2307 * @param declaringType The generic type's declaring type.
2308 * @param typeVariableTokens Any type variables that are directly declared by the member that declares the type being reduced.
2309 */
2310 public Reducing(TypeDescription declaringType, List<? extends TypeVariableToken> typeVariableTokens) {
2311 this.declaringType = declaringType;
2312 this.typeVariableTokens = typeVariableTokens;
2313 }
2314
2315 /**
2316 * {@inheritDoc}
2317 */
2318 public TypeDescription onGenericArray(Generic genericArray) {
2319 Generic targetType = genericArray;
2320 int arity = 0;
2321 do {
2322 targetType = targetType.getComponentType();
2323 arity++;
2324 } while (targetType.isArray());
2325 return TargetType.resolve(targetType.getSort().isTypeVariable()
2326 ? TypeDescription.ArrayProjection.of(declaringType.findVariable(targetType.getSymbol()).asErasure(), arity)
2327 : genericArray.asErasure(), declaringType);
2328 }
2329
2330 /**
2331 * {@inheritDoc}
2332 */
2333 public TypeDescription onWildcard(Generic wildcard) {
2334 throw new IllegalStateException("A wildcard cannot be a top-level type: " + wildcard);
2335 }
2336
2337 /**
2338 * {@inheritDoc}
2339 */
2340 public TypeDescription onParameterizedType(Generic parameterizedType) {
2341 return TargetType.resolve(parameterizedType.asErasure(), declaringType);
2342 }
2343
2344 /**
2345 * {@inheritDoc}
2346 */
2347 public TypeDescription onTypeVariable(Generic typeVariable) {
2348 for (TypeVariableToken typeVariableToken : typeVariableTokens) {
2349 if (typeVariable.getSymbol().equals(typeVariableToken.getSymbol())) {
2350 return typeVariableToken.getBounds().get(0).accept(this);
2351 }
2352 }
2353 return TargetType.resolve(declaringType.findVariable(typeVariable.getSymbol()).asErasure(), declaringType);
2354 }
2355
2356 /**
2357 * {@inheritDoc}
2358 */
2359 public TypeDescription onNonGenericType(Generic typeDescription) {
2360 return TargetType.resolve(typeDescription.asErasure(), declaringType);
2361 }
2362 }
2363 }
2364
2365 /**
2366 * An annotation reader is responsible for lazily evaluating type annotations if this language
2367 * feature is available on the current JVM.
2368 */
2369 interface AnnotationReader {
2370
2371 /**
2372 * The dispatcher to use.
2373 */
2374 Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE);
2375
2376 /**
2377 * Resolves the underlying {@link AnnotatedElement}.
2378 *
2379 * @return The underlying annotated element.
2380 */
2381 AnnotatedElement resolve();
2382
2383 /**
2384 * Returns the underlying type annotations as a list.
2385 *
2386 * @return The underlying type annotations as a list.
2387 */
2388 AnnotationList asList();
2389
2390 /**
2391 * Returns a reader for type annotations of an represented element's wildcard upper bound.
2392 *
2393 * @param index The wildcard bound's index.
2394 * @return An annotation reader for the underlying annotated upper bound.
2395 */
2396 AnnotationReader ofWildcardUpperBoundType(int index);
2397
2398 /**
2399 * Returns a reader for type annotations of an represented element's wildcard lower bound.
2400 *
2401 * @param index The wildcard bound's index.
2402 * @return An annotation reader for the underlying annotated lower bound.
2403 */
2404 AnnotationReader ofWildcardLowerBoundType(int index);
2405
2406 /**
2407 * Returns a reader for type annotations of a type variable's bound.
2408 *
2409 * @param index The bound's index.
2410 * @return An annotation reader for the underlying annotated bound.
2411 */
2412 AnnotationReader ofTypeVariableBoundType(int index);
2413
2414 /**
2415 * Returns a reader for type annotations of a parameterized type's type argument.
2416 *
2417 * @param index The bound's index.
2418 * @return An annotation reader for the underlying annotated bound..
2419 */
2420 AnnotationReader ofTypeArgument(int index);
2421
2422 /**
2423 * <p>
2424 * Returns a reader for type annotations of a parameterized type's owner type.
2425 * </p>
2426 * <p>
2427 * <b>Important</b>: This feature is not currently implemented by the Java reflection API.
2428 * </p>
2429 *
2430 * @return An annotation reader for the underlying owner type.
2431 */
2432 AnnotationReader ofOwnerType();
2433
2434 /**
2435 * <p>
2436 * Returns a reader for type annotations of an inner class type's outer type.
2437 * </p>
2438 * <p>
2439 * <b>Important</b>: This feature is not currently implemented by the Java reflection API.
2440 * </p>
2441 *
2442 * @return An annotation reader for the underlying owner type.
2443 */
2444 AnnotationReader ofOuterClass();
2445
2446 /**
2447 * Returns a reader for type annotations of an array's component type.
2448 *
2449 * @return An annotation reader for the underlying component type.
2450 */
2451 AnnotationReader ofComponentType();
2452
2453 /**
2454 * A dispatcher that represents the type annotation API via reflective calls if the language feature is available on the current JVM.
2455 */
2456 interface Dispatcher {
2457
2458 /**
2459 * An empty array that can be used to indicate no arguments to avoid an allocation on a reflective call.
2460 */
2461 Object[] NO_ARGUMENTS = new Object[0];
2462
2463 /**
2464 * Resolves a formal type variable's type annotations.
2465 *
2466 * @param typeVariable The type variable to represent.
2467 * @return A suitable annotation reader.
2468 */
2469 AnnotationReader resolveTypeVariable(TypeVariable<?> typeVariable);
2470
2471 /**
2472 * Resolves a loaded type's super class's type annotations.
2473 *
2474 * @param type The type to represent.
2475 * @return A suitable annotation reader.
2476 */
2477 AnnotationReader resolveSuperClassType(Class<?> type);
2478
2479 /**
2480 * Resolves a loaded type's interface type's type annotations.
2481 *
2482 * @param type The type to represent.
2483 * @param index The index of the interface.
2484 * @return A suitable annotation reader.
2485 */
2486 AnnotationReader resolveInterfaceType(Class<?> type, int index);
2487
2488 /**
2489 * Resolves a loaded field's type's type annotations.
2490 *
2491 * @param field The field to represent.
2492 * @return A suitable annotation reader.
2493 */
2494 AnnotationReader resolveFieldType(Field field);
2495
2496 /**
2497 * Resolves a loaded method's return type's type annotations.
2498 *
2499 * @param method The method to represent.
2500 * @return A suitable annotation reader.
2501 */
2502 AnnotationReader resolveReturnType(Method method);
2503
2504 /**
2505 * Resolves a loaded executable's type argument type's type annotations.
2506 *
2507 * @param executable The executable to represent.
2508 * @param index The type argument's index.
2509 * @return A suitable annotation reader.
2510 */
2511 AnnotationReader resolveParameterType(AccessibleObject executable, int index);
2512
2513 /**
2514 * Resolves a loaded executable's exception type's type annotations.
2515 *
2516 * @param executable The executable to represent.
2517 * @param index The type argument's index.
2518 * @return A suitable annotation reader.
2519 */
2520 AnnotationReader resolveExceptionType(AccessibleObject executable, int index);
2521
2522 /**
2523 * Resolves a method's or constructor's receiver type. If receiver types are not available on the executing VM,
2524 * {@code null} is returned.
2525 *
2526 * @param executable The executable for which the receiver type should be resolved.
2527 * @return The executable's receiver type or {@code null}.
2528 */
2529 Generic resolveReceiverType(AccessibleObject executable);
2530
2531 /**
2532 * Resolves the annotated type as generic type description.
2533 *
2534 * @param annotatedType The loaded annotated type.
2535 * @return A description of the supplied annotated type.
2536 */
2537 Generic resolve(AnnotatedElement annotatedType);
2538
2539 /**
2540 * A creation action for a dispatcher.
2541 */
2542 enum CreationAction implements PrivilegedAction<Dispatcher> {
2543
2544 /**
2545 * The singleton instance.
2546 */
2547 INSTANCE;
2548
2549 /**
2550 * {@inheritDoc}
2551 */
2552 public Dispatcher run() {
2553 try {
2554 return new ForJava8CapableVm(Class.class.getMethod("getAnnotatedSuperclass"),
2555 Class.class.getMethod("getAnnotatedInterfaces"),
2556 Field.class.getMethod("getAnnotatedType"),
2557 Method.class.getMethod("getAnnotatedReturnType"),
2558 Class.forName("java.lang.reflect.Executable").getMethod("getAnnotatedParameterTypes"),
2559 Class.forName("java.lang.reflect.Executable").getMethod("getAnnotatedExceptionTypes"),
2560 Class.forName("java.lang.reflect.Executable").getMethod("getAnnotatedReceiverType"),
2561 Class.forName("java.lang.reflect.AnnotatedType").getMethod("getType"));
2562 } catch (RuntimeException exception) {
2563 throw exception;
2564 } catch (Exception ignored) {
2565 return Dispatcher.ForLegacyVm.INSTANCE;
2566 }
2567 }
2568 }
2569
2570 /**
2571 * A dispatcher for {@link AnnotationReader}s on a legacy VM that does not support type annotations.
2572 */
2573 enum ForLegacyVm implements Dispatcher {
2574
2575 /**
2576 * The singleton instance.
2577 */
2578 INSTANCE;
2579
2580 /**
2581 * {@inheritDoc}
2582 */
2583 public AnnotationReader resolveTypeVariable(TypeVariable<?> typeVariable) {
2584 return NoOp.INSTANCE;
2585 }
2586
2587 /**
2588 * {@inheritDoc}
2589 */
2590 public AnnotationReader resolveSuperClassType(Class<?> type) {
2591 return NoOp.INSTANCE;
2592 }
2593
2594 /**
2595 * {@inheritDoc}
2596 */
2597 public AnnotationReader resolveInterfaceType(Class<?> type, int index) {
2598 return NoOp.INSTANCE;
2599 }
2600
2601 /**
2602 * {@inheritDoc}
2603 */
2604 public AnnotationReader resolveFieldType(Field field) {
2605 return NoOp.INSTANCE;
2606 }
2607
2608 /**
2609 * {@inheritDoc}
2610 */
2611 public AnnotationReader resolveReturnType(Method method) {
2612 return NoOp.INSTANCE;
2613 }
2614
2615 /**
2616 * {@inheritDoc}
2617 */
2618 public AnnotationReader resolveParameterType(AccessibleObject executable, int index) {
2619 return NoOp.INSTANCE;
2620 }
2621
2622 /**
2623 * {@inheritDoc}
2624 */
2625 public AnnotationReader resolveExceptionType(AccessibleObject executable, int index) {
2626 return NoOp.INSTANCE;
2627 }
2628
2629 /**
2630 * {@inheritDoc}
2631 */
2632 public Generic resolveReceiverType(AccessibleObject executable) {
2633 return UNDEFINED;
2634 }
2635
2636 /**
2637 * {@inheritDoc}
2638 */
2639 public Generic resolve(AnnotatedElement annotatedType) {
2640 throw new UnsupportedOperationException("Loaded annotated type cannot be represented on this VM");
2641 }
2642 }
2643
2644 /**
2645 * A dispatcher for a modern JVM that supports type annotations.
2646 */
2647 @HashCodeAndEqualsPlugin.Enhance
2648 class ForJava8CapableVm implements Dispatcher {
2649
2650 /**
2651 * The {@code java.lang.Class#getAnnotatedSuperclass} method.
2652 */
2653 private final Method getAnnotatedSuperclass;
2654
2655 /**
2656 * The {@code java.lang.Class#getAnnotatedInterfaces} method.
2657 */
2658 private final Method getAnnotatedInterfaces;
2659
2660 /**
2661 * The {@code java.lang.reflect.Field#getAnnotatedType} method.
2662 */
2663 private final Method getAnnotatedType;
2664
2665 /**
2666 * The {@code java.lang.reflect.Method#getAnnotatedReturnType} method.
2667 */
2668 private final Method getAnnotatedReturnType;
2669
2670 /**
2671 * The {@code java.lang.reflect.Executable#getAnnotatedParameterTypes} method.
2672 */
2673 private final Method getAnnotatedParameterTypes;
2674
2675 /**
2676 * The {@code java.lang.reflect.Executable#getAnnotatedExceptionTypes} method.
2677 */
2678 private final Method getAnnotatedExceptionTypes;
2679
2680 /**
2681 * The {@code java.lang.reflect.Executable#getAnnotatedReceiverType} method.
2682 */
2683 private final Method getAnnotatedReceiverType;
2684
2685 /**
2686 * The {@code java.lang.reflect.AnnotatedType#getType} method.
2687 */
2688 private final Method getType;
2689
2690 /**
2691 * Creates a new dispatcher for a VM that supports type annotations.
2692 *
2693 * @param getAnnotatedSuperclass The {@code java.lang.Class#getAnnotatedSuperclass} method.
2694 * @param getAnnotatedInterfaces The {@code java.lang.Class#getAnnotatedInterfaces} method.
2695 * @param getAnnotatedType The {@code java.lang.reflect.Field#getAnnotatedType} method.
2696 * @param getAnnotatedReturnType The {@code java.lang.reflect.Method#getAnnotatedReturnType} method.
2697 * @param getAnnotatedParameterTypes The {@code java.lang.reflect.Executable#getAnnotatedParameterTypes} method.
2698 * @param getAnnotatedExceptionTypes The {@code java.lang.reflect.Executable#getAnnotatedExceptionTypes} method.
2699 * @param getAnnotatedReceiverType The {@code java.lang.reflect.Executable#getAnnotatedReceiverType} method.
2700 * @param getType The {@code java.lang.reflect.AnnotatedType#getType} method.
2701 */
2702 protected ForJava8CapableVm(Method getAnnotatedSuperclass,
2703 Method getAnnotatedInterfaces,
2704 Method getAnnotatedType,
2705 Method getAnnotatedReturnType,
2706 Method getAnnotatedParameterTypes,
2707 Method getAnnotatedExceptionTypes,
2708 Method getAnnotatedReceiverType,
2709 Method getType) {
2710 this.getAnnotatedSuperclass = getAnnotatedSuperclass;
2711 this.getAnnotatedInterfaces = getAnnotatedInterfaces;
2712 this.getAnnotatedType = getAnnotatedType;
2713 this.getAnnotatedReturnType = getAnnotatedReturnType;
2714 this.getAnnotatedParameterTypes = getAnnotatedParameterTypes;
2715 this.getAnnotatedExceptionTypes = getAnnotatedExceptionTypes;
2716 this.getAnnotatedReceiverType = getAnnotatedReceiverType;
2717 this.getType = getType;
2718 }
2719
2720 /**
2721 * {@inheritDoc}
2722 */
2723 public AnnotationReader resolveTypeVariable(TypeVariable<?> typeVariable) {
2724 return new AnnotatedTypeVariableType(typeVariable);
2725 }
2726
2727 /**
2728 * {@inheritDoc}
2729 */
2730 public AnnotationReader resolveSuperClassType(Class<?> type) {
2731 return new AnnotatedSuperClass(type);
2732 }
2733
2734 /**
2735 * {@inheritDoc}
2736 */
2737 public AnnotationReader resolveInterfaceType(Class<?> type, int index) {
2738 return new AnnotatedInterfaceType(type, index);
2739 }
2740
2741 /**
2742 * {@inheritDoc}
2743 */
2744 public AnnotationReader resolveFieldType(Field field) {
2745 return new AnnotatedFieldType(field);
2746 }
2747
2748 /**
2749 * {@inheritDoc}
2750 */
2751 public AnnotationReader resolveReturnType(Method method) {
2752 return new AnnotatedReturnType(method);
2753 }
2754
2755 /**
2756 * {@inheritDoc}
2757 */
2758 public AnnotationReader resolveParameterType(AccessibleObject executable, int index) {
2759 return new AnnotatedParameterizedType(executable, index);
2760 }
2761
2762 /**
2763 * {@inheritDoc}
2764 */
2765 public AnnotationReader resolveExceptionType(AccessibleObject executable, int index) {
2766 return new AnnotatedExceptionType(executable, index);
2767 }
2768
2769 /**
2770 * {@inheritDoc}
2771 */
2772 public Generic resolveReceiverType(AccessibleObject executable) {
2773 try {
2774 return resolve((AnnotatedElement) getAnnotatedReceiverType.invoke(executable, NO_ARGUMENTS));
2775 } catch (IllegalAccessException exception) {
2776 throw new IllegalStateException("Cannot access java.lang.reflect.Executable#getAnnotatedReceiverType", exception);
2777 } catch (InvocationTargetException exception) {
2778 throw new IllegalStateException("Error invoking java.lang.reflect.Executable#getAnnotatedReceiverType", exception.getCause());
2779 }
2780 }
2781
2782 /**
2783 * {@inheritDoc}
2784 */
2785 public Generic resolve(AnnotatedElement annotatedType) {
2786 try {
2787 return annotatedType == null
2788 ? UNDEFINED
2789 : Sort.describe((java.lang.reflect.Type) getType.invoke(annotatedType, NO_ARGUMENTS), new Resolved(annotatedType));
2790 } catch (IllegalAccessException exception) {
2791 throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedType#getType", exception);
2792 } catch (InvocationTargetException exception) {
2793 throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedType#getType", exception.getCause());
2794 }
2795 }
2796
2797 /**
2798 * A delegator for an existing {@code java.lang.reflect.AnnotatedElement}.
2799 */
2800 @HashCodeAndEqualsPlugin.Enhance
2801 protected static class Resolved extends Delegator {
2802
2803 /**
2804 * The represented annotated element.
2805 */
2806 private final AnnotatedElement annotatedElement;
2807
2808 /**
2809 * Creates a new resolved delegator.
2810 *
2811 * @param annotatedElement The represented annotated element.
2812 */
2813 protected Resolved(AnnotatedElement annotatedElement) {
2814 this.annotatedElement = annotatedElement;
2815 }
2816
2817 /**
2818 * {@inheritDoc}
2819 */
2820 public AnnotatedElement resolve() {
2821 return annotatedElement;
2822 }
2823 }
2824
2825 /**
2826 * A delegating annotation reader for an annotated type variable.
2827 */
2828 @HashCodeAndEqualsPlugin.Enhance
2829 protected static class AnnotatedTypeVariableType extends Delegator {
2830
2831 /**
2832 * The represented type variable.
2833 */
2834 private final TypeVariable<?> typeVariable;
2835
2836 /**
2837 * Creates a new annotation reader for the given type variable.
2838 *
2839 * @param typeVariable The represented type variable.
2840 */
2841 protected AnnotatedTypeVariableType(TypeVariable<?> typeVariable) {
2842 this.typeVariable = typeVariable;
2843 }
2844
2845 /**
2846 * {@inheritDoc}
2847 */
2848 public AnnotatedElement resolve() {
2849 return (AnnotatedElement) typeVariable;
2850 }
2851
2852 /**
2853 * {@inheritDoc}
2854 */
2855 public AnnotationReader ofTypeVariableBoundType(int index) {
2856 return new ForTypeVariableBoundType.OfFormalTypeVariable(typeVariable, index);
2857 }
2858 }
2859
2860 /**
2861 * A delegating annotation reader for an annotated super type.
2862 */
2863 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
2864 protected class AnnotatedSuperClass extends Delegator {
2865
2866 /**
2867 * The represented type.
2868 */
2869 private final Class<?> type;
2870
2871 /**
2872 * Creates a new annotation reader for an annotated super type.
2873 *
2874 * @param type The represented type.
2875 */
2876 protected AnnotatedSuperClass(Class<?> type) {
2877 this.type = type;
2878 }
2879
2880 /**
2881 * {@inheritDoc}
2882 */
2883 public AnnotatedElement resolve() {
2884 try {
2885 return (AnnotatedElement) getAnnotatedSuperclass.invoke(type, NO_ARGUMENTS);
2886 } catch (IllegalAccessException exception) {
2887 throw new IllegalStateException("Cannot access java.lang.Class#getAnnotatedSuperclass", exception);
2888 } catch (InvocationTargetException exception) {
2889 throw new IllegalStateException("Error invoking java.lang.Class#getAnnotatedSuperclass", exception.getCause());
2890 }
2891 }
2892 }
2893
2894 /**
2895 * A delegating annotation reader for an annotated interface type.
2896 */
2897 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
2898 protected class AnnotatedInterfaceType extends Delegator {
2899
2900 /**
2901 * The represented interface type.
2902 */
2903 private final Class<?> type;
2904
2905 /**
2906 * The interface type's index.
2907 */
2908 private final int index;
2909
2910 /**
2911 * Creates a new annotation reader for an annotated interface type.
2912 *
2913 * @param type The represented interface type.
2914 * @param index The interface type's index.
2915 */
2916 protected AnnotatedInterfaceType(Class<?> type, int index) {
2917 this.type = type;
2918 this.index = index;
2919 }
2920
2921 /**
2922 * {@inheritDoc}
2923 */
2924 public AnnotatedElement resolve() {
2925 try {
2926 return (AnnotatedElement) Array.get(getAnnotatedInterfaces.invoke(type), index);
2927 } catch (IllegalAccessException exception) {
2928 throw new IllegalStateException("Cannot access java.lang.Class#getAnnotatedInterfaces", exception);
2929 } catch (InvocationTargetException exception) {
2930 throw new IllegalStateException("Error invoking java.lang.Class#getAnnotatedInterfaces", exception.getCause());
2931 }
2932 }
2933 }
2934
2935 /**
2936 * A delegating annotation reader for an annotated field variable.
2937 */
2938 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
2939 protected class AnnotatedFieldType extends Delegator {
2940
2941 /**
2942 * The represented field.
2943 */
2944 private final Field field;
2945
2946 /**
2947 * Creates a new annotation reader for an annotated field type.
2948 *
2949 * @param field The represented field.
2950 */
2951 protected AnnotatedFieldType(Field field) {
2952 this.field = field;
2953 }
2954
2955 /**
2956 * {@inheritDoc}
2957 */
2958 public AnnotatedElement resolve() {
2959 try {
2960 return (AnnotatedElement) getAnnotatedType.invoke(field, NO_ARGUMENTS);
2961 } catch (IllegalAccessException exception) {
2962 throw new IllegalStateException("Cannot access java.lang.reflect.Field#getAnnotatedType", exception);
2963 } catch (InvocationTargetException exception) {
2964 throw new IllegalStateException("Error invoking java.lang.reflect.Field#getAnnotatedType", exception.getCause());
2965 }
2966 }
2967 }
2968
2969 /**
2970 * A delegating annotation reader for an annotated return variable.
2971 */
2972 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
2973 protected class AnnotatedReturnType extends Delegator {
2974
2975 /**
2976 * The represented method.
2977 */
2978 private final Method method;
2979
2980 /**
2981 * Creates a new annotation reader for an annotated return type.
2982 *
2983 * @param method The represented method.
2984 */
2985 protected AnnotatedReturnType(Method method) {
2986 this.method = method;
2987 }
2988
2989 /**
2990 * {@inheritDoc}
2991 */
2992 public AnnotatedElement resolve() {
2993 try {
2994 return (AnnotatedElement) getAnnotatedReturnType.invoke(method, NO_ARGUMENTS);
2995 } catch (IllegalAccessException exception) {
2996 throw new IllegalStateException("Cannot access java.lang.reflect.Method#getAnnotatedReturnType", exception);
2997 } catch (InvocationTargetException exception) {
2998 throw new IllegalStateException("Error invoking java.lang.reflect.Method#getAnnotatedReturnType", exception.getCause());
2999 }
3000 }
3001 }
3002
3003 /**
3004 * A delegating annotation reader for an annotated parameter variable.
3005 */
3006 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
3007 protected class AnnotatedParameterizedType extends Delegator {
3008
3009 /**
3010 * The represented executable.
3011 */
3012 private final AccessibleObject executable;
3013
3014 /**
3015 * The type argument's index.
3016 */
3017 private final int index;
3018
3019 /**
3020 * Creates a new annotation reader for an annotated type argument type.
3021 *
3022 * @param executable The represented executable.
3023 * @param index The type argument's index.
3024 */
3025 protected AnnotatedParameterizedType(AccessibleObject executable, int index) {
3026 this.executable = executable;
3027 this.index = index;
3028 }
3029
3030 /**
3031 * {@inheritDoc}
3032 */
3033 public AnnotatedElement resolve() {
3034 try {
3035 return (AnnotatedElement) Array.get(getAnnotatedParameterTypes.invoke(executable, NO_ARGUMENTS), index);
3036 } catch (IllegalAccessException exception) {
3037 throw new IllegalStateException("Cannot access java.lang.reflect.Executable#getAnnotatedParameterTypes", exception);
3038 } catch (InvocationTargetException exception) {
3039 throw new IllegalStateException("Error invoking java.lang.reflect.Executable#getAnnotatedParameterTypes", exception.getCause());
3040 }
3041 }
3042 }
3043
3044 /**
3045 * A delegating annotation reader for an annotated exception variable.
3046 */
3047 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
3048 protected class AnnotatedExceptionType extends Delegator {
3049
3050 /**
3051 * The represented executable.
3052 */
3053 private final AccessibleObject executable;
3054
3055 /**
3056 * The exception type's index.
3057 */
3058 private final int index;
3059
3060 /**
3061 * Creates a new annotation reader for an annotated exception type.
3062 *
3063 * @param executable The represented executable.
3064 * @param index The exception type's index.
3065 */
3066 protected AnnotatedExceptionType(AccessibleObject executable, int index) {
3067 this.executable = executable;
3068 this.index = index;
3069 }
3070
3071 /**
3072 * {@inheritDoc}
3073 */
3074 public AnnotatedElement resolve() {
3075 try {
3076 return (AnnotatedElement) Array.get(getAnnotatedExceptionTypes.invoke(executable, NO_ARGUMENTS), index);
3077 } catch (IllegalAccessException exception) {
3078 throw new IllegalStateException("Cannot access java.lang.reflect.Executable#getAnnotatedExceptionTypes", exception);
3079 } catch (InvocationTargetException exception) {
3080 throw new IllegalStateException("Error invoking java.lang.reflect.Executable#getAnnotatedExceptionTypes", exception.getCause());
3081 }
3082 }
3083 }
3084 }
3085 }
3086
3087 /**
3088 * A non-operational annotation reader.
3089 */
3090 enum NoOp implements AnnotationReader, AnnotatedElement {
3091
3092 /**
3093 * The singleton instance.
3094 */
3095 INSTANCE;
3096
3097 /**
3098 * {@inheritDoc}
3099 */
3100 public AnnotatedElement resolve() {
3101 return this;
3102 }
3103
3104 /**
3105 * {@inheritDoc}
3106 */
3107 public AnnotationList asList() {
3108 return new AnnotationList.Empty();
3109 }
3110
3111 /**
3112 * {@inheritDoc}
3113 */
3114 public AnnotationReader ofWildcardUpperBoundType(int index) {
3115 return this;
3116 }
3117
3118 /**
3119 * {@inheritDoc}
3120 */
3121 public AnnotationReader ofWildcardLowerBoundType(int index) {
3122 return this;
3123 }
3124
3125 /**
3126 * {@inheritDoc}
3127 */
3128 public AnnotationReader ofTypeVariableBoundType(int index) {
3129 return this;
3130 }
3131
3132 /**
3133 * {@inheritDoc}
3134 */
3135 public AnnotationReader ofTypeArgument(int index) {
3136 return this;
3137 }
3138
3139 /**
3140 * {@inheritDoc}
3141 */
3142 public AnnotationReader ofOwnerType() {
3143 return this;
3144 }
3145
3146 /**
3147 * {@inheritDoc}
3148 */
3149 public AnnotationReader ofOuterClass() {
3150 return this;
3151 }
3152
3153 /**
3154 * {@inheritDoc}
3155 */
3156 public AnnotationReader ofComponentType() {
3157 return this;
3158 }
3159
3160 /**
3161 * {@inheritDoc}
3162 */
3163 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
3164 throw new IllegalStateException("Cannot resolve annotations for no-op reader: " + this);
3165 }
3166
3167 /**
3168 * {@inheritDoc}
3169 */
3170 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
3171 throw new IllegalStateException("Cannot resolve annotations for no-op reader: " + this);
3172 }
3173
3174 /**
3175 * {@inheritDoc}
3176 */
3177 public Annotation[] getAnnotations() {
3178 throw new IllegalStateException("Cannot resolve annotations for no-op reader: " + this);
3179 }
3180
3181 /**
3182 * {@inheritDoc}
3183 */
3184 public Annotation[] getDeclaredAnnotations() {
3185 return new Annotation[0];
3186 }
3187 }
3188
3189 /**
3190 * A delegating annotation reader that delegates all invocations to an annotation reader that wraps the previous one.
3191 */
3192 abstract class Delegator implements AnnotationReader {
3193
3194 /**
3195 * An empty array that can be used to indicate no arguments to avoid an allocation on a reflective call.
3196 */
3197 protected static final Object[] NO_ARGUMENTS = new Object[0];
3198
3199 /**
3200 * {@inheritDoc}
3201 */
3202 public AnnotationReader ofWildcardUpperBoundType(int index) {
3203 return new ForWildcardUpperBoundType(this, index);
3204 }
3205
3206 /**
3207 * {@inheritDoc}
3208 */
3209 public AnnotationReader ofWildcardLowerBoundType(int index) {
3210 return new ForWildcardLowerBoundType(this, index);
3211 }
3212
3213 /**
3214 * {@inheritDoc}
3215 */
3216 public AnnotationReader ofTypeVariableBoundType(int index) {
3217 return new ForTypeVariableBoundType(this, index);
3218 }
3219
3220 /**
3221 * {@inheritDoc}
3222 */
3223 public AnnotationReader ofTypeArgument(int index) {
3224 return new ForTypeArgument(this, index);
3225 }
3226
3227 /**
3228 * {@inheritDoc}
3229 */
3230 public AnnotationReader ofOwnerType() {
3231 return ForOwnerType.of(this);
3232 }
3233
3234 /**
3235 * {@inheritDoc}
3236 */
3237 public AnnotationReader ofOuterClass() {
3238 return ForOwnerType.of(this);
3239 }
3240
3241 /**
3242 * {@inheritDoc}
3243 */
3244 public AnnotationReader ofComponentType() {
3245 return new ForComponentType(this);
3246 }
3247
3248 /**
3249 * {@inheritDoc}
3250 */
3251 public AnnotationList asList() {
3252 return new AnnotationList.ForLoadedAnnotations(resolve().getDeclaredAnnotations());
3253 }
3254
3255 /**
3256 * A chained delegator that bases its result on an underlying annotation reader.
3257 */
3258 @HashCodeAndEqualsPlugin.Enhance
3259 protected abstract static class Chained extends Delegator {
3260
3261 /**
3262 * Indicates that a method is not available on the current VM.
3263 */
3264 protected static final Method NOT_AVAILABLE = null;
3265
3266 /**
3267 * The underlying annotation reader.
3268 */
3269 protected final AnnotationReader annotationReader;
3270
3271 /**
3272 * Creates a new chained annotation reader.
3273 *
3274 * @param annotationReader The underlying annotation reader.
3275 */
3276 protected Chained(AnnotationReader annotationReader) {
3277 this.annotationReader = annotationReader;
3278 }
3279
3280 /**
3281 * Resolves the method to invoke or returns {@code null} if the method does not exist on the current VM.
3282 *
3283 * @param typeName The declaring type's name.
3284 * @param methodName The method's name.
3285 * @return The resolved method or {@code null}.
3286 */
3287 @SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception should not be rethrown but trigger a fallback")
3288 protected static Method of(String typeName, String methodName) {
3289 try {
3290 return Class.forName(typeName).getMethod(methodName);
3291 } catch (Exception exception) {
3292 return NOT_AVAILABLE;
3293 }
3294 }
3295
3296 /**
3297 * {@inheritDoc}
3298 */
3299 public AnnotatedElement resolve() {
3300 return resolve(annotationReader.resolve());
3301 }
3302
3303 /**
3304 * Resolves the type annotations from a given annotated element into the annotated element that this instance represents.
3305 *
3306 * @param annotatedElement The original annotated element.
3307 * @return The resolved annotated element.
3308 */
3309 protected abstract AnnotatedElement resolve(AnnotatedElement annotatedElement);
3310 }
3311
3312 /**
3313 * An annotation reader for a {@code java.lang.reflect.RecordComponent}.
3314 */
3315 protected static class ForRecordComponent extends Delegator {
3316
3317 /**
3318 * The represented {@code java.lang.reflect.RecordComponent}.
3319 */
3320 private final Object recordComponent;
3321
3322 /**
3323 * Creates a new annotation reader for a {@code java.lang.reflect.RecordComponent}.
3324 *
3325 * @param recordComponent The represented {@code java.lang.reflect.RecordComponent}.
3326 */
3327 protected ForRecordComponent(Object recordComponent) {
3328 this.recordComponent = recordComponent;
3329 }
3330
3331 /**
3332 * {@inheritDoc}
3333 */
3334 public AnnotatedElement resolve() {
3335 return RecordComponentDescription.ForLoadedRecordComponent.DISPATCHER.getAnnotatedType(recordComponent);
3336 }
3337 }
3338 }
3339
3340 /**
3341 * A chained annotation reader for reading a wildcard type's upper bound type.
3342 */
3343 @HashCodeAndEqualsPlugin.Enhance
3344 class ForWildcardUpperBoundType extends Delegator.Chained {
3345
3346 /**
3347 * The {@code java.lang.reflect.AnnotatedWildcardType#getAnnotatedUpperBounds} method.
3348 */
3349 private static final Method GET_ANNOTATED_UPPER_BOUNDS = of("java.lang.reflect.AnnotatedWildcardType", "getAnnotatedUpperBounds");
3350
3351 /**
3352 * The wildcard bound's index.
3353 */
3354 private final int index;
3355
3356 /**
3357 * Creates a chained annotation reader for reading a upper-bound wildcard's bound type.
3358 *
3359 * @param annotationReader The annotation reader from which to delegate.
3360 * @param index The wildcard bound's index.
3361 */
3362 protected ForWildcardUpperBoundType(AnnotationReader annotationReader, int index) {
3363 super(annotationReader);
3364 this.index = index;
3365 }
3366
3367 @Override
3368 protected AnnotatedElement resolve(AnnotatedElement annotatedElement) {
3369 if (!GET_ANNOTATED_UPPER_BOUNDS.getDeclaringClass().isInstance(annotatedElement)) { // Avoid problem with Kotlin compiler.
3370 return NoOp.INSTANCE;
3371 }
3372 try {
3373 Object annotatedUpperBounds = GET_ANNOTATED_UPPER_BOUNDS.invoke(annotatedElement, NO_ARGUMENTS);
3374 return Array.getLength(annotatedUpperBounds) == 0 // Wildcards with a lower bound do not define annotations for their implicit upper bound.
3375 ? NoOp.INSTANCE
3376 : (AnnotatedElement) Array.get(annotatedUpperBounds, index);
3377 } catch (ClassCastException ignored) { // To avoid bug on early releases of Java 8.
3378 return NoOp.INSTANCE;
3379 } catch (IllegalAccessException exception) {
3380 throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedWildcardType#getAnnotatedUpperBounds", exception);
3381 } catch (InvocationTargetException exception) {
3382 throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedWildcardType#getAnnotatedUpperBounds", exception.getCause());
3383 }
3384 }
3385 }
3386
3387 /**
3388 * A chained annotation reader for reading a wildcard type's lower bound type.
3389 */
3390 @HashCodeAndEqualsPlugin.Enhance
3391 class ForWildcardLowerBoundType extends Delegator.Chained {
3392
3393 /**
3394 * The {@code java.lang.reflect.AnnotatedWildcardType#getAnnotatedLowerBounds} method.
3395 */
3396 private static final Method GET_ANNOTATED_LOWER_BOUNDS = of("java.lang.reflect.AnnotatedWildcardType", "getAnnotatedLowerBounds");
3397
3398 /**
3399 * The wildcard bound's index.
3400 */
3401 private final int index;
3402
3403 /**
3404 * Creates a chained annotation reader for reading a lower-bound wildcard's bound type.
3405 *
3406 * @param annotationReader The annotation reader from which to delegate.
3407 * @param index The wildcard bound's index.
3408 */
3409 protected ForWildcardLowerBoundType(AnnotationReader annotationReader, int index) {
3410 super(annotationReader);
3411 this.index = index;
3412 }
3413
3414 @Override
3415 protected AnnotatedElement resolve(AnnotatedElement annotatedElement) {
3416 if (!GET_ANNOTATED_LOWER_BOUNDS.getDeclaringClass().isInstance(annotatedElement)) { // Avoid problem with Kotlin compiler.
3417 return NoOp.INSTANCE;
3418 }
3419 try {
3420 return (AnnotatedElement) Array.get(GET_ANNOTATED_LOWER_BOUNDS.invoke(annotatedElement, NO_ARGUMENTS), index);
3421 } catch (ClassCastException ignored) { // To avoid bug on early releases of Java 8.
3422 return NoOp.INSTANCE;
3423 } catch (IllegalAccessException exception) {
3424 throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedWildcardType#getAnnotatedLowerBounds", exception);
3425 } catch (InvocationTargetException exception) {
3426 throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedWildcardType#getAnnotatedLowerBounds", exception.getCause());
3427 }
3428 }
3429 }
3430
3431 /**
3432 * A chained annotation reader for reading a type variable's type argument.
3433 */
3434 @HashCodeAndEqualsPlugin.Enhance
3435 class ForTypeVariableBoundType extends Delegator.Chained {
3436
3437 /**
3438 * The {@code java.lang.reflect.AnnotatedTypeVariable#getAnnotatedBounds} method.
3439 */
3440 private static final Method GET_ANNOTATED_BOUNDS = of("java.lang.reflect.AnnotatedTypeVariable", "getAnnotatedBounds");
3441
3442 /**
3443 * The type variable's index.
3444 */
3445 private final int index;
3446
3447 /**
3448 * Creates a chained annotation reader for reading a type variable's bound type.
3449 *
3450 * @param annotationReader The annotation reader from which to delegate.
3451 * @param index The type variable's index.
3452 */
3453 protected ForTypeVariableBoundType(AnnotationReader annotationReader, int index) {
3454 super(annotationReader);
3455 this.index = index;
3456 }
3457
3458 @Override
3459 protected AnnotatedElement resolve(AnnotatedElement annotatedElement) {
3460 if (!GET_ANNOTATED_BOUNDS.getDeclaringClass().isInstance(annotatedElement)) { // Avoid problem with Kotlin compiler.
3461 return NoOp.INSTANCE;
3462 }
3463 try {
3464 return (AnnotatedElement) Array.get(GET_ANNOTATED_BOUNDS.invoke(annotatedElement, NO_ARGUMENTS), index);
3465 } catch (ClassCastException ignored) { // To avoid bug on early releases of Java 8.
3466 return NoOp.INSTANCE;
3467 } catch (IllegalAccessException exception) {
3468 throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedTypeVariable#getAnnotatedBounds", exception);
3469 } catch (InvocationTargetException exception) {
3470 throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedTypeVariable#getAnnotatedBounds", exception.getCause());
3471 }
3472 }
3473
3474 /**
3475 * A chained annotation reader for reading a formal type variable's type argument.
3476 */
3477 @HashCodeAndEqualsPlugin.Enhance
3478 protected static class OfFormalTypeVariable extends Delegator {
3479
3480 /**
3481 * The {@code java.lang.reflect.TypeVariable#getAnnotatedBounds} method.
3482 */
3483 private static final Method GET_ANNOTATED_BOUNDS = of(TypeVariable.class.getName(), "getAnnotatedBounds");
3484
3485 /**
3486 * The represented type variable.
3487 */
3488 private final TypeVariable<?> typeVariable;
3489
3490 /**
3491 * The type variable's index.
3492 */
3493 private final int index;
3494
3495 /**
3496 * Creates a chained annotation reader for reading a formal type variable's bound type.
3497 *
3498 * @param typeVariable The represented type variable.
3499 * @param index The type variable's index.
3500 */
3501 protected OfFormalTypeVariable(TypeVariable<?> typeVariable, int index) {
3502 this.typeVariable = typeVariable;
3503 this.index = index;
3504 }
3505
3506 /**
3507 * {@inheritDoc}
3508 */
3509 public AnnotatedElement resolve() {
3510 try {
3511 return (AnnotatedElement) Array.get(GET_ANNOTATED_BOUNDS.invoke(typeVariable, NO_ARGUMENTS), index);
3512 } catch (ClassCastException ignored) { // To avoid bug on early releases of Java 8.
3513 return NoOp.INSTANCE;
3514 } catch (IllegalAccessException exception) {
3515 throw new IllegalStateException("Cannot access java.lang.reflect.TypeVariable#getAnnotatedBounds", exception);
3516 } catch (InvocationTargetException exception) {
3517 throw new IllegalStateException("Error invoking java.lang.reflect.TypeVariable#getAnnotatedBounds", exception.getCause());
3518 }
3519 }
3520 }
3521 }
3522
3523 /**
3524 * A chained annotation reader for reading a parameterized type's type argument.
3525 */
3526 @HashCodeAndEqualsPlugin.Enhance
3527 class ForTypeArgument extends Delegator.Chained {
3528
3529 /**
3530 * The {@code java.lang.reflect.AnnotatedParameterizedType#getAnnotatedActualTypeArguments} method.
3531 */
3532 private static final Method GET_ANNOTATED_ACTUAL_TYPE_ARGUMENTS = of("java.lang.reflect.AnnotatedParameterizedType", "getAnnotatedActualTypeArguments");
3533
3534 /**
3535 * The type argument's index.
3536 */
3537 private final int index;
3538
3539 /**
3540 * Creates a chained annotation reader for reading a component type.
3541 *
3542 * @param annotationReader The annotation reader from which to delegate.
3543 * @param index The type argument's index.
3544 */
3545 protected ForTypeArgument(AnnotationReader annotationReader, int index) {
3546 super(annotationReader);
3547 this.index = index;
3548 }
3549
3550 @Override
3551 protected AnnotatedElement resolve(AnnotatedElement annotatedElement) {
3552 if (!GET_ANNOTATED_ACTUAL_TYPE_ARGUMENTS.getDeclaringClass().isInstance(annotatedElement)) { // Avoid problem with Kotlin compiler.
3553 return NoOp.INSTANCE;
3554 }
3555 try {
3556 return (AnnotatedElement) Array.get(GET_ANNOTATED_ACTUAL_TYPE_ARGUMENTS.invoke(annotatedElement, NO_ARGUMENTS), index);
3557 } catch (ClassCastException ignored) { // To avoid bug on early releases of Java 8.
3558 return NoOp.INSTANCE;
3559 } catch (IllegalAccessException exception) {
3560 throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedParameterizedType#getAnnotatedActualTypeArguments", exception);
3561 } catch (InvocationTargetException exception) {
3562 throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedParameterizedType#getAnnotatedActualTypeArguments", exception.getCause());
3563 }
3564 }
3565 }
3566
3567 /**
3568 * A chained annotation reader for reading a component type.
3569 */
3570 class ForComponentType extends Delegator.Chained {
3571
3572 /**
3573 * The {@code java.lang.reflect.AnnotatedArrayType#getAnnotatedGenericComponentType} method.
3574 */
3575 private static final Method GET_ANNOTATED_GENERIC_COMPONENT_TYPE = of("java.lang.reflect.AnnotatedArrayType", "getAnnotatedGenericComponentType");
3576
3577 /**
3578 * Creates a chained annotation reader for reading a component type.
3579 *
3580 * @param annotationReader The annotation reader from which to delegate.
3581 */
3582 protected ForComponentType(AnnotationReader annotationReader) {
3583 super(annotationReader);
3584 }
3585
3586 @Override
3587 protected AnnotatedElement resolve(AnnotatedElement annotatedElement) {
3588 if (!GET_ANNOTATED_GENERIC_COMPONENT_TYPE.getDeclaringClass().isInstance(annotatedElement)) { // Avoid problem with Kotlin compiler.
3589 return NoOp.INSTANCE;
3590 }
3591 try {
3592 return (AnnotatedElement) GET_ANNOTATED_GENERIC_COMPONENT_TYPE.invoke(annotatedElement, NO_ARGUMENTS);
3593 } catch (ClassCastException ignored) { // To avoid bug on early releases of Java 8.
3594 return NoOp.INSTANCE;
3595 } catch (IllegalAccessException exception) {
3596 throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedArrayType#getAnnotatedGenericComponentType", exception);
3597 } catch (InvocationTargetException exception) {
3598 throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedArrayType#getAnnotatedGenericComponentType", exception.getCause());
3599 }
3600 }
3601 }
3602
3603 /**
3604 * A chained annotation reader for reading an owner type.
3605 */
3606 class ForOwnerType extends Delegator.Chained {
3607
3608 /**
3609 * The {@code java.lang.reflect.AnnotatedType#getAnnotatedOwnerType} method.
3610 */
3611 private static final Method GET_ANNOTATED_OWNER_TYPE = of("java.lang.reflect.AnnotatedType", "getAnnotatedOwnerType");
3612
3613 /**
3614 * Creates a chained annotation reader for reading an owner type if it is accessible. This method checks if annotated
3615 * owner types are available on the executing VM (Java 9+). If this is not the case, a non-operational annotation
3616 * reader is returned.
3617 *
3618 * @param annotationReader The annotation reader from which to delegate.
3619 * @return An annotation reader for the resolved type's owner type.
3620 */
3621 private static AnnotationReader of(AnnotationReader annotationReader) {
3622 return GET_ANNOTATED_OWNER_TYPE == null
3623 ? NoOp.INSTANCE
3624 : new ForOwnerType(annotationReader);
3625 }
3626
3627 /**
3628 * Creates a chained annotation reader for reading an owner type if it is accessible.
3629 *
3630 * @param annotationReader The annotation reader from which to delegate.
3631 */
3632 protected ForOwnerType(AnnotationReader annotationReader) {
3633 super(annotationReader);
3634 }
3635
3636 @Override
3637 protected AnnotatedElement resolve(AnnotatedElement annotatedElement) {
3638 if (!GET_ANNOTATED_OWNER_TYPE.getDeclaringClass().isInstance(annotatedElement)) { // Avoid problem with Kotlin compiler.
3639 return NoOp.INSTANCE;
3640 }
3641 try {
3642 AnnotatedElement annotatedOwnerType = (AnnotatedElement) GET_ANNOTATED_OWNER_TYPE.invoke(annotatedElement, NO_ARGUMENTS);
3643 return annotatedOwnerType == null
3644 ? NoOp.INSTANCE
3645 : annotatedOwnerType;
3646 } catch (ClassCastException ignored) { // To avoid bug on early releases of Java 8.
3647 return NoOp.INSTANCE;
3648 } catch (IllegalAccessException exception) {
3649 throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedType#getAnnotatedOwnerType", exception);
3650 } catch (InvocationTargetException exception) {
3651 throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedType#getAnnotatedOwnerType", exception.getCause());
3652 }
3653 }
3654 }
3655 }
3656
3657 /**
3658 * An abstract base implementation of a generic type description.
3659 */
3660 abstract class AbstractBase extends ModifierReviewable.AbstractBase implements Generic {
3661
3662 /**
3663 * {@inheritDoc}
3664 */
3665 public int getModifiers() {
3666 return asErasure().getModifiers();
3667 }
3668
3669 /**
3670 * {@inheritDoc}
3671 */
3672 public Generic asGenericType() {
3673 return this;
3674 }
3675
3676 /**
3677 * {@inheritDoc}
3678 */
3679 public Generic asRawType() {
3680 return asErasure().asGenericType();
3681 }
3682
3683 /**
3684 * {@inheritDoc}
3685 */
3686 public boolean represents(java.lang.reflect.Type type) {
3687 return equals(Sort.describe(type));
3688 }
3689 }
3690
3691 /**
3692 * <p>
3693 * A raw type representation of a non-generic type. This raw type differs from a raw type in the Java programming language by
3694 * representing a minimal erasure compared to Java's full erasure. This means that generic types are preserved as long as they
3695 * do not involve a type variable. Nested type variables are erased on the deepest possible level.
3696 * </p>
3697 * <p>
3698 * All fields, methods, interfaces and the super type that are returned from this instance represent appropriately erased types.
3699 * </p>
3700 */
3701 abstract class OfNonGenericType extends AbstractBase {
3702
3703 /**
3704 * {@inheritDoc}
3705 */
3706 public Sort getSort() {
3707 return Sort.NON_GENERIC;
3708 }
3709
3710 /**
3711 * {@inheritDoc}
3712 */
3713 public Generic getSuperClass() {
3714 TypeDescription erasure = asErasure();
3715 Generic superClass = erasure.getSuperClass();
3716 if (TypeDescription.AbstractBase.RAW_TYPES) {
3717 return superClass;
3718 }
3719 return superClass == null
3720 ? Generic.UNDEFINED
3721 : new Generic.LazyProjection.WithResolvedErasure(superClass, new Visitor.ForRawType(erasure), Empty.INSTANCE);
3722 }
3723
3724 /**
3725 * {@inheritDoc}
3726 */
3727 public TypeList.Generic getInterfaces() {
3728 TypeDescription erasure = asErasure();
3729 if (TypeDescription.AbstractBase.RAW_TYPES) {
3730 return erasure.getInterfaces();
3731 }
3732 return new TypeList.Generic.ForDetachedTypes.WithResolvedErasure(erasure.getInterfaces(), new Visitor.ForRawType(erasure));
3733 }
3734
3735 /**
3736 * {@inheritDoc}
3737 */
3738 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
3739 TypeDescription erasure = asErasure();
3740 return new FieldList.TypeSubstituting(this, erasure.getDeclaredFields(), TypeDescription.AbstractBase.RAW_TYPES
3741 ? Visitor.NoOp.INSTANCE
3742 : new Visitor.ForRawType(erasure));
3743 }
3744
3745 /**
3746 * {@inheritDoc}
3747 */
3748 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
3749 TypeDescription erasure = asErasure();
3750 return new MethodList.TypeSubstituting(this, erasure.getDeclaredMethods(), TypeDescription.AbstractBase.RAW_TYPES
3751 ? Visitor.NoOp.INSTANCE
3752 : new Visitor.ForRawType(erasure));
3753 }
3754
3755 /**
3756 * {@inheritDoc}
3757 */
3758 public RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents() {
3759 TypeDescription erasure = asErasure();
3760 return new RecordComponentList.TypeSubstituting(this, erasure.getRecordComponents(), TypeDescription.AbstractBase.RAW_TYPES
3761 ? Visitor.NoOp.INSTANCE
3762 : new Visitor.ForRawType(erasure));
3763 }
3764
3765 /**
3766 * {@inheritDoc}
3767 */
3768 public TypeList.Generic getTypeArguments() {
3769 throw new IllegalStateException("A non-generic type does not imply type arguments: " + this);
3770 }
3771
3772 /**
3773 * {@inheritDoc}
3774 */
3775 public Generic findBindingOf(Generic typeVariable) {
3776 throw new IllegalStateException("A non-generic type does not imply type arguments: " + this);
3777 }
3778
3779 /**
3780 * {@inheritDoc}
3781 */
3782 public <T> T accept(Visitor<T> visitor) {
3783 return visitor.onNonGenericType(this);
3784 }
3785
3786 /**
3787 * {@inheritDoc}
3788 */
3789 public String getTypeName() {
3790 return asErasure().getTypeName();
3791 }
3792
3793 /**
3794 * {@inheritDoc}
3795 */
3796 public TypeList.Generic getUpperBounds() {
3797 throw new IllegalStateException("A non-generic type does not imply upper type bounds: " + this);
3798 }
3799
3800 /**
3801 * {@inheritDoc}
3802 */
3803 public TypeList.Generic getLowerBounds() {
3804 throw new IllegalStateException("A non-generic type does not imply lower type bounds: " + this);
3805 }
3806
3807 /**
3808 * {@inheritDoc}
3809 */
3810 public TypeVariableSource getTypeVariableSource() {
3811 throw new IllegalStateException("A non-generic type does not imply a type variable source: " + this);
3812 }
3813
3814 /**
3815 * {@inheritDoc}
3816 */
3817 public String getSymbol() {
3818 throw new IllegalStateException("A non-generic type does not imply a symbol: " + this);
3819 }
3820
3821 /**
3822 * {@inheritDoc}
3823 */
3824 public StackSize getStackSize() {
3825 return asErasure().getStackSize();
3826 }
3827
3828 /**
3829 * {@inheritDoc}
3830 */
3831 public String getActualName() {
3832 return asErasure().getActualName();
3833 }
3834
3835 /**
3836 * {@inheritDoc}
3837 */
3838 public boolean isArray() {
3839 return asErasure().isArray();
3840 }
3841
3842 /**
3843 * {@inheritDoc}
3844 */
3845 public boolean isPrimitive() {
3846 return asErasure().isPrimitive();
3847 }
3848
3849 /**
3850 * {@inheritDoc}
3851 */
3852 public boolean isRecord() {
3853 return asErasure().isRecord();
3854 }
3855
3856 /**
3857 * {@inheritDoc}
3858 */
3859 public boolean represents(java.lang.reflect.Type type) {
3860 return asErasure().represents(type);
3861 }
3862
3863 /**
3864 * {@inheritDoc}
3865 */
3866 public Iterator<TypeDefinition> iterator() {
3867 return new SuperClassIterator(this);
3868 }
3869
3870 @Override
3871 @CachedReturnPlugin.Enhance
3872 public int hashCode() {
3873 return asErasure().hashCode();
3874 }
3875
3876 @Override
3877 @SuppressFBWarnings(value = "EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS", justification = "Type check is performed by erasure implementation")
3878 public boolean equals(Object other) {
3879 return this == other || asErasure().equals(other);
3880 }
3881
3882 @Override
3883 public String toString() {
3884 return asErasure().toString();
3885 }
3886
3887 /**
3888 * Represents a non-generic type for a loaded {@link Class}.
3889 */
3890 public static class ForLoadedType extends OfNonGenericType {
3891
3892 /**
3893 * A cache of generic type descriptions for commonly used types to avoid unnecessary allocations.
3894 */
3895 @SuppressFBWarnings(value = "MS_MUTABLE_COLLECTION_PKGPROTECT", justification = "This collection is not exposed.")
3896 private static final Map<Class<?>, Generic> TYPE_CACHE;
3897
3898 /*
3899 * Initializes the type cache.
3900 */
3901 static {
3902 TYPE_CACHE = new HashMap<Class<?>, Generic>();
3903 TYPE_CACHE.put(TargetType.class, new ForLoadedType(TargetType.class));
3904 TYPE_CACHE.put(Object.class, new ForLoadedType(Object.class));
3905 TYPE_CACHE.put(String.class, new ForLoadedType(String.class));
3906 TYPE_CACHE.put(Boolean.class, new ForLoadedType(Boolean.class));
3907 TYPE_CACHE.put(Byte.class, new ForLoadedType(Byte.class));
3908 TYPE_CACHE.put(Short.class, new ForLoadedType(Short.class));
3909 TYPE_CACHE.put(Character.class, new ForLoadedType(Character.class));
3910 TYPE_CACHE.put(Integer.class, new ForLoadedType(Integer.class));
3911 TYPE_CACHE.put(Long.class, new ForLoadedType(Long.class));
3912 TYPE_CACHE.put(Float.class, new ForLoadedType(Float.class));
3913 TYPE_CACHE.put(Double.class, new ForLoadedType(Double.class));
3914 TYPE_CACHE.put(void.class, new ForLoadedType(void.class));
3915 TYPE_CACHE.put(boolean.class, new ForLoadedType(boolean.class));
3916 TYPE_CACHE.put(byte.class, new ForLoadedType(byte.class));
3917 TYPE_CACHE.put(short.class, new ForLoadedType(short.class));
3918 TYPE_CACHE.put(char.class, new ForLoadedType(char.class));
3919 TYPE_CACHE.put(int.class, new ForLoadedType(int.class));
3920 TYPE_CACHE.put(long.class, new ForLoadedType(long.class));
3921 TYPE_CACHE.put(float.class, new ForLoadedType(float.class));
3922 TYPE_CACHE.put(double.class, new ForLoadedType(double.class));
3923 }
3924
3925 /**
3926 * The type that this instance represents.
3927 */
3928 private final Class<?> type;
3929
3930 /**
3931 * The annotation reader to query for the non-generic type's annotations.
3932 */
3933 private final AnnotationReader annotationReader;
3934
3935 /**
3936 * Creates a new description of a generic type of a loaded type. This constructor should not normally be used.
3937 * Use {@link ForLoadedType#of(Class)} instead.
3938 *
3939 * @param type The represented type.
3940 */
3941 public ForLoadedType(Class<?> type) {
3942 this(type, AnnotationReader.NoOp.INSTANCE);
3943 }
3944
3945 /**
3946 * /**
3947 * Creates a new description of a generic type of a loaded type.
3948 *
3949 * @param type The represented type.
3950 * @param annotationReader The annotation reader to query for the non-generic type's annotations.
3951 */
3952 protected ForLoadedType(Class<?> type, AnnotationReader annotationReader) {
3953 this.type = type;
3954 this.annotationReader = annotationReader;
3955 }
3956
3957 /**
3958 * Returns a new immutable generic type description for a loaded type.
3959 *
3960 * @param type The type to be represented by this generic type description.
3961 * @return The generic type description representing the given type.
3962 */
3963 public static Generic of(Class<?> type) {
3964 Generic typeDescription = TYPE_CACHE.get(type);
3965 return typeDescription == null
3966 ? new ForLoadedType(type)
3967 : typeDescription;
3968 }
3969
3970 /**
3971 * {@inheritDoc}
3972 */
3973 public TypeDescription asErasure() {
3974 return TypeDescription.ForLoadedType.of(type);
3975 }
3976
3977 /**
3978 * {@inheritDoc}
3979 */
3980 public Generic getOwnerType() {
3981 Class<?> declaringClass = this.type.getDeclaringClass();
3982 return declaringClass == null
3983 ? Generic.UNDEFINED
3984 : new ForLoadedType(declaringClass, annotationReader.ofOuterClass());
3985 }
3986
3987 /**
3988 * {@inheritDoc}
3989 */
3990 public Generic getComponentType() {
3991 Class<?> componentType = type.getComponentType();
3992 return componentType == null
3993 ? Generic.UNDEFINED
3994 : new ForLoadedType(componentType, annotationReader.ofComponentType());
3995 }
3996
3997 /**
3998 * {@inheritDoc}
3999 */
4000 public AnnotationList getDeclaredAnnotations() {
4001 return annotationReader.asList();
4002 }
4003
4004 /**
4005 * {@inheritDoc}
4006 */
4007 public boolean represents(java.lang.reflect.Type type) {
4008 return this.type == type || super.represents(type);
4009 }
4010 }
4011
4012 /**
4013 * A type description for a type erasure. Compared to a {@link Latent} representation, this
4014 * representation does not allow for the specification of any complex properties but does
4015 * not require any form of navigation on the type.
4016 */
4017 public static class ForErasure extends OfNonGenericType {
4018
4019 /**
4020 * The represented type erasure.
4021 */
4022 private final TypeDescription typeDescription;
4023
4024 /**
4025 * Creates a new description of a non-generic type as an erasure.
4026 *
4027 * @param typeDescription The represented type erasure.
4028 */
4029 public ForErasure(TypeDescription typeDescription) {
4030 this.typeDescription = typeDescription;
4031 }
4032
4033 /**
4034 * {@inheritDoc}
4035 */
4036 public TypeDescription asErasure() {
4037 return typeDescription;
4038 }
4039
4040 /**
4041 * {@inheritDoc}
4042 */
4043 public Generic getOwnerType() {
4044 TypeDescription declaringType = typeDescription.getDeclaringType();
4045 return declaringType == null
4046 ? Generic.UNDEFINED
4047 : declaringType.asGenericType();
4048 }
4049
4050 /**
4051 * {@inheritDoc}
4052 */
4053 public Generic getComponentType() {
4054 TypeDescription componentType = typeDescription.getComponentType();
4055 return componentType == null
4056 ? Generic.UNDEFINED
4057 : componentType.asGenericType();
4058 }
4059
4060 /**
4061 * {@inheritDoc}
4062 */
4063 public AnnotationList getDeclaredAnnotations() {
4064 return new AnnotationList.Empty();
4065 }
4066 }
4067
4068 /**
4069 * A latent description of a non-generic type.
4070 */
4071 public static class Latent extends OfNonGenericType {
4072
4073 /**
4074 * The non-generic type's raw type.
4075 */
4076 private final TypeDescription typeDescription;
4077
4078 /**
4079 * The non-generic type's declaring type.
4080 */
4081 private final TypeDescription.Generic declaringType;
4082
4083 /**
4084 * The annotation source to query for the declared annotations.
4085 */
4086 private final AnnotationSource annotationSource;
4087
4088 /**
4089 * Creates a non-generic type with an implicit owner type.
4090 *
4091 * @param typeDescription The non-generic type's raw type.
4092 * @param annotationSource The annotation source to query for the declared annotations.
4093 */
4094 public Latent(TypeDescription typeDescription, AnnotationSource annotationSource) {
4095 this(typeDescription, typeDescription.getDeclaringType(), annotationSource);
4096 }
4097
4098 /**
4099 * Creates a non-generic type with a raw owner type.
4100 *
4101 * @param typeDescription The non-generic type's raw type.
4102 * @param declaringType The non-generic type's declaring type.
4103 * @param annotationSource The annotation source to query for the declared annotations.
4104 */
4105 private Latent(TypeDescription typeDescription, TypeDescription declaringType, AnnotationSource annotationSource) {
4106 this(typeDescription,
4107 declaringType == null
4108 ? Generic.UNDEFINED
4109 : declaringType.asGenericType(),
4110 annotationSource);
4111 }
4112
4113 /**
4114 * Creates a non-generic type.
4115 *
4116 * @param typeDescription The non-generic type's raw type.
4117 * @param declaringType The non-generic type's declaring type.
4118 * @param annotationSource The annotation source to query for the declared annotations.
4119 */
4120 protected Latent(TypeDescription typeDescription, Generic declaringType, AnnotationSource annotationSource) {
4121 this.typeDescription = typeDescription;
4122 this.declaringType = declaringType;
4123 this.annotationSource = annotationSource;
4124 }
4125
4126 /**
4127 * {@inheritDoc}
4128 */
4129 public Generic getOwnerType() {
4130 return declaringType;
4131 }
4132
4133 /**
4134 * {@inheritDoc}
4135 */
4136 public Generic getComponentType() {
4137 TypeDescription componentType = typeDescription.getComponentType();
4138 return componentType == null
4139 ? Generic.UNDEFINED
4140 : componentType.asGenericType();
4141 }
4142
4143 /**
4144 * {@inheritDoc}
4145 */
4146 public AnnotationList getDeclaredAnnotations() {
4147 return annotationSource.getDeclaredAnnotations();
4148 }
4149
4150 /**
4151 * {@inheritDoc}
4152 */
4153 public TypeDescription asErasure() {
4154 return typeDescription;
4155 }
4156 }
4157
4158 /**
4159 * A representation of a raw type that preserves its generic super types' generic information with a minimum
4160 * but erases all of their members' types.
4161 */
4162 public static class ForReifiedErasure extends OfNonGenericType {
4163
4164 /**
4165 * The represented type erasure.
4166 */
4167 private final TypeDescription typeDescription;
4168
4169 /**
4170 * Creates a new reified non-generic type.
4171 *
4172 * @param typeDescription The represented type erasure.
4173 */
4174 protected ForReifiedErasure(TypeDescription typeDescription) {
4175 this.typeDescription = typeDescription;
4176 }
4177
4178 /**
4179 * Creates a new generic type representation for an erasure where any generified type is reified.
4180 *
4181 * @param typeDescription The erasure to represent.
4182 * @return An appropriate generic type representation where any generified type is reified.
4183 */
4184 protected static Generic of(TypeDescription typeDescription) {
4185 return typeDescription.isGenerified()
4186 ? new ForReifiedErasure(typeDescription)
4187 : new ForErasure(typeDescription);
4188 }
4189
4190 /**
4191 * {@inheritDoc}
4192 */
4193 public Generic getSuperClass() {
4194 Generic superClass = typeDescription.getSuperClass();
4195 return superClass == null
4196 ? Generic.UNDEFINED
4197 : new LazyProjection.WithResolvedErasure(superClass, Visitor.Reifying.INHERITING);
4198 }
4199
4200 /**
4201 * {@inheritDoc}
4202 */
4203 public TypeList.Generic getInterfaces() {
4204 return new TypeList.Generic.ForDetachedTypes.WithResolvedErasure(typeDescription.getInterfaces(), Visitor.Reifying.INHERITING);
4205 }
4206
4207 /**
4208 * {@inheritDoc}
4209 */
4210 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
4211 return new FieldList.TypeSubstituting(this, typeDescription.getDeclaredFields(), Visitor.TypeErasing.INSTANCE);
4212 }
4213
4214 /**
4215 * {@inheritDoc}
4216 */
4217 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
4218 return new MethodList.TypeSubstituting(this, typeDescription.getDeclaredMethods(), Visitor.TypeErasing.INSTANCE);
4219 }
4220
4221 /**
4222 * {@inheritDoc}
4223 */
4224 public TypeDescription asErasure() {
4225 return typeDescription;
4226 }
4227
4228 /**
4229 * {@inheritDoc}
4230 */
4231 public Generic getOwnerType() {
4232 TypeDescription declaringType = typeDescription.getDeclaringType();
4233 return declaringType == null
4234 ? Generic.UNDEFINED
4235 : of(declaringType);
4236 }
4237
4238 /**
4239 * {@inheritDoc}
4240 */
4241 public Generic getComponentType() {
4242 TypeDescription componentType = typeDescription.getComponentType();
4243 return componentType == null
4244 ? Generic.UNDEFINED
4245 : of(componentType);
4246 }
4247
4248 /**
4249 * {@inheritDoc}
4250 */
4251 public AnnotationList getDeclaredAnnotations() {
4252 return new AnnotationList.Empty();
4253 }
4254 }
4255 }
4256
4257 /**
4258 * A base implementation of a generic type description that represents a potentially generic array. Instances represent a non-generic type
4259 * if the given component type is non-generic.
4260 */
4261 abstract class OfGenericArray extends AbstractBase {
4262
4263 /**
4264 * {@inheritDoc}
4265 */
4266 public Sort getSort() {
4267 return getComponentType().getSort().isNonGeneric()
4268 ? Sort.NON_GENERIC
4269 : Sort.GENERIC_ARRAY;
4270 }
4271
4272 /**
4273 * {@inheritDoc}
4274 */
4275 public TypeDescription asErasure() {
4276 return ArrayProjection.of(getComponentType().asErasure(), 1);
4277 }
4278
4279 /**
4280 * {@inheritDoc}
4281 */
4282 public Generic getSuperClass() {
4283 return TypeDescription.Generic.OBJECT;
4284 }
4285
4286 /**
4287 * {@inheritDoc}
4288 */
4289 public TypeList.Generic getInterfaces() {
4290 return ARRAY_INTERFACES;
4291 }
4292
4293 /**
4294 * {@inheritDoc}
4295 */
4296 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
4297 return new FieldList.Empty<FieldDescription.InGenericShape>();
4298 }
4299
4300 /**
4301 * {@inheritDoc}
4302 */
4303 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
4304 return new MethodList.Empty<MethodDescription.InGenericShape>();
4305 }
4306
4307 /**
4308 * {@inheritDoc}
4309 */
4310 public RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents() {
4311 return new RecordComponentList.Empty<RecordComponentDescription.InGenericShape>();
4312 }
4313
4314 /**
4315 * {@inheritDoc}
4316 */
4317 public TypeList.Generic getUpperBounds() {
4318 throw new IllegalStateException("A generic array type does not imply upper type bounds: " + this);
4319 }
4320
4321 /**
4322 * {@inheritDoc}
4323 */
4324 public TypeList.Generic getLowerBounds() {
4325 throw new IllegalStateException("A generic array type does not imply lower type bounds: " + this);
4326 }
4327
4328 /**
4329 * {@inheritDoc}
4330 */
4331 public TypeVariableSource getTypeVariableSource() {
4332 throw new IllegalStateException("A generic array type does not imply a type variable source: " + this);
4333 }
4334
4335 /**
4336 * {@inheritDoc}
4337 */
4338 public TypeList.Generic getTypeArguments() {
4339 throw new IllegalStateException("A generic array type does not imply type arguments: " + this);
4340 }
4341
4342 /**
4343 * {@inheritDoc}
4344 */
4345 public Generic findBindingOf(Generic typeVariable) {
4346 throw new IllegalStateException("A generic array type does not imply type arguments: " + this);
4347 }
4348
4349 /**
4350 * {@inheritDoc}
4351 */
4352 public Generic getOwnerType() {
4353 return Generic.UNDEFINED;
4354 }
4355
4356 /**
4357 * {@inheritDoc}
4358 */
4359 public String getSymbol() {
4360 throw new IllegalStateException("A generic array type does not imply a symbol: " + this);
4361 }
4362
4363 /**
4364 * {@inheritDoc}
4365 */
4366 public String getTypeName() {
4367 return getSort().isNonGeneric()
4368 ? asErasure().getTypeName()
4369 : toString();
4370 }
4371
4372 /**
4373 * {@inheritDoc}
4374 */
4375 public String getActualName() {
4376 return getSort().isNonGeneric()
4377 ? asErasure().getActualName()
4378 : toString();
4379 }
4380
4381 /**
4382 * {@inheritDoc}
4383 */
4384 public boolean isArray() {
4385 return true;
4386 }
4387
4388 /**
4389 * {@inheritDoc}
4390 */
4391 public boolean isPrimitive() {
4392 return false;
4393 }
4394
4395 /**
4396 * {@inheritDoc}
4397 */
4398 public boolean isRecord() {
4399 return false;
4400 }
4401
4402 /**
4403 * {@inheritDoc}
4404 */
4405 public Iterator<TypeDefinition> iterator() {
4406 return new SuperClassIterator(this);
4407 }
4408
4409 /**
4410 * {@inheritDoc}
4411 */
4412 public <T> T accept(Visitor<T> visitor) {
4413 return getSort().isNonGeneric()
4414 ? visitor.onNonGenericType(this)
4415 : visitor.onGenericArray(this);
4416 }
4417
4418 /**
4419 * {@inheritDoc}
4420 */
4421 public StackSize getStackSize() {
4422 return StackSize.SINGLE;
4423 }
4424
4425 @Override
4426 @CachedReturnPlugin.Enhance
4427 public int hashCode() {
4428 return getSort().isNonGeneric()
4429 ? asErasure().hashCode()
4430 : getComponentType().hashCode();
4431 }
4432
4433 @Override
4434 @SuppressFBWarnings(value = "EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS", justification = "Type check is performed by erasure implementation")
4435 public boolean equals(Object other) {
4436 if (this == other) {
4437 return true;
4438 } else if (getSort().isNonGeneric()) {
4439 return asErasure().equals(other);
4440 }
4441 if (!(other instanceof Generic)) {
4442 return false;
4443 }
4444 Generic typeDescription = (Generic) other;
4445 return typeDescription.getSort().isGenericArray() && getComponentType().equals(typeDescription.getComponentType());
4446 }
4447
4448 @Override
4449 public String toString() {
4450 return getSort().isNonGeneric()
4451 ? asErasure().toString()
4452 : getComponentType().getTypeName() + "[]";
4453 }
4454
4455 /**
4456 * A description of a loaded generic array type.
4457 */
4458 public static class ForLoadedType extends OfGenericArray {
4459
4460 /**
4461 * The loaded generic array type.
4462 */
4463 private final GenericArrayType genericArrayType;
4464
4465 /**
4466 * The annotation reader to query for the generic array type's annotations.
4467 */
4468 private final AnnotationReader annotationReader;
4469
4470 /**
4471 * Creates a type description of the given generic array type.
4472 *
4473 * @param genericArrayType The loaded generic array type.
4474 */
4475 public ForLoadedType(GenericArrayType genericArrayType) {
4476 this(genericArrayType, AnnotationReader.NoOp.INSTANCE);
4477 }
4478
4479 /**
4480 * Creates a type description of the given generic array type.
4481 *
4482 * @param genericArrayType The loaded generic array type.
4483 * @param annotationReader The annotation reader to query for the generic array type's annotations.
4484 */
4485 protected ForLoadedType(GenericArrayType genericArrayType, AnnotationReader annotationReader) {
4486 this.genericArrayType = genericArrayType;
4487 this.annotationReader = annotationReader;
4488 }
4489
4490 /**
4491 * {@inheritDoc}
4492 */
4493 public Generic getComponentType() {
4494 return Sort.describe(genericArrayType.getGenericComponentType(), annotationReader.ofComponentType());
4495 }
4496
4497 /**
4498 * {@inheritDoc}
4499 */
4500 public AnnotationList getDeclaredAnnotations() {
4501 return annotationReader.asList();
4502 }
4503
4504 /**
4505 * {@inheritDoc}
4506 */
4507 public boolean represents(java.lang.reflect.Type type) {
4508 return genericArrayType == type || super.represents(type);
4509 }
4510 }
4511
4512 /**
4513 * A latent implementation of a generic array type.
4514 */
4515 public static class Latent extends OfGenericArray {
4516
4517 /**
4518 * The component type of the generic array.
4519 */
4520 private final Generic componentType;
4521
4522 /**
4523 * The annotation source to query for the declared annotations.
4524 */
4525 private final AnnotationSource annotationSource;
4526
4527 /**
4528 * Creates a latent representation of a generic array type.
4529 *
4530 * @param componentType The component type.
4531 * @param annotationSource The annotation source to query for the declared annotations.
4532 */
4533 public Latent(Generic componentType, AnnotationSource annotationSource) {
4534 this.componentType = componentType;
4535 this.annotationSource = annotationSource;
4536 }
4537
4538 /**
4539 * {@inheritDoc}
4540 */
4541 public Generic getComponentType() {
4542 return componentType;
4543 }
4544
4545 /**
4546 * {@inheritDoc}
4547 */
4548 public AnnotationList getDeclaredAnnotations() {
4549 return annotationSource.getDeclaredAnnotations();
4550 }
4551 }
4552 }
4553
4554 /**
4555 * A base implementation of a generic type description that represents a wildcard type.
4556 */
4557 abstract class OfWildcardType extends AbstractBase {
4558
4559 /**
4560 * The source code representation of a wildcard.
4561 */
4562 public static final String SYMBOL = "?";
4563
4564 /**
4565 * {@inheritDoc}
4566 */
4567 public Sort getSort() {
4568 return Sort.WILDCARD;
4569 }
4570
4571 /**
4572 * {@inheritDoc}
4573 */
4574 public TypeDescription asErasure() {
4575 throw new IllegalStateException("A wildcard does not represent an erasable type: " + this);
4576 }
4577
4578 /**
4579 * {@inheritDoc}
4580 */
4581 public Generic getSuperClass() {
4582 throw new IllegalStateException("A wildcard does not imply a super type definition: " + this);
4583 }
4584
4585 /**
4586 * {@inheritDoc}
4587 */
4588 public TypeList.Generic getInterfaces() {
4589 throw new IllegalStateException("A wildcard does not imply an interface type definition: " + this);
4590 }
4591
4592 /**
4593 * {@inheritDoc}
4594 */
4595 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
4596 throw new IllegalStateException("A wildcard does not imply field definitions: " + this);
4597 }
4598
4599 /**
4600 * {@inheritDoc}
4601 */
4602 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
4603 throw new IllegalStateException("A wildcard does not imply method definitions: " + this);
4604 }
4605
4606 /**
4607 * {@inheritDoc}
4608 */
4609 public RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents() {
4610 throw new IllegalStateException("A wildcard does not imply record component definitions: " + this);
4611 }
4612
4613 /**
4614 * {@inheritDoc}
4615 */
4616 public Generic getComponentType() {
4617 throw new IllegalStateException("A wildcard does not imply a component type: " + this);
4618 }
4619
4620 /**
4621 * {@inheritDoc}
4622 */
4623 public TypeVariableSource getTypeVariableSource() {
4624 throw new IllegalStateException("A wildcard does not imply a type variable source: " + this);
4625 }
4626
4627 /**
4628 * {@inheritDoc}
4629 */
4630 public TypeList.Generic getTypeArguments() {
4631 throw new IllegalStateException("A wildcard does not imply type arguments: " + this);
4632 }
4633
4634 /**
4635 * {@inheritDoc}
4636 */
4637 public Generic findBindingOf(Generic typeVariable) {
4638 throw new IllegalStateException("A wildcard does not imply type arguments: " + this);
4639 }
4640
4641 /**
4642 * {@inheritDoc}
4643 */
4644 public Generic getOwnerType() {
4645 throw new IllegalStateException("A wildcard does not imply an owner type: " + this);
4646 }
4647
4648 /**
4649 * {@inheritDoc}
4650 */
4651 public String getSymbol() {
4652 throw new IllegalStateException("A wildcard does not imply a symbol: " + this);
4653 }
4654
4655 /**
4656 * {@inheritDoc}
4657 */
4658 public String getTypeName() {
4659 return toString();
4660 }
4661
4662 /**
4663 * {@inheritDoc}
4664 */
4665 public String getActualName() {
4666 return toString();
4667 }
4668
4669 /**
4670 * {@inheritDoc}
4671 */
4672 public boolean isPrimitive() {
4673 return false;
4674 }
4675
4676 /**
4677 * {@inheritDoc}
4678 */
4679 public boolean isArray() {
4680 return false;
4681 }
4682
4683 /**
4684 * {@inheritDoc}
4685 */
4686 public boolean isRecord() {
4687 return false;
4688 }
4689
4690 /**
4691 * {@inheritDoc}
4692 */
4693 public boolean represents(java.lang.reflect.Type type) {
4694 return equals(Sort.describe(type));
4695 }
4696
4697 /**
4698 * {@inheritDoc}
4699 */
4700 public Iterator<TypeDefinition> iterator() {
4701 throw new IllegalStateException("A wildcard does not imply a super type definition: " + this);
4702 }
4703
4704 /**
4705 * {@inheritDoc}
4706 */
4707 public <T> T accept(Visitor<T> visitor) {
4708 return visitor.onWildcard(this);
4709 }
4710
4711 /**
4712 * {@inheritDoc}
4713 */
4714 public StackSize getStackSize() {
4715 throw new IllegalStateException("A wildcard does not imply an operand stack size: " + this);
4716 }
4717
4718 @Override
4719 @CachedReturnPlugin.Enhance
4720 public int hashCode() {
4721 int lowerHash = 1, upperHash = 1;
4722 for (Generic lowerBound : getLowerBounds()) {
4723 lowerHash = 31 * lowerHash + lowerBound.hashCode();
4724 }
4725 for (Generic upperBound : getUpperBounds()) {
4726 upperHash = 31 * upperHash + upperBound.hashCode();
4727 }
4728 return lowerHash ^ upperHash;
4729 }
4730
4731 @Override
4732 public boolean equals(Object other) {
4733 if (this == other) {
4734 return true;
4735 } else if (!(other instanceof Generic)) {
4736 return false;
4737 }
4738 Generic typeDescription = (Generic) other;
4739 return typeDescription.getSort().isWildcard()
4740 && getUpperBounds().equals(typeDescription.getUpperBounds())
4741 && getLowerBounds().equals(typeDescription.getLowerBounds());
4742 }
4743
4744 @Override
4745 public String toString() {
4746 StringBuilder stringBuilder = new StringBuilder(SYMBOL);
4747 TypeList.Generic bounds = getLowerBounds();
4748 if (!bounds.isEmpty()) {
4749 stringBuilder.append(" super ");
4750 } else {
4751 bounds = getUpperBounds();
4752 if (bounds.getOnly().equals(TypeDescription.Generic.OBJECT)) {
4753 return SYMBOL;
4754 }
4755 stringBuilder.append(" extends ");
4756 }
4757 return stringBuilder.append(bounds.getOnly().getTypeName()).toString();
4758 }
4759
4760 /**
4761 * Description of a loaded wildcard.
4762 */
4763 public static class ForLoadedType extends OfWildcardType {
4764
4765 /**
4766 * The represented loaded wildcard type.
4767 */
4768 private final WildcardType wildcardType;
4769
4770 /**
4771 * The annotation reader to query for the wildcard type's annotations.
4772 */
4773 private final AnnotationReader annotationReader;
4774
4775 /**
4776 * Creates a description of a loaded wildcard.
4777 *
4778 * @param wildcardType The represented loaded wildcard type.
4779 */
4780 public ForLoadedType(WildcardType wildcardType) {
4781 this(wildcardType, AnnotationReader.NoOp.INSTANCE);
4782 }
4783
4784 /**
4785 * Creates a description of a loaded wildcard.
4786 *
4787 * @param wildcardType The represented loaded wildcard type.
4788 * @param annotationReader The annotation reader to query for the wildcard type's annotations.
4789 */
4790 protected ForLoadedType(WildcardType wildcardType, AnnotationReader annotationReader) {
4791 this.wildcardType = wildcardType;
4792 this.annotationReader = annotationReader;
4793 }
4794
4795 /**
4796 * {@inheritDoc}
4797 */
4798 public TypeList.Generic getUpperBounds() {
4799 return new WildcardUpperBoundTypeList(wildcardType.getUpperBounds(), annotationReader);
4800 }
4801
4802 /**
4803 * {@inheritDoc}
4804 */
4805 public TypeList.Generic getLowerBounds() {
4806 return new WildcardLowerBoundTypeList(wildcardType.getLowerBounds(), annotationReader);
4807 }
4808
4809 /**
4810 * {@inheritDoc}
4811 */
4812 public AnnotationList getDeclaredAnnotations() {
4813 return annotationReader.asList();
4814 }
4815
4816 /**
4817 * {@inheritDoc}
4818 */
4819 public boolean represents(java.lang.reflect.Type type) {
4820 return wildcardType == type || super.represents(type);
4821 }
4822
4823 /**
4824 * A type list representing an upper-bound type variable's bound types.
4825 */
4826 protected static class WildcardUpperBoundTypeList extends TypeList.Generic.AbstractBase {
4827
4828 /**
4829 * The represented upper bounds.
4830 */
4831 private final java.lang.reflect.Type[] upperBound;
4832
4833 /**
4834 * The annotation reader to query for type annotations.
4835 */
4836 private final AnnotationReader annotationReader;
4837
4838 /**
4839 * Creates a type list for a wildcard type's upper bounds.
4840 *
4841 * @param upperBound The represented upper bounds.
4842 * @param annotationReader The annotation reader to query for type annotations.
4843 */
4844 protected WildcardUpperBoundTypeList(java.lang.reflect.Type[] upperBound, AnnotationReader annotationReader) {
4845 this.upperBound = upperBound;
4846 this.annotationReader = annotationReader;
4847 }
4848
4849 /**
4850 * {@inheritDoc}
4851 */
4852 public Generic get(int index) {
4853 return Sort.describe(upperBound[index], annotationReader.ofWildcardUpperBoundType(index));
4854 }
4855
4856 /**
4857 * {@inheritDoc}
4858 */
4859 public int size() {
4860 return upperBound.length;
4861 }
4862 }
4863
4864 /**
4865 * A type list representing an upper-bound type variable's bound types.
4866 */
4867 protected static class WildcardLowerBoundTypeList extends TypeList.Generic.AbstractBase {
4868
4869 /**
4870 * The represented lower bounds.
4871 */
4872 private final java.lang.reflect.Type[] lowerBound;
4873
4874 /**
4875 * The annotation reader to query for type annotations.
4876 */
4877 private final AnnotationReader annotationReader;
4878
4879 /**
4880 * Creates a type list for a wildcard type's lower bounds.
4881 *
4882 * @param lowerBound The represented lower bounds.
4883 * @param annotationReader The annotation reader to query for type annotations.
4884 */
4885 protected WildcardLowerBoundTypeList(java.lang.reflect.Type[] lowerBound, AnnotationReader annotationReader) {
4886 this.lowerBound = lowerBound;
4887 this.annotationReader = annotationReader;
4888 }
4889
4890 /**
4891 * {@inheritDoc}
4892 */
4893 public Generic get(int index) {
4894 return Sort.describe(lowerBound[index], annotationReader.ofWildcardLowerBoundType(index));
4895 }
4896
4897 /**
4898 * {@inheritDoc}
4899 */
4900 public int size() {
4901 return lowerBound.length;
4902 }
4903 }
4904 }
4905
4906 /**
4907 * A latent description of a wildcard type.
4908 */
4909 public static class Latent extends OfWildcardType {
4910
4911 /**
4912 * The wildcard's upper bounds.
4913 */
4914 private final List<? extends Generic> upperBounds;
4915
4916 /**
4917 * The wildcard's lower bounds.
4918 */
4919 private final List<? extends Generic> lowerBounds;
4920
4921 /**
4922 * The annotation source to query for the declared annotations.
4923 */
4924 private final AnnotationSource annotationSource;
4925
4926 /**
4927 * Creates a description of a latent wildcard.
4928 *
4929 * @param upperBounds The wildcard's upper bounds.
4930 * @param lowerBounds The wildcard's lower bounds.
4931 * @param annotationSource The annotation source to query for the declared annotations.
4932 */
4933 protected Latent(List<? extends Generic> upperBounds, List<? extends Generic> lowerBounds, AnnotationSource annotationSource) {
4934 this.upperBounds = upperBounds;
4935 this.lowerBounds = lowerBounds;
4936 this.annotationSource = annotationSource;
4937 }
4938
4939 /**
4940 * Creates an unbounded wildcard. Such a wildcard is implicitly bound above by the {@link Object} type.
4941 *
4942 * @param annotationSource The annotation source to query for the declared annotations.
4943 * @return A description of an unbounded wildcard.
4944 */
4945 public static Generic unbounded(AnnotationSource annotationSource) {
4946 return new Latent(Collections.singletonList(TypeDescription.Generic.OBJECT), Collections.<Generic>emptyList(), annotationSource);
4947 }
4948
4949 /**
4950 * Creates a wildcard with an upper bound.
4951 *
4952 * @param upperBound The upper bound of the wildcard.
4953 * @param annotationSource The annotation source to query for the declared annotations.
4954 * @return A wildcard with the given upper bound.
4955 */
4956 public static Generic boundedAbove(Generic upperBound, AnnotationSource annotationSource) {
4957 return new Latent(Collections.singletonList(upperBound), Collections.<Generic>emptyList(), annotationSource);
4958 }
4959
4960 /**
4961 * Creates a wildcard with a lower bound. Such a wildcard is implicitly bounded above by the {@link Object} type.
4962 *
4963 * @param lowerBound The lower bound of the wildcard.
4964 * @param annotationSource The annotation source to query for the declared annotations.
4965 * @return A wildcard with the given lower bound.
4966 */
4967 public static Generic boundedBelow(Generic lowerBound, AnnotationSource annotationSource) {
4968 return new Latent(Collections.singletonList(TypeDescription.Generic.OBJECT), Collections.singletonList(lowerBound), annotationSource);
4969 }
4970
4971 /**
4972 * {@inheritDoc}
4973 */
4974 public TypeList.Generic getUpperBounds() {
4975 return new TypeList.Generic.Explicit(upperBounds);
4976 }
4977
4978 /**
4979 * {@inheritDoc}
4980 */
4981 public TypeList.Generic getLowerBounds() {
4982 return new TypeList.Generic.Explicit(lowerBounds);
4983 }
4984
4985 /**
4986 * {@inheritDoc}
4987 */
4988 public AnnotationList getDeclaredAnnotations() {
4989 return annotationSource.getDeclaredAnnotations();
4990 }
4991 }
4992 }
4993
4994 /**
4995 * A base implementation of a generic type description that represents a parameterized type.
4996 */
4997 abstract class OfParameterizedType extends AbstractBase {
4998
4999 /**
5000 * {@inheritDoc}
5001 */
5002 public Sort getSort() {
5003 return Sort.PARAMETERIZED;
5004 }
5005
5006 /**
5007 * {@inheritDoc}
5008 */
5009 public Generic getSuperClass() {
5010 Generic superClass = asErasure().getSuperClass();
5011 return superClass == null
5012 ? Generic.UNDEFINED
5013 : new LazyProjection.WithResolvedErasure(superClass, new Visitor.Substitutor.ForTypeVariableBinding(this));
5014 }
5015
5016 /**
5017 * {@inheritDoc}
5018 */
5019 public TypeList.Generic getInterfaces() {
5020 return new TypeList.Generic.ForDetachedTypes.WithResolvedErasure(asErasure().getInterfaces(), new Visitor.Substitutor.ForTypeVariableBinding(this));
5021 }
5022
5023 /**
5024 * {@inheritDoc}
5025 */
5026 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
5027 return new FieldList.TypeSubstituting(this, asErasure().getDeclaredFields(), new Visitor.Substitutor.ForTypeVariableBinding(this));
5028 }
5029
5030 /**
5031 * {@inheritDoc}
5032 */
5033 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
5034 return new MethodList.TypeSubstituting(this, asErasure().getDeclaredMethods(), new Visitor.Substitutor.ForTypeVariableBinding(this));
5035 }
5036
5037 /**
5038 * {@inheritDoc}
5039 */
5040 public RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents() {
5041 return new RecordComponentList.TypeSubstituting(this, asErasure().getRecordComponents(), new Visitor.Substitutor.ForTypeVariableBinding(this));
5042 }
5043
5044 /**
5045 * {@inheritDoc}
5046 */
5047 public Generic findBindingOf(Generic typeVariable) {
5048 Generic typeDescription = this;
5049 do {
5050 TypeList.Generic typeArguments = typeDescription.getTypeArguments(), typeVariables = typeDescription.asErasure().getTypeVariables();
5051 for (int index = 0; index < Math.min(typeArguments.size(), typeVariables.size()); index++) {
5052 if (typeVariable.equals(typeVariables.get(index))) {
5053 return typeArguments.get(index);
5054 }
5055 }
5056 typeDescription = typeDescription.getOwnerType();
5057 } while (typeDescription != null && typeDescription.getSort().isParameterized());
5058 return Generic.UNDEFINED;
5059 }
5060
5061 /**
5062 * {@inheritDoc}
5063 */
5064 public TypeList.Generic getUpperBounds() {
5065 throw new IllegalStateException("A parameterized type does not imply upper bounds: " + this);
5066 }
5067
5068 /**
5069 * {@inheritDoc}
5070 */
5071 public TypeList.Generic getLowerBounds() {
5072 throw new IllegalStateException("A parameterized type does not imply lower bounds: " + this);
5073 }
5074
5075 /**
5076 * {@inheritDoc}
5077 */
5078 public Generic getComponentType() {
5079 throw new IllegalStateException("A parameterized type does not imply a component type: " + this);
5080 }
5081
5082 /**
5083 * {@inheritDoc}
5084 */
5085 public TypeVariableSource getTypeVariableSource() {
5086 throw new IllegalStateException("A parameterized type does not imply a type variable source: " + this);
5087 }
5088
5089 /**
5090 * {@inheritDoc}
5091 */
5092 public String getSymbol() {
5093 throw new IllegalStateException("A parameterized type does not imply a symbol: " + this);
5094 }
5095
5096 /**
5097 * {@inheritDoc}
5098 */
5099 public String getTypeName() {
5100 return toString();
5101 }
5102
5103 /**
5104 * {@inheritDoc}
5105 */
5106 public String getActualName() {
5107 return toString();
5108 }
5109
5110 /**
5111 * {@inheritDoc}
5112 */
5113 public boolean isPrimitive() {
5114 return false;
5115 }
5116
5117 /**
5118 * {@inheritDoc}
5119 */
5120 public boolean isArray() {
5121 return false;
5122 }
5123
5124 /**
5125 * {@inheritDoc}
5126 */
5127 public boolean isRecord() {
5128 return asErasure().isRecord();
5129 }
5130
5131 /**
5132 * {@inheritDoc}
5133 */
5134 public boolean represents(java.lang.reflect.Type type) {
5135 return equals(Sort.describe(type));
5136 }
5137
5138 /**
5139 * {@inheritDoc}
5140 */
5141 public Iterator<TypeDefinition> iterator() {
5142 return new SuperClassIterator(this);
5143 }
5144
5145 /**
5146 * {@inheritDoc}
5147 */
5148 public <T> T accept(Visitor<T> visitor) {
5149 return visitor.onParameterizedType(this);
5150 }
5151
5152 /**
5153 * {@inheritDoc}
5154 */
5155 public StackSize getStackSize() {
5156 return StackSize.SINGLE;
5157 }
5158
5159 @Override
5160 @CachedReturnPlugin.Enhance
5161 public int hashCode() {
5162 int result = 1;
5163 for (Generic typeArgument : getTypeArguments()) {
5164 result = 31 * result + typeArgument.hashCode();
5165 }
5166 Generic ownerType = getOwnerType();
5167 return result ^ (ownerType == null
5168 ? asErasure().hashCode()
5169 : ownerType.hashCode());
5170 }
5171
5172 @Override
5173 public boolean equals(Object other) {
5174 if (this == other) {
5175 return true;
5176 } else if (!(other instanceof Generic)) {
5177 return false;
5178 }
5179 Generic typeDescription = (Generic) other;
5180 if (!typeDescription.getSort().isParameterized()) {
5181 return false;
5182 }
5183 Generic ownerType = getOwnerType(), otherOwnerType = typeDescription.getOwnerType();
5184 return asErasure().equals(typeDescription.asErasure())
5185 && !(ownerType == null && otherOwnerType != null) && !(ownerType != null && !ownerType.equals(otherOwnerType))
5186 && getTypeArguments().equals(typeDescription.getTypeArguments());
5187 }
5188
5189 @Override
5190 public String toString() {
5191 StringBuilder stringBuilder = new StringBuilder();
5192 RenderingDelegate.CURRENT.apply(stringBuilder, asErasure(), getOwnerType());
5193 TypeList.Generic typeArguments = getTypeArguments();
5194 if (!typeArguments.isEmpty()) {
5195 stringBuilder.append('<');
5196 boolean multiple = false;
5197 for (Generic typeArgument : typeArguments) {
5198 if (multiple) {
5199 stringBuilder.append(", ");
5200 }
5201 stringBuilder.append(typeArgument.getTypeName());
5202 multiple = true;
5203 }
5204 stringBuilder.append('>');
5205 }
5206 return stringBuilder.toString();
5207 }
5208
5209 /**
5210 * A rendering delegate for resolving a parameterized type's {@link Object#toString()} representation.
5211 */
5212 protected enum RenderingDelegate {
5213
5214 /**
5215 * A rendering delegate for any VM prior to Java 9 where types are concatenated using a {@code .} character
5216 * and where the fully qualified names are appended to non-parameterized types.
5217 */
5218 FOR_LEGACY_VM {
5219 @Override
5220 protected void apply(StringBuilder stringBuilder, TypeDescription erasure, Generic ownerType) {
5221 if (ownerType != null) {
5222 stringBuilder.append(ownerType.getTypeName()).append('.').append(ownerType.getSort().isParameterized()
5223 ? erasure.getSimpleName()
5224 : erasure.getName());
5225 } else {
5226 stringBuilder.append(erasure.getName());
5227 }
5228 }
5229 },
5230
5231 /**
5232 * A rendering delegate for any VM supporting Java 8 or newer where a type's simple name is appended.
5233 */
5234 FOR_JAVA_8_CAPABLE_VM {
5235 @Override
5236 protected void apply(StringBuilder stringBuilder, TypeDescription erasure, Generic ownerType) {
5237 if (ownerType != null) {
5238 stringBuilder.append(ownerType.getTypeName()).append('$');
5239 if (ownerType.getSort().isParameterized()) {
5240 stringBuilder.append(erasure.getName().replace(ownerType.asErasure().getName() + "$", ""));
5241 } else {
5242 stringBuilder.append(erasure.getSimpleName());
5243 }
5244 } else {
5245 stringBuilder.append(erasure.getName());
5246 }
5247 }
5248 };
5249
5250 /**
5251 * A rendering delegate for the current VM.
5252 */
5253 protected static final RenderingDelegate CURRENT = ClassFileVersion.ofThisVm(ClassFileVersion.JAVA_V6).isAtLeast(ClassFileVersion.JAVA_V8)
5254 ? RenderingDelegate.FOR_JAVA_8_CAPABLE_VM
5255 : RenderingDelegate.FOR_LEGACY_VM;
5256
5257 /**
5258 * Applies this rendering delegate.
5259 *
5260 * @param stringBuilder The string builder which is used for creating a parameterized type's string representation.
5261 * @param erasure The rendered type's erasure.
5262 * @param ownerType The rendered type's owner type.
5263 */
5264 protected abstract void apply(StringBuilder stringBuilder, TypeDescription erasure, Generic ownerType);
5265 }
5266
5267 /**
5268 * Description of a loaded parameterized type.
5269 */
5270 public static class ForLoadedType extends OfParameterizedType {
5271
5272 /**
5273 * The represented parameterized type.
5274 */
5275 private final ParameterizedType parameterizedType;
5276
5277 /**
5278 * The annotation reader to query for the parameterized type's annotations.
5279 */
5280 private final AnnotationReader annotationReader;
5281
5282 /**
5283 * Creates a description of the loaded parameterized type.
5284 *
5285 * @param parameterizedType The represented parameterized type.
5286 */
5287 public ForLoadedType(ParameterizedType parameterizedType) {
5288 this(parameterizedType, AnnotationReader.NoOp.INSTANCE);
5289 }
5290
5291 /**
5292 * Creates a description of the loaded parameterized type.
5293 *
5294 * @param parameterizedType The represented parameterized type.
5295 * @param annotationReader The annotation reader to query for the parameterized type's annotations.
5296 */
5297 protected ForLoadedType(ParameterizedType parameterizedType, AnnotationReader annotationReader) {
5298 this.parameterizedType = parameterizedType;
5299 this.annotationReader = annotationReader;
5300 }
5301
5302 /**
5303 * {@inheritDoc}
5304 */
5305 public TypeList.Generic getTypeArguments() {
5306 return new ParameterArgumentTypeList(parameterizedType.getActualTypeArguments(), annotationReader);
5307 }
5308
5309 /**
5310 * {@inheritDoc}
5311 */
5312 public Generic getOwnerType() {
5313 java.lang.reflect.Type ownerType = parameterizedType.getOwnerType();
5314 return ownerType == null
5315 ? Generic.UNDEFINED
5316 : Sort.describe(ownerType, annotationReader.ofOwnerType());
5317 }
5318
5319 /**
5320 * {@inheritDoc}
5321 */
5322 public TypeDescription asErasure() {
5323 return TypeDescription.ForLoadedType.of((Class<?>) parameterizedType.getRawType());
5324 }
5325
5326 /**
5327 * {@inheritDoc}
5328 */
5329 public AnnotationList getDeclaredAnnotations() {
5330 return annotationReader.asList();
5331 }
5332
5333 /**
5334 * {@inheritDoc}
5335 */
5336 public boolean represents(java.lang.reflect.Type type) {
5337 return parameterizedType == type || super.represents(type);
5338 }
5339
5340 /**
5341 * A type list that represents a loaded parameterized type's parameter types.
5342 */
5343 protected static class ParameterArgumentTypeList extends TypeList.Generic.AbstractBase {
5344
5345 /**
5346 * The represented argument types.
5347 */
5348 private final java.lang.reflect.Type[] argumentType;
5349
5350 /**
5351 * The annotation reader to query for type annotations.
5352 */
5353 private final AnnotationReader annotationReader;
5354
5355 /**
5356 * Creates a list representing a parameterized type's type arguments.
5357 *
5358 * @param argumentType The represented argument types.
5359 * @param annotationReader The annotation reader to query for type annotations.
5360 */
5361 protected ParameterArgumentTypeList(java.lang.reflect.Type[] argumentType, AnnotationReader annotationReader) {
5362 this.argumentType = argumentType;
5363 this.annotationReader = annotationReader;
5364 }
5365
5366 /**
5367 * {@inheritDoc}
5368 */
5369 public Generic get(int index) {
5370 // Obfuscators sometimes render parameterized type arguments as null values.
5371 return Sort.describe(argumentType[index], annotationReader.ofTypeArgument(index));
5372 }
5373
5374 /**
5375 * {@inheritDoc}
5376 */
5377 public int size() {
5378 return argumentType.length;
5379 }
5380 }
5381 }
5382
5383 /**
5384 * A latent description of a parameterized type.
5385 */
5386 public static class Latent extends OfParameterizedType {
5387
5388 /**
5389 * The raw type of the described parameterized type.
5390 */
5391 private final TypeDescription rawType;
5392
5393 /**
5394 * This parameterized type's owner type or {@code null} if no owner type exists.
5395 */
5396 private final Generic ownerType;
5397
5398 /**
5399 * The parameters of this parameterized type.
5400 */
5401 private final List<? extends Generic> parameters;
5402
5403 /**
5404 * The annotation source to query for the declared annotations.
5405 */
5406 private final AnnotationSource annotationSource;
5407
5408 /**
5409 * Creates a description of a latent parameterized type.
5410 *
5411 * @param rawType The raw type of the described parameterized type.
5412 * @param ownerType This parameterized type's owner type or {@code null} if no owner type exists.
5413 * @param parameters The parameters of this parameterized type.
5414 * @param annotationSource The annotation source to query for the declared annotations.
5415 */
5416 public Latent(TypeDescription rawType,
5417 Generic ownerType,
5418 List<? extends Generic> parameters,
5419 AnnotationSource annotationSource) {
5420 this.rawType = rawType;
5421 this.ownerType = ownerType;
5422 this.parameters = parameters;
5423 this.annotationSource = annotationSource;
5424 }
5425
5426 /**
5427 * {@inheritDoc}
5428 */
5429 public TypeDescription asErasure() {
5430 return rawType;
5431 }
5432
5433 /**
5434 * {@inheritDoc}
5435 */
5436 public Generic getOwnerType() {
5437 return ownerType;
5438 }
5439
5440 /**
5441 * {@inheritDoc}
5442 */
5443 public TypeList.Generic getTypeArguments() {
5444 return new TypeList.Generic.Explicit(parameters);
5445 }
5446
5447 /**
5448 * {@inheritDoc}
5449 */
5450 public AnnotationList getDeclaredAnnotations() {
5451 return annotationSource.getDeclaredAnnotations();
5452 }
5453 }
5454
5455 /**
5456 * A representation of a parameterized type that is a super type of a raw type but preserves the minimal type information
5457 * that is required for allowing creating correct erasures for overridden methods. All members' types are erased and all
5458 * type arguments are reduced to their erasure.
5459 */
5460 public static class ForReifiedType extends OfParameterizedType {
5461
5462 /**
5463 * The represented parameterized type.
5464 */
5465 private final Generic parameterizedType;
5466
5467 /**
5468 * Creates a new reified parameterized type.
5469 *
5470 * @param parameterizedType The represented parameterized type.
5471 */
5472 protected ForReifiedType(Generic parameterizedType) {
5473 this.parameterizedType = parameterizedType;
5474 }
5475
5476 /**
5477 * {@inheritDoc}
5478 */
5479 public Generic getSuperClass() {
5480 Generic superClass = super.getSuperClass();
5481 return superClass == null
5482 ? Generic.UNDEFINED
5483 : new LazyProjection.WithResolvedErasure(superClass, Visitor.Reifying.INHERITING);
5484 }
5485
5486 /**
5487 * {@inheritDoc}
5488 */
5489 public TypeList.Generic getInterfaces() {
5490 return new TypeList.Generic.ForDetachedTypes.WithResolvedErasure(super.getInterfaces(), Visitor.Reifying.INHERITING);
5491 }
5492
5493 /**
5494 * {@inheritDoc}
5495 */
5496 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
5497 return new FieldList.TypeSubstituting(this, super.getDeclaredFields(), Visitor.TypeErasing.INSTANCE);
5498 }
5499
5500 /**
5501 * {@inheritDoc}
5502 */
5503 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
5504 return new MethodList.TypeSubstituting(this, super.getDeclaredMethods(), Visitor.TypeErasing.INSTANCE);
5505 }
5506
5507 /**
5508 * {@inheritDoc}
5509 */
5510 public TypeList.Generic getTypeArguments() {
5511 return new TypeList.Generic.ForDetachedTypes(parameterizedType.getTypeArguments(), Visitor.TypeErasing.INSTANCE);
5512 }
5513
5514 /**
5515 * {@inheritDoc}
5516 */
5517 public Generic getOwnerType() {
5518 Generic ownerType = parameterizedType.getOwnerType();
5519 return ownerType == null
5520 ? Generic.UNDEFINED
5521 : ownerType.accept(Visitor.Reifying.INHERITING);
5522 }
5523
5524 /**
5525 * {@inheritDoc}
5526 */
5527 public TypeDescription asErasure() {
5528 return parameterizedType.asErasure();
5529 }
5530
5531 /**
5532 * {@inheritDoc}
5533 */
5534 public AnnotationList getDeclaredAnnotations() {
5535 return new AnnotationList.Empty();
5536 }
5537 }
5538
5539 /**
5540 * Represents an erasure as a generic type where all type variables are representing their own arguments.
5541 */
5542 public static class ForGenerifiedErasure extends OfParameterizedType {
5543
5544 /**
5545 * The represented erasure.
5546 */
5547 private final TypeDescription typeDescription;
5548
5549 /**
5550 * Creates a new generified erasure.
5551 *
5552 * @param typeDescription The represented erasure.
5553 */
5554 protected ForGenerifiedErasure(TypeDescription typeDescription) {
5555 this.typeDescription = typeDescription;
5556 }
5557
5558 /**
5559 * Represents the supplied type description as a generified erasure if it is generified or as a non-generic type if not so.
5560 *
5561 * @param typeDescription The represented erasure.
5562 * @return An appropriate generic type.
5563 */
5564 public static Generic of(TypeDescription typeDescription) {
5565 return typeDescription.isGenerified()
5566 ? new ForGenerifiedErasure(typeDescription)
5567 : new OfNonGenericType.ForErasure(typeDescription);
5568 }
5569
5570 /**
5571 * {@inheritDoc}
5572 */
5573 public TypeDescription asErasure() {
5574 return typeDescription;
5575 }
5576
5577 /**
5578 * {@inheritDoc}
5579 */
5580 public TypeList.Generic getTypeArguments() {
5581 return new TypeList.Generic.ForDetachedTypes(typeDescription.getTypeVariables(), Visitor.AnnotationStripper.INSTANCE);
5582 }
5583
5584 /**
5585 * {@inheritDoc}
5586 */
5587 public Generic getOwnerType() {
5588 TypeDescription declaringType = typeDescription.getDeclaringType();
5589 return declaringType == null
5590 ? Generic.UNDEFINED
5591 : of(declaringType);
5592 }
5593
5594 /**
5595 * {@inheritDoc}
5596 */
5597 public AnnotationList getDeclaredAnnotations() {
5598 return new AnnotationList.Empty();
5599 }
5600 }
5601 }
5602
5603 /**
5604 * A base implementation of a generic type description that represents a type variable.
5605 */
5606 abstract class OfTypeVariable extends AbstractBase {
5607
5608 /**
5609 * {@inheritDoc}
5610 */
5611 public Sort getSort() {
5612 return Sort.VARIABLE;
5613 }
5614
5615 /**
5616 * {@inheritDoc}
5617 */
5618 public TypeDescription asErasure() {
5619 TypeList.Generic upperBounds = getUpperBounds();
5620 return upperBounds.isEmpty()
5621 ? TypeDescription.OBJECT
5622 : upperBounds.get(0).asErasure();
5623 }
5624
5625 /**
5626 * {@inheritDoc}
5627 */
5628 public Generic getSuperClass() {
5629 throw new IllegalStateException("A type variable does not imply a super type definition: " + this);
5630 }
5631
5632 /**
5633 * {@inheritDoc}
5634 */
5635 public TypeList.Generic getInterfaces() {
5636 throw new IllegalStateException("A type variable does not imply an interface type definition: " + this);
5637 }
5638
5639 /**
5640 * {@inheritDoc}
5641 */
5642 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
5643 throw new IllegalStateException("A type variable does not imply field definitions: " + this);
5644 }
5645
5646 /**
5647 * {@inheritDoc}
5648 */
5649 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
5650 throw new IllegalStateException("A type variable does not imply method definitions: " + this);
5651 }
5652
5653 /**
5654 * {@inheritDoc}
5655 */
5656 public RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents() {
5657 throw new IllegalStateException("A type variable does not imply record component definitions: " + this);
5658 }
5659
5660 /**
5661 * {@inheritDoc}
5662 */
5663 public Generic getComponentType() {
5664 throw new IllegalStateException("A type variable does not imply a component type: " + this);
5665 }
5666
5667 /**
5668 * {@inheritDoc}
5669 */
5670 public TypeList.Generic getTypeArguments() {
5671 throw new IllegalStateException("A type variable does not imply type arguments: " + this);
5672 }
5673
5674 /**
5675 * {@inheritDoc}
5676 */
5677 public Generic findBindingOf(Generic typeVariable) {
5678 throw new IllegalStateException("A type variable does not imply type arguments: " + this);
5679 }
5680
5681 /**
5682 * {@inheritDoc}
5683 */
5684 public TypeList.Generic getLowerBounds() {
5685 throw new IllegalStateException("A type variable does not imply lower bounds: " + this);
5686 }
5687
5688 /**
5689 * {@inheritDoc}
5690 */
5691 public Generic getOwnerType() {
5692 throw new IllegalStateException("A type variable does not imply an owner type: " + this);
5693 }
5694
5695 /**
5696 * {@inheritDoc}
5697 */
5698 public String getTypeName() {
5699 return toString();
5700 }
5701
5702 /**
5703 * {@inheritDoc}
5704 */
5705 public String getActualName() {
5706 return getSymbol();
5707 }
5708
5709 /**
5710 * {@inheritDoc}
5711 */
5712 public <T> T accept(Visitor<T> visitor) {
5713 return visitor.onTypeVariable(this);
5714 }
5715
5716 /**
5717 * {@inheritDoc}
5718 */
5719 public StackSize getStackSize() {
5720 return StackSize.SINGLE;
5721 }
5722
5723 /**
5724 * {@inheritDoc}
5725 */
5726 public boolean isArray() {
5727 return false;
5728 }
5729
5730 /**
5731 * {@inheritDoc}
5732 */
5733 public boolean isPrimitive() {
5734 return false;
5735 }
5736
5737 /**
5738 * {@inheritDoc}
5739 */
5740 public boolean isRecord() {
5741 return false;
5742 }
5743
5744 /**
5745 * {@inheritDoc}
5746 */
5747 public boolean represents(java.lang.reflect.Type type) {
5748 return equals(Sort.describe(type));
5749 }
5750
5751 /**
5752 * {@inheritDoc}
5753 */
5754 public Iterator<TypeDefinition> iterator() {
5755 throw new IllegalStateException("A type variable does not imply a super type definition: " + this);
5756 }
5757
5758 @Override
5759 @CachedReturnPlugin.Enhance
5760 public int hashCode() {
5761 return getTypeVariableSource().hashCode() ^ getSymbol().hashCode();
5762 }
5763
5764 @Override
5765 public boolean equals(Object other) {
5766 if (this == other) {
5767 return true;
5768 } else if (!(other instanceof Generic)) {
5769 return false;
5770 }
5771 Generic typeDescription = (Generic) other;
5772 return typeDescription.getSort().isTypeVariable()
5773 && getSymbol().equals(typeDescription.getSymbol())
5774 && getTypeVariableSource().equals(typeDescription.getTypeVariableSource());
5775 }
5776
5777 @Override
5778 public String toString() {
5779 return getSymbol();
5780 }
5781
5782 /**
5783 * Implementation of a symbolic type variable.
5784 */
5785 public static class Symbolic extends Generic.AbstractBase {
5786
5787 /**
5788 * The symbol of the symbolic type variable.
5789 */
5790 private final String symbol;
5791
5792 /**
5793 * The annotation source to query for the declared annotations.
5794 */
5795 private final AnnotationSource annotationSource;
5796
5797 /**
5798 * Creates a symbolic type variable.
5799 *
5800 * @param symbol The symbol of the symbolic type variable.
5801 * @param annotationSource The annotation source to query for the declared annotations.
5802 */
5803 public Symbolic(String symbol, AnnotationSource annotationSource) {
5804 this.symbol = symbol;
5805 this.annotationSource = annotationSource;
5806 }
5807
5808 /**
5809 * {@inheritDoc}
5810 */
5811 public Sort getSort() {
5812 return Sort.VARIABLE_SYMBOLIC;
5813 }
5814
5815 /**
5816 * {@inheritDoc}
5817 */
5818 public String getSymbol() {
5819 return symbol;
5820 }
5821
5822 /**
5823 * {@inheritDoc}
5824 */
5825 public AnnotationList getDeclaredAnnotations() {
5826 return annotationSource.getDeclaredAnnotations();
5827 }
5828
5829 /**
5830 * {@inheritDoc}
5831 */
5832 public TypeDescription asErasure() {
5833 throw new IllegalStateException("A symbolic type variable does not imply an erasure: " + this);
5834 }
5835
5836 /**
5837 * {@inheritDoc}
5838 */
5839 public TypeList.Generic getUpperBounds() {
5840 throw new IllegalStateException("A symbolic type variable does not imply an upper type bound: " + this);
5841 }
5842
5843 /**
5844 * {@inheritDoc}
5845 */
5846 public TypeVariableSource getTypeVariableSource() {
5847 throw new IllegalStateException("A symbolic type variable does not imply a variable source: " + this);
5848 }
5849
5850 /**
5851 * {@inheritDoc}
5852 */
5853 public Generic getSuperClass() {
5854 throw new IllegalStateException("A symbolic type variable does not imply a super type definition: " + this);
5855 }
5856
5857 /**
5858 * {@inheritDoc}
5859 */
5860 public TypeList.Generic getInterfaces() {
5861 throw new IllegalStateException("A symbolic type variable does not imply an interface type definition: " + this);
5862 }
5863
5864 /**
5865 * {@inheritDoc}
5866 */
5867 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
5868 throw new IllegalStateException("A symbolic type variable does not imply field definitions: " + this);
5869 }
5870
5871 /**
5872 * {@inheritDoc}
5873 */
5874 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
5875 throw new IllegalStateException("A symbolic type variable does not imply method definitions: " + this);
5876 }
5877
5878 /**
5879 * {@inheritDoc}
5880 */
5881 public RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents() {
5882 throw new IllegalStateException("A symbolic type variable does not imply record component definitions: " + this);
5883 }
5884
5885 /**
5886 * {@inheritDoc}
5887 */
5888 public Generic getComponentType() {
5889 throw new IllegalStateException("A symbolic type variable does not imply a component type: " + this);
5890 }
5891
5892 /**
5893 * {@inheritDoc}
5894 */
5895 public TypeList.Generic getTypeArguments() {
5896 throw new IllegalStateException("A symbolic type variable does not imply type arguments: " + this);
5897 }
5898
5899 /**
5900 * {@inheritDoc}
5901 */
5902 public Generic findBindingOf(Generic typeVariable) {
5903 throw new IllegalStateException("A symbolic type variable does not imply type arguments: " + this);
5904 }
5905
5906 /**
5907 * {@inheritDoc}
5908 */
5909 public TypeList.Generic getLowerBounds() {
5910 throw new IllegalStateException("A symbolic type variable does not imply lower bounds: " + this);
5911 }
5912
5913 /**
5914 * {@inheritDoc}
5915 */
5916 public Generic getOwnerType() {
5917 throw new IllegalStateException("A symbolic type variable does not imply an owner type: " + this);
5918 }
5919
5920 /**
5921 * {@inheritDoc}
5922 */
5923 public String getTypeName() {
5924 return toString();
5925 }
5926
5927 /**
5928 * {@inheritDoc}
5929 */
5930 public String getActualName() {
5931 return getSymbol();
5932 }
5933
5934 /**
5935 * {@inheritDoc}
5936 */
5937 public <T> T accept(Visitor<T> visitor) {
5938 return visitor.onTypeVariable(this);
5939 }
5940
5941 /**
5942 * {@inheritDoc}
5943 */
5944 public StackSize getStackSize() {
5945 return StackSize.SINGLE;
5946 }
5947
5948 /**
5949 * {@inheritDoc}
5950 */
5951 public boolean isArray() {
5952 return false;
5953 }
5954
5955 /**
5956 * {@inheritDoc}
5957 */
5958 public boolean isPrimitive() {
5959 return false;
5960 }
5961
5962 /**
5963 * {@inheritDoc}
5964 */
5965 public boolean isRecord() {
5966 return false;
5967 }
5968
5969 /**
5970 * {@inheritDoc}
5971 */
5972 public boolean represents(java.lang.reflect.Type type) {
5973 if (type == null) {
5974 throw new NullPointerException();
5975 }
5976 return false;
5977 }
5978
5979 /**
5980 * {@inheritDoc}
5981 */
5982 public Iterator<TypeDefinition> iterator() {
5983 throw new IllegalStateException("A symbolic type variable does not imply a super type definition: " + this);
5984 }
5985
5986 @Override
5987 public int hashCode() {
5988 return symbol.hashCode();
5989 }
5990
5991 @Override
5992 public boolean equals(Object other) {
5993 if (this == other) {
5994 return true;
5995 } else if (!(other instanceof Generic)) {
5996 return false;
5997 }
5998 Generic typeDescription = (Generic) other;
5999 return typeDescription.getSort().isTypeVariable() && getSymbol().equals(typeDescription.getSymbol());
6000 }
6001
6002 @Override
6003 public String toString() {
6004 return getSymbol();
6005 }
6006 }
6007
6008 /**
6009 * Description of a loaded type variable.
6010 */
6011 public static class ForLoadedType extends OfTypeVariable {
6012
6013 /**
6014 * The represented type variable.
6015 */
6016 private final TypeVariable<?> typeVariable;
6017
6018 /**
6019 * The annotation reader to query for the variable's annotations.
6020 */
6021 private final AnnotationReader annotationReader;
6022
6023 /**
6024 * Creates a description of a loaded type variable.
6025 *
6026 * @param typeVariable The represented type variable.
6027 */
6028 public ForLoadedType(TypeVariable<?> typeVariable) {
6029 this(typeVariable, AnnotationReader.NoOp.INSTANCE);
6030 }
6031
6032 /**
6033 * Creates a description of a loaded type variable with an annotation.
6034 *
6035 * @param typeVariable The represented type variable.
6036 * @param annotationReader The annotation reader to query for the variable's annotations.
6037 */
6038 protected ForLoadedType(TypeVariable<?> typeVariable, AnnotationReader annotationReader) {
6039 this.typeVariable = typeVariable;
6040 this.annotationReader = annotationReader;
6041 }
6042
6043 /**
6044 * {@inheritDoc}
6045 */
6046 public TypeVariableSource getTypeVariableSource() {
6047 GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
6048 if (genericDeclaration instanceof Class) {
6049 return TypeDescription.ForLoadedType.of((Class<?>) genericDeclaration);
6050 } else if (genericDeclaration instanceof Method) {
6051 return new MethodDescription.ForLoadedMethod((Method) genericDeclaration);
6052 } else if (genericDeclaration instanceof Constructor) {
6053 return new MethodDescription.ForLoadedConstructor((Constructor<?>) genericDeclaration);
6054 } else {
6055 throw new IllegalStateException("Unknown declaration: " + genericDeclaration);
6056 }
6057 }
6058
6059 /**
6060 * {@inheritDoc}
6061 */
6062 public TypeList.Generic getUpperBounds() {
6063 return new TypeVariableBoundList(typeVariable.getBounds(), annotationReader);
6064 }
6065
6066 /**
6067 * {@inheritDoc}
6068 */
6069 public String getSymbol() {
6070 return typeVariable.getName();
6071 }
6072
6073 /**
6074 * {@inheritDoc}
6075 */
6076 public AnnotationList getDeclaredAnnotations() {
6077 return annotationReader.asList();
6078 }
6079
6080 /**
6081 * {@inheritDoc}
6082 */
6083 public boolean represents(java.lang.reflect.Type type) {
6084 return typeVariable == type || super.represents(type);
6085 }
6086
6087 /**
6088 * A list of type variable bounds for a loaded {@link TypeVariable} that resolves annotations..
6089 */
6090 protected static class TypeVariableBoundList extends TypeList.Generic.AbstractBase {
6091
6092 /**
6093 * The type variable bounds.
6094 */
6095 private final java.lang.reflect.Type[] bound;
6096
6097 /**
6098 * The annotation reader to query for the type bounds.
6099 */
6100 private final AnnotationReader annotationReader;
6101
6102 /**
6103 * Creates a new list for a {@link TypeVariable}'s bound.
6104 *
6105 * @param bound The type variable bounds.
6106 * @param annotationReader The annotation reader to query for the type bounds.
6107 */
6108 protected TypeVariableBoundList(java.lang.reflect.Type[] bound, AnnotationReader annotationReader) {
6109 this.bound = bound;
6110 this.annotationReader = annotationReader;
6111 }
6112
6113 /**
6114 * {@inheritDoc}
6115 */
6116 public Generic get(int index) {
6117 return Sort.describe(bound[index], annotationReader.ofTypeVariableBoundType(index));
6118 }
6119
6120 /**
6121 * {@inheritDoc}
6122 */
6123 public int size() {
6124 return bound.length;
6125 }
6126 }
6127 }
6128
6129 /**
6130 * A type variable with explicit annotations that replace the annotations that are declared by the provided type variable.
6131 */
6132 public static class WithAnnotationOverlay extends OfTypeVariable {
6133
6134 /**
6135 * The type variable to represent.
6136 */
6137 private final Generic typeVariable;
6138
6139 /**
6140 * The annotation source to query for the declared annotations.
6141 */
6142 private final AnnotationSource annotationSource;
6143
6144 /**
6145 * Creates a new type definition for a type variable with explicit annotations.
6146 *
6147 * @param typeVariable The type variable to represent.
6148 * @param annotationSource The annotation source to query for the declared annotations.
6149 */
6150 public WithAnnotationOverlay(Generic typeVariable, AnnotationSource annotationSource) {
6151 this.typeVariable = typeVariable;
6152 this.annotationSource = annotationSource;
6153 }
6154
6155 /**
6156 * {@inheritDoc}
6157 */
6158 public AnnotationList getDeclaredAnnotations() {
6159 return annotationSource.getDeclaredAnnotations();
6160 }
6161
6162 /**
6163 * {@inheritDoc}
6164 */
6165 public TypeList.Generic getUpperBounds() {
6166 return typeVariable.getUpperBounds();
6167 }
6168
6169 /**
6170 * {@inheritDoc}
6171 */
6172 public TypeVariableSource getTypeVariableSource() {
6173 return typeVariable.getTypeVariableSource();
6174 }
6175
6176 /**
6177 * {@inheritDoc}
6178 */
6179 public String getSymbol() {
6180 return typeVariable.getSymbol();
6181 }
6182 }
6183 }
6184
6185 /**
6186 * A lazy projection of a generic type. Such projections allow to only read generic type information in case it is required. This
6187 * is meaningful as the Java virtual needs to process generic type information which requires extra resources. Also, this allows
6188 * the extraction of non-generic type information even if the generic type information is invalid.
6189 */
6190 abstract class LazyProjection extends AbstractBase {
6191
6192 /**
6193 * Resolves the actual generic type.
6194 *
6195 * @return An actual description of the represented generic type.
6196 */
6197 protected abstract Generic resolve();
6198
6199 /**
6200 * {@inheritDoc}
6201 */
6202 public Sort getSort() {
6203 return resolve().getSort();
6204 }
6205
6206 /**
6207 * {@inheritDoc}
6208 */
6209 public FieldList<FieldDescription.InGenericShape> getDeclaredFields() {
6210 return resolve().getDeclaredFields();
6211 }
6212
6213 /**
6214 * {@inheritDoc}
6215 */
6216 public MethodList<MethodDescription.InGenericShape> getDeclaredMethods() {
6217 return resolve().getDeclaredMethods();
6218 }
6219
6220 /**
6221 * {@inheritDoc}
6222 */
6223 public RecordComponentList<RecordComponentDescription.InGenericShape> getRecordComponents() {
6224 return resolve().getRecordComponents();
6225 }
6226
6227 /**
6228 * {@inheritDoc}
6229 */
6230 public TypeList.Generic getUpperBounds() {
6231 return resolve().getUpperBounds();
6232 }
6233
6234 /**
6235 * {@inheritDoc}
6236 */
6237 public TypeList.Generic getLowerBounds() {
6238 return resolve().getLowerBounds();
6239 }
6240
6241 /**
6242 * {@inheritDoc}
6243 */
6244 public Generic getComponentType() {
6245 return resolve().getComponentType();
6246 }
6247
6248 /**
6249 * {@inheritDoc}
6250 */
6251 public TypeList.Generic getTypeArguments() {
6252 return resolve().getTypeArguments();
6253 }
6254
6255 /**
6256 * {@inheritDoc}
6257 */
6258 public Generic findBindingOf(Generic typeVariable) {
6259 return resolve().findBindingOf(typeVariable);
6260 }
6261
6262 /**
6263 * {@inheritDoc}
6264 */
6265 public TypeVariableSource getTypeVariableSource() {
6266 return resolve().getTypeVariableSource();
6267 }
6268
6269 /**
6270 * {@inheritDoc}
6271 */
6272 public Generic getOwnerType() {
6273 return resolve().getOwnerType();
6274 }
6275
6276 /**
6277 * {@inheritDoc}
6278 */
6279 public String getTypeName() {
6280 return resolve().getTypeName();
6281 }
6282
6283 /**
6284 * {@inheritDoc}
6285 */
6286 public String getSymbol() {
6287 return resolve().getSymbol();
6288 }
6289
6290 /**
6291 * {@inheritDoc}
6292 */
6293 public String getActualName() {
6294 return resolve().getActualName();
6295 }
6296
6297 /**
6298 * {@inheritDoc}
6299 */
6300 public <T> T accept(Visitor<T> visitor) {
6301 return resolve().accept(visitor);
6302 }
6303
6304 /**
6305 * {@inheritDoc}
6306 */
6307 public StackSize getStackSize() {
6308 return asErasure().getStackSize();
6309 }
6310
6311 /**
6312 * {@inheritDoc}
6313 */
6314 public boolean isArray() {
6315 return asErasure().isArray();
6316 }
6317
6318 /**
6319 * {@inheritDoc}
6320 */
6321 public boolean isPrimitive() {
6322 return asErasure().isPrimitive();
6323 }
6324
6325 /**
6326 * {@inheritDoc}
6327 */
6328 public boolean isRecord() {
6329 return asErasure().isRecord();
6330 }
6331
6332 /**
6333 * {@inheritDoc}
6334 */
6335 public boolean represents(java.lang.reflect.Type type) {
6336 return resolve().represents(type);
6337 }
6338
6339 @Override
6340 @CachedReturnPlugin.Enhance
6341 public int hashCode() {
6342 return resolve().hashCode();
6343 }
6344
6345 @Override
6346 public boolean equals(Object other) {
6347 return this == other || other instanceof TypeDefinition && resolve().equals(other);
6348 }
6349
6350 @Override
6351 public String toString() {
6352 return resolve().toString();
6353 }
6354
6355 /**
6356 * A lazy projection of a type with a lazy resolution of super class and interface types. A lazy navigation
6357 * must only be used for describing types that are guaranteed to define a super class and interface types,
6358 * i.e. non-generic types and parameterized types. Lazy navigation can also be applied to array types where
6359 * the usage does however make little sense as those properties are never generic.
6360 */
6361 public abstract static class WithLazyNavigation extends LazyProjection {
6362
6363 /**
6364 * {@inheritDoc}
6365 */
6366 public Generic getSuperClass() {
6367 return LazySuperClass.of(this);
6368 }
6369
6370 /**
6371 * {@inheritDoc}
6372 */
6373 public TypeList.Generic getInterfaces() {
6374 return LazyInterfaceList.of(this);
6375 }
6376
6377 /**
6378 * {@inheritDoc}
6379 */
6380 public Iterator<TypeDefinition> iterator() {
6381 return new TypeDefinition.SuperClassIterator(this);
6382 }
6383
6384 /**
6385 * A lazy super class description for a lazy projection.
6386 */
6387 protected static class LazySuperClass extends WithLazyNavigation {
6388
6389 /**
6390 * The lazy projection for which this description is a delegate.
6391 */
6392 private final LazyProjection delegate;
6393
6394 /**
6395 * Creates a new lazy super class description.
6396 *
6397 * @param delegate The lazy projection for which this description is a delegate.
6398 */
6399 protected LazySuperClass(LazyProjection delegate) {
6400 this.delegate = delegate;
6401 }
6402
6403 /**
6404 * Resolves a lazy super class description.
6405 *
6406 * @param delegate The lazy projection for which this description is a delegate.
6407 * @return A lazy description of the super class or {@code null} if the delegate does not define a super class.
6408 */
6409 protected static Generic of(LazyProjection delegate) {
6410 return delegate.asErasure().getSuperClass() == null
6411 ? Generic.UNDEFINED
6412 : new LazySuperClass(delegate);
6413 }
6414
6415 /**
6416 * {@inheritDoc}
6417 */
6418 public AnnotationList getDeclaredAnnotations() {
6419 return resolve().getDeclaredAnnotations();
6420 }
6421
6422 /**
6423 * {@inheritDoc}
6424 */
6425 public TypeDescription asErasure() {
6426 return delegate.asErasure().getSuperClass().asErasure();
6427 }
6428
6429 @Override
6430 @CachedReturnPlugin.Enhance("resolved")
6431 protected Generic resolve() {
6432 return delegate.resolve().getSuperClass();
6433 }
6434 }
6435
6436 /**
6437 * A lazy interface type description for a lazy projection.
6438 */
6439 protected static class LazyInterfaceType extends WithLazyNavigation {
6440
6441 /**
6442 * The lazy projection for which this description is a delegate.
6443 */
6444 private final LazyProjection delegate;
6445
6446 /**
6447 * The index of the interface in question.
6448 */
6449 private final int index;
6450
6451 /**
6452 * The raw interface that is declared by the erasure of the represented lazy projection.
6453 */
6454 private final TypeDescription.Generic rawInterface;
6455
6456 /**
6457 * Creates a new lazy interface type.
6458 *
6459 * @param delegate The lazy projection for which this description is a delegate.
6460 * @param index The index of the interface in question.
6461 * @param rawInterface The raw interface that is declared by the erasure of the represented lazy projection.
6462 */
6463 protected LazyInterfaceType(LazyProjection delegate, int index, Generic rawInterface) {
6464 this.delegate = delegate;
6465 this.index = index;
6466 this.rawInterface = rawInterface;
6467 }
6468
6469 /**
6470 * {@inheritDoc}
6471 */
6472 public AnnotationList getDeclaredAnnotations() {
6473 return resolve().getDeclaredAnnotations();
6474 }
6475
6476 /**
6477 * {@inheritDoc}
6478 */
6479 public TypeDescription asErasure() {
6480 return rawInterface.asErasure();
6481 }
6482
6483 @Override
6484 @CachedReturnPlugin.Enhance("resolved")
6485 protected Generic resolve() {
6486 return delegate.resolve().getInterfaces().get(index);
6487 }
6488 }
6489
6490 /**
6491 * A lazy representation of a lazy projection's interfaces.
6492 */
6493 protected static class LazyInterfaceList extends TypeList.Generic.AbstractBase {
6494
6495 /**
6496 * The lazy projection for which this description is a delegate.
6497 */
6498 private final LazyProjection delegate;
6499
6500 /**
6501 * A list of raw interface types declared by the lazy projection's erasure.
6502 */
6503 private final TypeList.Generic rawInterfaces;
6504
6505 /**
6506 * Creates a new lazy interface list.
6507 *
6508 * @param delegate The lazy projection for which this description is a delegate.
6509 * @param rawInterfaces A list of raw interface types declared by the lazy projection's erasure.
6510 */
6511 protected LazyInterfaceList(LazyProjection delegate, TypeList.Generic rawInterfaces) {
6512 this.delegate = delegate;
6513 this.rawInterfaces = rawInterfaces;
6514 }
6515
6516 /**
6517 * Resolves a lazy interface list.
6518 *
6519 * @param delegate The delegate for which to represent interfaces.
6520 * @return A lazy list representing the delegate's interfaces lazily.
6521 */
6522 protected static TypeList.Generic of(LazyProjection delegate) {
6523 return new LazyInterfaceList(delegate, delegate.asErasure().getInterfaces());
6524 }
6525
6526 /**
6527 * {@inheritDoc}
6528 */
6529 public Generic get(int index) {
6530 return new LazyInterfaceType(delegate, index, rawInterfaces.get(index));
6531 }
6532
6533 /**
6534 * {@inheritDoc}
6535 */
6536 public int size() {
6537 return rawInterfaces.size();
6538 }
6539 }
6540
6541 /**
6542 * A description of an annotated lazy type with lazy navigation.
6543 */
6544 protected abstract static class OfAnnotatedElement extends WithLazyNavigation {
6545
6546 /**
6547 * Returns the current type's annotation reader.
6548 *
6549 * @return The current type's annotation reader.
6550 */
6551 protected abstract AnnotationReader getAnnotationReader();
6552
6553 /**
6554 * {@inheritDoc}
6555 */
6556 public AnnotationList getDeclaredAnnotations() {
6557 return getAnnotationReader().asList();
6558 }
6559 }
6560 }
6561
6562 /**
6563 * A lazy projection of a type that resolves super class and interface types eagerly.
6564 */
6565 public abstract static class WithEagerNavigation extends LazyProjection {
6566
6567 /**
6568 * {@inheritDoc}
6569 */
6570 public Generic getSuperClass() {
6571 return resolve().getSuperClass();
6572 }
6573
6574 /**
6575 * {@inheritDoc}
6576 */
6577 public TypeList.Generic getInterfaces() {
6578 return resolve().getInterfaces();
6579 }
6580
6581 /**
6582 * {@inheritDoc}
6583 */
6584 public Iterator<TypeDefinition> iterator() {
6585 return resolve().iterator();
6586 }
6587
6588 /**
6589 * A description of an annotated lazy type with eager navigation.
6590 */
6591 protected abstract static class OfAnnotatedElement extends WithEagerNavigation {
6592
6593 /**
6594 * Returns the current type's annotation reader.
6595 *
6596 * @return The current type's annotation reader.
6597 */
6598 protected abstract AnnotationReader getAnnotationReader();
6599
6600 /**
6601 * {@inheritDoc}
6602 */
6603 public AnnotationList getDeclaredAnnotations() {
6604 return getAnnotationReader().asList();
6605 }
6606 }
6607 }
6608
6609 /**
6610 * A lazy projection of a generic super type.
6611 */
6612 public static class ForLoadedSuperClass extends LazyProjection.WithLazyNavigation.OfAnnotatedElement {
6613
6614 /**
6615 * The type of which the super class is represented.
6616 */
6617 private final Class<?> type;
6618
6619 /**
6620 * Creates a new lazy projection of a type's super class.
6621 *
6622 * @param type The type of which the super class is represented.
6623 */
6624 public ForLoadedSuperClass(Class<?> type) {
6625 this.type = type;
6626 }
6627
6628 /**
6629 * {@inheritDoc}
6630 */
6631 @CachedReturnPlugin.Enhance("resolved")
6632 protected Generic resolve() {
6633 java.lang.reflect.Type superClass = type.getGenericSuperclass();
6634 return superClass == null
6635 ? Generic.UNDEFINED
6636 : Sort.describe(superClass, getAnnotationReader());
6637 }
6638
6639 /**
6640 * {@inheritDoc}
6641 */
6642 public TypeDescription asErasure() {
6643 Class<?> superClass = type.getSuperclass();
6644 return superClass == null
6645 ? TypeDescription.UNDEFINED
6646 : ForLoadedType.of(superClass);
6647 }
6648
6649 @Override
6650 protected AnnotationReader getAnnotationReader() {
6651 return AnnotationReader.DISPATCHER.resolveSuperClassType(type);
6652 }
6653 }
6654
6655 /**
6656 * A lazy projection of a field's type.
6657 */
6658 public static class ForLoadedFieldType extends LazyProjection.WithEagerNavigation.OfAnnotatedElement {
6659
6660 /**
6661 * The field of which the type is represented.
6662 */
6663 private final Field field;
6664
6665 /**
6666 * Create's a lazy projection of a field type.
6667 *
6668 * @param field The field of which the type is represented.
6669 */
6670 public ForLoadedFieldType(Field field) {
6671 this.field = field;
6672 }
6673
6674 @Override
6675 @CachedReturnPlugin.Enhance("resolved")
6676 protected Generic resolve() {
6677 return Sort.describe(field.getGenericType(), getAnnotationReader());
6678 }
6679
6680 /**
6681 * {@inheritDoc}
6682 */
6683 public TypeDescription asErasure() {
6684 return ForLoadedType.of(field.getType());
6685 }
6686
6687 @Override
6688 protected AnnotationReader getAnnotationReader() {
6689 return AnnotationReader.DISPATCHER.resolveFieldType(field);
6690 }
6691 }
6692
6693 /**
6694 * A lazy projection of a method's generic return type.
6695 */
6696 public static class ForLoadedReturnType extends LazyProjection.WithEagerNavigation.OfAnnotatedElement {
6697
6698 /**
6699 * The method which defines the return type.
6700 */
6701 private final Method method;
6702
6703 /**
6704 * Creates a new lazy projection of a method's return type.
6705 *
6706 * @param method The method which defines the return type.
6707 */
6708 public ForLoadedReturnType(Method method) {
6709 this.method = method;
6710 }
6711
6712 @Override
6713 @CachedReturnPlugin.Enhance("resolved")
6714 protected Generic resolve() {
6715 return Sort.describe(method.getGenericReturnType(), getAnnotationReader());
6716 }
6717
6718 /**
6719 * {@inheritDoc}
6720 */
6721 public TypeDescription asErasure() {
6722 return ForLoadedType.of(method.getReturnType());
6723 }
6724
6725 @Override
6726 protected AnnotationReader getAnnotationReader() {
6727 return AnnotationReader.DISPATCHER.resolveReturnType(method);
6728 }
6729 }
6730
6731 /**
6732 * A lazy projection of the parameter type of a {@link Constructor}.
6733 */
6734 public static class OfConstructorParameter extends LazyProjection.WithEagerNavigation.OfAnnotatedElement {
6735
6736 /**
6737 * The constructor of which a parameter type is represented.
6738 */
6739 private final Constructor<?> constructor;
6740
6741 /**
6742 * The parameter's index.
6743 */
6744 private final int index;
6745
6746 /**
6747 * The erasure of the parameter type.
6748 */
6749 private final Class<?>[] erasure;
6750
6751 /**
6752 * Creates a lazy projection of a constructor's parameter.
6753 *
6754 * @param constructor The constructor of which a parameter type is represented.
6755 * @param index The parameter's index.
6756 * @param erasure The erasure of the parameter type.
6757 */
6758 @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is never exposed outside of the class")
6759 public OfConstructorParameter(Constructor<?> constructor, int index, Class<?>[] erasure) {
6760 this.constructor = constructor;
6761 this.index = index;
6762 this.erasure = erasure;
6763 }
6764
6765 @Override
6766 @CachedReturnPlugin.Enhance("delegate")
6767 protected Generic resolve() {
6768 java.lang.reflect.Type[] type = constructor.getGenericParameterTypes();
6769 return erasure.length == type.length
6770 ? Sort.describe(type[index], getAnnotationReader())
6771 : OfNonGenericType.ForLoadedType.of(erasure[index]);
6772 }
6773
6774 /**
6775 * {@inheritDoc}
6776 */
6777 public TypeDescription asErasure() {
6778 return TypeDescription.ForLoadedType.of(erasure[index]);
6779 }
6780
6781 @Override
6782 protected AnnotationReader getAnnotationReader() {
6783 return AnnotationReader.DISPATCHER.resolveParameterType(constructor, index);
6784 }
6785 }
6786
6787 /**
6788 * A lazy projection of the parameter type of a {@link Method}.
6789 */
6790 public static class OfMethodParameter extends LazyProjection.WithEagerNavigation.OfAnnotatedElement {
6791
6792 /**
6793 * The method of which a parameter type is represented.
6794 */
6795 private final Method method;
6796
6797 /**
6798 * The parameter's index.
6799 */
6800 private final int index;
6801
6802 /**
6803 * The erasures of the method's parameter types.
6804 */
6805 private final Class<?>[] erasure;
6806
6807 /**
6808 * Creates a lazy projection of a constructor's parameter.
6809 *
6810 * @param method The method of which a parameter type is represented.
6811 * @param index The parameter's index.
6812 * @param erasure The erasures of the method's parameter types.
6813 */
6814 @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is never exposed outside of the class")
6815 public OfMethodParameter(Method method, int index, Class<?>[] erasure) {
6816 this.method = method;
6817 this.index = index;
6818 this.erasure = erasure;
6819 }
6820
6821 @Override
6822 @CachedReturnPlugin.Enhance("resolved")
6823 protected Generic resolve() {
6824 java.lang.reflect.Type[] type = method.getGenericParameterTypes();
6825 return erasure.length == type.length
6826 ? Sort.describe(type[index], getAnnotationReader())
6827 : OfNonGenericType.ForLoadedType.of(erasure[index]);
6828 }
6829
6830 /**
6831 * {@inheritDoc}
6832 */
6833 public TypeDescription asErasure() {
6834 return TypeDescription.ForLoadedType.of(erasure[index]);
6835 }
6836
6837 @Override
6838 protected AnnotationReader getAnnotationReader() {
6839 return AnnotationReader.DISPATCHER.resolveParameterType(method, index);
6840 }
6841 }
6842
6843 /**
6844 * A lazy projection of a {@code java.lang.reflect.RecordComponent}'s type.
6845 */
6846 public static class OfRecordComponent extends LazyProjection.WithEagerNavigation.OfAnnotatedElement {
6847
6848 /**
6849 * The represented record component.
6850 */
6851 private final Object recordComponent;
6852
6853 /**
6854 * Creates a lazy projection of a {@code java.lang.reflect.RecordComponent}'s type.
6855 *
6856 * @param recordComponent The represented record component.
6857 */
6858 protected OfRecordComponent(Object recordComponent) {
6859 this.recordComponent = recordComponent;
6860 }
6861
6862 @Override
6863 @CachedReturnPlugin.Enhance("resolved")
6864 protected Generic resolve() {
6865 return Sort.describe(RecordComponentDescription.ForLoadedRecordComponent.DISPATCHER.getGenericType(recordComponent), getAnnotationReader());
6866 }
6867
6868 @Override
6869 public TypeDescription asErasure() {
6870 return ForLoadedType.of(RecordComponentDescription.ForLoadedRecordComponent.DISPATCHER.getType(recordComponent));
6871 }
6872
6873 @Override
6874 protected AnnotationReader getAnnotationReader() {
6875 return new AnnotationReader.Delegator.ForRecordComponent(recordComponent);
6876 }
6877 }
6878
6879 /**
6880 * A lazy projection that applies a visitor only when resolving the generic type but not when reading the erasure.
6881 */
6882 public static class WithResolvedErasure extends LazyProjection.WithEagerNavigation {
6883
6884 /**
6885 * The unresolved generic type.
6886 */
6887 private final Generic delegate;
6888
6889 /**
6890 * The visitor to apply for resolving the generic type.
6891 */
6892 private final Visitor<? extends Generic> visitor;
6893
6894 /**
6895 * The annotation source to apply.
6896 */
6897 private final AnnotationSource annotationSource;
6898
6899 /**
6900 * Creates a lazy projection with a resolved erasure that retains the delegates type annotations.
6901 *
6902 * @param delegate The unresolved generic type.
6903 * @param visitor The visitor to apply for resolving the generic type.
6904 */
6905 public WithResolvedErasure(Generic delegate, Visitor<? extends Generic> visitor) {
6906 this(delegate, visitor, delegate);
6907 }
6908
6909 /**
6910 * Creates a lazy projection with a resolved erasure.
6911 *
6912 * @param delegate The unresolved generic type.
6913 * @param visitor The visitor to apply for resolving the generic type.
6914 * @param annotationSource The annotation source representing this type's type annotations.
6915 */
6916 public WithResolvedErasure(Generic delegate, Visitor<? extends Generic> visitor, AnnotationSource annotationSource) {
6917 this.delegate = delegate;
6918 this.visitor = visitor;
6919 this.annotationSource = annotationSource;
6920 }
6921
6922 /**
6923 * {@inheritDoc}
6924 */
6925 public AnnotationList getDeclaredAnnotations() {
6926 return annotationSource.getDeclaredAnnotations();
6927 }
6928
6929 /**
6930 * {@inheritDoc}
6931 */
6932 public TypeDescription asErasure() {
6933 return delegate.asErasure();
6934 }
6935
6936 @Override
6937 @CachedReturnPlugin.Enhance("resolved")
6938 protected Generic resolve() {
6939 return delegate.accept(visitor);
6940 }
6941 }
6942 }
6943
6944 /**
6945 * A builder for creating describing a generic type as a {@link Generic}.
6946 */
6947 @HashCodeAndEqualsPlugin.Enhance
6948 abstract class Builder {
6949
6950 /**
6951 * Represents an undefined {@link java.lang.reflect.Type} within a build step.
6952 */
6953 private static final java.lang.reflect.Type UNDEFINED = null;
6954
6955 /**
6956 * The type annotations of the current annotated type.
6957 */
6958 protected final List<? extends AnnotationDescription> annotations;
6959
6960 /**
6961 * Creates a new builder for a generic type description.
6962 *
6963 * @param annotations The type annotations of the current annotated type.
6964 */
6965 protected Builder(List<? extends AnnotationDescription> annotations) {
6966 this.annotations = annotations;
6967 }
6968
6969 /**
6970 * Creates a raw type of a type description.
6971 *
6972 * @param type The type to represent as a raw type.
6973 * @return A builder for creating a raw type.
6974 */
6975 public static Builder rawType(Class<?> type) {
6976 return rawType(ForLoadedType.of(type));
6977 }
6978
6979 /**
6980 * Creates a raw type of a type description.
6981 *
6982 * @param type The type to represent as a raw type.
6983 * @return A builder for creating a raw type.
6984 */
6985 public static Builder rawType(TypeDescription type) {
6986 return new Builder.OfNonGenericType(type);
6987 }
6988
6989 /**
6990 * Creates a raw type of a type description where the supplied owner type is used as .
6991 *
6992 * @param type The type to represent as a raw type.
6993 * @param ownerType The raw type's (annotated) declaring type or {@code null} if no owner type should be declared.
6994 * @return A builder for creating a raw type.
6995 */
6996 public static Builder rawType(Class<?> type, Generic ownerType) {
6997 return rawType(ForLoadedType.of(type), ownerType);
6998 }
6999
7000 /**
7001 * Creates a raw type of a type description.
7002 *
7003 * @param type The type to represent as a raw type.
7004 * @param ownerType The raw type's (annotated) declaring type or {@code null} if no owner type should be declared.
7005 * @return A builder for creating a raw type.
7006 */
7007 public static Builder rawType(TypeDescription type, Generic ownerType) {
7008 TypeDescription declaringType = type.getDeclaringType();
7009 if (declaringType == null && ownerType != null) {
7010 throw new IllegalArgumentException(type + " does not have a declaring type: " + ownerType);
7011 } else if (declaringType != null && (ownerType == null || !declaringType.equals(ownerType.asErasure()))) {
7012 throw new IllegalArgumentException(ownerType + " is not the declaring type of " + type);
7013 }
7014 return new Builder.OfNonGenericType(type, ownerType);
7015 }
7016
7017 /**
7018 * Creates an unbound wildcard without type annotations.
7019 *
7020 * @return A description of an unbound wildcard without type annotations.
7021 */
7022 public static Generic unboundWildcard() {
7023 return unboundWildcard(Collections.<AnnotationDescription>emptySet());
7024 }
7025
7026 /**
7027 * Creates an unbound wildcard.
7028 *
7029 * @param annotation The type annotations of the unbound wildcard.
7030 * @return A description of an unbound wildcard.
7031 */
7032 public static Generic unboundWildcard(Annotation... annotation) {
7033 return unboundWildcard(Arrays.asList(annotation));
7034 }
7035
7036 /**
7037 * Creates an unbound wildcard.
7038 *
7039 * @param annotations The type annotations of the unbound wildcard.
7040 * @return A description of an unbound wildcard.
7041 */
7042 public static Generic unboundWildcard(List<? extends Annotation> annotations) {
7043 return unboundWildcard(new AnnotationList.ForLoadedAnnotations(annotations));
7044 }
7045
7046 /**
7047 * Creates an unbound wildcard.
7048 *
7049 * @param annotation The type annotations of the unbound wildcard.
7050 * @return A description of an unbound wildcard.
7051 */
7052 public static Generic unboundWildcard(AnnotationDescription... annotation) {
7053 return unboundWildcard(Arrays.asList(annotation));
7054 }
7055
7056 /**
7057 * Creates an unbound wildcard.
7058 *
7059 * @param annotations The type annotations of the unbound wildcard.
7060 * @return A description of an unbound wildcard.
7061 */
7062 public static Generic unboundWildcard(Collection<? extends AnnotationDescription> annotations) {
7063 return OfWildcardType.Latent.unbounded(new Explicit(new ArrayList<AnnotationDescription>(annotations)));
7064 }
7065
7066 /**
7067 * Creates a symbolic type variable of the given name.
7068 *
7069 * @param symbol The symbolic name of the type variable.
7070 * @return A builder for creating a type variable.
7071 */
7072 public static Builder typeVariable(String symbol) {
7073 return new OfTypeVariable(symbol);
7074 }
7075
7076 /**
7077 * Creates a parameterized type without an owner type or with a non-generic owner type.
7078 *
7079 * @param rawType A raw version of the type to describe as a parameterized type.
7080 * @param parameter The type arguments to attach to the raw type as parameters.
7081 * @return A builder for creating a parameterized type.
7082 */
7083 public static Builder parameterizedType(Class<?> rawType, java.lang.reflect.Type... parameter) {
7084 return parameterizedType(rawType, Arrays.asList(parameter));
7085 }
7086
7087 /**
7088 * Creates a parameterized type without an owner type or with a non-generic owner type.
7089 *
7090 * @param rawType A raw version of the type to describe as a parameterized type.
7091 * @param parameters The type arguments to attach to the raw type as parameters.
7092 * @return A builder for creating a parameterized type.
7093 */
7094 public static Builder parameterizedType(Class<?> rawType, List<? extends java.lang.reflect.Type> parameters) {
7095 return parameterizedType(rawType, UNDEFINED, parameters);
7096 }
7097
7098 /**
7099 * Creates a parameterized type.
7100 *
7101 * @param rawType A raw version of the type to describe as a parameterized type.
7102 * @param ownerType The owner type of the parameterized type.
7103 * @param parameters The type arguments to attach to the raw type as parameters.
7104 * @return A builder for creating a parameterized type.
7105 */
7106 public static Builder parameterizedType(Class<?> rawType, java.lang.reflect.Type ownerType, List<? extends java.lang.reflect.Type> parameters) {
7107 return parameterizedType(ForLoadedType.of(rawType),
7108 ownerType == null
7109 ? null
7110 : Sort.describe(ownerType),
7111 new TypeList.Generic.ForLoadedTypes(parameters));
7112 }
7113
7114 /**
7115 * Creates a parameterized type without an owner type or with a non-generic owner type.
7116 *
7117 * @param rawType A raw version of the type to describe as a parameterized type.
7118 * @param parameter The type arguments to attach to the raw type as parameters.
7119 * @return A builder for creating a parameterized type.
7120 */
7121 public static Builder parameterizedType(TypeDescription rawType, TypeDefinition... parameter) {
7122 return parameterizedType(rawType, Arrays.asList(parameter));
7123 }
7124
7125 /**
7126 * Creates a parameterized type without an owner type or with a non-generic owner type.
7127 *
7128 * @param rawType A raw version of the type to describe as a parameterized type.
7129 * @param parameters The type arguments to attach to the raw type as parameters.
7130 * @return A builder for creating a parameterized type.
7131 */
7132 public static Builder parameterizedType(TypeDescription rawType, Collection<? extends TypeDefinition> parameters) {
7133 return parameterizedType(rawType, Generic.UNDEFINED, parameters);
7134 }
7135
7136 /**
7137 * Creates a parameterized type.
7138 *
7139 * @param rawType A raw version of the type to describe as a parameterized type.
7140 * @param ownerType The owner type of the parameterized type.
7141 * @param parameters The type arguments to attach to the raw type as parameters.
7142 * @return A builder for creating a parameterized type.
7143 */
7144 public static Builder parameterizedType(TypeDescription rawType, Generic ownerType, Collection<? extends TypeDefinition> parameters) {
7145 TypeDescription declaringType = rawType.getDeclaringType();
7146 if (ownerType == null && declaringType != null && rawType.isStatic()) {
7147 ownerType = declaringType.asGenericType();
7148 }
7149 if (!rawType.represents(TargetType.class)) {
7150 if (!rawType.isGenerified()) {
7151 throw new IllegalArgumentException(rawType + " is not a parameterized type");
7152 } else if (ownerType == null && declaringType != null && !rawType.isStatic()) {
7153 throw new IllegalArgumentException(rawType + " requires an owner type");
7154 } else if (ownerType != null && !ownerType.asErasure().equals(declaringType)) {
7155 throw new IllegalArgumentException(ownerType + " does not represent required owner for " + rawType);
7156 } else if (ownerType != null && (rawType.isStatic() ^ ownerType.getSort().isNonGeneric())) {
7157 throw new IllegalArgumentException(ownerType + " does not define the correct parameters for owning " + rawType);
7158 } else if (rawType.getTypeVariables().size() != parameters.size()) {
7159 throw new IllegalArgumentException(parameters + " does not contain number of required parameters for " + rawType);
7160 }
7161 }
7162 return new Builder.OfParameterizedType(rawType, ownerType, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(parameters)));
7163 }
7164
7165 /**
7166 * Transforms this type into the upper bound of a wildcard type.
7167 *
7168 * @return A generic type description of a wildcard type with this builder's type as an upper bound.
7169 */
7170 public Generic asWildcardUpperBound() {
7171 return asWildcardUpperBound(Collections.<AnnotationDescription>emptySet());
7172 }
7173
7174 /**
7175 * Transforms this type into the upper bound of a wildcard type.
7176 *
7177 * @param annotation Type annotations to be declared by the wildcard type.
7178 * @return A generic type description of a wildcard type with this builder's type as an upper bound.
7179 */
7180 public Generic asWildcardUpperBound(Annotation... annotation) {
7181 return asWildcardUpperBound(Arrays.asList(annotation));
7182 }
7183
7184 /**
7185 * Transforms this type into the upper bound of a wildcard type.
7186 *
7187 * @param annotations Type annotations to be declared by the wildcard type.
7188 * @return A generic type description of a wildcard type with this builder's type as an upper bound.
7189 */
7190 public Generic asWildcardUpperBound(List<? extends Annotation> annotations) {
7191 return asWildcardUpperBound(new AnnotationList.ForLoadedAnnotations(annotations));
7192 }
7193
7194 /**
7195 * Transforms this type into the upper bound of a wildcard type.
7196 *
7197 * @param annotation Type annotations to be declared by the wildcard type.
7198 * @return A generic type description of a wildcard type with this builder's type as an upper bound.
7199 */
7200 public Generic asWildcardUpperBound(AnnotationDescription... annotation) {
7201 return asWildcardUpperBound(Arrays.asList(annotation));
7202 }
7203
7204 /**
7205 * Transforms this type into the upper bound of a wildcard type.
7206 *
7207 * @param annotations Type annotations to be declared by the wildcard type.
7208 * @return A generic type description of a wildcard type with this builder's type as an upper bound.
7209 */
7210 public Generic asWildcardUpperBound(Collection<? extends AnnotationDescription> annotations) {
7211 return OfWildcardType.Latent.boundedAbove(build(), new Explicit(new ArrayList<AnnotationDescription>(annotations)));
7212 }
7213
7214 /**
7215 * Transforms this type into the lower bound of a wildcard type.
7216 *
7217 * @return A generic type description of a wildcard type with this builder's type as an lower bound.
7218 */
7219 public Generic asWildcardLowerBound() {
7220 return asWildcardLowerBound(Collections.<AnnotationDescription>emptySet());
7221 }
7222
7223 /**
7224 * Transforms this type into the lower bound of a wildcard type.
7225 *
7226 * @param annotation Type annotations to be declared by the wildcard type.
7227 * @return A generic type description of a wildcard type with this builder's type as an lower bound.
7228 */
7229 public Generic asWildcardLowerBound(Annotation... annotation) {
7230 return asWildcardLowerBound(Arrays.asList(annotation));
7231 }
7232
7233 /**
7234 * Transforms this type into the lower bound of a wildcard type.
7235 *
7236 * @param annotations Type annotations to be declared by the wildcard type.
7237 * @return A generic type description of a wildcard type with this builder's type as an lower bound.
7238 */
7239 public Generic asWildcardLowerBound(List<? extends Annotation> annotations) {
7240 return asWildcardLowerBound(new AnnotationList.ForLoadedAnnotations(annotations));
7241 }
7242
7243 /**
7244 * Transforms this type into the lower bound of a wildcard type.
7245 *
7246 * @param annotation Type annotations to be declared by the wildcard type.
7247 * @return A generic type description of a wildcard type with this builder's type as an lower bound.
7248 */
7249 public Generic asWildcardLowerBound(AnnotationDescription... annotation) {
7250 return asWildcardLowerBound(Arrays.asList(annotation));
7251 }
7252
7253 /**
7254 * Transforms this type into the lower bound of a wildcard type.
7255 *
7256 * @param annotations Type annotations to be declared by the wildcard type.
7257 * @return A generic type description of a wildcard type with this builder's type as an lower bound.
7258 */
7259 public Generic asWildcardLowerBound(Collection<? extends AnnotationDescription> annotations) {
7260 return OfWildcardType.Latent.boundedBelow(build(), new Explicit(new ArrayList<AnnotationDescription>(annotations)));
7261 }
7262
7263 /**
7264 * Represents the built type into an array.
7265 *
7266 * @return A builder for creating an array of the currently built type.
7267 */
7268 public Builder asArray() {
7269 return asArray(1);
7270 }
7271
7272 /**
7273 * Represents the built type into an array.
7274 *
7275 * @param arity The arity of the array.
7276 * @return A builder for creating an array of the currently built type.
7277 */
7278 public Builder asArray(int arity) {
7279 if (arity < 1) {
7280 throw new IllegalArgumentException("Cannot define an array of a non-positive arity: " + arity);
7281 }
7282 TypeDescription.Generic typeDescription = build();
7283 while (--arity > 0) {
7284 typeDescription = new OfGenericArray.Latent(typeDescription, Empty.INSTANCE);
7285 }
7286 return new Builder.OfGenericArrayType(typeDescription);
7287 }
7288
7289 /**
7290 * Defines type annotations to be declared by the current type.
7291 *
7292 * @param annotation Type annotations to be declared by the current type.
7293 * @return A new builder where the current type declares the supplied type annotations.
7294 */
7295 public Builder annotate(Annotation... annotation) {
7296 return annotate(Arrays.asList(annotation));
7297 }
7298
7299 /**
7300 * Defines type annotations to be declared by the current type.
7301 *
7302 * @param annotations Type annotations to be declared by the current type.
7303 * @return A new builder where the current type declares the supplied type annotations.
7304 */
7305 public Builder annotate(List<? extends Annotation> annotations) {
7306 return annotate(new AnnotationList.ForLoadedAnnotations(annotations));
7307 }
7308
7309 /**
7310 * Defines type annotations to be declared by the current type.
7311 *
7312 * @param annotation Type annotations to be declared by the current type.
7313 * @return A new builder where the current type declares the supplied type annotations.
7314 */
7315 public Builder annotate(AnnotationDescription... annotation) {
7316 return annotate(Arrays.asList(annotation));
7317 }
7318
7319 /**
7320 * Defines type annotations to be declared by the current type.
7321 *
7322 * @param annotations Type annotations to be declared by the current type.
7323 * @return A new builder where the current type declares the supplied type annotations.
7324 */
7325 public Builder annotate(Collection<? extends AnnotationDescription> annotations) {
7326 return doAnnotate(new ArrayList<AnnotationDescription>(annotations));
7327 }
7328
7329 /**
7330 * Creates a new builder for the current type and the applied type annotations.
7331 *
7332 * @param annotations Type annotations to be declared by the current type.
7333 * @return A new builder where the current type declares the supplied type annotations.
7334 */
7335 protected abstract Builder doAnnotate(List<? extends AnnotationDescription> annotations);
7336
7337 /**
7338 * Finalizes the build and finalizes the created type as a generic type description.
7339 *
7340 * @return A generic type description of the built type.
7341 */
7342 public Generic build() {
7343 return doBuild();
7344 }
7345
7346 /**
7347 * Finalizes the build and finalizes the created type as a generic type description.
7348 *
7349 * @param annotation Type annotations place for the built generic type to declare.
7350 * @return A generic type description of the built type.
7351 */
7352 public Generic build(Annotation... annotation) {
7353 return build(Arrays.asList(annotation));
7354 }
7355
7356 /**
7357 * Finalizes the build and finalizes the created type as a generic type description.
7358 *
7359 * @param annotations Type annotations place for the built generic type to declare.
7360 * @return A generic type description of the built type.
7361 */
7362 public Generic build(List<? extends Annotation> annotations) {
7363 return build(new AnnotationList.ForLoadedAnnotations(annotations));
7364 }
7365
7366 /**
7367 * Finalizes the build and finalizes the created type as a generic type description.
7368 *
7369 * @param annotation Type annotations place for the built generic type to declare.
7370 * @return A generic type description of the built type.
7371 */
7372 public Generic build(AnnotationDescription... annotation) {
7373 return build(Arrays.asList(annotation));
7374 }
7375
7376 /**
7377 * Finalizes the build and finalizes the created type as a generic type description.
7378 *
7379 * @param annotations Type annotations place for the built generic type to declare.
7380 * @return A generic type description of the built type.
7381 */
7382 public Generic build(Collection<? extends AnnotationDescription> annotations) {
7383 return doAnnotate(new ArrayList<AnnotationDescription>(annotations)).doBuild();
7384 }
7385
7386 /**
7387 * Builds the generic type.
7388 *
7389 * @return The generic type.
7390 */
7391 protected abstract Generic doBuild();
7392
7393 /**
7394 * A generic type builder for building a non-generic type.
7395 */
7396 @HashCodeAndEqualsPlugin.Enhance
7397 protected static class OfNonGenericType extends Builder {
7398
7399 /**
7400 * The type's erasure.
7401 */
7402 private final TypeDescription typeDescription;
7403
7404 /**
7405 * The raw type's (annotated) declaring type or {@code null} if no such type is defined.
7406 */
7407 @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
7408 private final Generic ownerType;
7409
7410 /**
7411 * Creates a builder for a non-generic type.
7412 *
7413 * @param typeDescription The type's erasure.
7414 */
7415 protected OfNonGenericType(TypeDescription typeDescription) {
7416 this(typeDescription, typeDescription.getDeclaringType());
7417 }
7418
7419 /**
7420 * Creates a builder for a non-generic type.
7421 *
7422 * @param typeDescription The type's erasure.
7423 * @param ownerType The raw type's raw declaring type or {@code null} if no such type is defined.
7424 */
7425 private OfNonGenericType(TypeDescription typeDescription, TypeDescription ownerType) {
7426 this(typeDescription, ownerType == null
7427 ? Generic.UNDEFINED
7428 : ownerType.asGenericType());
7429 }
7430
7431 /**
7432 * Creates a builder for a non-generic type.
7433 *
7434 * @param typeDescription The type's erasure.
7435 * @param ownerType The raw type's (annotated) declaring type.
7436 */
7437 protected OfNonGenericType(TypeDescription typeDescription, Generic ownerType) {
7438 this(typeDescription, ownerType, Collections.<AnnotationDescription>emptyList());
7439 }
7440
7441 /**
7442 * Creates a builder for a non-generic type.
7443 *
7444 * @param typeDescription The type's erasure.
7445 * @param ownerType The raw type's (annotated) declaring type.
7446 * @param annotations The type's type annotations.
7447 */
7448 protected OfNonGenericType(TypeDescription typeDescription, Generic ownerType, List<? extends AnnotationDescription> annotations) {
7449 super(annotations);
7450 this.ownerType = ownerType;
7451 this.typeDescription = typeDescription;
7452 }
7453
7454 @Override
7455 protected Builder doAnnotate(List<? extends AnnotationDescription> annotations) {
7456 return new OfNonGenericType(typeDescription, ownerType, CompoundList.of(this.annotations, annotations));
7457 }
7458
7459 @Override
7460 protected Generic doBuild() {
7461 if (typeDescription.represents(void.class) && !annotations.isEmpty()) {
7462 throw new IllegalArgumentException("The void non-type cannot be annotated");
7463 }
7464 return new Generic.OfNonGenericType.Latent(typeDescription, ownerType, new Explicit(annotations));
7465 }
7466 }
7467
7468 /**
7469 * A generic type builder for building a parameterized type.
7470 */
7471 @HashCodeAndEqualsPlugin.Enhance
7472 protected static class OfParameterizedType extends Builder {
7473
7474 /**
7475 * The raw base type.
7476 */
7477 private final TypeDescription rawType;
7478
7479 /**
7480 * The generic owner type.
7481 */
7482 private final Generic ownerType;
7483
7484 /**
7485 * The parameter types.
7486 */
7487 private final List<? extends Generic> parameterTypes;
7488
7489 /**
7490 * Creates a builder for a parameterized type.
7491 *
7492 * @param rawType The raw base type.
7493 * @param ownerType The generic owner type.
7494 * @param parameterTypes The parameter types.
7495 */
7496 protected OfParameterizedType(TypeDescription rawType, Generic ownerType, List<? extends Generic> parameterTypes) {
7497 this(rawType, ownerType, parameterTypes, Collections.<AnnotationDescription>emptyList());
7498 }
7499
7500 /**
7501 * Creates a builder for a parameterized type.
7502 *
7503 * @param rawType The raw base type.
7504 * @param ownerType The generic owner type.
7505 * @param parameterTypes The parameter types.
7506 * @param annotations The type's type annotations.
7507 */
7508 protected OfParameterizedType(TypeDescription rawType,
7509 Generic ownerType,
7510 List<? extends Generic> parameterTypes,
7511 List<? extends AnnotationDescription> annotations) {
7512 super(annotations);
7513 this.rawType = rawType;
7514 this.ownerType = ownerType;
7515 this.parameterTypes = parameterTypes;
7516 }
7517
7518 @Override
7519 protected Builder doAnnotate(List<? extends AnnotationDescription> annotations) {
7520 return new OfParameterizedType(rawType, ownerType, parameterTypes, CompoundList.of(this.annotations, annotations));
7521 }
7522
7523 @Override
7524 protected Generic doBuild() {
7525 return new Generic.OfParameterizedType.Latent(rawType, ownerType, parameterTypes, new Explicit(annotations));
7526 }
7527 }
7528
7529 /**
7530 * A generic type builder building a generic array type.
7531 */
7532 @HashCodeAndEqualsPlugin.Enhance
7533 protected static class OfGenericArrayType extends Builder {
7534
7535 /**
7536 * The generic component type.
7537 */
7538 private final Generic componentType;
7539
7540 /**
7541 * Creates a type builder for building a generic array type.
7542 *
7543 * @param componentType The generic component type.
7544 */
7545 protected OfGenericArrayType(Generic componentType) {
7546 this(componentType, Collections.<AnnotationDescription>emptyList());
7547 }
7548
7549 /**
7550 * Creates a type builder for building a generic array type.
7551 *
7552 * @param componentType The generic component type.
7553 * @param annotations The type's type annotations.
7554 */
7555 protected OfGenericArrayType(Generic componentType, List<? extends AnnotationDescription> annotations) {
7556 super(annotations);
7557 this.componentType = componentType;
7558 }
7559
7560 @Override
7561 protected Builder doAnnotate(List<? extends AnnotationDescription> annotations) {
7562 return new OfGenericArrayType(componentType, CompoundList.of(this.annotations, annotations));
7563 }
7564
7565 @Override
7566 protected Generic doBuild() {
7567 return new Generic.OfGenericArray.Latent(componentType, new Explicit(annotations));
7568 }
7569 }
7570
7571 /**
7572 * A generic type builder building a symbolic type variable.
7573 */
7574 @HashCodeAndEqualsPlugin.Enhance
7575 protected static class OfTypeVariable extends Builder {
7576
7577 /**
7578 * The variable's symbol.
7579 */
7580 private final String symbol;
7581
7582 /**
7583 * Creates a new builder for a symbolic type variable.
7584 *
7585 * @param symbol The variable's symbol.
7586 */
7587 protected OfTypeVariable(String symbol) {
7588 this(symbol, Collections.<AnnotationDescription>emptyList());
7589 }
7590
7591 /**
7592 * Creates a new builder for a symbolic type variable.
7593 *
7594 * @param symbol The variable's symbol.
7595 * @param annotations The type's type annotations.
7596 */
7597 protected OfTypeVariable(String symbol, List<? extends AnnotationDescription> annotations) {
7598 super(annotations);
7599 this.symbol = symbol;
7600 }
7601
7602 @Override
7603 protected Builder doAnnotate(List<? extends AnnotationDescription> annotations) {
7604 return new OfTypeVariable(symbol, CompoundList.of(this.annotations, annotations));
7605 }
7606
7607 @Override
7608 protected Generic doBuild() {
7609 return new Generic.OfTypeVariable.Symbolic(symbol, new Explicit(annotations));
7610 }
7611 }
7612 }
7613 }
7614
7615 /**
7616 * An abstract base implementation of a type description.
7617 */
7618 abstract class AbstractBase extends TypeVariableSource.AbstractBase implements TypeDescription {
7619
7620 /**
7621 * The {@link TypeDefinition#RAW_TYPES_PROPERTY} property.
7622 */
7623 public static final boolean RAW_TYPES;
7624
7625 /*
7626 * Reads the raw type property.
7627 */
7628 static {
7629 boolean rawTypes;
7630 try {
7631 rawTypes = Boolean.parseBoolean(AccessController.doPrivileged(new GetSystemPropertyAction(RAW_TYPES_PROPERTY)));
7632 } catch (Exception ignored) {
7633 rawTypes = false;
7634 }
7635 RAW_TYPES = rawTypes;
7636 }
7637
7638 /**
7639 * Checks if a specific type is assignable to another type where the source type must be a super
7640 * type of the target type.
7641 *
7642 * @param sourceType The source type to which another type is to be assigned to.
7643 * @param targetType The target type that is to be assigned to the source type.
7644 * @return {@code true} if the target type is assignable to the source type.
7645 */
7646 private static boolean isAssignable(TypeDescription sourceType, TypeDescription targetType) {
7647 // Means that '[sourceType] var = ([targetType]) val;' is a valid assignment. This is true, if:
7648 // (1) Both types are equal (implies primitive types.)
7649 if (sourceType.equals(targetType)) {
7650 return true;
7651 }
7652 // (2) For arrays, there are special assignment rules.
7653 if (targetType.isArray()) {
7654 return sourceType.isArray()
7655 ? isAssignable(sourceType.getComponentType(), targetType.getComponentType())
7656 : sourceType.represents(Object.class) || ARRAY_INTERFACES.contains(sourceType.asGenericType());
7657 }
7658 // (3) Interfaces do not extend the Object type but are assignable to the Object type.
7659 if (sourceType.represents(Object.class)) {
7660 return !targetType.isPrimitive();
7661 }
7662 // (4) The sub type has a super type and this super type is assignable to the super type.
7663 Generic superClass = targetType.getSuperClass();
7664 if (superClass != null && sourceType.isAssignableFrom(superClass.asErasure())) {
7665 return true;
7666 }
7667 // (5) If the target type is an interface, any of this type's interfaces might be assignable to it.
7668 if (sourceType.isInterface()) {
7669 for (TypeDescription interfaceType : targetType.getInterfaces().asErasures()) {
7670 if (sourceType.isAssignableFrom(interfaceType)) {
7671 return true;
7672 }
7673 }
7674 }
7675 // (6) None of these criteria are true, i.e. the types are not assignable.
7676 return false;
7677 }
7678
7679 /**
7680 * {@inheritDoc}
7681 */
7682 public boolean isAssignableFrom(Class<?> type) {
7683 return isAssignableFrom(ForLoadedType.of(type));
7684 }
7685
7686 /**
7687 * {@inheritDoc}
7688 */
7689 public boolean isAssignableFrom(TypeDescription typeDescription) {
7690 return isAssignable(this, typeDescription);
7691 }
7692
7693 /**
7694 * {@inheritDoc}
7695 */
7696 public boolean isAssignableTo(Class<?> type) {
7697 return isAssignableTo(ForLoadedType.of(type));
7698 }
7699
7700 /**
7701 * {@inheritDoc}
7702 */
7703 public boolean isAssignableTo(TypeDescription typeDescription) {
7704 return isAssignable(typeDescription, this);
7705 }
7706
7707 /**
7708 * {@inheritDoc}
7709 */
7710 public boolean isInHierarchyWith(Class<?> type) {
7711 return isAssignableTo(type) || isAssignableFrom(type);
7712 }
7713
7714 /**
7715 * {@inheritDoc}
7716 */
7717 public boolean isInHierarchyWith(TypeDescription typeDescription) {
7718 return isAssignableTo(typeDescription) || isAssignableFrom(typeDescription);
7719 }
7720
7721 /**
7722 * {@inheritDoc}
7723 */
7724 public TypeDescription asErasure() {
7725 return this;
7726 }
7727
7728 /**
7729 * {@inheritDoc}
7730 */
7731 public Generic asGenericType() {
7732 return new Generic.OfNonGenericType.ForErasure(this);
7733 }
7734
7735 /**
7736 * {@inheritDoc}
7737 */
7738 public Sort getSort() {
7739 return Sort.NON_GENERIC;
7740 }
7741
7742 /**
7743 * {@inheritDoc}
7744 */
7745 public boolean isInstance(Object value) {
7746 return isAssignableFrom(value.getClass());
7747 }
7748
7749 /**
7750 * {@inheritDoc}
7751 */
7752 public boolean isAnnotationValue(Object value) {
7753 if ((represents(Class.class) && value instanceof TypeDescription)
7754 || (value instanceof AnnotationDescription && ((AnnotationDescription) value).getAnnotationType().equals(this))
7755 || (value instanceof EnumerationDescription && ((EnumerationDescription) value).getEnumerationType().equals(this))
7756 || (represents(String.class) && value instanceof String)
7757 || (represents(boolean.class) && value instanceof Boolean)
7758 || (represents(byte.class) && value instanceof Byte)
7759 || (represents(short.class) && value instanceof Short)
7760 || (represents(char.class) && value instanceof Character)
7761 || (represents(int.class) && value instanceof Integer)
7762 || (represents(long.class) && value instanceof Long)
7763 || (represents(float.class) && value instanceof Float)
7764 || (represents(double.class) && value instanceof Double)
7765 || (represents(String[].class) && value instanceof String[])
7766 || (represents(boolean[].class) && value instanceof boolean[])
7767 || (represents(byte[].class) && value instanceof byte[])
7768 || (represents(short[].class) && value instanceof short[])
7769 || (represents(char[].class) && value instanceof char[])
7770 || (represents(int[].class) && value instanceof int[])
7771 || (represents(long[].class) && value instanceof long[])
7772 || (represents(float[].class) && value instanceof float[])
7773 || (represents(double[].class) && value instanceof double[])
7774 || (represents(Class[].class) && value instanceof TypeDescription[])) {
7775 return true;
7776 } else if (isAssignableTo(Annotation[].class) && value instanceof AnnotationDescription[]) {
7777 for (AnnotationDescription annotationDescription : (AnnotationDescription[]) value) {
7778 if (!annotationDescription.getAnnotationType().equals(getComponentType())) {
7779 return false;
7780 }
7781 }
7782 return true;
7783 } else if (isAssignableTo(Enum[].class) && value instanceof EnumerationDescription[]) {
7784 for (EnumerationDescription enumerationDescription : (EnumerationDescription[]) value) {
7785 if (!enumerationDescription.getEnumerationType().equals(getComponentType())) {
7786 return false;
7787 }
7788 }
7789 return true;
7790 } else {
7791 return false;
7792 }
7793 }
7794
7795 /**
7796 * {@inheritDoc}
7797 */
7798 public String getInternalName() {
7799 return getName().replace('.', '/');
7800 }
7801
7802 /**
7803 * {@inheritDoc}
7804 */
7805 public int getActualModifiers(boolean superFlag) {
7806 int actualModifiers = getModifiers()
7807 | (getDeclaredAnnotations().isAnnotationPresent(Deprecated.class) ? Opcodes.ACC_DEPRECATED : EMPTY_MASK)
7808 | (isRecord() ? Opcodes.ACC_RECORD : EMPTY_MASK)
7809 | (superFlag ? Opcodes.ACC_SUPER : EMPTY_MASK);
7810 if (isPrivate()) {
7811 return actualModifiers & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC);
7812 } else if (isProtected()) {
7813 return actualModifiers & ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC) | Opcodes.ACC_PUBLIC;
7814 } else {
7815 return actualModifiers & ~Opcodes.ACC_STATIC;
7816 }
7817 }
7818
7819 /**
7820 * {@inheritDoc}
7821 */
7822 public String getGenericSignature() {
7823 try {
7824 SignatureWriter signatureWriter = new SignatureWriter();
7825 boolean generic = false;
7826 for (Generic typeVariable : getTypeVariables()) {
7827 signatureWriter.visitFormalTypeParameter(typeVariable.getSymbol());
7828 for (Generic upperBound : typeVariable.getUpperBounds()) {
7829 upperBound.accept(new Generic.Visitor.ForSignatureVisitor(upperBound.asErasure().isInterface()
7830 ? signatureWriter.visitInterfaceBound()
7831 : signatureWriter.visitClassBound()));
7832 }
7833 generic = true;
7834 }
7835 Generic superClass = getSuperClass();
7836 // The object type itself is non generic and implicitly returns a non-generic signature
7837 if (superClass == null) {
7838 superClass = TypeDescription.Generic.OBJECT;
7839 }
7840 superClass.accept(new Generic.Visitor.ForSignatureVisitor(signatureWriter.visitSuperclass()));
7841 generic = generic || !superClass.getSort().isNonGeneric();
7842 for (Generic interfaceType : getInterfaces()) {
7843 interfaceType.accept(new Generic.Visitor.ForSignatureVisitor(signatureWriter.visitInterface()));
7844 generic = generic || !interfaceType.getSort().isNonGeneric();
7845 }
7846 return generic
7847 ? signatureWriter.toString()
7848 : NON_GENERIC_SIGNATURE;
7849 } catch (GenericSignatureFormatError ignored) {
7850 return NON_GENERIC_SIGNATURE;
7851 }
7852 }
7853
7854 /**
7855 * {@inheritDoc}
7856 */
7857 public boolean isSamePackage(TypeDescription typeDescription) {
7858 PackageDescription thisPackage = getPackage(), otherPackage = typeDescription.getPackage();
7859 return thisPackage == null || otherPackage == null
7860 ? thisPackage == otherPackage
7861 : thisPackage.equals(otherPackage);
7862 }
7863
7864 /**
7865 * {@inheritDoc}
7866 */
7867 public boolean isVisibleTo(TypeDescription typeDescription) {
7868 return isPrimitive() || (isArray()
7869 ? getComponentType().isVisibleTo(typeDescription)
7870 : isPublic() || isProtected() || isSamePackage(typeDescription)/* || equals(typeDescription.asErasure()) */);
7871 }
7872
7873 /**
7874 * {@inheritDoc}
7875 */
7876 public boolean isAccessibleTo(TypeDescription typeDescription) {
7877 return isPrimitive() || (isArray()
7878 ? getComponentType().isVisibleTo(typeDescription)
7879 : isPublic() || isSamePackage(typeDescription)/* || equals(typeDescription.asErasure()) */);
7880 }
7881
7882 /**
7883 * {@inheritDoc}
7884 */
7885 public AnnotationList getInheritedAnnotations() {
7886 Generic superClass = getSuperClass();
7887 AnnotationList declaredAnnotations = getDeclaredAnnotations();
7888 if (superClass == null) {
7889 return declaredAnnotations;
7890 } else {
7891 Set<TypeDescription> annotationTypes = new HashSet<TypeDescription>();
7892 for (AnnotationDescription annotationDescription : declaredAnnotations) {
7893 annotationTypes.add(annotationDescription.getAnnotationType());
7894 }
7895 return new AnnotationList.Explicit(CompoundList.of(declaredAnnotations, superClass.asErasure().getInheritedAnnotations().inherited(annotationTypes)));
7896 }
7897 }
7898
7899 /**
7900 * {@inheritDoc}
7901 */
7902 public String getActualName() {
7903 if (isArray()) {
7904 TypeDescription typeDescription = this;
7905 int dimensions = 0;
7906 do {
7907 dimensions++;
7908 typeDescription = typeDescription.getComponentType();
7909 } while (typeDescription.isArray());
7910 StringBuilder stringBuilder = new StringBuilder();
7911 stringBuilder.append(typeDescription.getActualName());
7912 for (int i = 0; i < dimensions; i++) {
7913 stringBuilder.append("[]");
7914 }
7915 return stringBuilder.toString();
7916 } else {
7917 return getName();
7918 }
7919 }
7920
7921 /**
7922 * {@inheritDoc}
7923 */
7924 public boolean isPrimitiveWrapper() {
7925 return represents(Boolean.class)
7926 || represents(Byte.class)
7927 || represents(Short.class)
7928 || represents(Character.class)
7929 || represents(Integer.class)
7930 || represents(Long.class)
7931 || represents(Float.class)
7932 || represents(Double.class);
7933 }
7934
7935 /**
7936 * {@inheritDoc}
7937 */
7938 public boolean isAnnotationReturnType() {
7939 return isPrimitive()
7940 || represents(String.class)
7941 || (isAssignableTo(Enum.class) && !represents(Enum.class))
7942 || (isAssignableTo(Annotation.class) && !represents(Annotation.class))
7943 || represents(Class.class)
7944 || (isArray() && !getComponentType().isArray() && getComponentType().isAnnotationReturnType());
7945 }
7946
7947 /**
7948 * {@inheritDoc}
7949 */
7950 public boolean isAnnotationValue() {
7951 return isPrimitive()
7952 || represents(String.class)
7953 || isAssignableTo(TypeDescription.class)
7954 || isAssignableTo(AnnotationDescription.class)
7955 || isAssignableTo(EnumerationDescription.class)
7956 || (isArray() && !getComponentType().isArray() && getComponentType().isAnnotationValue());
7957 }
7958
7959 /**
7960 * {@inheritDoc}
7961 */
7962 @SuppressFBWarnings(value = "EC_UNRELATED_CLASS_AND_INTERFACE", justification = "Fits equality contract for type definitions")
7963 public boolean represents(java.lang.reflect.Type type) {
7964 return equals(Sort.describe(type));
7965 }
7966
7967 /**
7968 * {@inheritDoc}
7969 */
7970 public String getTypeName() {
7971 return getName();
7972 }
7973
7974 /**
7975 * {@inheritDoc}
7976 */
7977 public TypeVariableSource getEnclosingSource() {
7978 MethodDescription enclosingMethod = getEnclosingMethod();
7979 return enclosingMethod == null
7980 ? (isStatic() ? TypeVariableSource.UNDEFINED : getEnclosingType()) // Top-level classes (non-static) have no enclosing type.
7981 : enclosingMethod;
7982 }
7983
7984 /**
7985 * {@inheritDoc}
7986 */
7987 public boolean isInferrable() {
7988 return false;
7989 }
7990
7991 /**
7992 * {@inheritDoc}
7993 */
7994 public <T> T accept(TypeVariableSource.Visitor<T> visitor) {
7995 return visitor.onType(this);
7996 }
7997
7998 /**
7999 * {@inheritDoc}
8000 */
8001 public boolean isPackageType() {
8002 return getSimpleName().equals(PackageDescription.PACKAGE_CLASS_NAME);
8003 }
8004
8005 /**
8006 * {@inheritDoc}
8007 */
8008 public boolean isGenerified() {
8009 if (!getTypeVariables().isEmpty()) {
8010 return true;
8011 } else if (isStatic()) {
8012 return false;
8013 }
8014 TypeDescription declaringType = getDeclaringType();
8015 return declaringType != null && declaringType.isGenerified();
8016 }
8017
8018 /**
8019 * {@inheritDoc}
8020 */
8021 public int getInnerClassCount() {
8022 if (isStatic()) {
8023 return 0;
8024 }
8025 TypeDescription declaringType = getDeclaringType();
8026 return declaringType == null
8027 ? 0
8028 : declaringType.getInnerClassCount() + 1;
8029 }
8030
8031 /**
8032 * {@inheritDoc}
8033 */
8034 public boolean isInnerClass() {
8035 return !isStatic() && isNestedClass();
8036 }
8037
8038 /**
8039 * {@inheritDoc}
8040 */
8041 public boolean isNestedClass() {
8042 return getDeclaringType() != null;
8043 }
8044
8045 /**
8046 * {@inheritDoc}
8047 */
8048 public TypeDescription asBoxed() {
8049 if (represents(boolean.class)) {
8050 return ForLoadedType.of(Boolean.class);
8051 } else if (represents(byte.class)) {
8052 return ForLoadedType.of(Byte.class);
8053 } else if (represents(short.class)) {
8054 return ForLoadedType.of(Short.class);
8055 } else if (represents(char.class)) {
8056 return ForLoadedType.of(Character.class);
8057 } else if (represents(int.class)) {
8058 return ForLoadedType.of(Integer.class);
8059 } else if (represents(long.class)) {
8060 return ForLoadedType.of(Long.class);
8061 } else if (represents(float.class)) {
8062 return ForLoadedType.of(Float.class);
8063 } else if (represents(double.class)) {
8064 return ForLoadedType.of(Double.class);
8065 } else {
8066 return this;
8067 }
8068 }
8069
8070 /**
8071 * {@inheritDoc}
8072 */
8073 public TypeDescription asUnboxed() {
8074 if (represents(Boolean.class)) {
8075 return ForLoadedType.of(boolean.class);
8076 } else if (represents(Byte.class)) {
8077 return ForLoadedType.of(byte.class);
8078 } else if (represents(Short.class)) {
8079 return ForLoadedType.of(short.class);
8080 } else if (represents(Character.class)) {
8081 return ForLoadedType.of(char.class);
8082 } else if (represents(Integer.class)) {
8083 return ForLoadedType.of(int.class);
8084 } else if (represents(Long.class)) {
8085 return ForLoadedType.of(long.class);
8086 } else if (represents(Float.class)) {
8087 return ForLoadedType.of(float.class);
8088 } else if (represents(Double.class)) {
8089 return ForLoadedType.of(double.class);
8090 } else {
8091 return this;
8092 }
8093 }
8094
8095 /**
8096 * {@inheritDoc}
8097 */
8098 public Object getDefaultValue() {
8099 if (represents(boolean.class)) {
8100 return false;
8101 } else if (represents(byte.class)) {
8102 return (byte) 0;
8103 } else if (represents(short.class)) {
8104 return (short) 0;
8105 } else if (represents(char.class)) {
8106 return (char) 0;
8107 } else if (represents(int.class)) {
8108 return 0;
8109 } else if (represents(long.class)) {
8110 return 0L;
8111 } else if (represents(float.class)) {
8112 return 0f;
8113 } else if (represents(double.class)) {
8114 return 0d;
8115 } else {
8116 return null;
8117 }
8118 }
8119
8120 /**
8121 * {@inheritDoc}
8122 */
8123 public boolean isNestHost() {
8124 return equals(getNestHost());
8125 }
8126
8127 /**
8128 * {@inheritDoc}
8129 */
8130 public boolean isNestMateOf(Class<?> type) {
8131 return isNestMateOf(ForLoadedType.of(type));
8132 }
8133
8134 /**
8135 * {@inheritDoc}
8136 */
8137 public boolean isNestMateOf(TypeDescription typeDescription) {
8138 return getNestHost().equals(typeDescription.getNestHost());
8139 }
8140
8141 /**
8142 * {@inheritDoc}
8143 */
8144 public boolean isMemberType() {
8145 return !isLocalType() && !isAnonymousType() && getDeclaringType() != null;
8146 }
8147
8148 /**
8149 * {@inheritDoc}
8150 */
8151 public boolean isCompileTimeConstant() {
8152 return represents(int.class)
8153 || represents(long.class)
8154 || represents(float.class)
8155 || represents(double.class)
8156 || represents(String.class)
8157 || represents(Class.class)
8158 || equals(JavaType.METHOD_TYPE.getTypeStub())
8159 || equals(JavaType.METHOD_HANDLE.getTypeStub());
8160 }
8161
8162 /**
8163 * {@inheritDoc}
8164 */
8165 public boolean isSealed() {
8166 return !isPrimitive() && !isArray() && !getPermittedSubclasses().isEmpty();
8167 }
8168
8169 /**
8170 * {@inheritDoc}
8171 */
8172 public Iterator<TypeDefinition> iterator() {
8173 return new SuperClassIterator(this);
8174 }
8175
8176 @Override
8177 @CachedReturnPlugin.Enhance
8178 public int hashCode() {
8179 return getName().hashCode();
8180 }
8181
8182 @Override
8183 public boolean equals(Object other) {
8184 if (this == other) {
8185 return true;
8186 } else if (!(other instanceof TypeDefinition)) {
8187 return false;
8188 }
8189 TypeDefinition typeDefinition = (TypeDefinition) other;
8190 return typeDefinition.getSort().isNonGeneric() && getName().equals(typeDefinition.asErasure().getName());
8191 }
8192
8193 @Override
8194 public String toString() {
8195 return (isPrimitive() ? "" : (isInterface() ? "interface" : "class") + " ") + getName();
8196 }
8197
8198 /**
8199 * An adapter implementation of a {@link TypeDescription} that
8200 * describes any type that is not an array or a primitive type.
8201 */
8202 public abstract static class OfSimpleType extends TypeDescription.AbstractBase {
8203
8204 /**
8205 * {@inheritDoc}
8206 */
8207 public boolean isPrimitive() {
8208 return false;
8209 }
8210
8211 /**
8212 * {@inheritDoc}
8213 */
8214 public boolean isArray() {
8215 return false;
8216 }
8217
8218 /**
8219 * {@inheritDoc}
8220 */
8221 public TypeDescription getComponentType() {
8222 return TypeDescription.UNDEFINED;
8223 }
8224
8225 /**
8226 * {@inheritDoc}
8227 */
8228 public String getDescriptor() {
8229 return "L" + getInternalName() + ";";
8230 }
8231
8232 /**
8233 * {@inheritDoc}
8234 */
8235 public String getCanonicalName() {
8236 if (isAnonymousType() || isLocalType()) {
8237 return NO_NAME;
8238 }
8239 String internalName = getInternalName();
8240 TypeDescription enclosingType = getEnclosingType();
8241 if (enclosingType != null && internalName.startsWith(enclosingType.getInternalName() + "$")) {
8242 return enclosingType.getCanonicalName() + "." + internalName.substring(enclosingType.getInternalName().length() + 1);
8243 } else {
8244 return getName();
8245 }
8246 }
8247
8248 /**
8249 * {@inheritDoc}
8250 */
8251 public String getSimpleName() {
8252 String internalName = getInternalName();
8253 TypeDescription enclosingType = getEnclosingType();
8254 int simpleNameIndex;
8255 if (enclosingType != null && internalName.startsWith(enclosingType.getInternalName() + "$")) {
8256 simpleNameIndex = enclosingType.getInternalName().length() + 1;
8257 } else {
8258 simpleNameIndex = internalName.lastIndexOf('/');
8259 if (simpleNameIndex == -1) {
8260 return internalName;
8261 }
8262 }
8263 while (simpleNameIndex < internalName.length() && !Character.isLetter(internalName.charAt(simpleNameIndex))) {
8264 simpleNameIndex += 1;
8265 }
8266 return internalName.substring(simpleNameIndex);
8267 }
8268
8269 /**
8270 * {@inheritDoc}
8271 */
8272 public StackSize getStackSize() {
8273 return StackSize.SINGLE;
8274 }
8275
8276 /**
8277 * An implementation of a type description that delegates all properties but the type's name to a delegate.
8278 */
8279 public abstract static class WithDelegation extends OfSimpleType {
8280
8281 /**
8282 * Returns the delegate type description to this type instance.
8283 *
8284 * @return The delegate type description.
8285 */
8286 protected abstract TypeDescription delegate();
8287
8288 /**
8289 * {@inheritDoc}
8290 */
8291 public Generic getSuperClass() {
8292 return delegate().getSuperClass();
8293 }
8294
8295 /**
8296 * {@inheritDoc}
8297 */
8298 public TypeList.Generic getInterfaces() {
8299 return delegate().getInterfaces();
8300 }
8301
8302 /**
8303 * {@inheritDoc}
8304 */
8305 public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
8306 return delegate().getDeclaredFields();
8307 }
8308
8309 /**
8310 * {@inheritDoc}
8311 */
8312 public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
8313 return delegate().getDeclaredMethods();
8314 }
8315
8316 /**
8317 * {@inheritDoc}
8318 */
8319 public TypeDescription getDeclaringType() {
8320 return delegate().getDeclaringType();
8321 }
8322
8323 /**
8324 * {@inheritDoc}
8325 */
8326 public MethodDescription.InDefinedShape getEnclosingMethod() {
8327 return delegate().getEnclosingMethod();
8328 }
8329
8330 /**
8331 * {@inheritDoc}
8332 */
8333 public TypeDescription getEnclosingType() {
8334 return delegate().getEnclosingType();
8335 }
8336
8337 /**
8338 * {@inheritDoc}
8339 */
8340 public TypeList getDeclaredTypes() {
8341 return delegate().getDeclaredTypes();
8342 }
8343
8344 /**
8345 * {@inheritDoc}
8346 */
8347 public boolean isAnonymousType() {
8348 return delegate().isAnonymousType();
8349 }
8350
8351 /**
8352 * {@inheritDoc}
8353 */
8354 public boolean isLocalType() {
8355 return delegate().isLocalType();
8356 }
8357
8358 /**
8359 * {@inheritDoc}
8360 */
8361 public PackageDescription getPackage() {
8362 return delegate().getPackage();
8363 }
8364
8365 /**
8366 * {@inheritDoc}
8367 */
8368 public AnnotationList getDeclaredAnnotations() {
8369 return delegate().getDeclaredAnnotations();
8370 }
8371
8372 /**
8373 * {@inheritDoc}
8374 */
8375 public TypeList.Generic getTypeVariables() {
8376 return delegate().getTypeVariables();
8377 }
8378
8379 /**
8380 * {@inheritDoc}
8381 */
8382 public int getModifiers() {
8383 return delegate().getModifiers();
8384 }
8385
8386 @Override
8387 public String getGenericSignature() {
8388 // Embrace use of native generic signature by direct delegation.
8389 return delegate().getGenericSignature();
8390 }
8391
8392 @Override
8393 public int getActualModifiers(boolean superFlag) {
8394 // Embrace use of native actual modifiers by direct delegation.
8395 return delegate().getActualModifiers(superFlag);
8396 }
8397
8398 /**
8399 * {@inheritDoc}
8400 */
8401 public TypeDescription getNestHost() {
8402 return delegate().getNestHost();
8403 }
8404
8405 /**
8406 * {@inheritDoc}
8407 */
8408 public TypeList getNestMembers() {
8409 return delegate().getNestMembers();
8410 }
8411
8412 /**
8413 * {@inheritDoc}
8414 */
8415 public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
8416 return delegate().getRecordComponents();
8417 }
8418
8419 /**
8420 * {@inheritDoc}
8421 */
8422 public boolean isRecord() {
8423 return delegate().isRecord();
8424 }
8425
8426 /**
8427 * {@inheritDoc}
8428 */
8429 public TypeList getPermittedSubclasses() {
8430 return delegate().getPermittedSubclasses();
8431 }
8432 }
8433 }
8434 }
8435
8436 /**
8437 * A type description implementation that represents a loaded type.
8438 */
8439 @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "Field is only used as a cache store and is implicitly recomputed")
8440 class ForLoadedType extends AbstractBase implements Serializable {
8441
8442 /**
8443 * The class's serial version UID.
8444 */
8445 private static final long serialVersionUID = 1L;
8446
8447 /**
8448 * A dispatcher for invking methods on {@link Class} reflectively.
8449 */
8450 private static final Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE);
8451
8452 /**
8453 * A cache of type descriptions for commonly used types to avoid unnecessary allocations.
8454 */
8455 @SuppressFBWarnings(value = "MS_MUTABLE_COLLECTION_PKGPROTECT", justification = "This collection is not exposed.")
8456 private static final Map<Class<?>, TypeDescription> TYPE_CACHE;
8457
8458 /*
8459 * Initializes the type cache.
8460 */
8461 static {
8462 TYPE_CACHE = new HashMap<Class<?>, TypeDescription>();
8463 TYPE_CACHE.put(TargetType.class, new ForLoadedType(TargetType.class));
8464 TYPE_CACHE.put(Object.class, new ForLoadedType(Object.class));
8465 TYPE_CACHE.put(String.class, new ForLoadedType(String.class));
8466 TYPE_CACHE.put(Boolean.class, new ForLoadedType(Boolean.class));
8467 TYPE_CACHE.put(Byte.class, new ForLoadedType(Byte.class));
8468 TYPE_CACHE.put(Short.class, new ForLoadedType(Short.class));
8469 TYPE_CACHE.put(Character.class, new ForLoadedType(Character.class));
8470 TYPE_CACHE.put(Integer.class, new ForLoadedType(Integer.class));
8471 TYPE_CACHE.put(Long.class, new ForLoadedType(Long.class));
8472 TYPE_CACHE.put(Float.class, new ForLoadedType(Float.class));
8473 TYPE_CACHE.put(Double.class, new ForLoadedType(Double.class));
8474 TYPE_CACHE.put(void.class, new ForLoadedType(void.class));
8475 TYPE_CACHE.put(boolean.class, new ForLoadedType(boolean.class));
8476 TYPE_CACHE.put(byte.class, new ForLoadedType(byte.class));
8477 TYPE_CACHE.put(short.class, new ForLoadedType(short.class));
8478 TYPE_CACHE.put(char.class, new ForLoadedType(char.class));
8479 TYPE_CACHE.put(int.class, new ForLoadedType(int.class));
8480 TYPE_CACHE.put(long.class, new ForLoadedType(long.class));
8481 TYPE_CACHE.put(float.class, new ForLoadedType(float.class));
8482 TYPE_CACHE.put(double.class, new ForLoadedType(double.class));
8483 }
8484
8485 /**
8486 * The loaded type this instance represents.
8487 */
8488 private final Class<?> type;
8489
8490 /**
8491 * Creates a new immutable type description for a loaded type. This constructor should not normally be used.
8492 * Use {@link ForLoadedType#of(Class)} instead.
8493 *
8494 * @param type The type to be represented by this type description.
8495 */
8496 public ForLoadedType(Class<?> type) {
8497 this.type = type;
8498 }
8499
8500 /**
8501 * Returns the type's actual name where it is taken into consideration that this type might be loaded anonymously.
8502 * In this case, the remainder of the types name is suffixed by {@code /<id>} which is removed when using this method
8503 * but is retained when calling {@link Class#getName()}.
8504 *
8505 * @param type The type for which to resolve its name.
8506 * @return The type's actual name.
8507 */
8508 public static String getName(Class<?> type) {
8509 String name = type.getName();
8510 int anonymousLoaderIndex = name.indexOf('/');
8511 return anonymousLoaderIndex == -1
8512 ? name
8513 : name.substring(0, anonymousLoaderIndex);
8514 }
8515
8516 /**
8517 * Returns a new immutable type description for a loaded type.
8518 *
8519 * @param type The type to be represented by this type description.
8520 * @return The type description representing the given type.
8521 */
8522 public static TypeDescription of(Class<?> type) {
8523 TypeDescription typeDescription = TYPE_CACHE.get(type);
8524 return typeDescription == null
8525 ? new ForLoadedType(type)
8526 : typeDescription;
8527 }
8528
8529 @Override
8530 public boolean isAssignableFrom(Class<?> type) {
8531 return this.type.isAssignableFrom(type) || super.isAssignableFrom(type);
8532 }
8533
8534 @Override
8535 public boolean isAssignableFrom(TypeDescription typeDescription) {
8536 return typeDescription instanceof ForLoadedType && type.isAssignableFrom(((ForLoadedType) typeDescription).type) || super.isAssignableFrom(typeDescription);
8537 }
8538
8539 @Override
8540 public boolean isAssignableTo(Class<?> type) {
8541 return type.isAssignableFrom(this.type) || super.isAssignableTo(type);
8542 }
8543
8544 @Override
8545 public boolean isAssignableTo(TypeDescription typeDescription) {
8546 return typeDescription instanceof ForLoadedType && ((ForLoadedType) typeDescription).type.isAssignableFrom(type) || super.isAssignableTo(typeDescription);
8547 }
8548
8549 @Override
8550 public boolean isInHierarchyWith(Class<?> type) {
8551 return type.isAssignableFrom(this.type) || this.type.isAssignableFrom(type) || super.isInHierarchyWith(type);
8552 }
8553
8554 @Override
8555 public boolean isInHierarchyWith(TypeDescription typeDescription) {
8556 return typeDescription instanceof ForLoadedType && (((ForLoadedType) typeDescription).type.isAssignableFrom(type)
8557 || type.isAssignableFrom(((ForLoadedType) typeDescription).type)) || super.isInHierarchyWith(typeDescription);
8558 }
8559
8560 @Override
8561 public boolean represents(java.lang.reflect.Type type) {
8562 return type == this.type || super.represents(type);
8563 }
8564
8565 /**
8566 * {@inheritDoc}
8567 */
8568 public TypeDescription getComponentType() {
8569 Class<?> componentType = type.getComponentType();
8570 return componentType == null
8571 ? TypeDescription.UNDEFINED
8572 : ForLoadedType.of(componentType);
8573 }
8574
8575 /**
8576 * {@inheritDoc}
8577 */
8578 public boolean isArray() {
8579 return type.isArray();
8580 }
8581
8582 /**
8583 * {@inheritDoc}
8584 */
8585 public boolean isPrimitive() {
8586 return type.isPrimitive();
8587 }
8588
8589 @Override
8590 public boolean isAnnotation() {
8591 return type.isAnnotation();
8592 }
8593
8594 /**
8595 * {@inheritDoc}
8596 */
8597 public Generic getSuperClass() {
8598 if (RAW_TYPES) {
8599 return type.getSuperclass() == null
8600 ? TypeDescription.Generic.UNDEFINED
8601 : Generic.OfNonGenericType.ForLoadedType.of(type.getSuperclass());
8602 }
8603 return type.getSuperclass() == null
8604 ? TypeDescription.Generic.UNDEFINED
8605 : new Generic.LazyProjection.ForLoadedSuperClass(type);
8606 }
8607
8608 /**
8609 * {@inheritDoc}
8610 */
8611 public TypeList.Generic getInterfaces() {
8612 if (RAW_TYPES) {
8613 return isArray()
8614 ? ARRAY_INTERFACES
8615 : new TypeList.Generic.ForLoadedTypes(type.getInterfaces());
8616 }
8617 return isArray()
8618 ? ARRAY_INTERFACES
8619 : new TypeList.Generic.OfLoadedInterfaceTypes(type);
8620 }
8621
8622 /**
8623 * {@inheritDoc}
8624 */
8625 public TypeDescription getDeclaringType() {
8626 Class<?> declaringType = type.getDeclaringClass();
8627 return declaringType == null
8628 ? TypeDescription.UNDEFINED
8629 : ForLoadedType.of(declaringType);
8630 }
8631
8632 /**
8633 * {@inheritDoc}
8634 */
8635 public MethodDescription.InDefinedShape getEnclosingMethod() {
8636 Method enclosingMethod = type.getEnclosingMethod();
8637 Constructor<?> enclosingConstructor = type.getEnclosingConstructor();
8638 if (enclosingMethod != null) {
8639 return new MethodDescription.ForLoadedMethod(enclosingMethod);
8640 } else if (enclosingConstructor != null) {
8641 return new MethodDescription.ForLoadedConstructor(enclosingConstructor);
8642 } else {
8643 return MethodDescription.UNDEFINED;
8644 }
8645 }
8646
8647 /**
8648 * {@inheritDoc}
8649 */
8650 public TypeDescription getEnclosingType() {
8651 Class<?> enclosingType = type.getEnclosingClass();
8652 return enclosingType == null
8653 ? TypeDescription.UNDEFINED
8654 : ForLoadedType.of(enclosingType);
8655 }
8656
8657 /**
8658 * {@inheritDoc}
8659 */
8660 public TypeList getDeclaredTypes() {
8661 return new TypeList.ForLoadedTypes(type.getDeclaredClasses());
8662 }
8663
8664 /**
8665 * {@inheritDoc}
8666 */
8667 public String getSimpleName() {
8668 String simpleName = type.getSimpleName();
8669 int anonymousLoaderIndex = simpleName.indexOf('/');
8670 if (anonymousLoaderIndex == -1) {
8671 return simpleName;
8672 } else {
8673 StringBuilder normalized = new StringBuilder(simpleName.substring(0, anonymousLoaderIndex));
8674 Class<?> type = this.type;
8675 while (type.isArray()) {
8676 normalized.append("[]");
8677 type = type.getComponentType();
8678 }
8679 return normalized.toString();
8680 }
8681 }
8682
8683 /**
8684 * {@inheritDoc}
8685 */
8686 public boolean isAnonymousType() {
8687 return type.isAnonymousClass();
8688 }
8689
8690 /**
8691 * {@inheritDoc}
8692 */
8693 public boolean isLocalType() {
8694 return type.isLocalClass();
8695 }
8696
8697 @Override
8698 public boolean isMemberType() {
8699 return type.isMemberClass();
8700 }
8701
8702 /**
8703 * {@inheritDoc}
8704 */
8705 @CachedReturnPlugin.Enhance("declaredFields")
8706 public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
8707 return new FieldList.ForLoadedFields(type.getDeclaredFields());
8708 }
8709
8710 /**
8711 * {@inheritDoc}
8712 */
8713 @CachedReturnPlugin.Enhance("declaredMethods")
8714 public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
8715 return new MethodList.ForLoadedMethods(type);
8716 }
8717
8718 /**
8719 * {@inheritDoc}
8720 */
8721 public PackageDescription getPackage() {
8722 if (type.isArray() || type.isPrimitive()) {
8723 return PackageDescription.UNDEFINED;
8724 } else {
8725 Package aPackage = type.getPackage();
8726 if (aPackage == null) {
8727 String name = type.getName();
8728 int index = name.lastIndexOf('.');
8729 return index == -1
8730 ? new PackageDescription.Simple(EMPTY_NAME)
8731 : new PackageDescription.Simple(name.substring(0, index));
8732 } else {
8733 return new PackageDescription.ForLoadedPackage(aPackage);
8734 }
8735 }
8736 }
8737
8738 /**
8739 * {@inheritDoc}
8740 */
8741 public StackSize getStackSize() {
8742 return StackSize.of(type);
8743 }
8744
8745 /**
8746 * {@inheritDoc}
8747 */
8748 public String getName() {
8749 return getName(type);
8750 }
8751
8752 /**
8753 * {@inheritDoc}
8754 */
8755 public String getCanonicalName() {
8756 String canonicalName = type.getCanonicalName();
8757 if (canonicalName == null) {
8758 return NO_NAME;
8759 }
8760 int anonymousLoaderIndex = canonicalName.indexOf('/');
8761 if (anonymousLoaderIndex == -1) {
8762 return canonicalName;
8763 } else {
8764 StringBuilder normalized = new StringBuilder(canonicalName.substring(0, anonymousLoaderIndex));
8765 Class<?> type = this.type;
8766 while (type.isArray()) {
8767 normalized.append("[]");
8768 type = type.getComponentType();
8769 }
8770 return normalized.toString();
8771 }
8772 }
8773
8774 /**
8775 * {@inheritDoc}
8776 */
8777 public String getDescriptor() {
8778 String name = type.getName();
8779 int anonymousLoaderIndex = name.indexOf('/');
8780 return anonymousLoaderIndex == -1
8781 ? Type.getDescriptor(type)
8782 : "L" + name.substring(0, anonymousLoaderIndex).replace('.', '/') + ";";
8783 }
8784
8785 /**
8786 * {@inheritDoc}
8787 */
8788 public int getModifiers() {
8789 return type.getModifiers();
8790 }
8791
8792 /**
8793 * {@inheritDoc}
8794 */
8795 public TypeList.Generic getTypeVariables() {
8796 if (RAW_TYPES) {
8797 return new TypeList.Generic.Empty();
8798 }
8799 return TypeList.Generic.ForLoadedTypes.OfTypeVariables.of(type);
8800 }
8801
8802 /**
8803 * {@inheritDoc}
8804 */
8805 @CachedReturnPlugin.Enhance("declaredAnnotations")
8806 public AnnotationList getDeclaredAnnotations() {
8807 return new AnnotationList.ForLoadedAnnotations(type.getDeclaredAnnotations());
8808 }
8809
8810 /**
8811 * {@inheritDoc}
8812 */
8813 public Generic asGenericType() {
8814 return Generic.OfNonGenericType.ForLoadedType.of(type);
8815 }
8816
8817 /**
8818 * {@inheritDoc}
8819 */
8820 public TypeDescription getNestHost() {
8821 return TypeDescription.ForLoadedType.of(DISPATCHER.getNestHost(type));
8822 }
8823
8824 /**
8825 * {@inheritDoc}
8826 */
8827 public TypeList getNestMembers() {
8828 return new TypeList.ForLoadedTypes(DISPATCHER.getNestMembers(type));
8829 }
8830
8831 @Override
8832 public boolean isNestHost() {
8833 return DISPATCHER.getNestHost(type) == type;
8834 }
8835
8836 @Override
8837 public boolean isNestMateOf(Class<?> type) {
8838 return DISPATCHER.isNestmateOf(this.type, type) || super.isNestMateOf(ForLoadedType.of(type));
8839 }
8840
8841 @Override
8842 public boolean isNestMateOf(TypeDescription typeDescription) {
8843 return typeDescription instanceof ForLoadedType && DISPATCHER.isNestmateOf(type, ((ForLoadedType) typeDescription).type) || super.isNestMateOf(typeDescription);
8844 }
8845
8846 /**
8847 * {@inheritDoc}
8848 */
8849 public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
8850 Object[] recordComponent = RecordComponentDescription.ForLoadedRecordComponent.DISPATCHER.getRecordComponents(type);
8851 return recordComponent == null
8852 ? new RecordComponentList.Empty<RecordComponentDescription.InDefinedShape>()
8853 : new RecordComponentList.ForLoadedRecordComponents();
8854 }
8855
8856 /**
8857 * {@inheritDoc}
8858 */
8859 public boolean isRecord() {
8860 return RecordComponentDescription.ForLoadedRecordComponent.DISPATCHER.isRecord(type);
8861 }
8862
8863 /**
8864 * {@inheritDoc}
8865 */
8866 public TypeList getPermittedSubclasses() {
8867 return new ClassDescriptionTypeList(type.getClassLoader(), DISPATCHER.getPermittedSubclasses(type));
8868 }
8869
8870 /**
8871 * A dispatcher for using methods of {@link Class} that are not declared for Java 6.
8872 */
8873 protected interface Dispatcher {
8874
8875 /**
8876 * Returns the specified class's nest host.
8877 *
8878 * @param type The class for which to locate the nest host.
8879 * @return The nest host of the specified class.
8880 */
8881 Class<?> getNestHost(Class<?> type);
8882
8883 /**
8884 * Returns the nest members of the other class.
8885 *
8886 * @param type The type to get the nest members for.
8887 * @return An array containing all nest members of the specified type's nest group.
8888 */
8889 Class<?>[] getNestMembers(Class<?> type);
8890
8891 /**
8892 * Returns {@code true} if the specified type is a nest mate of the other type.
8893 *
8894 * @param type The type to evaluate for being a nest mate of another type.
8895 * @param candidate The candidate type.
8896 * @return {@code true} if the specified type is a nest mate of the other class.
8897 */
8898 boolean isNestmateOf(Class<?> type, Class<?> candidate);
8899
8900 /**
8901 * Returns the permitted subclasses of the supplied type.
8902 *
8903 * @param type The type for which to check the permitted subclasses.
8904 * @return An array of descriptors of permitted subclasses.
8905 */
8906 Object[] getPermittedSubclasses(Class<?> type);
8907
8908 /**
8909 * Returns the internal name of a permitted subclass.
8910 *
8911 * @param permittedSubclass The permitted subclass descriptor.
8912 * @return The permitted subclasses internal name.
8913 */
8914 String getInternalName(Object permittedSubclass);
8915
8916 /**
8917 * An action to resolve the dispatcher for invoking methods of {@link Class} reflectively.
8918 */
8919 enum CreationAction implements PrivilegedAction<Dispatcher> {
8920
8921 /**
8922 * The singleton instance.
8923 */
8924 INSTANCE;
8925
8926 /**
8927 * {@inheritDoc}
8928 */
8929 @SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception should not be rethrown but trigger a fallback")
8930 public Dispatcher run() {
8931 try {
8932 try {
8933 return new ForJava16CapableVm(Class.class.getMethod("getNestHost"),
8934 Class.class.getMethod("getNestMembers"),
8935 Class.class.getMethod("isNestmateOf", Class.class),
8936 Class.class.getMethod("permittedSubclasses"),
8937 Class.forName("java.lang.constant.ClassDesc").getMethod("descriptorString"));
8938 } catch (Exception ignored) {
8939 return new ForJava11CapableVm(Class.class.getMethod("getNestHost"),
8940 Class.class.getMethod("getNestMembers"),
8941 Class.class.getMethod("isNestmateOf", Class.class));
8942 }
8943 } catch (NoSuchMethodException ignored) {
8944 return ForLegacyVm.INSTANCE;
8945 }
8946 }
8947 }
8948
8949 /**
8950 * A dispatcher for a legacy VM.
8951 */
8952 enum ForLegacyVm implements Dispatcher {
8953
8954 /**
8955 * The singleton instance.
8956 */
8957 INSTANCE;
8958
8959 /**
8960 * {@inheritDoc}
8961 */
8962 public Class<?> getNestHost(Class<?> type) {
8963 return type;
8964 }
8965
8966 /**
8967 * {@inheritDoc}
8968 */
8969 public Class<?>[] getNestMembers(Class<?> type) {
8970 return new Class<?>[]{type};
8971 }
8972
8973 /**
8974 * {@inheritDoc}
8975 */
8976 public boolean isNestmateOf(Class<?> type, Class<?> candidate) {
8977 return type == candidate;
8978 }
8979
8980 /**
8981 * {@inheritDoc}
8982 */
8983 public Object[] getPermittedSubclasses(Class<?> type) {
8984 return new Object[0];
8985 }
8986
8987 /**
8988 * {@inheritDoc}
8989 */
8990 public String getInternalName(Object permittedSubclass) {
8991 throw new IllegalStateException("Not supported on the current VM");
8992 }
8993 }
8994
8995 /**
8996 * A dispatcher for a Java 11-capable VM.
8997 */
8998 class ForJava11CapableVm implements Dispatcher {
8999
9000 /**
9001 * The {@code java.lang.Class#getNestHost} method.
9002 */
9003 private final Method getNestHost;
9004
9005 /**
9006 * The {@code java.lang.Class#getNestMembers} method.
9007 */
9008 private final Method getNestMembers;
9009
9010 /**
9011 * The {@code java.lang.Class#isNestmateOf} method.
9012 */
9013 private final Method isNestmateOf;
9014
9015 /**
9016 * Creates a dispatcher for a Java 11-capable VM.
9017 *
9018 * @param getNestHost The {@code java.lang.Class#getNestHost} method.
9019 * @param getNestMembers The {@code java.lang.Class#getNestMembers} method.
9020 * @param isNestmateOf The {@code java.lang.Class#isNestmateOf} method.
9021 */
9022 protected ForJava11CapableVm(Method getNestHost, Method getNestMembers, Method isNestmateOf) {
9023 this.getNestHost = getNestHost;
9024 this.getNestMembers = getNestMembers;
9025 this.isNestmateOf = isNestmateOf;
9026 }
9027
9028 /**
9029 * {@inheritDoc}
9030 */
9031 public Class<?> getNestHost(Class<?> type) {
9032 try {
9033 return (Class<?>) getNestHost.invoke(type);
9034 } catch (IllegalAccessException exception) {
9035 throw new IllegalStateException("Could not access Class::getNestHost", exception);
9036 } catch (InvocationTargetException exception) {
9037 throw new IllegalStateException("Could not invoke Class::getNestHost", exception.getCause());
9038 }
9039 }
9040
9041 /**
9042 * {@inheritDoc}
9043 */
9044 public Class<?>[] getNestMembers(Class<?> type) {
9045 try {
9046 return (Class<?>[]) getNestMembers.invoke(type);
9047 } catch (IllegalAccessException exception) {
9048 throw new IllegalStateException("Could not access Class::getNestMembers", exception);
9049 } catch (InvocationTargetException exception) {
9050 throw new IllegalStateException("Could not invoke Class::getNestMembers", exception.getCause());
9051 }
9052 }
9053
9054 /**
9055 * {@inheritDoc}
9056 */
9057 public boolean isNestmateOf(Class<?> type, Class<?> candidate) {
9058 try {
9059 return (Boolean) isNestmateOf.invoke(type, candidate);
9060 } catch (IllegalAccessException exception) {
9061 throw new IllegalStateException("Could not access Class::isNestmateOf", exception);
9062 } catch (InvocationTargetException exception) {
9063 throw new IllegalStateException("Could not invoke Class::isNestmateOf", exception.getCause());
9064 }
9065 }
9066
9067 /**
9068 * {@inheritDoc}
9069 */
9070 public Object[] getPermittedSubclasses(Class<?> type) {
9071 return new Object[0];
9072 }
9073
9074 /**
9075 * {@inheritDoc}
9076 */
9077 public String getInternalName(Object permittedSubclass) {
9078 throw new IllegalStateException("Not supported on the current VM");
9079 }
9080 }
9081
9082 /**
9083 * A dispatcher for a Java 16-capable VM.
9084 */
9085 class ForJava16CapableVm implements Dispatcher {
9086
9087 /**
9088 * The {@code java.lang.Class#getNestHost} method.
9089 */
9090 private final Method getNestHost;
9091
9092 /**
9093 * The {@code java.lang.Class#getNestMembers} method.
9094 */
9095 private final Method getNestMembers;
9096
9097 /**
9098 * The {@code java.lang.Class#isNestmateOf} method.
9099 */
9100 private final Method isNestmateOf;
9101
9102 /**
9103 * The {@code java.lang.Class#permittedSubclasses} method.
9104 */
9105 private final Method permittedSubclasses;
9106
9107 /**
9108 * The {@code java.lang.constant.ClassDesc#descriptorString} method.
9109 */
9110 private final Method descriptorString;
9111
9112 /**
9113 * Creates a dispatcher for a Java 11-capable VM.
9114 *
9115 * @param getNestHost The {@code java.lang.Class#getNestHost} method.
9116 * @param getNestMembers The {@code java.lang.Class#getNestMembers} method.
9117 * @param isNestmateOf The {@code java.lang.Class#isNestmateOf} method.
9118 * @param permittedSubclasses The {@code java.lang.Class#permittedSubclasses} method.
9119 * @param descriptorString The {@code java.lang.constant.ClassDesc#descriptorString} method.
9120 */
9121 protected ForJava16CapableVm(Method getNestHost, Method getNestMembers, Method isNestmateOf, Method permittedSubclasses, Method descriptorString) {
9122 this.getNestHost = getNestHost;
9123 this.getNestMembers = getNestMembers;
9124 this.isNestmateOf = isNestmateOf;
9125 this.permittedSubclasses = permittedSubclasses;
9126 this.descriptorString = descriptorString;
9127 }
9128
9129 /**
9130 * {@inheritDoc}
9131 */
9132 public Class<?> getNestHost(Class<?> type) {
9133 try {
9134 return (Class<?>) getNestHost.invoke(type);
9135 } catch (IllegalAccessException exception) {
9136 throw new IllegalStateException("Could not access Class::getNestHost", exception);
9137 } catch (InvocationTargetException exception) {
9138 throw new IllegalStateException("Could not invoke Class::getNestHost", exception.getCause());
9139 }
9140 }
9141
9142 /**
9143 * {@inheritDoc}
9144 */
9145 public Class<?>[] getNestMembers(Class<?> type) {
9146 try {
9147 return (Class<?>[]) getNestMembers.invoke(type);
9148 } catch (IllegalAccessException exception) {
9149 throw new IllegalStateException("Could not access Class::getNestMembers", exception);
9150 } catch (InvocationTargetException exception) {
9151 throw new IllegalStateException("Could not invoke Class::getNestMembers", exception.getCause());
9152 }
9153 }
9154
9155 /**
9156 * {@inheritDoc}
9157 */
9158 public boolean isNestmateOf(Class<?> type, Class<?> candidate) {
9159 try {
9160 return (Boolean) isNestmateOf.invoke(type, candidate);
9161 } catch (IllegalAccessException exception) {
9162 throw new IllegalStateException("Could not access Class::isNestmateOf", exception);
9163 } catch (InvocationTargetException exception) {
9164 throw new IllegalStateException("Could not invoke Class::isNestmateOf", exception.getCause());
9165 }
9166 }
9167
9168 /**
9169 * {@inheritDoc}
9170 */
9171 public Object[] getPermittedSubclasses(Class<?> type) {
9172 try {
9173 return (Object[]) permittedSubclasses.invoke(type);
9174 } catch (IllegalAccessException exception) {
9175 throw new IllegalStateException("Could not access Class::permittedSubclasses", exception);
9176 } catch (InvocationTargetException exception) {
9177 throw new IllegalStateException("Could not invoke Class::permittedSubclasses", exception.getCause());
9178 }
9179 }
9180
9181 /**
9182 * {@inheritDoc}
9183 */
9184 public String getInternalName(Object permittedSubclass) {
9185 try {
9186 return (String) descriptorString.invoke(permittedSubclass);
9187 } catch (IllegalAccessException exception) {
9188 throw new IllegalStateException("Could not access ClassDesc::descriptorString", exception);
9189 } catch (InvocationTargetException exception) {
9190 throw new IllegalStateException("Could not invoke ClassDesc::descriptorString", exception.getCause());
9191 }
9192 }
9193 }
9194 }
9195
9196 /**
9197 * A list of type descriptions represented by class descriptions.
9198 */
9199 protected static class ClassDescriptionTypeList extends TypeList.AbstractBase {
9200
9201 /**
9202 * The represented class loader.
9203 */
9204 private final ClassLoader classLoader;
9205
9206 /**
9207 * An array of represented permitted subclasses.
9208 */
9209 private final Object[] permittedSubclass;
9210
9211 /**
9212 * Creates a new list of type descriptions.
9213 *
9214 * @param classLoader The represented class loader.
9215 * @param permittedSubclass An array of represented permitted subclasses.
9216 */
9217 protected ClassDescriptionTypeList(ClassLoader classLoader, Object[] permittedSubclass) {
9218 this.classLoader = classLoader;
9219 this.permittedSubclass = permittedSubclass;
9220 }
9221
9222 /**
9223 * {@inheritDoc}
9224 */
9225 public TypeDescription get(int index) {
9226 return new InternalNameLazyType(classLoader, DISPATCHER.getInternalName(permittedSubclass[index]));
9227 }
9228
9229 /**
9230 * {@inheritDoc}
9231 */
9232 public int size() {
9233 return permittedSubclass.length;
9234 }
9235
9236 /**
9237 * A lazy representation of an internal name for a given class loader.
9238 */
9239 protected static class InternalNameLazyType extends OfSimpleType.WithDelegation {
9240
9241 /**
9242 * The represented class loader.
9243 */
9244 private final ClassLoader classLoader;
9245
9246 /**
9247 * The represented internal name.
9248 */
9249 private final String internalName;
9250
9251 /**
9252 * Creates a new lazy representation of an internal name.
9253 *
9254 * @param classLoader The represented class loader.
9255 * @param internalName The represented internal name.
9256 */
9257 protected InternalNameLazyType(ClassLoader classLoader, String internalName) {
9258 this.classLoader = classLoader;
9259 this.internalName = internalName;
9260 }
9261
9262 @Override
9263 @CachedReturnPlugin.Enhance
9264 protected TypeDescription delegate() {
9265 try {
9266 return ForLoadedType.of(Class.forName(getName(), false, classLoader));
9267 } catch (ClassNotFoundException exception) {
9268 throw new IllegalStateException(exception);
9269 }
9270 }
9271
9272 /**
9273 * {@inheritDoc}
9274 */
9275 public String getName() {
9276 return internalName.replace('/', '.');
9277 }
9278 }
9279 }
9280 }
9281
9282 /**
9283 * A projection for an array type based on an existing {@link TypeDescription}.
9284 */
9285 class ArrayProjection extends AbstractBase {
9286
9287 /**
9288 * Modifiers that every array in Java implies.
9289 */
9290 private static final int ARRAY_IMPLIED = Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT;
9291
9292 /**
9293 * Modifiers that no array in Java displays.
9294 */
9295 private static final int ARRAY_EXCLUDED = Opcodes.ACC_INTERFACE | Opcodes.ACC_ANNOTATION | Opcodes.ACC_STATIC;
9296
9297 /**
9298 * The base component type which is itself not an array.
9299 */
9300 private final TypeDescription componentType;
9301
9302 /**
9303 * The arity of this array.
9304 */
9305 private final int arity;
9306
9307 /**
9308 * Creates a new array projection.
9309 *
9310 * @param componentType The base component type of the array which is itself not an array.
9311 * @param arity The arity of this array.
9312 */
9313 protected ArrayProjection(TypeDescription componentType, int arity) {
9314 this.componentType = componentType;
9315 this.arity = arity;
9316 }
9317
9318 /**
9319 * Creates an array projection of an arity of one.
9320 *
9321 * @param componentType The component type of the array.
9322 * @return A projection of the component type as an array of the given value with an arity of one.
9323 */
9324 public static TypeDescription of(TypeDescription componentType) {
9325 return of(componentType, 1);
9326 }
9327
9328 /**
9329 * Creates an array projection.
9330 *
9331 * @param componentType The component type of the array.
9332 * @param arity The arity of this array.
9333 * @return A projection of the component type as an array of the given value with the supplied arity.
9334 */
9335 public static TypeDescription of(TypeDescription componentType, int arity) {
9336 if (arity < 0) {
9337 throw new IllegalArgumentException("Arrays cannot have a negative arity");
9338 }
9339 while (componentType.isArray()) {
9340 componentType = componentType.getComponentType();
9341 arity++;
9342 }
9343 return arity == 0
9344 ? componentType
9345 : new ArrayProjection(componentType, arity);
9346 }
9347
9348 /**
9349 * {@inheritDoc}
9350 */
9351 public boolean isArray() {
9352 return true;
9353 }
9354
9355 /**
9356 * {@inheritDoc}
9357 */
9358 public TypeDescription getComponentType() {
9359 return arity == 1
9360 ? componentType
9361 : new ArrayProjection(componentType, arity - 1);
9362 }
9363
9364 /**
9365 * {@inheritDoc}
9366 */
9367 public boolean isPrimitive() {
9368 return false;
9369 }
9370
9371 /**
9372 * {@inheritDoc}
9373 */
9374 public Generic getSuperClass() {
9375 return TypeDescription.Generic.OBJECT;
9376 }
9377
9378 /**
9379 * {@inheritDoc}
9380 */
9381 public TypeList.Generic getInterfaces() {
9382 return ARRAY_INTERFACES;
9383 }
9384
9385 /**
9386 * {@inheritDoc}
9387 */
9388 public MethodDescription.InDefinedShape getEnclosingMethod() {
9389 return MethodDescription.UNDEFINED;
9390 }
9391
9392 /**
9393 * {@inheritDoc}
9394 */
9395 public TypeDescription getEnclosingType() {
9396 return TypeDescription.UNDEFINED;
9397 }
9398
9399 /**
9400 * {@inheritDoc}
9401 */
9402 public TypeList getDeclaredTypes() {
9403 return new TypeList.Empty();
9404 }
9405
9406 /**
9407 * {@inheritDoc}
9408 */
9409 public String getSimpleName() {
9410 StringBuilder stringBuilder = new StringBuilder(componentType.getSimpleName());
9411 for (int i = 0; i < arity; i++) {
9412 stringBuilder.append("[]");
9413 }
9414 return stringBuilder.toString();
9415 }
9416
9417 /**
9418 * {@inheritDoc}
9419 */
9420 public String getCanonicalName() {
9421 String canonicalName = componentType.getCanonicalName();
9422 if (canonicalName == null) {
9423 return NO_NAME;
9424 }
9425 StringBuilder stringBuilder = new StringBuilder(canonicalName);
9426 for (int i = 0; i < arity; i++) {
9427 stringBuilder.append("[]");
9428 }
9429 return stringBuilder.toString();
9430 }
9431
9432 /**
9433 * {@inheritDoc}
9434 */
9435 public boolean isAnonymousType() {
9436 return false;
9437 }
9438
9439 /**
9440 * {@inheritDoc}
9441 */
9442 public boolean isLocalType() {
9443 return false;
9444 }
9445
9446 @Override
9447 public boolean isMemberType() {
9448 return false;
9449 }
9450
9451 /**
9452 * {@inheritDoc}
9453 */
9454 public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
9455 return new FieldList.Empty<FieldDescription.InDefinedShape>();
9456 }
9457
9458 /**
9459 * {@inheritDoc}
9460 */
9461 public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
9462 return new MethodList.Empty<MethodDescription.InDefinedShape>();
9463 }
9464
9465 /**
9466 * {@inheritDoc}
9467 */
9468 public StackSize getStackSize() {
9469 return StackSize.SINGLE;
9470 }
9471
9472 /**
9473 * {@inheritDoc}
9474 */
9475 public AnnotationList getDeclaredAnnotations() {
9476 return new AnnotationList.Empty();
9477 }
9478
9479 /**
9480 * {@inheritDoc}
9481 */
9482 public AnnotationList getInheritedAnnotations() {
9483 return new AnnotationList.Empty();
9484 }
9485
9486 /**
9487 * {@inheritDoc}
9488 */
9489 public PackageDescription getPackage() {
9490 return PackageDescription.UNDEFINED;
9491 }
9492
9493 /**
9494 * {@inheritDoc}
9495 */
9496 public String getName() {
9497 String descriptor = componentType.getDescriptor();
9498 StringBuilder stringBuilder = new StringBuilder(descriptor.length() + arity);
9499 for (int index = 0; index < arity; index++) {
9500 stringBuilder.append('[');
9501 }
9502 for (int index = 0; index < descriptor.length(); index++) {
9503 char character = descriptor.charAt(index);
9504 stringBuilder.append(character == '/' ? '.' : character);
9505 }
9506 return stringBuilder.toString();
9507 }
9508
9509 /**
9510 * {@inheritDoc}
9511 */
9512 public String getDescriptor() {
9513 StringBuilder stringBuilder = new StringBuilder();
9514 for (int i = 0; i < arity; i++) {
9515 stringBuilder.append('[');
9516 }
9517 return stringBuilder.append(componentType.getDescriptor()).toString();
9518 }
9519
9520 /**
9521 * {@inheritDoc}
9522 */
9523 public TypeDescription getDeclaringType() {
9524 return TypeDescription.UNDEFINED;
9525 }
9526
9527 /**
9528 * {@inheritDoc}
9529 */
9530 public int getModifiers() {
9531 return (getComponentType().getModifiers() & ~ARRAY_EXCLUDED) | ARRAY_IMPLIED;
9532 }
9533
9534 /**
9535 * {@inheritDoc}
9536 */
9537 public TypeList.Generic getTypeVariables() {
9538 return new TypeList.Generic.Empty();
9539 }
9540
9541 /**
9542 * {@inheritDoc}
9543 */
9544 public TypeDescription getNestHost() {
9545 return this;
9546 }
9547
9548 /**
9549 * {@inheritDoc}
9550 */
9551 public TypeList getNestMembers() {
9552 return new TypeList.Explicit(this);
9553 }
9554
9555 /**
9556 * {@inheritDoc}
9557 */
9558 public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
9559 return new RecordComponentList.Empty<RecordComponentDescription.InDefinedShape>();
9560 }
9561
9562 /**
9563 * {@inheritDoc}
9564 */
9565 public boolean isRecord() {
9566 return false;
9567 }
9568
9569 /**
9570 * {@inheritDoc}
9571 */
9572 public TypeList getPermittedSubclasses() {
9573 return new TypeList.Empty();
9574 }
9575 }
9576
9577 /**
9578 * <p>
9579 * A latent type description for a type without methods or fields.
9580 * </p>
9581 * <p>
9582 * <b>Important</b>: This type does not define most of its properties and should only be used as a simple placeholder. For more
9583 * complex placeholders, use an {@link net.bytebuddy.dynamic.scaffold.InstrumentedType.Default}.
9584 * </p>
9585 */
9586 class Latent extends AbstractBase.OfSimpleType {
9587
9588 /**
9589 * The name of the type.
9590 */
9591 private final String name;
9592
9593 /**
9594 * The modifiers of the type.
9595 */
9596 private final int modifiers;
9597
9598 /**
9599 * The super type or {@code null} if no such type exists.
9600 */
9601 private final Generic superClass;
9602
9603 /**
9604 * The interfaces that this type implements.
9605 */
9606 private final List<? extends Generic> interfaces;
9607
9608 /**
9609 * Creates a new latent type.
9610 *
9611 * @param name The name of the type.
9612 * @param modifiers The modifiers of the type.
9613 * @param superClass The super type or {@code null} if no such type exists.
9614 * @param anInterface The interfaces that this type implements.
9615 */
9616 public Latent(String name, int modifiers, Generic superClass, Generic... anInterface) {
9617 this(name, modifiers, superClass, Arrays.asList(anInterface));
9618 }
9619
9620 /**
9621 * Creates a new latent type.
9622 *
9623 * @param name The name of the type.
9624 * @param modifiers The modifiers of the type.
9625 * @param superClass The super type or {@code null} if no such type exists.
9626 * @param interfaces The interfaces that this type implements.
9627 */
9628 public Latent(String name, int modifiers, Generic superClass, List<? extends Generic> interfaces) {
9629 this.name = name;
9630 this.modifiers = modifiers;
9631 this.superClass = superClass;
9632 this.interfaces = interfaces;
9633 }
9634
9635 /**
9636 * {@inheritDoc}
9637 */
9638 public Generic getSuperClass() {
9639 return superClass;
9640 }
9641
9642 /**
9643 * {@inheritDoc}
9644 */
9645 public TypeList.Generic getInterfaces() {
9646 return new TypeList.Generic.Explicit(interfaces);
9647 }
9648
9649 /**
9650 * {@inheritDoc}
9651 */
9652 public MethodDescription.InDefinedShape getEnclosingMethod() {
9653 throw new IllegalStateException("Cannot resolve enclosing method of a latent type description: " + this);
9654 }
9655
9656 /**
9657 * {@inheritDoc}
9658 */
9659 public TypeDescription getEnclosingType() {
9660 throw new IllegalStateException("Cannot resolve enclosing type of a latent type description: " + this);
9661 }
9662
9663 /**
9664 * {@inheritDoc}
9665 */
9666 public TypeList getDeclaredTypes() {
9667 throw new IllegalStateException("Cannot resolve inner types of a latent type description: " + this);
9668 }
9669
9670 /**
9671 * {@inheritDoc}
9672 */
9673 public boolean isAnonymousType() {
9674 throw new IllegalStateException("Cannot resolve anonymous type property of a latent type description: " + this);
9675 }
9676
9677 /**
9678 * {@inheritDoc}
9679 */
9680 public boolean isLocalType() {
9681 throw new IllegalStateException("Cannot resolve local class property of a latent type description: " + this);
9682 }
9683
9684 /**
9685 * {@inheritDoc}
9686 */
9687 public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
9688 throw new IllegalStateException("Cannot resolve declared fields of a latent type description: " + this);
9689 }
9690
9691 /**
9692 * {@inheritDoc}
9693 */
9694 public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
9695 throw new IllegalStateException("Cannot resolve declared methods of a latent type description: " + this);
9696 }
9697
9698 /**
9699 * {@inheritDoc}
9700 */
9701 public PackageDescription getPackage() {
9702 String name = getName();
9703 int index = name.lastIndexOf('.');
9704 return new PackageDescription.Simple(index == -1
9705 ? EMPTY_NAME
9706 : name.substring(0, index));
9707 }
9708
9709 /**
9710 * {@inheritDoc}
9711 */
9712 public AnnotationList getDeclaredAnnotations() {
9713 throw new IllegalStateException("Cannot resolve declared annotations of a latent type description: " + this);
9714 }
9715
9716 /**
9717 * {@inheritDoc}
9718 */
9719 public TypeDescription getDeclaringType() {
9720 throw new IllegalStateException("Cannot resolve declared type of a latent type description: " + this);
9721 }
9722
9723 /**
9724 * {@inheritDoc}
9725 */
9726 public int getModifiers() {
9727 return modifiers;
9728 }
9729
9730 /**
9731 * {@inheritDoc}
9732 */
9733 public String getName() {
9734 return name;
9735 }
9736
9737 /**
9738 * {@inheritDoc}
9739 */
9740 public TypeList.Generic getTypeVariables() {
9741 throw new IllegalStateException("Cannot resolve type variables of a latent type description: " + this);
9742 }
9743
9744 /**
9745 * {@inheritDoc}
9746 */
9747 public TypeDescription getNestHost() {
9748 throw new IllegalStateException("Cannot resolve nest host of a latent type description: " + this);
9749 }
9750
9751 /**
9752 * {@inheritDoc}
9753 */
9754 public TypeList getNestMembers() {
9755 throw new IllegalStateException("Cannot resolve nest mates of a latent type description: " + this);
9756 }
9757
9758 /**
9759 * {@inheritDoc}
9760 */
9761 public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
9762 throw new IllegalStateException("Cannot resolve record components of a latent type description: " + this);
9763 }
9764
9765 /**
9766 * {@inheritDoc}
9767 */
9768 public boolean isRecord() {
9769 throw new IllegalStateException("Cannot resolve record attribute of a latent type description: " + this);
9770 }
9771
9772 /**
9773 * {@inheritDoc}
9774 */
9775 public TypeList getPermittedSubclasses() {
9776 throw new IllegalStateException("Cannot resolve permitted subclasses of a latent type description: " + this);
9777 }
9778 }
9779
9780 /**
9781 * A type representation of a package description.
9782 */
9783 class ForPackageDescription extends AbstractBase.OfSimpleType {
9784
9785 /**
9786 * The package to be described as a type.
9787 */
9788 private final PackageDescription packageDescription;
9789
9790 /**
9791 * Creates a new type description of a package description.
9792 *
9793 * @param packageDescription The package to be described as a type.
9794 */
9795 public ForPackageDescription(PackageDescription packageDescription) {
9796 this.packageDescription = packageDescription;
9797 }
9798
9799 /**
9800 * {@inheritDoc}
9801 */
9802 public Generic getSuperClass() {
9803 return TypeDescription.Generic.OBJECT;
9804 }
9805
9806 /**
9807 * {@inheritDoc}
9808 */
9809 public TypeList.Generic getInterfaces() {
9810 return new TypeList.Generic.Empty();
9811 }
9812
9813 /**
9814 * {@inheritDoc}
9815 */
9816 public MethodDescription.InDefinedShape getEnclosingMethod() {
9817 return MethodDescription.UNDEFINED;
9818 }
9819
9820 /**
9821 * {@inheritDoc}
9822 */
9823 public TypeDescription getEnclosingType() {
9824 return TypeDescription.UNDEFINED;
9825 }
9826
9827 /**
9828 * {@inheritDoc}
9829 */
9830 public boolean isAnonymousType() {
9831 return false;
9832 }
9833
9834 /**
9835 * {@inheritDoc}
9836 */
9837 public boolean isLocalType() {
9838 return false;
9839 }
9840
9841 /**
9842 * {@inheritDoc}
9843 */
9844 public TypeList getDeclaredTypes() {
9845 return new TypeList.Empty();
9846 }
9847
9848 /**
9849 * {@inheritDoc}
9850 */
9851 public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
9852 return new FieldList.Empty<FieldDescription.InDefinedShape>();
9853 }
9854
9855 /**
9856 * {@inheritDoc}
9857 */
9858 public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
9859 return new MethodList.Empty<MethodDescription.InDefinedShape>();
9860 }
9861
9862 /**
9863 * {@inheritDoc}
9864 */
9865 public PackageDescription getPackage() {
9866 return packageDescription;
9867 }
9868
9869 /**
9870 * {@inheritDoc}
9871 */
9872 public AnnotationList getDeclaredAnnotations() {
9873 return packageDescription.getDeclaredAnnotations();
9874 }
9875
9876 /**
9877 * {@inheritDoc}
9878 */
9879 public TypeDescription getDeclaringType() {
9880 return TypeDescription.UNDEFINED;
9881 }
9882
9883 /**
9884 * {@inheritDoc}
9885 */
9886 public TypeList.Generic getTypeVariables() {
9887 return new TypeList.Generic.Empty();
9888 }
9889
9890 /**
9891 * {@inheritDoc}
9892 */
9893 public int getModifiers() {
9894 return PackageDescription.PACKAGE_MODIFIERS;
9895 }
9896
9897 /**
9898 * {@inheritDoc}
9899 */
9900 public String getName() {
9901 return packageDescription.getName() + "." + PackageDescription.PACKAGE_CLASS_NAME;
9902 }
9903
9904 /**
9905 * {@inheritDoc}
9906 */
9907 public TypeDescription getNestHost() {
9908 return this;
9909 }
9910
9911 /**
9912 * {@inheritDoc}
9913 */
9914 public TypeList getNestMembers() {
9915 return new TypeList.Explicit(this);
9916 }
9917
9918 /**
9919 * {@inheritDoc}
9920 */
9921 public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
9922 return new RecordComponentList.Empty<RecordComponentDescription.InDefinedShape>();
9923 }
9924
9925 /**
9926 * {@inheritDoc}
9927 */
9928 public boolean isRecord() {
9929 return false;
9930 }
9931
9932 /**
9933 * {@inheritDoc}
9934 */
9935 public TypeList getPermittedSubclasses() {
9936 return new TypeList.Empty();
9937 }
9938 }
9939
9940 /**
9941 * A delegating type description that always attempts to load the super types of a delegate type.
9942 */
9943 class SuperTypeLoading extends AbstractBase {
9944
9945 /**
9946 * The delegate type description.
9947 */
9948 private final TypeDescription delegate;
9949
9950 /**
9951 * The class loader to use for loading a super type.
9952 */
9953 private final ClassLoader classLoader;
9954
9955 /**
9956 * A delegate for loading a type.
9957 */
9958 private final ClassLoadingDelegate classLoadingDelegate;
9959
9960 /**
9961 * Creates a super type loading type description.
9962 *
9963 * @param delegate The delegate type description.
9964 * @param classLoader The class loader to use for loading a super type.
9965 */
9966 public SuperTypeLoading(TypeDescription delegate, ClassLoader classLoader) {
9967 this(delegate, classLoader, ClassLoadingDelegate.Simple.INSTANCE);
9968 }
9969
9970 /**
9971 * Creates a super type loading type description.
9972 *
9973 * @param delegate The delegate type description.
9974 * @param classLoader The class loader to use for loading a super type.
9975 * @param classLoadingDelegate A delegate for loading a type.
9976 */
9977 public SuperTypeLoading(TypeDescription delegate, ClassLoader classLoader, ClassLoadingDelegate classLoadingDelegate) {
9978 this.delegate = delegate;
9979 this.classLoader = classLoader;
9980 this.classLoadingDelegate = classLoadingDelegate;
9981 }
9982
9983 /**
9984 * {@inheritDoc}
9985 */
9986 public AnnotationList getDeclaredAnnotations() {
9987 return delegate.getDeclaredAnnotations();
9988 }
9989
9990 /**
9991 * {@inheritDoc}
9992 */
9993 public int getModifiers() {
9994 return delegate.getModifiers();
9995 }
9996
9997 /**
9998 * {@inheritDoc}
9999 */
10000 public TypeList.Generic getTypeVariables() {
10001 return delegate.getTypeVariables();
10002 }
10003
10004 /**
10005 * {@inheritDoc}
10006 */
10007 public String getDescriptor() {
10008 return delegate.getDescriptor();
10009 }
10010
10011 /**
10012 * {@inheritDoc}
10013 */
10014 public String getName() {
10015 return delegate.getName();
10016 }
10017
10018 /**
10019 * {@inheritDoc}
10020 */
10021 public Generic getSuperClass() {
10022 Generic superClass = delegate.getSuperClass();
10023 return superClass == null
10024 ? Generic.UNDEFINED
10025 : new ClassLoadingTypeProjection(superClass, classLoader, classLoadingDelegate);
10026 }
10027
10028 /**
10029 * {@inheritDoc}
10030 */
10031 public TypeList.Generic getInterfaces() {
10032 return new ClassLoadingTypeList(delegate.getInterfaces(), classLoader, classLoadingDelegate);
10033 }
10034
10035 /**
10036 * {@inheritDoc}
10037 */
10038 public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
10039 return delegate.getDeclaredFields();
10040 }
10041
10042 /**
10043 * {@inheritDoc}
10044 */
10045 public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
10046 return delegate.getDeclaredMethods();
10047 }
10048
10049 /**
10050 * {@inheritDoc}
10051 */
10052 public StackSize getStackSize() {
10053 return delegate.getStackSize();
10054 }
10055
10056 /**
10057 * {@inheritDoc}
10058 */
10059 public boolean isArray() {
10060 return delegate.isArray();
10061 }
10062
10063 /**
10064 * {@inheritDoc}
10065 */
10066 public boolean isPrimitive() {
10067 return delegate.isPrimitive();
10068 }
10069
10070 /**
10071 * {@inheritDoc}
10072 */
10073 public TypeDescription getComponentType() {
10074 return delegate.getComponentType();
10075 }
10076
10077 /**
10078 * {@inheritDoc}
10079 */
10080 public TypeDescription getDeclaringType() {
10081 return delegate.getDeclaringType();
10082 }
10083
10084 /**
10085 * {@inheritDoc}
10086 */
10087 public TypeList getDeclaredTypes() {
10088 return delegate.getDeclaredTypes();
10089 }
10090
10091 /**
10092 * {@inheritDoc}
10093 */
10094 public MethodDescription.InDefinedShape getEnclosingMethod() {
10095 return delegate.getEnclosingMethod();
10096 }
10097
10098 /**
10099 * {@inheritDoc}
10100 */
10101 public TypeDescription getEnclosingType() {
10102 return delegate.getEnclosingType();
10103 }
10104
10105 /**
10106 * {@inheritDoc}
10107 */
10108 public String getSimpleName() {
10109 return delegate.getSimpleName();
10110 }
10111
10112 /**
10113 * {@inheritDoc}
10114 */
10115 public String getCanonicalName() {
10116 return delegate.getCanonicalName();
10117 }
10118
10119 /**
10120 * {@inheritDoc}
10121 */
10122 public boolean isAnonymousType() {
10123 return delegate.isAnonymousType();
10124 }
10125
10126 /**
10127 * {@inheritDoc}
10128 */
10129 public boolean isLocalType() {
10130 return delegate.isLocalType();
10131 }
10132
10133 /**
10134 * {@inheritDoc}
10135 */
10136 public PackageDescription getPackage() {
10137 return delegate.getPackage();
10138 }
10139
10140 /**
10141 * {@inheritDoc}
10142 */
10143 public TypeDescription getNestHost() {
10144 return delegate.getNestHost();
10145 }
10146
10147 /**
10148 * {@inheritDoc}
10149 */
10150 public TypeList getNestMembers() {
10151 return delegate.getNestMembers();
10152 }
10153
10154 /**
10155 * {@inheritDoc}
10156 */
10157 public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
10158 return delegate.getRecordComponents();
10159 }
10160
10161 /**
10162 * {@inheritDoc}
10163 */
10164 public boolean isRecord() {
10165 return delegate.isRecord();
10166 }
10167
10168 /**
10169 * {@inheritDoc}
10170 */
10171 public TypeList getPermittedSubclasses() {
10172 return delegate.getPermittedSubclasses();
10173 }
10174
10175 /**
10176 * A class loading delegate is responsible for resolving a type given a class loader and a type name.
10177 */
10178 public interface ClassLoadingDelegate {
10179
10180 /**
10181 * Loads a type.
10182 *
10183 * @param name The type's name,
10184 * @param classLoader The class loader to load the type from which might be {@code null} to represent the bootstrap class loader.
10185 * @return The loaded type.
10186 * @throws ClassNotFoundException If the type could not be found.
10187 */
10188 Class<?> load(String name, ClassLoader classLoader) throws ClassNotFoundException;
10189
10190 /**
10191 * A simple class loading delegate that simply loads a type.
10192 */
10193 enum Simple implements ClassLoadingDelegate {
10194
10195 /**
10196 * The singleton instance.
10197 */
10198 INSTANCE;
10199
10200 /**
10201 * {@inheritDoc}
10202 */
10203 public Class<?> load(String name, ClassLoader classLoader) throws ClassNotFoundException {
10204 return Class.forName(name, false, classLoader);
10205 }
10206 }
10207 }
10208
10209 /**
10210 * A type projection that attempts to load any super type of the delegate type.
10211 */
10212 protected static class ClassLoadingTypeProjection extends TypeDescription.Generic.LazyProjection {
10213
10214 /**
10215 * The delegate type description.
10216 */
10217 private final Generic delegate;
10218
10219 /**
10220 * The class loader to use for loading types which might be {@code null} to represent the bootstrap class loader.
10221 */
10222 private final ClassLoader classLoader;
10223
10224 /**
10225 * A delegate for loading a type.
10226 */
10227 private final ClassLoadingDelegate classLoadingDelegate;
10228
10229 /**
10230 * Creates a class loading type description.
10231 *
10232 * @param delegate The delegate type description.
10233 * @param classLoader The class loader to use for loading types which might be {@code null} to represent the bootstrap class loader.
10234 * @param classLoadingDelegate A delegate for loading a type.
10235 */
10236 protected ClassLoadingTypeProjection(Generic delegate, ClassLoader classLoader, ClassLoadingDelegate classLoadingDelegate) {
10237 this.delegate = delegate;
10238 this.classLoader = classLoader;
10239 this.classLoadingDelegate = classLoadingDelegate;
10240 }
10241
10242 /**
10243 * {@inheritDoc}
10244 */
10245 public AnnotationList getDeclaredAnnotations() {
10246 return delegate.getDeclaredAnnotations();
10247 }
10248
10249 /**
10250 * {@inheritDoc}
10251 */
10252 @CachedReturnPlugin.Enhance("erasure")
10253 public TypeDescription asErasure() {
10254 try {
10255 return ForLoadedType.of(classLoadingDelegate.load(delegate.asErasure().getName(), classLoader));
10256 } catch (ClassNotFoundException ignored) {
10257 return delegate.asErasure();
10258 }
10259 }
10260
10261 @Override
10262 protected Generic resolve() {
10263 return delegate;
10264 }
10265
10266 /**
10267 * {@inheritDoc}
10268 */
10269 @CachedReturnPlugin.Enhance("superClass")
10270 public Generic getSuperClass() {
10271 Generic superClass = delegate.getSuperClass();
10272 if (superClass == null) {
10273 return Generic.UNDEFINED;
10274 } else {
10275 try {
10276 return new ClassLoadingTypeProjection(superClass,
10277 classLoadingDelegate.load(delegate.asErasure().getName(), classLoader).getClassLoader(),
10278 classLoadingDelegate);
10279 } catch (ClassNotFoundException ignored) {
10280 return superClass;
10281 }
10282 }
10283 }
10284
10285 /**
10286 * {@inheritDoc}
10287 */
10288 @CachedReturnPlugin.Enhance("interfaces")
10289 public TypeList.Generic getInterfaces() {
10290 TypeList.Generic interfaces = delegate.getInterfaces();
10291 try {
10292 return new ClassLoadingTypeList(interfaces,
10293 classLoadingDelegate.load(delegate.asErasure().getName(), classLoader).getClassLoader(),
10294 classLoadingDelegate);
10295 } catch (ClassNotFoundException ignored) {
10296 return interfaces;
10297 }
10298 }
10299
10300 /**
10301 * {@inheritDoc}
10302 */
10303 public Iterator<TypeDefinition> iterator() {
10304 return new SuperClassIterator(this);
10305 }
10306 }
10307
10308 /**
10309 * A type list that attempts loading any type.
10310 */
10311 protected static class ClassLoadingTypeList extends TypeList.Generic.AbstractBase {
10312
10313 /**
10314 * The delegate type list.
10315 */
10316 private final TypeList.Generic delegate;
10317
10318 /**
10319 * The class loader to use for loading types which might be {@code null} to represent the bootstrap class loader.
10320 */
10321 private final ClassLoader classLoader;
10322
10323 /**
10324 * A delegate for loading a type.
10325 */
10326 private final ClassLoadingDelegate classLoadingDelegate;
10327
10328 /**
10329 * Creates a class loading type list.
10330 *
10331 * @param delegate The delegate type list.
10332 * @param classLoader The class loader to use for loading types which might be {@code null} to represent the bootstrap class loader.
10333 * @param classLoadingDelegate A delegate for loading a type.
10334 */
10335 protected ClassLoadingTypeList(TypeList.Generic delegate, ClassLoader classLoader, ClassLoadingDelegate classLoadingDelegate) {
10336 this.delegate = delegate;
10337 this.classLoader = classLoader;
10338 this.classLoadingDelegate = classLoadingDelegate;
10339 }
10340
10341 /**
10342 * {@inheritDoc}
10343 */
10344 public Generic get(int index) {
10345 return new ClassLoadingTypeProjection(delegate.get(index), classLoader, classLoadingDelegate);
10346 }
10347
10348 /**
10349 * {@inheritDoc}
10350 */
10351 public int size() {
10352 return delegate.size();
10353 }
10354 }
10355 }
10356 }
10357