1
16 package net.bytebuddy.description.method;
17
18 import net.bytebuddy.build.CachedReturnPlugin;
19 import net.bytebuddy.description.ByteCodeElement;
20 import net.bytebuddy.description.ModifierReviewable;
21 import net.bytebuddy.description.NamedElement;
22 import net.bytebuddy.description.TypeVariableSource;
23 import net.bytebuddy.description.annotation.AnnotationDescription;
24 import net.bytebuddy.description.annotation.AnnotationList;
25 import net.bytebuddy.description.annotation.AnnotationValue;
26 import net.bytebuddy.description.enumeration.EnumerationDescription;
27 import net.bytebuddy.description.modifier.ModifierContributor;
28 import net.bytebuddy.description.modifier.Visibility;
29 import net.bytebuddy.description.type.TypeDefinition;
30 import net.bytebuddy.description.type.TypeDescription;
31 import net.bytebuddy.description.type.TypeList;
32 import net.bytebuddy.description.type.TypeVariableToken;
33 import net.bytebuddy.matcher.ElementMatcher;
34 import net.bytebuddy.matcher.ElementMatchers;
35 import net.bytebuddy.utility.JavaType;
36 import net.bytebuddy.jar.asm.Opcodes;
37 import net.bytebuddy.jar.asm.Type;
38 import net.bytebuddy.jar.asm.signature.SignatureWriter;
39
40 import java.lang.annotation.Annotation;
41 import java.lang.reflect.Constructor;
42 import java.lang.reflect.GenericSignatureFormatError;
43 import java.lang.reflect.Method;
44 import java.lang.reflect.Modifier;
45 import java.util.ArrayList;
46 import java.util.Collections;
47 import java.util.Iterator;
48 import java.util.List;
49
50 import static net.bytebuddy.matcher.ElementMatchers.not;
51 import static net.bytebuddy.matcher.ElementMatchers.ofSort;
52
53
57 public interface MethodDescription extends TypeVariableSource,
58 ModifierReviewable.ForMethodDescription,
59 NamedElement.WithGenericName,
60 ByteCodeElement,
61 ByteCodeElement.TypeDependant<MethodDescription.InDefinedShape, MethodDescription.Token> {
62
63
66 String CONSTRUCTOR_INTERNAL_NAME = "<init>";
67
68
71 String TYPE_INITIALIZER_INTERNAL_NAME = "<clinit>";
72
73
76 int TYPE_INITIALIZER_MODIFIER = Opcodes.ACC_STATIC;
77
78
82 InDefinedShape UNDEFINED = null;
83
84
89 TypeDescription.Generic getReturnType();
90
91
96 ParameterList<?> getParameters();
97
98
103 TypeList.Generic getExceptionTypes();
104
105
111 int getActualModifiers();
112
113
120 int getActualModifiers(boolean manifest);
121
122
131 int getActualModifiers(boolean manifest, Visibility visibility);
132
133
138 boolean isConstructor();
139
140
145 boolean isMethod();
146
147
152 boolean isTypeInitializer();
153
154
160 boolean represents(Method method);
161
162
168 boolean represents(Constructor<?> constructor);
169
170
175 boolean isVirtual();
176
177
184 int getStackSize();
185
186
191 boolean isDefaultMethod();
192
193
200 boolean isSpecializableFor(TypeDescription typeDescription);
201
202
207 AnnotationValue<?, ?> getDefaultValue();
208
209
217 <T> T getDefaultValue(Class<T> type);
218
219
226 boolean isInvokableOn(TypeDescription typeDescription);
227
228
233 boolean isInvokeBootstrap();
234
235
241 boolean isInvokeBootstrap(List<? extends TypeDefinition> arguments);
242
243
248 boolean isConstantBootstrap();
249
250
256 boolean isConstantBootstrap(List<? extends TypeDefinition> arguments);
257
258
263 boolean isDefaultValue();
264
265
271 boolean isDefaultValue(AnnotationValue<?, ?> annotationValue);
272
273
281 TypeDescription.Generic getReceiverType();
282
283
288 SignatureToken asSignatureToken();
289
290
295 TypeToken asTypeToken();
296
297
303 boolean isBridgeCompatible(TypeToken typeToken);
304
305
308 interface InGenericShape extends MethodDescription {
309
310
313 TypeDescription.Generic getDeclaringType();
314
315
318 ParameterList<ParameterDescription.InGenericShape> getParameters();
319 }
320
321
324 interface InDefinedShape extends MethodDescription {
325
326
329 TypeDescription getDeclaringType();
330
331
334 ParameterList<ParameterDescription.InDefinedShape> getParameters();
335
336
339 abstract class AbstractBase extends MethodDescription.AbstractBase implements InDefinedShape {
340
341
344 public InDefinedShape asDefined() {
345 return this;
346 }
347
348
351 public TypeDescription.Generic getReceiverType() {
352 if (isStatic()) {
353 return TypeDescription.Generic.UNDEFINED;
354 } else if (isConstructor()) {
355 TypeDescription declaringType = getDeclaringType(), enclosingDeclaringType = getDeclaringType().getEnclosingType();
356 if (enclosingDeclaringType == null) {
357 return TypeDescription.Generic.OfParameterizedType.ForGenerifiedErasure.of(declaringType);
358 } else {
359 return declaringType.isStatic()
360 ? enclosingDeclaringType.asGenericType()
361 : TypeDescription.Generic.OfParameterizedType.ForGenerifiedErasure.of(enclosingDeclaringType);
362 }
363 } else {
364 return TypeDescription.Generic.OfParameterizedType.ForGenerifiedErasure.of(getDeclaringType());
365 }
366 }
367 }
368 }
369
370
373 abstract class AbstractBase extends TypeVariableSource.AbstractBase implements MethodDescription {
374
375
378 private static final int SOURCE_MODIFIERS = Modifier.PUBLIC
379 | Modifier.PROTECTED
380 | Modifier.PRIVATE
381 | Modifier.ABSTRACT
382 | Modifier.STATIC
383 | Modifier.FINAL
384 | Modifier.SYNCHRONIZED
385 | Modifier.NATIVE;
386
387
390 public int getStackSize() {
391 return getParameters().asTypeList().getStackSize() + (isStatic() ? 0 : 1);
392 }
393
394
397 public boolean isMethod() {
398 return !isConstructor() && !isTypeInitializer();
399 }
400
401
404 public boolean isConstructor() {
405 return CONSTRUCTOR_INTERNAL_NAME.equals(getInternalName());
406 }
407
408
411 public boolean isTypeInitializer() {
412 return TYPE_INITIALIZER_INTERNAL_NAME.equals(getInternalName());
413 }
414
415
418 public boolean represents(Method method) {
419 return equals(new ForLoadedMethod(method));
420 }
421
422
425 public boolean represents(Constructor<?> constructor) {
426 return equals(new ForLoadedConstructor(constructor));
427 }
428
429
432 public String getName() {
433 return isMethod()
434 ? getInternalName()
435 : getDeclaringType().asErasure().getName();
436 }
437
438
441 public String getActualName() {
442 return isMethod()
443 ? getName()
444 : EMPTY_NAME;
445 }
446
447
450 public String getDescriptor() {
451 StringBuilder descriptor = new StringBuilder().append('(');
452 for (TypeDescription parameterType : getParameters().asTypeList().asErasures()) {
453 descriptor.append(parameterType.getDescriptor());
454 }
455 return descriptor.append(')').append(getReturnType().asErasure().getDescriptor()).toString();
456 }
457
458
461 public String getGenericSignature() {
462 try {
463 SignatureWriter signatureWriter = new SignatureWriter();
464 boolean generic = false;
465 for (TypeDescription.Generic typeVariable : getTypeVariables()) {
466 signatureWriter.visitFormalTypeParameter(typeVariable.getSymbol());
467 boolean classBound = true;
468 for (TypeDescription.Generic upperBound : typeVariable.getUpperBounds()) {
469 upperBound.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(classBound
470 ? signatureWriter.visitClassBound()
471 : signatureWriter.visitInterfaceBound()));
472 classBound = false;
473 }
474 generic = true;
475 }
476 for (TypeDescription.Generic parameterType : getParameters().asTypeList()) {
477 parameterType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(signatureWriter.visitParameterType()));
478 generic = generic || !parameterType.getSort().isNonGeneric();
479 }
480 TypeDescription.Generic returnType = getReturnType();
481 returnType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(signatureWriter.visitReturnType()));
482 generic = generic || !returnType.getSort().isNonGeneric();
483 TypeList.Generic exceptionTypes = getExceptionTypes();
484 if (!exceptionTypes.filter(not(ofSort(TypeDefinition.Sort.NON_GENERIC))).isEmpty()) {
485 for (TypeDescription.Generic exceptionType : exceptionTypes) {
486 exceptionType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(signatureWriter.visitExceptionType()));
487 generic = generic || !exceptionType.getSort().isNonGeneric();
488 }
489 }
490 return generic
491 ? signatureWriter.toString()
492 : NON_GENERIC_SIGNATURE;
493 } catch (GenericSignatureFormatError ignored) {
494 return NON_GENERIC_SIGNATURE;
495 }
496 }
497
498
501 public int getActualModifiers() {
502 return getModifiers() | (getDeclaredAnnotations().isAnnotationPresent(Deprecated.class)
503 ? Opcodes.ACC_DEPRECATED
504 : EMPTY_MASK);
505 }
506
507
510 public int getActualModifiers(boolean manifest) {
511 return manifest
512 ? getActualModifiers() & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)
513 : getActualModifiers() & ~Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT;
514 }
515
516
519 public int getActualModifiers(boolean manifest, Visibility visibility) {
520 return ModifierContributor.Resolver.of(Collections.singleton(getVisibility().expandTo(visibility))).resolve(getActualModifiers(manifest));
521 }
522
523
526 public boolean isVisibleTo(TypeDescription typeDescription) {
527 return (isVirtual() || getDeclaringType().asErasure().isVisibleTo(typeDescription))
528 && (isPublic()
529 || typeDescription.equals(getDeclaringType().asErasure())
530 || isProtected() && getDeclaringType().asErasure().isAssignableFrom(typeDescription)
531 || !isPrivate() && typeDescription.isSamePackage(getDeclaringType().asErasure())
532 || isPrivate() && typeDescription.isNestMateOf(getDeclaringType().asErasure()));
533 }
534
535
538 public boolean isAccessibleTo(TypeDescription typeDescription) {
539 return (isVirtual() || getDeclaringType().asErasure().isVisibleTo(typeDescription))
540 && (isPublic()
541 || typeDescription.equals(getDeclaringType().asErasure())
542 || !isPrivate() && typeDescription.isSamePackage(getDeclaringType().asErasure()))
543 || isPrivate() && typeDescription.isNestMateOf(getDeclaringType().asErasure());
544 }
545
546
549 public boolean isVirtual() {
550 return !(isConstructor() || isPrivate() || isStatic() || isTypeInitializer());
551 }
552
553
556 public boolean isDefaultMethod() {
557 return !isAbstract() && !isBridge() && getDeclaringType().isInterface();
558 }
559
560
563 public boolean isSpecializableFor(TypeDescription targetType) {
564 if (isStatic()) {
565 return false;
566 } else if (isPrivate() || isConstructor()) {
567 return getDeclaringType().equals(targetType);
568 } else {
569 return !isAbstract() && getDeclaringType().asErasure().isAssignableFrom(targetType);
570 }
571 }
572
573
576 public <T> T getDefaultValue(Class<T> type) {
577 return type.cast(getDefaultValue());
578 }
579
580
583 public boolean isInvokableOn(TypeDescription typeDescription) {
584 return !isStatic()
585 && !isTypeInitializer()
586 && isVisibleTo(typeDescription)
587 && (isVirtual()
588 ? getDeclaringType().asErasure().isAssignableFrom(typeDescription)
589 : getDeclaringType().asErasure().equals(typeDescription));
590 }
591
592
598 private boolean isBootstrap(TypeDescription selfType) {
599 TypeList parameterTypes = getParameters().asTypeList().asErasures();
600 switch (parameterTypes.size()) {
601 case 0:
602 return false;
603 case 1:
604 return parameterTypes.getOnly().represents(Object[].class);
605 case 2:
606 return JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isAssignableTo(parameterTypes.get(0))
607 && parameterTypes.get(1).represents(Object[].class);
608 case 3:
609 return JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isAssignableTo(parameterTypes.get(0))
610 && (parameterTypes.get(1).represents(Object.class) || parameterTypes.get(1).represents(String.class))
611 && (parameterTypes.get(2).represents(Object[].class) || parameterTypes.get(2).isAssignableFrom(selfType));
612 default:
613 return JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isAssignableTo(parameterTypes.get(0))
614 && (parameterTypes.get(1).represents(Object.class) || parameterTypes.get(1).represents(String.class))
615 && parameterTypes.get(2).isAssignableFrom(selfType);
616 }
617 }
618
619
626 private boolean isBootstrap(List<? extends TypeDefinition> types) {
627 TypeList targets = getParameters().asTypeList().asErasures();
628 if (targets.size() < 4) {
629 return types.isEmpty() || targets.get(targets.size() - 1).represents(Object[].class);
630 } else {
631 Iterator<TypeDescription> iterator = targets.subList(3, targets.size()).iterator();
632 for (TypeDefinition type : types) {
633 if (!iterator.hasNext()) {
634 return false;
635 }
636 TypeDescription target = iterator.next();
637 if (!iterator.hasNext() && target.represents(Object[].class)) {
638 return true;
639 } else if (!type.asErasure().isAssignableTo(target)) {
640 return false;
641 }
642 }
643 if (iterator.hasNext()) {
644 return iterator.next().represents(Object[].class) && !iterator.hasNext();
645 } else {
646 return true;
647 }
648 }
649 }
650
651
654 public boolean isInvokeBootstrap() {
655 TypeDescription returnType = getReturnType().asErasure();
656 if ((isMethod() && (!isStatic()
657 || !(JavaType.CALL_SITE.getTypeStub().isAssignableFrom(returnType) || JavaType.CALL_SITE.getTypeStub().isAssignableTo(returnType))))
658 || (isConstructor() && !JavaType.CALL_SITE.getTypeStub().isAssignableFrom(getDeclaringType().asErasure()))) {
659 return false;
660 }
661 return isBootstrap(JavaType.METHOD_TYPE.getTypeStub());
662 }
663
664
667 public boolean isInvokeBootstrap(List<? extends TypeDefinition> arguments) {
668 return isInvokeBootstrap() && isBootstrap(arguments);
669 }
670
671
674 public boolean isConstantBootstrap() {
675 return isBootstrap(TypeDescription.CLASS);
676 }
677
678
681 public boolean isConstantBootstrap(List<? extends TypeDefinition> arguments) {
682 return isConstantBootstrap() && isBootstrap(arguments);
683 }
684
685
688 public boolean isDefaultValue() {
689 return !isConstructor()
690 && !isStatic()
691 && getReturnType().asErasure().isAnnotationReturnType()
692 && getParameters().isEmpty();
693 }
694
695
698 public boolean isDefaultValue(AnnotationValue<?, ?> annotationValue) {
699 if (!isDefaultValue()) {
700 return false;
701 }
702 TypeDescription returnType = getReturnType().asErasure();
703 Object value = annotationValue.resolve();
704 return (returnType.represents(boolean.class) && value instanceof Boolean)
705 || (returnType.represents(byte.class) && value instanceof Byte)
706 || (returnType.represents(char.class) && value instanceof Character)
707 || (returnType.represents(short.class) && value instanceof Short)
708 || (returnType.represents(int.class) && value instanceof Integer)
709 || (returnType.represents(long.class) && value instanceof Long)
710 || (returnType.represents(float.class) && value instanceof Float)
711 || (returnType.represents(double.class) && value instanceof Double)
712 || (returnType.represents(String.class) && value instanceof String)
713 || (returnType.isAssignableTo(Enum.class) && value instanceof EnumerationDescription && isEnumerationType(returnType, (EnumerationDescription) value))
714 || (returnType.isAssignableTo(Annotation.class) && value instanceof AnnotationDescription && isAnnotationType(returnType, (AnnotationDescription) value))
715 || (returnType.represents(Class.class) && value instanceof TypeDescription)
716 || (returnType.represents(boolean[].class) && value instanceof boolean[])
717 || (returnType.represents(byte[].class) && value instanceof byte[])
718 || (returnType.represents(char[].class) && value instanceof char[])
719 || (returnType.represents(short[].class) && value instanceof short[])
720 || (returnType.represents(int[].class) && value instanceof int[])
721 || (returnType.represents(long[].class) && value instanceof long[])
722 || (returnType.represents(float[].class) && value instanceof float[])
723 || (returnType.represents(double[].class) && value instanceof double[])
724 || (returnType.represents(String[].class) && value instanceof String[])
725 || (returnType.isAssignableTo(Enum[].class) && value instanceof EnumerationDescription[] && isEnumerationType(returnType.getComponentType(), (EnumerationDescription[]) value))
726 || (returnType.isAssignableTo(Annotation[].class) && value instanceof AnnotationDescription[] && isAnnotationType(returnType.getComponentType(), (AnnotationDescription[]) value))
727 || (returnType.represents(Class[].class) && value instanceof TypeDescription[]);
728 }
729
730
737 private static boolean isEnumerationType(TypeDescription enumerationType, EnumerationDescription... enumerationDescription) {
738 for (EnumerationDescription anEnumerationDescription : enumerationDescription) {
739 if (!anEnumerationDescription.getEnumerationType().equals(enumerationType)) {
740 return false;
741 }
742 }
743 return true;
744 }
745
746
753 private static boolean isAnnotationType(TypeDescription annotationType, AnnotationDescription... annotationDescription) {
754 for (AnnotationDescription anAnnotationDescription : annotationDescription) {
755 if (!anAnnotationDescription.getAnnotationType().equals(annotationType)) {
756 return false;
757 }
758 }
759 return true;
760 }
761
762
765 public TypeVariableSource getEnclosingSource() {
766 return isStatic()
767 ? TypeVariableSource.UNDEFINED
768 : getDeclaringType().asErasure();
769 }
770
771
774 public boolean isInferrable() {
775 return true;
776 }
777
778
781 public <T> T accept(TypeVariableSource.Visitor<T> visitor) {
782 return visitor.onMethod(this.asDefined());
783 }
784
785
788 public boolean isGenerified() {
789 return !getTypeVariables().isEmpty();
790 }
791
792
795 public MethodDescription.Token asToken(ElementMatcher<? super TypeDescription> matcher) {
796 TypeDescription.Generic receiverType = getReceiverType();
797 return new MethodDescription.Token(getInternalName(),
798 getModifiers(),
799 getTypeVariables().asTokenList(matcher),
800 getReturnType().accept(new TypeDescription.Generic.Visitor.Substitutor.ForDetachment(matcher)),
801 getParameters().asTokenList(matcher),
802 getExceptionTypes().accept(new TypeDescription.Generic.Visitor.Substitutor.ForDetachment(matcher)),
803 getDeclaredAnnotations(),
804 getDefaultValue(),
805 receiverType == null
806 ? TypeDescription.Generic.UNDEFINED
807 : receiverType.accept(new TypeDescription.Generic.Visitor.Substitutor.ForDetachment(matcher)));
808 }
809
810
813 public SignatureToken asSignatureToken() {
814 return new SignatureToken(getInternalName(), getReturnType().asErasure(), getParameters().asTypeList().asErasures());
815 }
816
817
820 public TypeToken asTypeToken() {
821 return new TypeToken(getReturnType().asErasure(), getParameters().asTypeList().asErasures());
822 }
823
824
827 public boolean isBridgeCompatible(TypeToken typeToken) {
828 List<TypeDescription> types = getParameters().asTypeList().asErasures(), bridgeTypes = typeToken.getParameterTypes();
829 if (types.size() != bridgeTypes.size()) {
830 return false;
831 }
832 for (int index = 0; index < types.size(); index++) {
833 if (!types.get(index).equals(bridgeTypes.get(index)) && (types.get(index).isPrimitive() || bridgeTypes.get(index).isPrimitive())) {
834 return false;
835 }
836 }
837 TypeDescription returnType = getReturnType().asErasure(), bridgeReturnType = typeToken.getReturnType();
838 return returnType.equals(bridgeReturnType) || (!returnType.isPrimitive() && !bridgeReturnType.isPrimitive());
839 }
840
841 @Override
842 @CachedReturnPlugin.Enhance
843 public int hashCode() {
844 int hashCode = 17 + getDeclaringType().hashCode();
845 hashCode = 31 * hashCode + getInternalName().hashCode();
846 hashCode = 31 * hashCode + getReturnType().asErasure().hashCode();
847 return 31 * hashCode + getParameters().asTypeList().asErasures().hashCode();
848 }
849
850 @Override
851 public boolean equals(Object other) {
852 if (this == other) {
853 return true;
854 } else if (!(other instanceof MethodDescription)) {
855 return false;
856 }
857 MethodDescription methodDescription = (MethodDescription) other;
858 return getInternalName().equals(methodDescription.getInternalName())
859 && getDeclaringType().equals(methodDescription.getDeclaringType())
860 && getReturnType().asErasure().equals(methodDescription.getReturnType().asErasure())
861 && getParameters().asTypeList().asErasures().equals(methodDescription.getParameters().asTypeList().asErasures());
862 }
863
864
867 public String toGenericString() {
868 StringBuilder stringBuilder = new StringBuilder();
869 int modifiers = getModifiers() & SOURCE_MODIFIERS;
870 if (modifiers != EMPTY_MASK) {
871 stringBuilder.append(Modifier.toString(modifiers)).append(' ');
872 }
873 if (isMethod()) {
874 stringBuilder.append(getReturnType().getActualName()).append(' ');
875 stringBuilder.append(getDeclaringType().asErasure().getActualName()).append('.');
876 }
877 stringBuilder.append(getName()).append('(');
878 boolean first = true;
879 for (TypeDescription.Generic typeDescription : getParameters().asTypeList()) {
880 if (!first) {
881 stringBuilder.append(',');
882 } else {
883 first = false;
884 }
885 stringBuilder.append(typeDescription.getActualName());
886 }
887 stringBuilder.append(')');
888 TypeList.Generic exceptionTypes = getExceptionTypes();
889 if (!exceptionTypes.isEmpty()) {
890 stringBuilder.append(" throws ");
891 first = true;
892 for (TypeDescription.Generic typeDescription : exceptionTypes) {
893 if (!first) {
894 stringBuilder.append(',');
895 } else {
896 first = false;
897 }
898 stringBuilder.append(typeDescription.getActualName());
899 }
900 }
901 return stringBuilder.toString();
902 }
903
904 @Override
905 public String toString() {
906 StringBuilder stringBuilder = new StringBuilder();
907 int modifiers = getModifiers() & SOURCE_MODIFIERS;
908 if (modifiers != EMPTY_MASK) {
909 stringBuilder.append(Modifier.toString(modifiers)).append(' ');
910 }
911 if (isMethod()) {
912 stringBuilder.append(getReturnType().asErasure().getActualName()).append(' ');
913 stringBuilder.append(getDeclaringType().asErasure().getActualName()).append('.');
914 }
915 stringBuilder.append(getName()).append('(');
916 boolean first = true;
917 for (TypeDescription typeDescription : getParameters().asTypeList().asErasures()) {
918 if (!first) {
919 stringBuilder.append(',');
920 } else {
921 first = false;
922 }
923 stringBuilder.append(typeDescription.getActualName());
924 }
925 stringBuilder.append(')');
926 TypeList exceptionTypes = getExceptionTypes().asErasures();
927 if (!exceptionTypes.isEmpty()) {
928 stringBuilder.append(" throws ");
929 first = true;
930 for (TypeDescription typeDescription : exceptionTypes) {
931 if (!first) {
932 stringBuilder.append(',');
933 } else {
934 first = false;
935 }
936 stringBuilder.append(typeDescription.getActualName());
937 }
938 }
939 return stringBuilder.toString();
940 }
941 }
942
943
946 class ForLoadedConstructor extends InDefinedShape.AbstractBase implements ParameterDescription.ForLoadedParameter.ParameterAnnotationSource {
947
948
951 private final Constructor<?> constructor;
952
953
958 public ForLoadedConstructor(Constructor<?> constructor) {
959 this.constructor = constructor;
960 }
961
962
965 public TypeDescription getDeclaringType() {
966 return TypeDescription.ForLoadedType.of(constructor.getDeclaringClass());
967 }
968
969
972 public TypeDescription.Generic getReturnType() {
973 return TypeDescription.Generic.VOID;
974 }
975
976
979 @CachedReturnPlugin.Enhance("parameters")
980 public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
981 return ParameterList.ForLoadedExecutable.of(constructor, this);
982 }
983
984
987 public TypeList.Generic getExceptionTypes() {
988 return new TypeList.Generic.OfConstructorExceptionTypes(constructor);
989 }
990
991
994 public boolean isConstructor() {
995 return true;
996 }
997
998
1001 public boolean isTypeInitializer() {
1002 return false;
1003 }
1004
1005
1008 public boolean represents(Method method) {
1009 return false;
1010 }
1011
1012
1015 public boolean represents(Constructor<?> constructor) {
1016 return this.constructor.equals(constructor) || equals(new MethodDescription.ForLoadedConstructor(constructor));
1017 }
1018
1019
1022 public String getName() {
1023 return constructor.getName();
1024 }
1025
1026
1029 public int getModifiers() {
1030 return constructor.getModifiers();
1031 }
1032
1033
1036 public boolean isSynthetic() {
1037 return constructor.isSynthetic();
1038 }
1039
1040
1043 public String getInternalName() {
1044 return CONSTRUCTOR_INTERNAL_NAME;
1045 }
1046
1047
1050 public String getDescriptor() {
1051 return Type.getConstructorDescriptor(constructor);
1052 }
1053
1054
1057 public AnnotationValue<?, ?> getDefaultValue() {
1058 return AnnotationValue.UNDEFINED;
1059 }
1060
1061
1064 @CachedReturnPlugin.Enhance("declaredAnnotations")
1065 public AnnotationList getDeclaredAnnotations() {
1066 return new AnnotationList.ForLoadedAnnotations(constructor.getDeclaredAnnotations());
1067 }
1068
1069
1072 public TypeList.Generic getTypeVariables() {
1073 return TypeList.Generic.ForLoadedTypes.OfTypeVariables.of(constructor);
1074 }
1075
1076
1079 public TypeDescription.Generic getReceiverType() {
1080 TypeDescription.Generic receiverType = TypeDescription.Generic.AnnotationReader.DISPATCHER.resolveReceiverType(constructor);
1081 return receiverType == null
1082 ? super.getReceiverType()
1083 : receiverType;
1084 }
1085
1086
1089 @CachedReturnPlugin.Enhance("parameterAnnotations")
1090 public Annotation[][] getParameterAnnotations() {
1091 return constructor.getParameterAnnotations();
1092 }
1093 }
1094
1095
1098 class ForLoadedMethod extends InDefinedShape.AbstractBase implements ParameterDescription.ForLoadedParameter.ParameterAnnotationSource {
1099
1100
1103 private final Method method;
1104
1105
1110 public ForLoadedMethod(Method method) {
1111 this.method = method;
1112 }
1113
1114
1117 public TypeDescription getDeclaringType() {
1118 return TypeDescription.ForLoadedType.of(method.getDeclaringClass());
1119 }
1120
1121
1124 public TypeDescription.Generic getReturnType() {
1125 if (TypeDescription.AbstractBase.RAW_TYPES) {
1126 return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(method.getReturnType());
1127 }
1128 return new TypeDescription.Generic.LazyProjection.ForLoadedReturnType(method);
1129 }
1130
1131
1134 @CachedReturnPlugin.Enhance("parameters")
1135 public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
1136 return ParameterList.ForLoadedExecutable.of(method, this);
1137 }
1138
1139
1142 public TypeList.Generic getExceptionTypes() {
1143 if (TypeDescription.AbstractBase.RAW_TYPES) {
1144 return new TypeList.Generic.ForLoadedTypes(method.getExceptionTypes());
1145 }
1146 return new TypeList.Generic.OfMethodExceptionTypes(method);
1147 }
1148
1149
1152 public boolean isConstructor() {
1153 return false;
1154 }
1155
1156
1159 public boolean isTypeInitializer() {
1160 return false;
1161 }
1162
1163
1166 public boolean isBridge() {
1167 return method.isBridge();
1168 }
1169
1170
1173 public boolean represents(Method method) {
1174 return this.method.equals(method) || equals(new MethodDescription.ForLoadedMethod(method));
1175 }
1176
1177
1180 public boolean represents(Constructor<?> constructor) {
1181 return false;
1182 }
1183
1184
1187 public String getName() {
1188 return method.getName();
1189 }
1190
1191
1194 public int getModifiers() {
1195 return method.getModifiers();
1196 }
1197
1198
1201 public boolean isSynthetic() {
1202 return method.isSynthetic();
1203 }
1204
1205
1208 public String getInternalName() {
1209 return method.getName();
1210 }
1211
1212
1215 public String getDescriptor() {
1216 return Type.getMethodDescriptor(method);
1217 }
1218
1219
1224 public Method getLoadedMethod() {
1225 return method;
1226 }
1227
1228
1231 @CachedReturnPlugin.Enhance("declaredAnnotations")
1232 public AnnotationList getDeclaredAnnotations() {
1233 return new AnnotationList.ForLoadedAnnotations(method.getDeclaredAnnotations());
1234 }
1235
1236
1239 public AnnotationValue<?, ?> getDefaultValue() {
1240 Object value = method.getDefaultValue();
1241 return value == null
1242 ? AnnotationValue.UNDEFINED
1243 : AnnotationDescription.ForLoadedAnnotation.asValue(value, method.getReturnType());
1244 }
1245
1246
1249 public TypeList.Generic getTypeVariables() {
1250 if (TypeDescription.AbstractBase.RAW_TYPES) {
1251 return new TypeList.Generic.Empty();
1252 }
1253 return TypeList.Generic.ForLoadedTypes.OfTypeVariables.of(method);
1254 }
1255
1256
1259 public TypeDescription.Generic getReceiverType() {
1260 if (TypeDescription.AbstractBase.RAW_TYPES) {
1261 return super.getReceiverType();
1262 }
1263 TypeDescription.Generic receiverType = TypeDescription.Generic.AnnotationReader.DISPATCHER.resolveReceiverType(method);
1264 return receiverType == null
1265 ? super.getReceiverType()
1266 : receiverType;
1267 }
1268
1269
1272 @CachedReturnPlugin.Enhance("parameterAnnotations")
1273 public Annotation[][] getParameterAnnotations() {
1274 return method.getParameterAnnotations();
1275 }
1276 }
1277
1278
1282 class Latent extends InDefinedShape.AbstractBase {
1283
1284
1287 private final TypeDescription declaringType;
1288
1289
1292 private final String internalName;
1293
1294
1297 private final int modifiers;
1298
1299
1302 private final List<? extends TypeVariableToken> typeVariables;
1303
1304
1307 private final TypeDescription.Generic returnType;
1308
1309
1312 private final List<? extends ParameterDescription.Token> parameterTokens;
1313
1314
1317 private final List<? extends TypeDescription.Generic> exceptionTypes;
1318
1319
1322 private final List<? extends AnnotationDescription> declaredAnnotations;
1323
1324
1327 private final AnnotationValue<?, ?> defaultValue;
1328
1329
1332 private final TypeDescription.Generic receiverType;
1333
1334
1340 public Latent(TypeDescription declaringType, MethodDescription.Token token) {
1341 this(declaringType,
1342 token.getName(),
1343 token.getModifiers(),
1344 token.getTypeVariableTokens(),
1345 token.getReturnType(),
1346 token.getParameterTokens(),
1347 token.getExceptionTypes(),
1348 token.getAnnotations(),
1349 token.getDefaultValue(),
1350 token.getReceiverType());
1351 }
1352
1353
1367 public Latent(TypeDescription declaringType,
1368 String internalName,
1369 int modifiers,
1370 List<? extends TypeVariableToken> typeVariables,
1371 TypeDescription.Generic returnType,
1372 List<? extends ParameterDescription.Token> parameterTokens,
1373 List<? extends TypeDescription.Generic> exceptionTypes,
1374 List<? extends AnnotationDescription> declaredAnnotations,
1375 AnnotationValue<?, ?> defaultValue,
1376 TypeDescription.Generic receiverType) {
1377 this.declaringType = declaringType;
1378 this.internalName = internalName;
1379 this.modifiers = modifiers;
1380 this.typeVariables = typeVariables;
1381 this.returnType = returnType;
1382 this.parameterTokens = parameterTokens;
1383 this.exceptionTypes = exceptionTypes;
1384 this.declaredAnnotations = declaredAnnotations;
1385 this.defaultValue = defaultValue;
1386 this.receiverType = receiverType;
1387 }
1388
1389
1392 public TypeList.Generic getTypeVariables() {
1393 return TypeList.Generic.ForDetachedTypes.attachVariables(this, typeVariables);
1394 }
1395
1396
1399 public TypeDescription.Generic getReturnType() {
1400 return returnType.accept(TypeDescription.Generic.Visitor.Substitutor.ForAttachment.of(this));
1401 }
1402
1403
1406 public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
1407 return new ParameterList.ForTokens(this, parameterTokens);
1408 }
1409
1410
1413 public TypeList.Generic getExceptionTypes() {
1414 return TypeList.Generic.ForDetachedTypes.attach(this, exceptionTypes);
1415 }
1416
1417
1420 public AnnotationList getDeclaredAnnotations() {
1421 return new AnnotationList.Explicit(declaredAnnotations);
1422 }
1423
1424
1427 public String getInternalName() {
1428 return internalName;
1429 }
1430
1431
1434 public TypeDescription getDeclaringType() {
1435 return declaringType;
1436 }
1437
1438
1441 public int getModifiers() {
1442 return modifiers;
1443 }
1444
1445
1448 public AnnotationValue<?, ?> getDefaultValue() {
1449 return defaultValue;
1450 }
1451
1452
1455 public TypeDescription.Generic getReceiverType() {
1456 return receiverType == null
1457 ? super.getReceiverType()
1458 : receiverType.accept(TypeDescription.Generic.Visitor.Substitutor.ForAttachment.of(this));
1459 }
1460
1461
1464 public static class TypeInitializer extends InDefinedShape.AbstractBase {
1465
1466
1469 private final TypeDescription typeDescription;
1470
1471
1476 public TypeInitializer(TypeDescription typeDescription) {
1477 this.typeDescription = typeDescription;
1478 }
1479
1480
1483 public TypeDescription.Generic getReturnType() {
1484 return TypeDescription.Generic.VOID;
1485 }
1486
1487
1490 public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
1491 return new ParameterList.Empty<ParameterDescription.InDefinedShape>();
1492 }
1493
1494
1497 public TypeList.Generic getExceptionTypes() {
1498 return new TypeList.Generic.Empty();
1499 }
1500
1501
1504 public AnnotationValue<?, ?> getDefaultValue() {
1505 return AnnotationValue.UNDEFINED;
1506 }
1507
1508
1511 public TypeList.Generic getTypeVariables() {
1512 return new TypeList.Generic.Empty();
1513 }
1514
1515
1518 public AnnotationList getDeclaredAnnotations() {
1519 return new AnnotationList.Empty();
1520 }
1521
1522
1525 public TypeDescription getDeclaringType() {
1526 return typeDescription;
1527 }
1528
1529
1532 public int getModifiers() {
1533 return TYPE_INITIALIZER_MODIFIER;
1534 }
1535
1536
1539 public String getInternalName() {
1540 return MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME;
1541 }
1542 }
1543 }
1544
1545
1548 class TypeSubstituting extends AbstractBase implements InGenericShape {
1549
1550
1553 private final TypeDescription.Generic declaringType;
1554
1555
1558 private final MethodDescription methodDescription;
1559
1560
1563 private final TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor;
1564
1565
1572 public TypeSubstituting(TypeDescription.Generic declaringType,
1573 MethodDescription methodDescription,
1574 TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor) {
1575 this.declaringType = declaringType;
1576 this.methodDescription = methodDescription;
1577 this.visitor = visitor;
1578 }
1579
1580
1583 public TypeDescription.Generic getReturnType() {
1584 return methodDescription.getReturnType().accept(visitor);
1585 }
1586
1587
1590 public TypeList.Generic getTypeVariables() {
1591 return methodDescription.getTypeVariables().accept(visitor).filter(ElementMatchers.ofSort(TypeDefinition.Sort.VARIABLE));
1592 }
1593
1594
1597 public ParameterList<ParameterDescription.InGenericShape> getParameters() {
1598 return new ParameterList.TypeSubstituting(this, methodDescription.getParameters(), visitor);
1599 }
1600
1601
1604 public TypeList.Generic getExceptionTypes() {
1605 return new TypeList.Generic.ForDetachedTypes(methodDescription.getExceptionTypes(), visitor);
1606 }
1607
1608
1611 public AnnotationValue<?, ?> getDefaultValue() {
1612 return methodDescription.getDefaultValue();
1613 }
1614
1615
1618 public TypeDescription.Generic getReceiverType() {
1619 TypeDescription.Generic receiverType = methodDescription.getReceiverType();
1620 return receiverType == null
1621 ? TypeDescription.Generic.UNDEFINED
1622 : receiverType.accept(visitor);
1623 }
1624
1625
1628 public AnnotationList getDeclaredAnnotations() {
1629 return methodDescription.getDeclaredAnnotations();
1630 }
1631
1632
1635 public TypeDescription.Generic getDeclaringType() {
1636 return declaringType;
1637 }
1638
1639
1642 public int getModifiers() {
1643 return methodDescription.getModifiers();
1644 }
1645
1646
1649 public String getInternalName() {
1650 return methodDescription.getInternalName();
1651 }
1652
1653
1656 public InDefinedShape asDefined() {
1657 return methodDescription.asDefined();
1658 }
1659
1660
1663 public boolean isConstructor() {
1664 return methodDescription.isConstructor();
1665 }
1666
1667
1670 public boolean isMethod() {
1671 return methodDescription.isMethod();
1672 }
1673
1674
1677 public boolean isTypeInitializer() {
1678 return methodDescription.isTypeInitializer();
1679 }
1680 }
1681
1682
1685 class Token implements ByteCodeElement.Token<Token> {
1686
1687
1690 private final String name;
1691
1692
1695 private final int modifiers;
1696
1697
1700 private final List<? extends TypeVariableToken> typeVariableTokens;
1701
1702
1705 private final TypeDescription.Generic returnType;
1706
1707
1710 private final List<? extends ParameterDescription.Token> parameterTokens;
1711
1712
1715 private final List<? extends TypeDescription.Generic> exceptionTypes;
1716
1717
1720 private final List<? extends AnnotationDescription> annotations;
1721
1722
1725 private final AnnotationValue<?, ?> defaultValue;
1726
1727
1730 private final TypeDescription.Generic receiverType;
1731
1732
1738 public Token(int modifiers) {
1739 this(MethodDescription.CONSTRUCTOR_INTERNAL_NAME, modifiers, TypeDescription.Generic.VOID);
1740 }
1741
1742
1750 public Token(String name, int modifiers, TypeDescription.Generic returnType) {
1751 this(name, modifiers, returnType, Collections.<TypeDescription.Generic>emptyList());
1752 }
1753
1754
1762 public Token(String name, int modifiers, TypeDescription.Generic returnType, List<? extends TypeDescription.Generic> parameterTypes) {
1763 this(name,
1764 modifiers,
1765 Collections.<TypeVariableToken>emptyList(),
1766 returnType,
1767 new ParameterDescription.Token.TypeList(parameterTypes),
1768 Collections.<TypeDescription.Generic>emptyList(),
1769 Collections.<AnnotationDescription>emptyList(),
1770 AnnotationValue.UNDEFINED,
1771 TypeDescription.Generic.UNDEFINED);
1772 }
1773
1774
1787 public Token(String name,
1788 int modifiers,
1789 List<? extends TypeVariableToken> typeVariableTokens,
1790 TypeDescription.Generic returnType,
1791 List<? extends ParameterDescription.Token> parameterTokens,
1792 List<? extends TypeDescription.Generic> exceptionTypes,
1793 List<? extends AnnotationDescription> annotations,
1794 AnnotationValue<?, ?> defaultValue,
1795 TypeDescription.Generic receiverType) {
1796 this.name = name;
1797 this.modifiers = modifiers;
1798 this.typeVariableTokens = typeVariableTokens;
1799 this.returnType = returnType;
1800 this.parameterTokens = parameterTokens;
1801 this.exceptionTypes = exceptionTypes;
1802 this.annotations = annotations;
1803 this.defaultValue = defaultValue;
1804 this.receiverType = receiverType;
1805 }
1806
1807
1812 public String getName() {
1813 return name;
1814 }
1815
1816
1821 public int getModifiers() {
1822 return modifiers;
1823 }
1824
1825
1830 public TokenList<TypeVariableToken> getTypeVariableTokens() {
1831 return new TokenList<TypeVariableToken>(typeVariableTokens);
1832 }
1833
1834
1839 public TypeDescription.Generic getReturnType() {
1840 return returnType;
1841 }
1842
1843
1848 public TokenList<ParameterDescription.Token> getParameterTokens() {
1849 return new TokenList<ParameterDescription.Token>(parameterTokens);
1850 }
1851
1852
1857 public TypeList.Generic getExceptionTypes() {
1858 return new TypeList.Generic.Explicit(exceptionTypes);
1859 }
1860
1861
1866 public AnnotationList getAnnotations() {
1867 return new AnnotationList.Explicit(annotations);
1868 }
1869
1870
1875 public AnnotationValue<?, ?> getDefaultValue() {
1876 return defaultValue;
1877 }
1878
1879
1884 public TypeDescription.Generic getReceiverType() {
1885 return receiverType;
1886 }
1887
1888
1891 public Token accept(TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor) {
1892 return new Token(name,
1893 modifiers,
1894 getTypeVariableTokens().accept(visitor),
1895 returnType.accept(visitor),
1896 getParameterTokens().accept(visitor),
1897 getExceptionTypes().accept(visitor),
1898 annotations,
1899 defaultValue,
1900 receiverType == null
1901 ? TypeDescription.Generic.UNDEFINED
1902 : receiverType.accept(visitor));
1903 }
1904
1905
1911 public SignatureToken asSignatureToken(TypeDescription declaringType) {
1912 TypeDescription.Generic.Visitor<TypeDescription> visitor = new TypeDescription.Generic.Visitor.Reducing(declaringType, typeVariableTokens);
1913 List<TypeDescription> parameters = new ArrayList<TypeDescription>(parameterTokens.size());
1914 for (ParameterDescription.Token parameter : parameterTokens) {
1915 parameters.add(parameter.getType().accept(visitor));
1916 }
1917 return new SignatureToken(name, returnType.accept(visitor), parameters);
1918 }
1919
1920 @Override
1921 @CachedReturnPlugin.Enhance
1922 public int hashCode() {
1923 int result = name.hashCode();
1924 result = 31 * result + modifiers;
1925 result = 31 * result + typeVariableTokens.hashCode();
1926 result = 31 * result + returnType.hashCode();
1927 result = 31 * result + parameterTokens.hashCode();
1928 result = 31 * result + exceptionTypes.hashCode();
1929 result = 31 * result + annotations.hashCode();
1930 result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0);
1931 result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0);
1932 return result;
1933 }
1934
1935 @Override
1936 public boolean equals(Object other) {
1937 if (this == other) {
1938 return true;
1939 } else if (other == null || getClass() != other.getClass()) {
1940 return false;
1941 }
1942 Token token = (Token) other;
1943 return modifiers == token.modifiers
1944 && name.equals(token.name)
1945 && typeVariableTokens.equals(token.typeVariableTokens)
1946 && returnType.equals(token.returnType)
1947 && parameterTokens.equals(token.parameterTokens)
1948 && exceptionTypes.equals(token.exceptionTypes)
1949 && annotations.equals(token.annotations)
1950 && (defaultValue != null ? defaultValue.equals(token.defaultValue) : token.defaultValue == null)
1951 && (receiverType != null ? receiverType.equals(token.receiverType) : token.receiverType == null);
1952 }
1953
1954 @Override
1955 public String toString() {
1956 return "MethodDescription.Token{" +
1957 "name='" + name + '\'' +
1958 ", modifiers=" + modifiers +
1959 ", typeVariableTokens=" + typeVariableTokens +
1960 ", returnType=" + returnType +
1961 ", parameterTokens=" + parameterTokens +
1962 ", exceptionTypes=" + exceptionTypes +
1963 ", annotations=" + annotations +
1964 ", defaultValue=" + defaultValue +
1965 ", receiverType=" + receiverType +
1966 '}';
1967 }
1968 }
1969
1970
1973 class SignatureToken {
1974
1975
1978 private final String name;
1979
1980
1983 private final TypeDescription returnType;
1984
1985
1988 private final List<? extends TypeDescription> parameterTypes;
1989
1990
1997 public SignatureToken(String name, TypeDescription returnType, List<? extends TypeDescription> parameterTypes) {
1998 this.name = name;
1999 this.returnType = returnType;
2000 this.parameterTypes = parameterTypes;
2001 }
2002
2003
2008 public String getName() {
2009 return name;
2010 }
2011
2012
2017 public TypeDescription getReturnType() {
2018 return returnType;
2019 }
2020
2021
2026 @SuppressWarnings("unchecked")
2027 public List<TypeDescription> getParameterTypes() {
2028 return (List<TypeDescription>) parameterTypes;
2029 }
2030
2031
2036 public TypeToken asTypeToken() {
2037 return new TypeToken(returnType, parameterTypes);
2038 }
2039
2040 @Override
2041 @CachedReturnPlugin.Enhance
2042 public int hashCode() {
2043 int result = name.hashCode();
2044 result = 31 * result + returnType.hashCode();
2045 result = 31 * result + parameterTypes.hashCode();
2046 return result;
2047 }
2048
2049 @Override
2050 public boolean equals(Object other) {
2051 if (this == other) {
2052 return true;
2053 } else if (!(other instanceof SignatureToken)) {
2054 return false;
2055 }
2056 SignatureToken signatureToken = (SignatureToken) other;
2057 return name.equals(signatureToken.name)
2058 && returnType.equals(signatureToken.returnType)
2059 && parameterTypes.equals(signatureToken.parameterTypes);
2060 }
2061
2062 @Override
2063 public String toString() {
2064 StringBuilder stringBuilder = new StringBuilder().append(returnType).append(' ').append(name).append('(');
2065 boolean first = true;
2066 for (TypeDescription parameterType : parameterTypes) {
2067 if (first) {
2068 first = false;
2069 } else {
2070 stringBuilder.append(',');
2071 }
2072 stringBuilder.append(parameterType);
2073 }
2074 return stringBuilder.append(')').toString();
2075 }
2076 }
2077
2078
2081 class TypeToken {
2082
2083
2086 private final TypeDescription returnType;
2087
2088
2091 private final List<? extends TypeDescription> parameterTypes;
2092
2093
2099 public TypeToken(TypeDescription returnType, List<? extends TypeDescription> parameterTypes) {
2100 this.returnType = returnType;
2101 this.parameterTypes = parameterTypes;
2102 }
2103
2104
2109 public TypeDescription getReturnType() {
2110 return returnType;
2111 }
2112
2113
2118 @SuppressWarnings("unchecked")
2119 public List<TypeDescription> getParameterTypes() {
2120 return (List<TypeDescription>) parameterTypes;
2121 }
2122
2123 @Override
2124 @CachedReturnPlugin.Enhance
2125 public int hashCode() {
2126 int result = returnType.hashCode();
2127 result = 31 * result + parameterTypes.hashCode();
2128 return result;
2129 }
2130
2131 @Override
2132 public boolean equals(Object other) {
2133 if (this == other) {
2134 return true;
2135 } else if (!(other instanceof TypeToken)) {
2136 return false;
2137 }
2138 TypeToken typeToken = (TypeToken) other;
2139 return returnType.equals(typeToken.returnType) && parameterTypes.equals(typeToken.parameterTypes);
2140 }
2141
2142 @Override
2143 public String toString() {
2144 StringBuilder stringBuilder = new StringBuilder().append('(');
2145 for (TypeDescription parameterType : parameterTypes) {
2146 stringBuilder.append(parameterType.getDescriptor());
2147 }
2148 return stringBuilder.append(')').append(returnType.getDescriptor()).toString();
2149 }
2150 }
2151 }
2152