Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8310224

Allow void-returning filters for MethodHandles::collectCoordinates

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 22
    • core-libs
    • None
    • behavioral
    • minimal
    • Change to a preview API. An error case now becomes valid. It seems unlikely that a user relied on the exception being thrown, as this would typically indicate a bug in the program.
    • Java API
    • SE

      Summary

      Allow void-returning filters for MethodHandles::collectCoordinates

      Problem

      Currently MethodHandles::collectCoordinates, which is the var handle version of MethodHandles::collectArguments, rejects filters that return void as a type.

      However, MethodHandles::collectArguments does allow void filters. So there is a discrepancy between the two. MethodHandles::collectCoordinates does not follow the precedent in this regard.

      Solution

      Relax MethodHandles::collectCoordinates to allow void-returning filters, and update the specification of this method accordingly.

      Note, the underlying implementation already delegates to MethodHandles::collectArguments, so updating the implementation is trivial.

      Specification

      The javadoc of the MethodHandles::collectCoordinates method is updated as follows:

      diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      index 7d86f7478272..a3fcbb21165d 100644
      --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      @@ -8188,19 +8188,18 @@ public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newC
            * filter function and the target var handle is then called on the modified (usually shortened)
            * coordinate list.
            * <p>
      -     * If {@code R} is the return type of the filter (which cannot be void), the target var handle must accept a value of
      -     * type {@code R} as its coordinate in position {@code pos}, preceded and/or followed by
      -     * any coordinate not passed to the filter.
      -     * No coordinates are reordered, and the result returned from the filter
      -     * replaces (in order) the whole subsequence of coordinates originally
      -     * passed to the adapter.
      -     * <p>
      -     * The argument types (if any) of the filter
      -     * replace zero or one coordinate types of the target var handle, at position {@code pos},
      -     * in the resulting adapted var handle.
      -     * The return type of the filter must be identical to the
      -     * coordinate type of the target var handle at position {@code pos}, and that target var handle
      -     * coordinate is supplied by the return value of the filter.
      +     * If {@code R} is the return type of the filter, then:
      +     * <ul>
      +     * <li>if {@code R} <em>is not</em> {@code void}, the target var handle must have a coordinate of type {@code R} in
      +     * position {@code pos}. The parameter types of the filter will replace the coordinate type at position {@code pos}
      +     * of the target var handle. When the returned var handle is invoked, it will be as if the filter is invoked first,
      +     * and its result is passed in place of the coordinate at position {@code pos} in a downstream invocation of the
      +     * target var handle.</li>
      +     * <li> if {@code R} <em>is</em> {@code void}, the parameter types (if any) of the filter will be inserted in the
      +     * coordinate type list of the target var handle at position {@code pos}. In this case, when the returned var handle
      +     * is invoked, the filter essentially acts as a side effect, consuming some of the coordinate values, before a
      +     * downstream invocation of the target var handle.</li>
      +     * </ul>
            * <p>
            * If any of the filters throws a checked exception when invoked, the resulting var handle will
            * throw an {@link IllegalStateException}.
      @@ -8209,12 +8208,12 @@ public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newC
            * atomic access guarantees as those featured by the target var handle.
            *
            * @param target the var handle to invoke after the coordinates have been filtered
      -     * @param pos the position of the coordinate to be filtered
      +     * @param pos the position in the coordinate list of the target var handle where the filter is to be inserted
            * @param filter the filter method handle
            * @return an adapter var handle which filters the incoming coordinate values,
            * before calling the target var handle
            * @throws IllegalArgumentException if the return type of {@code filter}
      -     * is void, or it is not the same as the {@code pos} coordinate of the target var handle,
      +     * is not void, and it is not the same as the {@code pos} coordinate of the target var handle,
            * if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
            * if the resulting var handle's type would have <a href="MethodHandle.html#maxarity">too many coordinates</a>,
            * or if it's determined that {@code filter} throws any checked exceptions.

            jvernee Jorn Vernee
            jvernee Jorn Vernee
            Maurizio Cimadamore
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: