@Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof Generic)) { return false; } Generic typeDescription = (Generic) other; if (!typeDescription.getSort().isParameterized()) { return false; } Generic ownerType = getOwnerType(), otherOwnerType = typeDescription.getOwnerType(); return asErasure().equals(typeDescription.asErasure()) && !(ownerType == null && otherOwnerType != null) && !(ownerType != null && !ownerType.equals(otherOwnerType)) && getTypeArguments().equals(typeDescription.getTypeArguments()); }
/** * Delegates any intercepted method to invoke a non-{@code static} method that is declared by the supplied type's instance or any * of its super types. To be considered a valid delegation target, a method must be visible and accessible to the instrumented type. * This is the case if the method's declaring type is either public or in the same package as the instrumented type and if the method * is either public or non-private and in the same package as the instrumented type. Private methods can only be used as * a delegation target if the delegation is targeting the instrumented type. * * @param target The target instance for the delegation. * @param type The most specific type of which {@code target} should be considered. Must be a super type of the target's actual type. * @param fieldName The name of the field that is holding the {@code target} instance. * @param methodGraphCompiler The method graph compiler to use. * @return A method delegation that redirects method calls to a static method of the supplied type. */ public MethodDelegation to(Object target, Type type, String fieldName, MethodGraph.Compiler methodGraphCompiler) { TypeDescription.Generic typeDescription = TypeDefinition.Sort.describe(type); if (!typeDescription.asErasure().isInstance(target)) { throw new IllegalArgumentException(target + " is not an instance of " + type); } return new MethodDelegation(new ImplementationDelegate.ForField.WithInstance(fieldName, methodGraphCompiler, parameterBinders, matcher, target, typeDescription), parameterBinders, ambiguityResolver, bindingResolver); }
@Override @SuppressFBWarnings(value = "EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS", justification = "Type check is performed by erasure implementation") public boolean equals(Object other) { if (this == other) { return true; } else if (getSort().isNonGeneric()) { return asErasure().equals(other); } if (!(other instanceof Generic)) { return false; } Generic typeDescription = (Generic) other; return typeDescription.getSort().isGenericArray() && getComponentType().equals(typeDescription.getComponentType()); }
private static TypeDescription entityType(TypeDescription.Generic type) { if ( type.getSort().isParameterized() ) { if ( type.asErasure().isAssignableTo( Collection.class ) ) { return type.getTypeArguments().get( 0 ).asErasure(); } if ( type.asErasure().isAssignableTo( Map.class ) ) { return type.getTypeArguments().get( 1 ).asErasure(); } } return type.asErasure(); }
} else if (!bounds.add(bound)) { throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + " for " + this); } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) { throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + this); } else if (!bounds.add(bound)) { throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + " for " + methodDescription); } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) { throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + methodDescription);
generic = generic || !parameterType.getSort().isNonGeneric(); generic = generic || !returnType.getSort().isNonGeneric(); TypeList.Generic exceptionTypes = getExceptionTypes(); if (!exceptionTypes.filter(not(ofSort(TypeDefinition.Sort.NON_GENERIC))).isEmpty()) { for (TypeDescription.Generic exceptionType : exceptionTypes) { exceptionType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(signatureWriter.visitExceptionType())); generic = generic || !exceptionType.getSort().isNonGeneric();
annotationAppender = annotationAppender.append(annotationDescription, annotationValueFilter, typeReference, EMPTY_TYPE_PATH); int boundIndex = !typeVariable.getUpperBounds().get(0).getSort().isTypeVariable() && typeVariable.getUpperBounds().get(0).isInterface() ? 1 : 0;
generic = generic || !superClass.getSort().isNonGeneric(); for (Generic interfaceType : getInterfaces()) { interfaceType.accept(new Generic.Visitor.ForSignatureVisitor(signatureWriter.visitInterface())); generic = generic || !interfaceType.getSort().isNonGeneric();
/** * Creates a parameterized type. * * @param rawType A raw version of the type to describe as a parameterized type. * @param ownerType The owner type of the parameterized type. * @param parameters The type arguments to attach to the raw type as parameters. * @return A builder for creating a parameterized type. */ public static Builder parameterizedType(TypeDescription rawType, Generic ownerType, Collection<? extends TypeDefinition> parameters) { TypeDescription declaringType = rawType.getDeclaringType(); if (ownerType == null && declaringType != null && rawType.isStatic()) { ownerType = declaringType.asGenericType(); } if (!rawType.represents(TargetType.class)) { if (!rawType.isGenerified()) { throw new IllegalArgumentException(rawType + " is not a parameterized type"); } else if (ownerType == null && declaringType != null && !rawType.isStatic()) { throw new IllegalArgumentException(rawType + " requires an owner type"); } else if (ownerType != null && !ownerType.asErasure().equals(declaringType)) { throw new IllegalArgumentException(ownerType + " does not represent required owner for " + rawType); } else if (ownerType != null && (rawType.isStatic() ^ ownerType.getSort().isNonGeneric())) { throw new IllegalArgumentException(ownerType + " does not define the correct parameters for owning " + rawType); } else if (rawType.getTypeVariables().size() != parameters.size()) { throw new IllegalArgumentException(parameters + " does not contain number of required parameters for " + rawType); } } return new Builder.OfParameterizedType(rawType, ownerType, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(parameters))); }
/** * <p> * Creates a new builder for subclassing the provided type. If the provided type is an interface, a new class implementing * this interface type is created. * </p> * <p> * When extending a class, Byte Buddy imitates all visible constructors of the subclassed type. Any constructor is implemented * to only invoke its super type constructor of equal signature. Another behavior can be specified by supplying an explicit * {@link ConstructorStrategy} by {@link ByteBuddy#subclass(Type, ConstructorStrategy)}. * </p> * <p> * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented * as raw types if they declare type variables. * </p> * <p> * <b>Note</b>: Byte Buddy does not cache previous subclasses but will attempt the generation of a new subclass. For caching * types, a external cache or {@link TypeCache} should be used. * </p> * * @param superType The super class or interface type to extend. The type must be a raw type or parameterized type. All type * variables that are referenced by the generic type must be declared by the generated subclass before creating * the type. * @return A type builder for creating a new class extending the provided class or interface. */ public DynamicType.Builder<?> subclass(Type superType) { return subclass(TypeDefinition.Sort.describe(superType)); }
/** * <p> * Creates a new builder for subclassing the provided type. If the provided type is an interface, a new class implementing * this interface type is created. * </p> * <p> * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented * as raw types if they declare type variables. * </p> * <p> * <b>Note</b>: Byte Buddy does not cache previous subclasses but will attempt the generation of a new subclass. For caching * types, a external cache or {@link TypeCache} should be used. * </p> * * @param superType The super class or interface type to extend. The type must be a raw type or parameterized * type. All type variables that are referenced by the generic type must be declared by the * generated subclass before creating the type. * @param constructorStrategy A constructor strategy that determines the * @return A type builder for creating a new class extending the provided class or interface. */ public DynamicType.Builder<?> subclass(Type superType, ConstructorStrategy constructorStrategy) { return subclass(TypeDefinition.Sort.describe(superType), constructorStrategy); }
/** * Visits a type which might define an owner type. * * @param ownableType The visited generic type. */ private void onOwnableType(Generic ownableType) { Generic ownerType = ownableType.getOwnerType(); if (ownerType != null && ownerType.getSort().isParameterized()) { onOwnableType(ownerType); signatureVisitor.visitInnerClassType(ownableType.asErasure().getSimpleName()); } else { signatureVisitor.visitClassType(ownableType.asErasure().getInternalName()); } for (Generic typeArgument : ownableType.getTypeArguments()) { typeArgument.accept(new OfTypeArgument(signatureVisitor)); } }
private static TypeDescription entityType(TypeDescription.Generic type) { if ( type.getSort().isParameterized() ) { if ( type.asErasure().isAssignableTo( Collection.class ) ) { return type.getTypeArguments().get( 0 ).asErasure(); } if ( type.asErasure().isAssignableTo( Map.class ) ) { return type.getTypeArguments().get( 1 ).asErasure(); } } return type.asErasure(); }
/** * {@inheritDoc} */ public Generic findBindingOf(Generic typeVariable) { Generic typeDescription = this; do { TypeList.Generic typeArguments = typeDescription.getTypeArguments(), typeVariables = typeDescription.asErasure().getTypeVariables(); for (int index = 0; index < Math.min(typeArguments.size(), typeVariables.size()); index++) { if (typeVariable.equals(typeVariables.get(index))) { return typeArguments.get(index); } } typeDescription = typeDescription.getOwnerType(); } while (typeDescription != null && typeDescription.getSort().isParameterized()); return Generic.UNDEFINED; }
/** * Creates a parameterized type. * * @param rawType A raw version of the type to describe as a parameterized type. * @param ownerType The owner type of the parameterized type. * @param parameters The type arguments to attach to the raw type as parameters. * @return A builder for creating a parameterized type. */ public static Builder parameterizedType(Class<?> rawType, java.lang.reflect.Type ownerType, List<? extends java.lang.reflect.Type> parameters) { return parameterizedType(ForLoadedType.of(rawType), ownerType == null ? null : Sort.describe(ownerType), new TypeList.Generic.ForLoadedTypes(parameters)); }
@Override protected void apply(StringBuilder stringBuilder, TypeDescription erasure, Generic ownerType) { if (ownerType != null) { stringBuilder.append(ownerType.getTypeName()).append('$'); if (ownerType.getSort().isParameterized()) { stringBuilder.append(erasure.getName().replace(ownerType.asErasure().getName() + "$", "")); } else { stringBuilder.append(erasure.getSimpleName()); } } else { stringBuilder.append(erasure.getName()); } } };
/** * Matches a method that declares the given generic exception type. For non-generic type, this matcher behaves identically to * {@link ElementMatchers#declaresException(TypeDescription)}. For exceptions that are expressed as type variables, only exceptions * that are represented as this type variable are matched. * * @param exceptionType The generic exception type that is matched exactly. * @param <T> The type of the matched object. * @return A matcher that matches any method that exactly matches the provided generic exception. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> declaresGenericException(TypeDescription.Generic exceptionType) { return !exceptionType.getSort().isWildcard() && exceptionType.asErasure().isAssignableTo(Throwable.class) ? ElementMatchers.<T>declaresGenericException(new CollectionItemMatcher<TypeDescription.Generic>(is(exceptionType))) : new BooleanMatcher<T>(false); }
/** * {@inheritDoc} */ public Generic resolve(AnnotatedElement annotatedType) { try { return annotatedType == null ? UNDEFINED : Sort.describe((java.lang.reflect.Type) getType.invoke(annotatedType, NO_ARGUMENTS), new Resolved(annotatedType)); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access java.lang.reflect.AnnotatedType#getType", exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Error invoking java.lang.reflect.AnnotatedType#getType", exception.getCause()); } }
/** * {@inheritDoc} */ public String getGenericSignature() { TypeDescription.Generic fieldType = getType(); try { return fieldType.getSort().isNonGeneric() ? NON_GENERIC_SIGNATURE : fieldType.accept(new TypeDescription.Generic.Visitor.ForSignatureVisitor(new SignatureWriter())).toString(); } catch (GenericSignatureFormatError ignored) { return NON_GENERIC_SIGNATURE; } }
/** * {@inheritDoc} */ public Composable setsValue(StackManipulation stackManipulation, Type type) { return setsValue(stackManipulation, TypeDescription.Generic.Sort.describe(type)); }