All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ui4j.bytebuddy.instrumentation.method.bytecode.bind.annotation.This Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
package com.ui4j.bytebuddy.instrumentation.method.bytecode.bind.annotation;

import com.ui4j.bytebuddy.instrumentation.Instrumentation;
import com.ui4j.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import com.ui4j.bytebuddy.instrumentation.method.MethodDescription;
import com.ui4j.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import com.ui4j.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation;
import com.ui4j.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner;
import com.ui4j.bytebuddy.instrumentation.method.bytecode.stack.member.MethodVariableAccess;
import com.ui4j.bytebuddy.instrumentation.type.TypeDescription;

import java.lang.annotation.*;

/**
 * Parameters that are annotated with this annotation will be assigned a reference to the instrumented object, if
 * the instrumented method is not static. Otherwise, the method with this parameter annotation will be excluded from
 * the list of possible binding candidates of the static source method.
 *
 * @see com.ui4j.bytebuddy.instrumentation.MethodDelegation
 * @see TargetMethodAnnotationDrivenBinder
 * @see com.ui4j.bytebuddy.instrumentation.method.bytecode.bind.annotation.RuntimeType
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface This {

    /**
     * A binder for handling the
     * {@link com.ui4j.bytebuddy.instrumentation.method.bytecode.bind.annotation.This}
     * annotation.
     *
     * @see TargetMethodAnnotationDrivenBinder
     */
    static enum Binder implements TargetMethodAnnotationDrivenBinder.ParameterBinder {

        /**
         * The singleton instance.
         */
        INSTANCE;

        /**
         * The index of the {@code this} reference of method variable arrays of non-static methods.
         */
        private static final int THIS_REFERENCE_INDEX = 0;

        @Override
        public Class getHandledType() {
            return This.class;
        }

        @Override
        public MethodDelegationBinder.ParameterBinding bind(AnnotationDescription.Loadable annotation,
                                                               int targetParameterIndex,
                                                               MethodDescription source,
                                                               MethodDescription target,
                                                               Instrumentation.Target instrumentationTarget,
                                                               Assigner assigner) {
            TypeDescription targetType = target.getParameterTypes().get(targetParameterIndex);
            if (targetType.isPrimitive()) {
                throw new IllegalStateException(String.format("The %d. argument virtual %s is a primitive type " +
                        "and can never be bound to an instance", targetParameterIndex, target));
            } else if (targetType.isArray()) {
                throw new IllegalStateException(String.format("The %d. argument virtual %s is an array type " +
                        "and can never be bound to an instance", targetParameterIndex, target));
            } else if (source.isStatic()) {
                return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE;
            }
            boolean runtimeType = RuntimeType.Verifier.check(target, targetParameterIndex);
            StackManipulation thisAssignment = assigner.assign(instrumentationTarget.getTypeDescription(), targetType, runtimeType);
            if (thisAssignment.isValid()) {
                return new MethodDelegationBinder.ParameterBinding.Anonymous(
                        new StackManipulation.Compound(
                                MethodVariableAccess.REFERENCE.loadFromIndex(THIS_REFERENCE_INDEX),
                                thisAssignment)
                );
            } else {
                return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE;
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy