Java Code Examples for net.bytebuddy.description.method.MethodDescription#isStatic()

The following examples show how to use net.bytebuddy.description.method.MethodDescription#isStatic() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: InvocationHandlerAdapter.java    From byte-buddy with Apache License 2.0 6 votes vote down vote up
/**
 * Applies an implementation that delegates to a invocation handler.
 *
 * @param methodVisitor         The method visitor for writing the byte code to.
 * @param implementationContext The implementation context for the current implementation.
 * @param instrumentedMethod    The method that is instrumented.
 * @param preparingManipulation A stack manipulation that applies any preparation to the operand stack.
 * @param fieldDescription      The field that contains the value for the invocation handler.
 * @return The size of the applied assignment.
 */
protected ByteCodeAppender.Size apply(MethodVisitor methodVisitor,
                                      Context implementationContext,
                                      MethodDescription instrumentedMethod,
                                      StackManipulation preparingManipulation,
                                      FieldDescription fieldDescription) {
    if (instrumentedMethod.isStatic()) {
        throw new IllegalStateException("It is not possible to apply an invocation handler onto the static method " + instrumentedMethod);
    }
    MethodConstant.CanCache methodConstant = privileged
            ? MethodConstant.ofPrivileged(instrumentedMethod.asDefined())
            : MethodConstant.of(instrumentedMethod.asDefined());
    StackManipulation.Size stackSize = new StackManipulation.Compound(
            preparingManipulation,
            FieldAccess.forField(fieldDescription).read(),
            MethodVariableAccess.loadThis(),
            cached ? methodConstant.cached() : methodConstant,
            ArrayFactory.forType(TypeDescription.Generic.OBJECT).withValues(argumentValuesOf(instrumentedMethod)),
            MethodInvocation.invoke(INVOCATION_HANDLER_TYPE.getDeclaredMethods().getOnly()),
            assigner.assign(TypeDescription.Generic.OBJECT, instrumentedMethod.getReturnType(), Assigner.Typing.DYNAMIC),
            MethodReturn.of(instrumentedMethod.getReturnType())
    ).apply(methodVisitor, implementationContext);
    return new ByteCodeAppender.Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize());
}
 
Example 2
Source File: RebaseImplementationTarget.java    From byte-buddy with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a special method invocation for the given method.
 *
 * @param resolvedMethod      The rebased method to be invoked.
 * @param instrumentedType    The instrumented type on which the method is to be invoked if it is non-static.
 * @param prependedParameters Any additional arguments that are to be provided to the rebased method.
 * @return A special method invocation of the rebased method.
 */
protected static Implementation.SpecialMethodInvocation of(MethodDescription resolvedMethod, TypeDescription instrumentedType, TypeList prependedParameters) {
    StackManipulation stackManipulation = resolvedMethod.isStatic()
            ? MethodInvocation.invoke(resolvedMethod)
            : MethodInvocation.invoke(resolvedMethod).special(instrumentedType);
    if (stackManipulation.isValid()) {
        List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(prependedParameters.size() + 1);
        for (TypeDescription prependedParameter : prependedParameters) {
            stackManipulations.add(DefaultValue.of(prependedParameter));
        }
        stackManipulations.add(stackManipulation);
        return new RebasedMethodInvocation(resolvedMethod, instrumentedType, new Compound(stackManipulations), prependedParameters);
    } else {
        return Illegal.INSTANCE;
    }
}
 
