/** * {@inheritDoc} */ public boolean isArray() { return delegate.isArray(); }
/** * {@inheritDoc} */ public boolean isArray() { return asErasure().isArray(); }
/** * {@inheritDoc} */ public boolean isArray() { return asErasure().isArray(); }
/** * Creates an array projection. * * @param componentType The component type of the array. * @param arity The arity of this array. * @return A projection of the component type as an array of the given value with the supplied arity. */ public static TypeDescription of(TypeDescription componentType, int arity) { if (arity < 0) { throw new IllegalArgumentException("Arrays cannot have a negative arity"); } while (componentType.isArray()) { componentType = componentType.getComponentType(); arity++; } return arity == 0 ? componentType : new ArrayProjection(componentType, arity); }
/** * Creates a type creation for the given type. * * @param typeDescription The type to be create. * @return A stack manipulation that represents the creation of the given type. */ public static StackManipulation of(TypeDescription typeDescription) { if (typeDescription.isArray() || typeDescription.isPrimitive() || typeDescription.isAbstract()) { throw new IllegalArgumentException(typeDescription + " is not instantiable"); } return new TypeCreation(typeDescription); }
/** * {@inheritDoc} */ public String getActualName() { if (isArray()) { TypeDescription typeDescription = this; int dimensions = 0; do { dimensions++; typeDescription = typeDescription.getComponentType(); } while (typeDescription.isArray()); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(typeDescription.getActualName()); for (int i = 0; i < dimensions; i++) { stringBuilder.append("[]"); } return stringBuilder.toString(); } else { return getName(); } }
if (type.isArray() || type.isPrimitive()) { throw new IllegalArgumentException("Cannot decorate array or primitive type: " + type);
/** * Resolves a type locator based upon an annotation value. * * @param typeDescription The annotation's value. * @return The appropriate type locator. */ protected static TypeLocator of(TypeDescription typeDescription) { if (typeDescription.represents(void.class)) { return ForParameterType.INSTANCE; } else if (typeDescription.represents(TargetType.class)) { return ForInstrumentedType.INSTANCE; } else if (typeDescription.isPrimitive() || typeDescription.isArray()) { throw new IllegalStateException("Cannot assign proxy to " + typeDescription); } else { return new ForType(typeDescription); } }
/** * Rebases the given type where any intercepted method that is declared by the redefined type is preserved within the * rebased type's class such that the class's original can be invoked from the new method implementations. Rebasing a * type can be seen similarly to creating a subclass where the subclass is later merged with the original class file. * * @param type The type that is being rebased. * @param classFileLocator The class file locator that is queried for the rebased type's class file. * @param methodNameTransformer The method name transformer for renaming a method that is rebased. * @param <T> The loaded type of the rebased type. * @return A type builder for rebasing the provided type. */ public <T> DynamicType.Builder<T> rebase(TypeDescription type, ClassFileLocator classFileLocator, MethodNameTransformer methodNameTransformer) { if (type.isArray() || type.isPrimitive()) { throw new IllegalArgumentException("Cannot rebase array or primitive type: " + type); } return new RebaseDynamicTypeBuilder<T>(instrumentedTypeFactory.represent(type), classFileVersion, auxiliaryTypeNamingStrategy, annotationValueFilterFactory, annotationRetention, implementationContextFactory, methodGraphCompiler, typeValidation, classWriterStrategy, ignoredMethods, type, classFileLocator, methodNameTransformer); }
/** * Resolves the given type description to the supplied target type if it represents the {@link TargetType} placeholder. * Array types are resolved to their component type and rebuilt as an array of the actual target type, if necessary. * * @param typeDescription The type description that might represent the {@link TargetType} placeholder. * @param targetType The actual target type. * @return A description of the resolved type. */ public static TypeDescription resolve(TypeDescription typeDescription, TypeDescription targetType) { int arity = 0; TypeDescription componentType = typeDescription; while (componentType.isArray()) { componentType = componentType.getComponentType(); arity++; } return componentType.represents(TargetType.class) ? TypeDescription.ArrayProjection.of(targetType, arity) : typeDescription; }
if (type.isArray() || type.isPrimitive()) { throw new IllegalArgumentException("Cannot redefine array or primitive type: " + type);
/** * Delegates any intercepted method to invoke a {@code static} method that is declared by the supplied type. To be considered * a valid delegation target, the target method must be visible and accessible to the instrumented type. This is the case if * the target type is either public or in the same package as the instrumented type and if the target 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 typeDescription The target type for the delegation. * @return A method delegation that redirects method calls to a static method of the supplied type. */ public MethodDelegation to(TypeDescription typeDescription) { if (typeDescription.isArray()) { throw new IllegalArgumentException("Cannot delegate to array " + typeDescription); } else if (typeDescription.isPrimitive()) { throw new IllegalArgumentException("Cannot delegate to primitive " + typeDescription); } return new MethodDelegation(ImplementationDelegate.ForStaticMethod.of(typeDescription.getDeclaredMethods().filter(isStatic().and(matcher)), TargetMethodAnnotationDrivenBinder.of(parameterBinders)), parameterBinders, ambiguityResolver, bindingResolver); }
/** * {@inheritDoc} */ public Boolean onGenericArray(Generic genericArray) { return typeDescription.isArray() ? genericArray.getComponentType().accept(new ForNonGenericType(typeDescription.getComponentType())) : typeDescription.represents(Object.class) || TypeDescription.ARRAY_INTERFACES.contains(typeDescription.asGenericType()); }
/** * {@inheritDoc} */ public boolean isAnnotationValue() { return isPrimitive() || represents(String.class) || isAssignableTo(TypeDescription.class) || isAssignableTo(AnnotationDescription.class) || isAssignableTo(EnumerationDescription.class) || (isArray() && !getComponentType().isArray() && getComponentType().isAnnotationValue()); }
/** * Resolves a var handle constant for an array. * * @param typeDescription The array type for which the var handle is resolved. * @return A dynamic constant that represents the created var handle constant. */ public static JavaConstant ofArrayVarHandle(TypeDescription typeDescription) { if (!typeDescription.isArray()) { throw new IllegalArgumentException("Not an array type: " + typeDescription); } return new Dynamic(new ConstantDynamic("arrayVarHandle", JavaType.VAR_HANDLE.getTypeStub().getDescriptor(), new Handle(Opcodes.H_INVOKESTATIC, CONSTANT_BOOTSTRAPS, "arrayVarHandle", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;", false), Type.getType(typeDescription.getDescriptor())), JavaType.VAR_HANDLE.getTypeStub()); }
/** * {@inheritDoc} */ public boolean isAnnotationReturnType() { return isPrimitive() || represents(String.class) || (isAssignableTo(Enum.class) && !represents(Enum.class)) || (isAssignableTo(Annotation.class) && !represents(Annotation.class)) || represents(Class.class) || (isArray() && !getComponentType().isArray() && getComponentType().isAnnotationReturnType()); }
/** * Performs the writing of a given annotation value to an annotation visitor. * * @param annotationVisitor The annotation visitor the write process is to be applied on. * @param valueType The type of the annotation value. * @param name The name of the annotation type. * @param value The annotation's value. */ public static void apply(AnnotationVisitor annotationVisitor, TypeDescription valueType, String name, Object value) { if (valueType.isArray()) { // The Android emulator reads annotation arrays as annotation types. Therefore, this check needs to come first. AnnotationVisitor arrayVisitor = annotationVisitor.visitArray(name); int length = Array.getLength(value); TypeDescription componentType = valueType.getComponentType(); for (int index = 0; index < length; index++) { apply(arrayVisitor, componentType, NO_NAME, Array.get(value, index)); } arrayVisitor.visitEnd(); } else if (valueType.isAnnotation()) { handle(annotationVisitor.visitAnnotation(name, valueType.getDescriptor()), (AnnotationDescription) value, AnnotationValueFilter.Default.APPEND_DEFAULTS); } else if (valueType.isEnum()) { annotationVisitor.visitEnum(name, valueType.getDescriptor(), ((EnumerationDescription) value).getValue()); } else if (valueType.represents(Class.class)) { annotationVisitor.visit(name, Type.getType(((TypeDescription) value).getDescriptor())); } else { annotationVisitor.visit(name, value); } }
/** * {@inheritDoc} */ public ParameterBinding<?> bind(AnnotationDescription.Loadable<S> annotation, MethodDescription source, ParameterDescription target, Implementation.Target implementationTarget, Assigner assigner, Assigner.Typing typing) { if (!declaringType(annotation).represents(void.class)) { if (declaringType(annotation).isPrimitive() || declaringType(annotation).isArray()) { throw new IllegalStateException("A primitive type or array type cannot declare a field: " + source); } else if (!implementationTarget.getInstrumentedType().isAssignableTo(declaringType(annotation))) { return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE; } } FieldLocator fieldLocator = declaringType(annotation).represents(void.class) ? new FieldLocator.ForClassHierarchy(implementationTarget.getInstrumentedType()) : new FieldLocator.ForExactType(declaringType(annotation), implementationTarget.getInstrumentedType()); FieldLocator.Resolution resolution = fieldName(annotation).equals(BEAN_PROPERTY) ? resolveAccessor(fieldLocator, source) : fieldLocator.locate(fieldName(annotation)); return resolution.isResolved() && !(source.isStatic() && !resolution.getField().isStatic()) ? bind(resolution.getField(), annotation, source, target, implementationTarget, assigner) : ParameterBinding.Illegal.INSTANCE; }