src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/java.base/share/classes/java/lang/invoke

src/java.base/share/classes/java/lang/invoke/MethodHandle.java

Print this page
rev 10938 : [mq]: remove.use_lf_editor


 850 assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
 851      * }</pre></blockquote>
 852      * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
 853      * @param arrayLength the number of arguments to spread from an incoming array argument
 854      * @return a new method handle which spreads its final array argument,
 855      *         before calling the original method handle
 856      * @throws NullPointerException if {@code arrayType} is a null reference
 857      * @throws IllegalArgumentException if {@code arrayType} is not an array type,
 858      *         or if target does not have at least
 859      *         {@code arrayLength} parameter types,
 860      *         or if {@code arrayLength} is negative,
 861      *         or if the resulting method handle's type would have
 862      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 863      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 864      * @see #asCollector
 865      */
 866     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
 867         MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
 868         int arity = type().parameterCount();
 869         int spreadArgPos = arity - arrayLength;
 870         if (USE_LAMBDA_FORM_EDITOR) {
 871             MethodHandle afterSpread = this.asType(postSpreadType);
 872             BoundMethodHandle mh = afterSpread.rebind();
 873             LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
 874             MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
 875             return mh.copyWith(preSpreadType, lform);
 876         } else {
 877             return MethodHandleImpl.makeSpreadArguments(this, arrayType, spreadArgPos, arrayLength);
 878         }
 879     }
 880 
 881     /**
 882      * See if {@code asSpreader} can be validly called with the given arguments.
 883      * Return the type of the method handle call after spreading but before conversions.
 884      */
 885     private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
 886         spreadArrayChecks(arrayType, arrayLength);
 887         int nargs = type().parameterCount();
 888         if (nargs < arrayLength || arrayLength < 0)
 889             throw newIllegalArgumentException("bad spread array length");
 890         Class<?> arrayElement = arrayType.getComponentType();
 891         MethodType mtype = type();
 892         boolean match = true, fail = false;
 893         for (int i = nargs - arrayLength; i < nargs; i++) {
 894             Class<?> ptype = mtype.parameterType(i);
 895             if (ptype != arrayElement) {
 896                 match = false;
 897                 if (!MethodType.canConvert(arrayElement, ptype)) {
 898                     fail = true;


 979   .asCollector(long[].class, 1);
 980 assertEquals("[123]", (String) longsToString.invokeExact((long)123));
 981      * }</pre></blockquote>
 982      * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
 983      * @param arrayLength the number of arguments to collect into a new array argument
 984      * @return a new method handle which collects some trailing argument
 985      *         into an array, before calling the original method handle
 986      * @throws NullPointerException if {@code arrayType} is a null reference
 987      * @throws IllegalArgumentException if {@code arrayType} is not an array type
 988      *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
 989      *         or {@code arrayLength} is not a legal array size,
 990      *         or the resulting method handle's type would have
 991      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 992      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 993      * @see #asSpreader
 994      * @see #asVarargsCollector
 995      */
 996     public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
 997         asCollectorChecks(arrayType, arrayLength);
 998         int collectArgPos = type().parameterCount() - 1;
 999         if (USE_LAMBDA_FORM_EDITOR) {
1000             BoundMethodHandle mh = rebind();
1001             MethodType resultType = type().asCollectorType(arrayType, arrayLength);
1002             MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1003             LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
1004             if (lform != null) {
1005                 return mh.copyWith(resultType, lform);
1006             }
1007             lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
1008             return mh.copyWithExtendL(resultType, lform, newArray);
1009         } else {
1010             MethodHandle target = this;
1011             if (arrayType != type().parameterType(collectArgPos))
1012                 target = MethodHandleImpl.makePairwiseConvert(this, type().changeParameterType(collectArgPos, arrayType), true);
1013             MethodHandle collector = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1014             return MethodHandles.collectArguments(target, collectArgPos, collector);
1015         }
1016     }
1017 
1018     /**
1019      * See if {@code asCollector} can be validly called with the given arguments.
1020      * Return false if the last parameter is not an exact match to arrayType.
1021      */
1022     /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
1023         spreadArrayChecks(arrayType, arrayLength);
1024         int nargs = type().parameterCount();
1025         if (nargs != 0) {
1026             Class<?> lastParam = type().parameterType(nargs-1);
1027             if (lastParam == arrayType)  return true;
1028             if (lastParam.isAssignableFrom(arrayType))  return false;
1029         }
1030         throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
1031     }
1032 
1033     /**
1034      * Makes a <em>variable arity</em> adapter which is able to accept
1035      * any number of trailing positional arguments and collect them




 850 assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
 851      * }</pre></blockquote>
 852      * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
 853      * @param arrayLength the number of arguments to spread from an incoming array argument
 854      * @return a new method handle which spreads its final array argument,
 855      *         before calling the original method handle
 856      * @throws NullPointerException if {@code arrayType} is a null reference
 857      * @throws IllegalArgumentException if {@code arrayType} is not an array type,
 858      *         or if target does not have at least
 859      *         {@code arrayLength} parameter types,
 860      *         or if {@code arrayLength} is negative,
 861      *         or if the resulting method handle's type would have
 862      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 863      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 864      * @see #asCollector
 865      */
 866     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
 867         MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
 868         int arity = type().parameterCount();
 869         int spreadArgPos = arity - arrayLength;

 870         MethodHandle afterSpread = this.asType(postSpreadType);
 871         BoundMethodHandle mh = afterSpread.rebind();
 872         LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
 873         MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
 874         return mh.copyWith(preSpreadType, lform);



 875     }
 876 
 877     /**
 878      * See if {@code asSpreader} can be validly called with the given arguments.
 879      * Return the type of the method handle call after spreading but before conversions.
 880      */
 881     private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
 882         spreadArrayChecks(arrayType, arrayLength);
 883         int nargs = type().parameterCount();
 884         if (nargs < arrayLength || arrayLength < 0)
 885             throw newIllegalArgumentException("bad spread array length");
 886         Class<?> arrayElement = arrayType.getComponentType();
 887         MethodType mtype = type();
 888         boolean match = true, fail = false;
 889         for (int i = nargs - arrayLength; i < nargs; i++) {
 890             Class<?> ptype = mtype.parameterType(i);
 891             if (ptype != arrayElement) {
 892                 match = false;
 893                 if (!MethodType.canConvert(arrayElement, ptype)) {
 894                     fail = true;


 975   .asCollector(long[].class, 1);
 976 assertEquals("[123]", (String) longsToString.invokeExact((long)123));
 977      * }</pre></blockquote>
 978      * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
 979      * @param arrayLength the number of arguments to collect into a new array argument
 980      * @return a new method handle which collects some trailing argument
 981      *         into an array, before calling the original method handle
 982      * @throws NullPointerException if {@code arrayType} is a null reference
 983      * @throws IllegalArgumentException if {@code arrayType} is not an array type
 984      *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
 985      *         or {@code arrayLength} is not a legal array size,
 986      *         or the resulting method handle's type would have
 987      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 988      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 989      * @see #asSpreader
 990      * @see #asVarargsCollector
 991      */
 992     public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
 993         asCollectorChecks(arrayType, arrayLength);
 994         int collectArgPos = type().parameterCount() - 1;

 995         BoundMethodHandle mh = rebind();
 996         MethodType resultType = type().asCollectorType(arrayType, arrayLength);
 997         MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
 998         LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
 999         if (lform != null) {
1000             return mh.copyWith(resultType, lform);
1001         }
1002         lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
1003         return mh.copyWithExtendL(resultType, lform, newArray);







1004     }
1005 
1006     /**
1007      * See if {@code asCollector} can be validly called with the given arguments.
1008      * Return false if the last parameter is not an exact match to arrayType.
1009      */
1010     /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
1011         spreadArrayChecks(arrayType, arrayLength);
1012         int nargs = type().parameterCount();
1013         if (nargs != 0) {
1014             Class<?> lastParam = type().parameterType(nargs-1);
1015             if (lastParam == arrayType)  return true;
1016             if (lastParam.isAssignableFrom(arrayType))  return false;
1017         }
1018         throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
1019     }
1020 
1021     /**
1022      * Makes a <em>variable arity</em> adapter which is able to accept
1023      * any number of trailing positional arguments and collect them


src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File