3749 * {@code pos}.
3750 * @since 9
3751 */
3752 public static
3753 MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos) {
3754 Objects.requireNonNull(target);
3755 Objects.requireNonNull(newTypes);
3756 return dropArgumentsToMatch(target, skip, newTypes, pos, false);
3757 }
3758
3759 /**
3760 * Adapts a target method handle by pre-processing
3761 * one or more of its arguments, each with its own unary filter function,
3762 * and then calling the target with each pre-processed argument
3763 * replaced by the result of its corresponding filter function.
3764 * <p>
3765 * The pre-processing is performed by one or more method handles,
3766 * specified in the elements of the {@code filters} array.
3767 * The first element of the filter array corresponds to the {@code pos}
3768 * argument of the target, and so on in sequence.
3769 * <p>
3770 * Null arguments in the array are treated as identity functions,
3771 * and the corresponding arguments left unchanged.
3772 * (If there are no non-null elements in the array, the original target is returned.)
3773 * Each filter is applied to the corresponding argument of the adapter.
3774 * <p>
3775 * If a filter {@code F} applies to the {@code N}th argument of
3776 * the target, then {@code F} must be a method handle which
3777 * takes exactly one argument. The type of {@code F}'s sole argument
3778 * replaces the corresponding argument type of the target
3779 * in the resulting adapted method handle.
3780 * The return type of {@code F} must be identical to the corresponding
3781 * parameter type of the target.
3782 * <p>
3783 * It is an error if there are elements of {@code filters}
3784 * (null or not)
3785 * which do not correspond to argument positions in the target.
3786 * <p><b>Example:</b>
3787 * <blockquote><pre>{@code
3788 import static java.lang.invoke.MethodHandles.*;
3819 * <p>
3820 * <em>Note:</em> The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
3821 * variable-arity method handle}, even if the original target method handle was.
3822 *
3823 * @param target the method handle to invoke after arguments are filtered
3824 * @param pos the position of the first argument to filter
3825 * @param filters method handles to call initially on filtered arguments
3826 * @return method handle which incorporates the specified argument filtering logic
3827 * @throws NullPointerException if the target is null
3828 * or if the {@code filters} array is null
3829 * @throws IllegalArgumentException if a non-null element of {@code filters}
3830 * does not match a corresponding argument type of target as described above,
3831 * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
3832 * or if the resulting method handle's type would have
3833 * <a href="MethodHandle.html#maxarity">too many parameters</a>
3834 */
3835 public static
3836 MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
3837 filterArgumentsCheckArity(target, pos, filters);
3838 MethodHandle adapter = target;
3839 int curPos = pos-1; // pre-incremented
3840 for (MethodHandle filter : filters) {
3841 curPos += 1;
3842 if (filter == null) continue; // ignore null elements of filters
3843 adapter = filterArgument(adapter, curPos, filter);
3844 }
3845 return adapter;
3846 }
3847
3848 /*non-public*/ static
3849 MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
3850 filterArgumentChecks(target, pos, filter);
3851 MethodType targetType = target.type();
3852 MethodType filterType = filter.type();
3853 BoundMethodHandle result = target.rebind();
3854 Class<?> newParamType = filterType.parameterType(0);
3855 LambdaForm lform = result.editor().filterArgumentForm(1 + pos, BasicType.basicType(newParamType));
3856 MethodType newType = targetType.changeParameterType(pos, newParamType);
3857 result = result.copyWithExtendL(newType, lform, filter);
3858 return result;
3859 }
3860
3861 private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
3862 MethodType targetType = target.type();
3863 int maxPos = targetType.parameterCount();
|
3749 * {@code pos}.
3750 * @since 9
3751 */
3752 public static
3753 MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos) {
3754 Objects.requireNonNull(target);
3755 Objects.requireNonNull(newTypes);
3756 return dropArgumentsToMatch(target, skip, newTypes, pos, false);
3757 }
3758
3759 /**
3760 * Adapts a target method handle by pre-processing
3761 * one or more of its arguments, each with its own unary filter function,
3762 * and then calling the target with each pre-processed argument
3763 * replaced by the result of its corresponding filter function.
3764 * <p>
3765 * The pre-processing is performed by one or more method handles,
3766 * specified in the elements of the {@code filters} array.
3767 * The first element of the filter array corresponds to the {@code pos}
3768 * argument of the target, and so on in sequence.
3769 * The filter functions are invoked in left to right order.
3770 * <p>
3771 * Null arguments in the array are treated as identity functions,
3772 * and the corresponding arguments left unchanged.
3773 * (If there are no non-null elements in the array, the original target is returned.)
3774 * Each filter is applied to the corresponding argument of the adapter.
3775 * <p>
3776 * If a filter {@code F} applies to the {@code N}th argument of
3777 * the target, then {@code F} must be a method handle which
3778 * takes exactly one argument. The type of {@code F}'s sole argument
3779 * replaces the corresponding argument type of the target
3780 * in the resulting adapted method handle.
3781 * The return type of {@code F} must be identical to the corresponding
3782 * parameter type of the target.
3783 * <p>
3784 * It is an error if there are elements of {@code filters}
3785 * (null or not)
3786 * which do not correspond to argument positions in the target.
3787 * <p><b>Example:</b>
3788 * <blockquote><pre>{@code
3789 import static java.lang.invoke.MethodHandles.*;
3820 * <p>
3821 * <em>Note:</em> The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
3822 * variable-arity method handle}, even if the original target method handle was.
3823 *
3824 * @param target the method handle to invoke after arguments are filtered
3825 * @param pos the position of the first argument to filter
3826 * @param filters method handles to call initially on filtered arguments
3827 * @return method handle which incorporates the specified argument filtering logic
3828 * @throws NullPointerException if the target is null
3829 * or if the {@code filters} array is null
3830 * @throws IllegalArgumentException if a non-null element of {@code filters}
3831 * does not match a corresponding argument type of target as described above,
3832 * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
3833 * or if the resulting method handle's type would have
3834 * <a href="MethodHandle.html#maxarity">too many parameters</a>
3835 */
3836 public static
3837 MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
3838 filterArgumentsCheckArity(target, pos, filters);
3839 MethodHandle adapter = target;
3840 // process filters in reverse order so that the invocation of
3841 // the resulting adapter will invoke the filters in left-to-right order
3842 for (int i = filters.length - 1; i >= 0; --i) {
3843 MethodHandle filter = filters[i];
3844 if (filter == null) continue; // ignore null elements of filters
3845 adapter = filterArgument(adapter, pos + i, filter);
3846 }
3847 return adapter;
3848 }
3849
3850 /*non-public*/ static
3851 MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
3852 filterArgumentChecks(target, pos, filter);
3853 MethodType targetType = target.type();
3854 MethodType filterType = filter.type();
3855 BoundMethodHandle result = target.rebind();
3856 Class<?> newParamType = filterType.parameterType(0);
3857 LambdaForm lform = result.editor().filterArgumentForm(1 + pos, BasicType.basicType(newParamType));
3858 MethodType newType = targetType.changeParameterType(pos, newParamType);
3859 result = result.copyWithExtendL(newType, lform, filter);
3860 return result;
3861 }
3862
3863 private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
3864 MethodType targetType = target.type();
3865 int maxPos = targetType.parameterCount();
|