@Override protected Map<Integer, TypeDefinition> resolveInitializationTypes(ArgumentHandler argumentHandler) { return adviceMethod.getReturnType().represents(void.class) ? Collections.<Integer, TypeDefinition>emptyMap() : Collections.<Integer, TypeDefinition>singletonMap(argumentHandler.exit(), adviceMethod.getReturnType()); }
/** * {@inheritDoc} */ public void injectReturnFrame(MethodVisitor methodVisitor) { if (!expandFrames && currentFrameDivergence == 0) { if (adviceMethod.getReturnType().represents(void.class)) { methodVisitor.visitFrame(Opcodes.F_SAME, EMPTY.length, EMPTY, EMPTY.length, EMPTY); } else { methodVisitor.visitFrame(Opcodes.F_SAME1, EMPTY.length, EMPTY, 1, new Object[]{toFrame(adviceMethod.getReturnType().asErasure())}); } } else { injectFullFrame(methodVisitor, startTypes, adviceMethod.getReturnType().represents(void.class) ? Collections.<TypeDescription>emptyList() : Collections.singletonList(adviceMethod.getReturnType().asErasure())); } }
/** * Creates a binder by installing two proxy types which are implemented by this binder if a field getter * or a field setter is requested by using the * {@link FieldProxy} annotation. * * @param getterType The type which should be used for getter proxies. The type must * represent an interface which defines a single method which returns an * {@link java.lang.Object} return type and does not take any arguments. The use of generics * is permitted. * @param setterType The type which should be uses for setter proxies. The type must * represent an interface which defines a single method which returns {@code void} * and takes a single {@link java.lang.Object}-typed argument. The use of generics * is permitted. * @return A binder for the {@link FieldProxy} annotation. */ public static TargetMethodAnnotationDrivenBinder.ParameterBinder<FieldProxy> install(TypeDescription getterType, TypeDescription setterType) { MethodDescription.InDefinedShape getterMethod = onlyMethod(getterType); if (!getterMethod.getReturnType().asErasure().represents(Object.class)) { throw new IllegalArgumentException(getterMethod + " must take a single Object-typed parameter"); } else if (getterMethod.getParameters().size() != 0) { throw new IllegalArgumentException(getterMethod + " must not declare parameters"); } MethodDescription.InDefinedShape setterMethod = onlyMethod(setterType); if (!setterMethod.getReturnType().asErasure().represents(void.class)) { throw new IllegalArgumentException(setterMethod + " must return void"); } else if (setterMethod.getParameters().size() != 1 || !setterMethod.getParameters().get(0).getType().asErasure().represents(Object.class)) { throw new IllegalArgumentException(setterMethod + " must declare a single Object-typed parameters"); } return new Binder(getterMethod, setterMethod); }
OffsetMapping.ForStubValue.INSTANCE, OffsetMapping.ForEnterValue.Factory.of(enterType), OffsetMapping.ForExitValue.Factory.of(adviceMethod.getReturnType()), new OffsetMapping.ForLocalValue.Factory(namedTypes), OffsetMapping.ForReturnValue.Factory.INSTANCE,
/** * {@inheritDoc} */ public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator) { for (MethodDescription.InDefinedShape methodDescription : typeDescription.getDeclaredMethods() .filter(not(isBridge()).<MethodDescription>and(isAnnotatedWith(Enhance.class)))) { if (methodDescription.isAbstract()) { throw new IllegalStateException("Cannot cache the value of an abstract method: " + methodDescription); } else if (!methodDescription.getParameters().isEmpty()) { throw new IllegalStateException("Cannot cache the value of a method with parameters: " + methodDescription); } else if (methodDescription.getReturnType().represents(void.class)) { throw new IllegalStateException("Cannot cache void result for " + methodDescription); } String name = methodDescription.getDeclaredAnnotations().ofType(Enhance.class).loadSilent().value(); if (name.length() == 0) { name = methodDescription.getName() + NAME_INFIX + randomString.nextString(); } builder = builder .defineField(name, methodDescription.getReturnType().asErasure(), methodDescription.isStatic() ? Ownership.STATIC : Ownership.MEMBER, Visibility.PRIVATE, SyntheticState.SYNTHETIC, FieldPersistence.TRANSIENT) .visit(Advice.withCustomMapping() .bind(CacheField.class, new CacheFieldOffsetMapping(name)) .to(adviceByType.get(methodDescription.getReturnType().isPrimitive() ? methodDescription.getReturnType().asErasure() : TypeDescription.OBJECT), this.classFileLocator) .on(is(methodDescription))); } return builder; }
/** * {@inheritDoc} */ protected MethodVisitor doApply(MethodVisitor methodVisitor, Context implementationContext, Assigner assigner, ArgumentHandler.ForAdvice argumentHandler, MethodSizeHandler.ForAdvice methodSizeHandler, StackMapFrameHandler.ForAdvice stackMapFrameHandler, TypeDescription instrumentedType, MethodDescription instrumentedMethod, SuppressionHandler.Bound suppressionHandler, RelocationHandler.Bound relocationHandler) { methodSizeHandler.requireLocalVariableLengthPadding(adviceMethod.getReturnType().getStackSize().getSize()); return super.doApply(methodVisitor, implementationContext, assigner, argumentHandler, methodSizeHandler, stackMapFrameHandler, instrumentedType, instrumentedMethod, suppressionHandler, relocationHandler); } }
/** * {@inheritDoc} */ public String lookup() { return typePool.describe(annotationName) .resolve() .getDeclaredMethods() .filter(named(name)) .getOnly() .getReturnType() .asErasure() .getComponentType() .getName(); } }
/** * Creates a method handle representation of the given method for an explicit special method invocation of an otherwise virtual method. * * @param methodDescription The method ro represent. * @param typeDescription The type on which the method is to be invoked on as a special method invocation. * @return A method handle representing the given method as special method invocation. */ public static MethodHandle ofSpecial(MethodDescription.InDefinedShape methodDescription, TypeDescription typeDescription) { if (!methodDescription.isSpecializableFor(typeDescription)) { throw new IllegalArgumentException("Cannot specialize " + methodDescription + " for " + typeDescription); } return new MethodHandle(HandleType.ofSpecial(methodDescription), typeDescription, methodDescription.getInternalName(), methodDescription.getReturnType().asErasure(), methodDescription.getParameters().asTypeList().asErasures()); }
/** * Handles the writing of a single annotation to an annotation visitor. * * @param annotationVisitor The annotation visitor the write process is to be applied on. * @param annotation The annotation to be written. * @param annotationValueFilter The value filter to apply for discovering which values of an annotation should be written. */ private static void handle(AnnotationVisitor annotationVisitor, AnnotationDescription annotation, AnnotationValueFilter annotationValueFilter) { for (MethodDescription.InDefinedShape methodDescription : annotation.getAnnotationType().getDeclaredMethods()) { if (annotationValueFilter.isRelevant(annotation, methodDescription)) { apply(annotationVisitor, methodDescription.getReturnType().asErasure(), methodDescription.getName(), annotation.getValue(methodDescription).resolve()); } } annotationVisitor.visitEnd(); }
/** * Creates a method invocation with an implicitly determined invocation type. If the method's return type derives from its declared shape, the value * is additionally casted to the value of the generically resolved method. * * @param methodDescription The method to be invoked. * @return A stack manipulation with implicitly determined invocation type. */ public static WithImplicitInvocationTargetType invoke(MethodDescription methodDescription) { MethodDescription.InDefinedShape declaredMethod = methodDescription.asDefined(); return declaredMethod.getReturnType().asErasure().equals(methodDescription.getReturnType().asErasure()) ? invoke(declaredMethod) : OfGenericMethod.of(methodDescription, invoke(declaredMethod)); }
/** * Creates a method handle representation of the given method. * * @param methodDescription The method ro represent. * @return A method handle representing the given method. */ public static MethodHandle of(MethodDescription.InDefinedShape methodDescription) { return new MethodHandle(HandleType.of(methodDescription), methodDescription.getDeclaringType().asErasure(), methodDescription.getInternalName(), methodDescription.getReturnType().asErasure(), methodDescription.getParameters().asTypeList().asErasures()); }
/** * {@inheritDoc} */ public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) { methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, METHOD_HANDLE, type.getMethodName(), methodDescription.isStatic() || methodDescription.isConstructor() ? methodDescription.getDescriptor() : "(" + methodDescription.getDeclaringType().getDescriptor() + methodDescription.getDescriptor().substring(1), false); int parameterSize = 1 + methodDescription.getStackSize(), returnValueSize = methodDescription.getReturnType().getStackSize().getSize(); return new Size(returnValueSize - parameterSize, Math.max(0, returnValueSize - parameterSize)); } }
/** * {@inheritDoc} */ public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) { methodVisitor.visitMethodInsn(opcode == legacyOpcode || implementationContext.getClassFileVersion().isAtLeast(ClassFileVersion.JAVA_V11) ? opcode : legacyOpcode, typeDescription.getInternalName(), methodDescription.getInternalName(), methodDescription.getDescriptor(), typeDescription.isInterface()); int parameterSize = methodDescription.getStackSize(), returnValueSize = methodDescription.getReturnType().getStackSize().getSize(); return new Size(returnValueSize - parameterSize, Math.max(0, returnValueSize - parameterSize)); }
/** * {@inheritDoc} */ public TypeDescription.Generic getReturnType() { return methodDescription.getReturnType().asRawType(); }
/** * {@inheritDoc} */ public TypeDescription getAdviceType() { return adviceMethod.getReturnType().asErasure(); }
/** * {@inheritDoc} */ public TypeDescription getAdviceType() { return adviceMethod.getReturnType().asErasure(); }
/** * {@inheritDoc} */ public TypeDefinition getAdviceType() { return adviceMethod.getReturnType(); }
/** * {@inheritDoc} */ public TypeDefinition getAdviceType() { return adviceMethod.getReturnType(); }
/** * {@inheritDoc} */ public TypeDefinition getAdviceType() { return adviceMethod.getReturnType(); } }
/** * {@inheritDoc} */ public TypeDefinition getAdviceType() { return adviceMethod.getReturnType(); } }