/** * {@inheritDoc} */ public StackManipulation virtual(TypeDescription invocationTarget) { if (methodDescription.isConstructor() || methodDescription.isStatic()) { return Illegal.INSTANCE; } else if (methodDescription.isPrivate()) { return methodDescription.getDeclaringType().equals(invocationTarget) ? this : Illegal.INSTANCE; } else if (invocationTarget.isInterface()) { return methodDescription.getDeclaringType().represents(Object.class) ? this : INTERFACE.new Invocation(methodDescription, invocationTarget); } else { return VIRTUAL.new Invocation(methodDescription, invocationTarget); } }
/** * Creates a method invocation with an implicitly determined invocation type. * * @param methodDescription The method to be invoked. * @return A stack manipulation with implicitly determined invocation type. */ public static WithImplicitInvocationTargetType invoke(MethodDescription.InDefinedShape methodDescription) { if (methodDescription.isTypeInitializer()) { return IllegalInvocation.INSTANCE; } else if (methodDescription.isStatic()) { // Check this property first, private static methods must use INVOKESTATIC return STATIC.new Invocation(methodDescription); } else if (methodDescription.isConstructor()) { return SPECIAL_CONSTRUCTOR.new Invocation(methodDescription); // Check this property second, constructors might be private } else if (methodDescription.isPrivate()) { return (methodDescription.getDeclaringType().isInterface() ? INTERFACE_PRIVATE : VIRTUAL_PRIVATE).new Invocation(methodDescription); } else if (methodDescription.getDeclaringType().isInterface()) { // Check this property last, default methods must be called by INVOKESPECIAL return INTERFACE.new Invocation(methodDescription); } else { return VIRTUAL.new Invocation(methodDescription); } }
/** * {@inheritDoc} */ public StackManipulation special(TypeDescription invocationTarget) { return methodDescription.isSpecializableFor(invocationTarget) ? SPECIAL.new Invocation(methodDescription, invocationTarget) : Illegal.INSTANCE; }