Example 3
Source File: TargetMethodAnnotationDrivenBinder.java    From byte-buddy with Apache License 2.0 6 votes vote down vote up
/**
 * {@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;
}
 
Example 4
Source File: FieldAccessor.java    From byte-buddy with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
    FieldDescription fieldDescription = fieldLocation.resolve(instrumentedMethod);
    if (!fieldDescription.isStatic() && instrumentedMethod.isStatic()) {
        throw new IllegalStateException("Cannot set instance field " + fieldDescription + " from " + instrumentedMethod);
    } else if (fieldDescription.isFinal() && instrumentedMethod.isMethod()) {
        throw new IllegalStateException("Cannot set final field " + fieldDescription + " from " + instrumentedMethod);
    }
    StackManipulation stackManipulation = resolve(initialized, fieldDescription, instrumentedType, instrumentedMethod);
    if (!stackManipulation.isValid()) {
        throw new IllegalStateException("Set value cannot be assigned to " + fieldDescription);
    }
    return new Size(new StackManipulation.Compound(
            instrumentedMethod.isStatic()
                    ? StackManipulation.Trivial.INSTANCE
                    : MethodVariableAccess.loadThis(),
            stackManipulation,
            FieldAccess.forField(fieldDescription).write(),
            terminationHandler.resolve(instrumentedMethod)
    ).apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize());
}
 
Example 5
Source File: FieldAccessor.java    From byte-buddy with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 */
protected StackManipulation resolve(FieldLocation.Prepared target,
                                    FieldDescription fieldDescription,
                                    TypeDescription instrumentedType,
                                    MethodDescription instrumentedMethod) {
    FieldDescription resolved = target.resolve(instrumentedMethod);
    if (!resolved.isStatic() && instrumentedMethod.isStatic()) {
        throw new IllegalStateException("Cannot set instance field " + fieldDescription + " from " + instrumentedMethod);
    }
    return new StackManipulation.Compound(
            resolved.isStatic()
                    ? StackManipulation.Trivial.INSTANCE
                    : MethodVariableAccess.loadThis(),
            FieldAccess.forField(resolved).read(),
            assigner.assign(resolved.getType(), fieldDescription.getType(), typing)
    );
}
 
Example 6
Source File: MethodCall.java    From byte-buddy with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 */
public StackManipulation toStackManipulation(MethodDescription invokedMethod, Assigner assigner, Assigner.Typing typing) {
    if (instrumentedMethod.isStatic() && !invokedMethod.isStatic() && !invokedMethod.isConstructor()) {
        throw new IllegalStateException("Cannot invoke " + invokedMethod + " from " + instrumentedMethod);
    } else if (invokedMethod.isConstructor() && (!instrumentedMethod.isConstructor()
            || !instrumentedType.equals(invokedMethod.getDeclaringType().asErasure())
            && !instrumentedType.getSuperClass().asErasure().equals(invokedMethod.getDeclaringType().asErasure()))) {
        throw new IllegalStateException("Cannot invoke " + invokedMethod + " from " + instrumentedMethod + " in " + instrumentedType);
    }
    return new StackManipulation.Compound(
            invokedMethod.isStatic()
                    ? StackManipulation.Trivial.INSTANCE
                    : MethodVariableAccess.loadThis(),
            invokedMethod.isConstructor()
                    ? Duplication.SINGLE
                    : StackManipulation.Trivial.INSTANCE
    );
}
 
Example 7
Source File: MethodCall.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public StackManipulation toStackManipulation(MethodDescription invokedMethod, Assigner assigner, Assigner.Typing typing) {
    if (!invokedMethod.isInvokableOn(fieldDescription.getType().asErasure())) {
        throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + fieldDescription);
    }
    StackManipulation stackManipulation = assigner.assign(fieldDescription.getType(), invokedMethod.getDeclaringType().asGenericType(), typing);
    if (!stackManipulation.isValid()) {
        throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + fieldDescription);
    }
    return new StackManipulation.Compound(invokedMethod.isStatic() || fieldDescription.isStatic()
            ? StackManipulation.Trivial.INSTANCE
            : MethodVariableAccess.loadThis(),
            FieldAccess.forField(fieldDescription).read(), stackManipulation);
}
 
Example 8
Source File: ToStringMethod.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
    if (instrumentedMethod.isStatic()) {
        throw new IllegalStateException("toString method must not be static: " + instrumentedMethod);
    } else if (!instrumentedMethod.getReturnType().asErasure().isAssignableFrom(String.class)) {
        throw new IllegalStateException("toString method does not return String-compatible type: " + instrumentedMethod);
    }
    List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(Math.max(0, fieldDescriptions.size() * 7 - 2) + 10);
    stackManipulations.add(TypeCreation.of(TypeDescription.ForLoadedType.of(StringBuilder.class)));
    stackManipulations.add(Duplication.SINGLE);
    stackManipulations.add(new TextConstant(prefix));
    stackManipulations.add(MethodInvocation.invoke(STRING_BUILDER_CONSTRUCTOR));
    stackManipulations.add(new TextConstant(start));
    stackManipulations.add(ValueConsumer.STRING);
    boolean first = true;
    for (FieldDescription.InDefinedShape fieldDescription : fieldDescriptions) {
        if (first) {
            first = false;
        } else {
            stackManipulations.add(new TextConstant(separator));
            stackManipulations.add(ValueConsumer.STRING);
        }
        stackManipulations.add(new TextConstant(fieldDescription.getName() + definer));
        stackManipulations.add(ValueConsumer.STRING);
        stackManipulations.add(MethodVariableAccess.loadThis());
        stackManipulations.add(FieldAccess.forField(fieldDescription).read());
        stackManipulations.add(ValueConsumer.of(fieldDescription.getType().asErasure()));
    }
    stackManipulations.add(new TextConstant(end));
    stackManipulations.add(ValueConsumer.STRING);
    stackManipulations.add(MethodInvocation.invoke(TO_STRING));
    stackManipulations.add(MethodReturn.REFERENCE);
    return new Size(new StackManipulation.Compound(stackManipulations).apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize());
}
 
Example 9
Source File: HashCodeMethod.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
    if (instrumentedMethod.isStatic()) {
        throw new IllegalStateException("Hash code method must not be static: " + instrumentedMethod);
    } else if (!instrumentedMethod.getReturnType().represents(int.class)) {
        throw new IllegalStateException("Hash code method does not return primitive integer: " + instrumentedMethod);
    }
    List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(2 + fieldDescriptions.size() * 8);
    stackManipulations.add(initialValue);
    int padding = 0;
    for (FieldDescription.InDefinedShape fieldDescription : fieldDescriptions) {
        stackManipulations.add(IntegerConstant.forValue(multiplier));
        stackManipulations.add(Multiplication.INTEGER);
        stackManipulations.add(MethodVariableAccess.loadThis());
        stackManipulations.add(FieldAccess.forField(fieldDescription).read());
        NullValueGuard nullValueGuard = fieldDescription.getType().isPrimitive() || fieldDescription.getType().isArray() || nonNullable.matches(fieldDescription)
                ? NullValueGuard.NoOp.INSTANCE
                : new NullValueGuard.UsingJump(instrumentedMethod);
        stackManipulations.add(nullValueGuard.before());
        stackManipulations.add(ValueTransformer.of(fieldDescription.getType()));
        stackManipulations.add(Addition.INTEGER);
        stackManipulations.add(nullValueGuard.after());
        padding = Math.max(padding, nullValueGuard.getRequiredVariablePadding());
    }
    stackManipulations.add(MethodReturn.INTEGER);
    return new Size(new StackManipulation.Compound(stackManipulations).apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize() + padding);
}
 
Example 10
Source File: MethodCallProxy.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a linked hash map of field names to their types where each field represents a parameter of the method.
 *
 * @param methodDescription The method to extract into fields.
 * @return A map of fields in the order they need to be loaded onto the operand stack for invoking the original
 * method, including a reference to the instance of the instrumented type that is invoked if applicable.
 */
private static LinkedHashMap<String, TypeDescription> extractFields(MethodDescription methodDescription) {
    LinkedHashMap<String, TypeDescription> typeDescriptions = new LinkedHashMap<String, TypeDescription>();
    int currentIndex = 0;
    if (!methodDescription.isStatic()) {
        typeDescriptions.put(fieldName(currentIndex++), methodDescription.getDeclaringType().asErasure());
    }
    for (ParameterDescription parameterDescription : methodDescription.getParameters()) {
        typeDescriptions.put(fieldName(currentIndex++), parameterDescription.getType().asErasure());
    }
    return typeDescriptions;
}
 
Example 11
Source File: EqualsMethod.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
    if (instrumentedMethod.isStatic()) {
        throw new IllegalStateException("Hash code method must not be static: " + instrumentedMethod);
    } else if (instrumentedMethod.getParameters().size() != 1 || instrumentedMethod.getParameters().getOnly().getType().isPrimitive()) {
        throw new IllegalStateException();
    } else if (!instrumentedMethod.getReturnType().represents(boolean.class)) {
        throw new IllegalStateException("Hash code method does not return primitive boolean: " + instrumentedMethod);
    }
    List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(3 + fieldDescriptions.size() * 8);
    stackManipulations.add(baseline);
    int padding = 0;
    for (FieldDescription.InDefinedShape fieldDescription : fieldDescriptions) {
        stackManipulations.add(MethodVariableAccess.loadThis());
        stackManipulations.add(FieldAccess.forField(fieldDescription).read());
        stackManipulations.add(MethodVariableAccess.REFERENCE.loadFrom(1));
        stackManipulations.add(TypeCasting.to(instrumentedType));
        stackManipulations.add(FieldAccess.forField(fieldDescription).read());
        NullValueGuard nullValueGuard = fieldDescription.getType().isPrimitive() || fieldDescription.getType().isArray() || nonNullable.matches(fieldDescription)
                ? NullValueGuard.NoOp.INSTANCE
                : new NullValueGuard.UsingJump(instrumentedMethod);
        stackManipulations.add(nullValueGuard.before());
        stackManipulations.add(ValueComparator.of(fieldDescription.getType()));
        stackManipulations.add(nullValueGuard.after());
        padding = Math.max(padding, nullValueGuard.getRequiredVariablePadding());
    }
    stackManipulations.add(IntegerConstant.forValue(true));
    stackManipulations.add(MethodReturn.INTEGER);
    return new Size(new StackManipulation.Compound(stackManipulations).apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize() + padding);
}
 
Example 12
Source File: FixedValue.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
    if (instrumentedMethod.isStatic() || !instrumentedType.isAssignableTo(instrumentedMethod.getReturnType().asErasure())) {
        throw new IllegalStateException("Cannot return 'this' from " + instrumentedMethod);
    }
    return new ByteCodeAppender.Simple(
            MethodVariableAccess.loadThis(),
            MethodReturn.REFERENCE
    ).apply(methodVisitor, implementationContext, instrumentedMethod);
}
 
Example 13
Source File: FieldAccessor.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) {
    if (!instrumentedMethod.isMethod()) {
        throw new IllegalArgumentException(instrumentedMethod + " does not describe a field getter or setter");
    }
    FieldDescription fieldDescription = fieldLocation.resolve(instrumentedMethod);
    if (!fieldDescription.isStatic() && instrumentedMethod.isStatic()) {
        throw new IllegalStateException("Cannot set instance field " + fieldDescription + " from " + instrumentedMethod);
    }
    StackManipulation implementation, initialization = fieldDescription.isStatic()
            ? StackManipulation.Trivial.INSTANCE
            : MethodVariableAccess.loadThis();
    if (!instrumentedMethod.getReturnType().represents(void.class)) {
        implementation = new StackManipulation.Compound(
                initialization,
                FieldAccess.forField(fieldDescription).read(),
                assigner.assign(fieldDescription.getType(), instrumentedMethod.getReturnType(), typing),
                MethodReturn.of(instrumentedMethod.getReturnType())
        );
    } else if (instrumentedMethod.getReturnType().represents(void.class) && instrumentedMethod.getParameters().size() == 1) {
        if (fieldDescription.isFinal() && instrumentedMethod.isMethod()) {
            throw new IllegalStateException("Cannot set final field " + fieldDescription + " from " + instrumentedMethod);
        }
        implementation = new StackManipulation.Compound(
                initialization,
                MethodVariableAccess.load(instrumentedMethod.getParameters().get(0)),
                assigner.assign(instrumentedMethod.getParameters().get(0).getType(), fieldDescription.getType(), typing),
                FieldAccess.forField(fieldDescription).write(),
                MethodReturn.VOID
        );
    } else {
        throw new IllegalArgumentException("Method " + instrumentedMethod + " is no bean accessor");
    }
    if (!implementation.isValid()) {
        throw new IllegalStateException("Cannot set or get value of " + instrumentedMethod + " using " + fieldDescription);
    }
    return new Size(implementation.apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize());
}
 
Example 14
Source File: MethodCall.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public List<ArgumentLoader> resolve(MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
    if (instrumentedMethod.isStatic()) {
        throw new IllegalStateException(instrumentedMethod + " is static and cannot supply an invoker instance");
    }
    return Collections.<ArgumentLoader>singletonList(this);
}
 
Example 15
Source File: MethodDelegation.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public StackManipulation prepare(MethodDescription instrumentedMethod) {
    if (instrumentedMethod.isStatic() && !methodDescription.isStatic()) {
        throw new IllegalStateException("Cannot invoke " + methodDescription + " from " + instrumentedMethod);
    }
    return new StackManipulation.Compound(methodDescription.isStatic()
            ? StackManipulation.Trivial.INSTANCE
            : MethodVariableAccess.loadThis(), MethodInvocation.invoke(methodDescription));
}
 
Example 16
Source File: InvokeDynamic.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Resolved resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) {
    return new Resolved.Simple(MethodVariableAccess.allArgumentsOf(instrumentedMethod).prependThisReference(),
            instrumentedMethod.isStatic()
                    ? instrumentedMethod.getParameters().asTypeList().asErasures()
                    : CompoundList.of(instrumentedMethod.getDeclaringType().asErasure(), instrumentedMethod.getParameters().asTypeList().asErasures()));
}
 
Example 17
Source File: InvokeDynamic.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Resolved resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) {
    if (instrumentedMethod.isStatic()) {
        throw new IllegalStateException("Cannot get this instance from static method: " + instrumentedMethod);
    } else if (!instrumentedType.isAssignableTo(typeDescription)) {
        throw new IllegalStateException(instrumentedType + " is not assignable to " + instrumentedType);
    }
    return new Resolved.Simple(MethodVariableAccess.loadThis(), typeDescription);
}
 
Example 18
Source File: InvokeDynamic.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public Resolved resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) {
    FieldLocator.Resolution resolution = fieldLocatorFactory.make(instrumentedType).locate(fieldName);
    if (!resolution.isResolved()) {
        throw new IllegalStateException("Cannot find a field " + fieldName + " for " + instrumentedType);
    } else if (!resolution.getField().isStatic() && instrumentedMethod.isStatic()) {
        throw new IllegalStateException("Cannot access non-static " + resolution.getField() + " from " + instrumentedMethod);
    }
    return doResolve(new StackManipulation.Compound(resolution.getField().isStatic()
                    ? StackManipulation.Trivial.INSTANCE
                    : MethodVariableAccess.loadThis(), FieldAccess.forField(resolution.getField()).read()),
            resolution.getField().getType(),
            assigner,
            typing);
}
 
Example 19
Source File: MethodDelegation.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public StackManipulation prepare(MethodDescription instrumentedMethod) {
    if (instrumentedMethod.isStatic() && !fieldDescription.isStatic()) {
        throw new IllegalStateException("Cannot read " + fieldDescription + " from " + instrumentedMethod);
    }
    return new StackManipulation.Compound(fieldDescription.isStatic()
            ? StackManipulation.Trivial.INSTANCE
            : MethodVariableAccess.loadThis(), FieldAccess.forField(fieldDescription).read());
}
 
Example 20
Source File: MemberSubstitution.java    From byte-buddy with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public StackManipulation resolve(TypeDescription targetType,
                                 ByteCodeElement target,
                                 TypeList.Generic parameters,
                                 TypeDescription.Generic result,
                                 int freeOffset) {
    MethodDescription methodDescription = methodResolver.resolve(targetType, target, parameters, result);
    if (!methodDescription.isAccessibleTo(instrumentedType)) {
        throw new IllegalStateException(instrumentedType + " cannot access " + methodDescription);
    }
    TypeList.Generic mapped = methodDescription.isStatic()
            ? methodDescription.getParameters().asTypeList()
            : new TypeList.Generic.Explicit(CompoundList.of(methodDescription.getDeclaringType(), methodDescription.getParameters().asTypeList()));
    if (!methodDescription.getReturnType().asErasure().isAssignableTo(result.asErasure())) {
        throw new IllegalStateException("Cannot assign return value of " + methodDescription + " to " + result);
    } else if (mapped.size() != parameters.size()) {
        throw new IllegalStateException("Cannot invoke " + methodDescription + " on " + parameters.size() + " parameters");
    }
    for (int index = 0; index < mapped.size(); index++) {
        if (!parameters.get(index).asErasure().isAssignableTo(mapped.get(index).asErasure())) {
            throw new IllegalStateException("Cannot invoke " + methodDescription + " on parameter " + index + " of type " + parameters.get(index));
        }
    }
    return methodDescription.isVirtual()
            ? MethodInvocation.invoke(methodDescription).virtual(mapped.get(THIS_REFERENCE).asErasure())
            : MethodInvocation.invoke(methodDescription);
}