855 MethodHandle caString3 = caToString.asCollector(char[].class, 3);
856 assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
857 MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
858 assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
859 * }</pre></blockquote>
860 * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
861 * @param arrayLength the number of arguments to spread from an incoming array argument
862 * @return a new method handle which spreads its final array argument,
863 * before calling the original method handle
864 * @throws NullPointerException if {@code arrayType} is a null reference
865 * @throws IllegalArgumentException if {@code arrayType} is not an array type,
866 * or if target does not have at least
867 * {@code arrayLength} parameter types,
868 * or if {@code arrayLength} is negative,
869 * or if the resulting method handle's type would have
870 * <a href="MethodHandle.html#maxarity">too many parameters</a>
871 * @throws WrongMethodTypeException if the implied {@code asType} call fails
872 * @see #asCollector
873 */
874 public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
875 MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
876 int arity = type().parameterCount();
877 int spreadArgPos = arity - arrayLength;
878 MethodHandle afterSpread = this.asType(postSpreadType);
879 BoundMethodHandle mh = afterSpread.rebind();
880 LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
881 MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
882 return mh.copyWith(preSpreadType, lform);
883 }
884
885 /**
886 * See if {@code asSpreader} can be validly called with the given arguments.
887 * Return the type of the method handle call after spreading but before conversions.
888 */
889 private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
890 spreadArrayChecks(arrayType, arrayLength);
891 int nargs = type().parameterCount();
892 if (nargs < arrayLength || arrayLength < 0)
893 throw newIllegalArgumentException("bad spread array length");
894 Class<?> arrayElement = arrayType.getComponentType();
895 MethodType mtype = type();
896 boolean match = true, fail = false;
897 for (int i = nargs - arrayLength; i < nargs; i++) {
898 Class<?> ptype = mtype.parameterType(i);
899 if (ptype != arrayElement) {
900 match = false;
901 if (!MethodType.canConvert(arrayElement, ptype)) {
902 fail = true;
903 break;
904 }
905 }
906 }
907 if (match) return mtype;
908 MethodType needType = mtype.asSpreaderType(arrayType, arrayLength);
909 if (!fail) return needType;
910 // elicit an error:
911 this.asType(needType);
912 throw newInternalError("should not return", null);
913 }
914
915 private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
916 Class<?> arrayElement = arrayType.getComponentType();
917 if (arrayElement == null)
918 throw newIllegalArgumentException("not an array type", arrayType);
919 if ((arrayLength & 0x7F) != arrayLength) {
920 if ((arrayLength & 0xFF) != arrayLength)
921 throw newIllegalArgumentException("array length is not legal", arrayLength);
922 assert(arrayLength >= 128);
923 if (arrayElement == long.class ||
924 arrayElement == double.class)
925 throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
926 }
927 }
928
981 MethodHandle longsToString = publicLookup()
982 .findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
983 .asCollector(long[].class, 1);
984 assertEquals("[123]", (String) longsToString.invokeExact((long)123));
985 * }</pre></blockquote>
986 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
987 * @param arrayLength the number of arguments to collect into a new array argument
988 * @return a new method handle which collects some trailing argument
989 * into an array, before calling the original method handle
990 * @throws NullPointerException if {@code arrayType} is a null reference
991 * @throws IllegalArgumentException if {@code arrayType} is not an array type
992 * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
993 * or {@code arrayLength} is not a legal array size,
994 * or the resulting method handle's type would have
995 * <a href="MethodHandle.html#maxarity">too many parameters</a>
996 * @throws WrongMethodTypeException if the implied {@code asType} call fails
997 * @see #asSpreader
998 * @see #asVarargsCollector
999 */
1000 public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
1001 asCollectorChecks(arrayType, arrayLength);
1002 int collectArgPos = type().parameterCount() - 1;
1003 BoundMethodHandle mh = rebind();
1004 MethodType resultType = type().asCollectorType(arrayType, arrayLength);
1005 MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1006 LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
1007 if (lform != null) {
1008 return mh.copyWith(resultType, lform);
1009 }
1010 lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
1011 return mh.copyWithExtendL(resultType, lform, newArray);
1012 }
1013
1014 /**
1015 * See if {@code asCollector} can be validly called with the given arguments.
1016 * Return false if the last parameter is not an exact match to arrayType.
1017 */
1018 /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
1019 spreadArrayChecks(arrayType, arrayLength);
1020 int nargs = type().parameterCount();
1021 if (nargs != 0) {
1022 Class<?> lastParam = type().parameterType(nargs-1);
1023 if (lastParam == arrayType) return true;
1024 if (lastParam.isAssignableFrom(arrayType)) return false;
1025 }
1026 throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
1027 }
1028
1029 /**
1030 * Makes a <em>variable arity</em> adapter which is able to accept
1031 * any number of trailing positional arguments and collect them
1032 * into an array argument.
1033 * <p>
1034 * The type and behavior of the adapter will be the same as
1035 * the type and behavior of the target, except that certain
1036 * {@code invoke} and {@code asType} requests can lead to
1037 * trailing positional arguments being collected into target's
1038 * trailing parameter.
1039 * Also, the last parameter type of the adapter will be
1040 * {@code arrayType}, even if the target has a different
1041 * last parameter type.
1042 * <p>
1043 * This transformation may return {@code this} if the method handle is
1044 * already of variable arity and its trailing parameter type
1045 * is identical to {@code arrayType}.
1046 * <p>
1161 * special role of the final argument, and of the effect of a
1162 * type match on that final argument, which determines whether
1163 * or not a single trailing argument is interpreted as a whole
1164 * array or a single element of an array to be collected.
1165 * Note that the dynamic type of the trailing argument has no
1166 * effect on this decision, only a comparison between the symbolic
1167 * type descriptor of the call site and the type descriptor of the method handle.)
1168 *
1169 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1170 * @return a new method handle which can collect any number of trailing arguments
1171 * into an array, before calling the original method handle
1172 * @throws NullPointerException if {@code arrayType} is a null reference
1173 * @throws IllegalArgumentException if {@code arrayType} is not an array type
1174 * or {@code arrayType} is not assignable to this method handle's trailing parameter type
1175 * @see #asCollector
1176 * @see #isVarargsCollector
1177 * @see #asFixedArity
1178 */
1179 public MethodHandle asVarargsCollector(Class<?> arrayType) {
1180 Objects.requireNonNull(arrayType);
1181 boolean lastMatch = asCollectorChecks(arrayType, 0);
1182 if (isVarargsCollector() && lastMatch)
1183 return this;
1184 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1185 }
1186
1187 /**
1188 * Determines if this method handle
1189 * supports {@linkplain #asVarargsCollector variable arity} calls.
1190 * Such method handles arise from the following sources:
1191 * <ul>
1192 * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
1193 * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
1194 * which resolves to a variable arity Java method or constructor
1195 * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
1196 * which resolves to a variable arity Java method or constructor
1197 * </ul>
1198 * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
1199 * @see #asVarargsCollector
1200 * @see #asFixedArity
1201 */
1324 }
1325
1326 /*non-public*/
1327 MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1328 if (!member.isVarargs()) return this;
1329 Class<?> arrayType = type().lastParameterType();
1330 if (arrayType.isArray()) {
1331 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1332 }
1333 throw member.makeAccessException("cannot make variable arity", null);
1334 }
1335
1336 /*non-public*/
1337 MethodHandle viewAsType(MethodType newType, boolean strict) {
1338 // No actual conversions, just a new view of the same method.
1339 // Note that this operation must not produce a DirectMethodHandle,
1340 // because retyped DMHs, like any transformed MHs,
1341 // cannot be cracked into MethodHandleInfo.
1342 assert viewAsTypeChecks(newType, strict);
1343 BoundMethodHandle mh = rebind();
1344 assert(!((MethodHandle)mh instanceof DirectMethodHandle));
1345 return mh.copyWith(newType, mh.form);
1346 }
1347
1348 /*non-public*/
1349 boolean viewAsTypeChecks(MethodType newType, boolean strict) {
1350 if (strict) {
1351 assert(type().isViewableAs(newType, true))
1352 : Arrays.asList(this, newType);
1353 } else {
1354 assert(type().basicType().isViewableAs(newType.basicType(), true))
1355 : Arrays.asList(this, newType);
1356 }
1357 return true;
1358 }
1359
1360 // Decoding
1361
1362 /*non-public*/
1363 LambdaForm internalForm() {
1364 return form;
|
855 MethodHandle caString3 = caToString.asCollector(char[].class, 3);
856 assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
857 MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
858 assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
859 * }</pre></blockquote>
860 * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
861 * @param arrayLength the number of arguments to spread from an incoming array argument
862 * @return a new method handle which spreads its final array argument,
863 * before calling the original method handle
864 * @throws NullPointerException if {@code arrayType} is a null reference
865 * @throws IllegalArgumentException if {@code arrayType} is not an array type,
866 * or if target does not have at least
867 * {@code arrayLength} parameter types,
868 * or if {@code arrayLength} is negative,
869 * or if the resulting method handle's type would have
870 * <a href="MethodHandle.html#maxarity">too many parameters</a>
871 * @throws WrongMethodTypeException if the implied {@code asType} call fails
872 * @see #asCollector
873 */
874 public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
875 return asSpreader(type().parameterCount() - arrayLength, arrayType, arrayLength);
876 }
877
878 /**
879 * Makes an <em>array-spreading</em> method handle, which accepts an array argument at a given position and spreads
880 * its elements as positional arguments in place of the array. The new method handle adapts, as its <i>target</i>,
881 * the current method handle. The type of the adapter will be the same as the type of the target, except that the
882 * {@code arrayLength} parameters of the target's type, starting at the zero-based position {@code spreadArgPos},
883 * are replaced by a single array parameter of type {@code arrayType}.
884 * <p>
885 * This method behaves very much like {@link #asSpreader(Class, int)}, but accepts an additional {@code spreadArgPos}
886 * argument to indicate at which position in the parameter list the spreading should take place.
887 * <p>
888 * @apiNote Example:
889 * <blockquote><pre>{@code
890 MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class));
891 MethodHandle compare2FromArray = compare.asSpreader(0, Object[].class, 2);
892 Object[] ints = new Object[]{3, 9, 7, 7};
893 Comparator<Integer> cmp = (a, b) -> a - b;
894 assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 0, 2), cmp) < 0);
895 assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 1, 3), cmp) > 0);
896 assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp) == 0);
897 * }</pre></blockquote>
898 * @param spreadArgPos the position (zero-based index) in the argument list at which spreading should start.
899 * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
900 * @param arrayLength the number of arguments to spread from an incoming array argument
901 * @return a new method handle which spreads an array argument at a given position,
902 * before calling the original method handle
903 * @throws NullPointerException if {@code arrayType} is a null reference
904 * @throws IllegalArgumentException if {@code arrayType} is not an array type,
905 * or if target does not have at least
906 * {@code arrayLength} parameter types,
907 * or if {@code arrayLength} is negative,
908 * or if {@code spreadArgPos} has an illegal value (negative, or together with arrayLength exceeding the
909 * number of arguments),
910 * or if the resulting method handle's type would have
911 * <a href="MethodHandle.html#maxarity">too many parameters</a>
912 * @throws WrongMethodTypeException if the implied {@code asType} call fails
913 *
914 * @see #asSpreader(Class, int)
915 * @since 9
916 */
917 public MethodHandle asSpreader(int spreadArgPos, Class<?> arrayType, int arrayLength) {
918 MethodType postSpreadType = asSpreaderChecks(arrayType, spreadArgPos, arrayLength);
919 MethodHandle afterSpread = this.asType(postSpreadType);
920 BoundMethodHandle mh = afterSpread.rebind();
921 LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
922 MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, spreadArgPos + arrayLength, arrayType);
923 return mh.copyWith(preSpreadType, lform);
924 }
925
926 /**
927 * See if {@code asSpreader} can be validly called with the given arguments.
928 * Return the type of the method handle call after spreading but before conversions.
929 */
930 private MethodType asSpreaderChecks(Class<?> arrayType, int pos, int arrayLength) {
931 spreadArrayChecks(arrayType, arrayLength);
932 int nargs = type().parameterCount();
933 if (nargs < arrayLength || arrayLength < 0)
934 throw newIllegalArgumentException("bad spread array length");
935 if (pos < 0 || pos + arrayLength > nargs) {
936 throw newIllegalArgumentException("bad spread position");
937 }
938 Class<?> arrayElement = arrayType.getComponentType();
939 MethodType mtype = type();
940 boolean match = true, fail = false;
941 for (int i = pos; i < arrayLength; i++) {
942 Class<?> ptype = mtype.parameterType(i);
943 if (ptype != arrayElement) {
944 match = false;
945 if (!MethodType.canConvert(arrayElement, ptype)) {
946 fail = true;
947 break;
948 }
949 }
950 }
951 if (match) return mtype;
952 MethodType needType = mtype.asSpreaderType(arrayType, pos, arrayLength);
953 if (!fail) return needType;
954 // elicit an error:
955 this.asType(needType);
956 throw newInternalError("should not return", null);
957 }
958
959 private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
960 Class<?> arrayElement = arrayType.getComponentType();
961 if (arrayElement == null)
962 throw newIllegalArgumentException("not an array type", arrayType);
963 if ((arrayLength & 0x7F) != arrayLength) {
964 if ((arrayLength & 0xFF) != arrayLength)
965 throw newIllegalArgumentException("array length is not legal", arrayLength);
966 assert(arrayLength >= 128);
967 if (arrayElement == long.class ||
968 arrayElement == double.class)
969 throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
970 }
971 }
972
1025 MethodHandle longsToString = publicLookup()
1026 .findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
1027 .asCollector(long[].class, 1);
1028 assertEquals("[123]", (String) longsToString.invokeExact((long)123));
1029 * }</pre></blockquote>
1030 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1031 * @param arrayLength the number of arguments to collect into a new array argument
1032 * @return a new method handle which collects some trailing argument
1033 * into an array, before calling the original method handle
1034 * @throws NullPointerException if {@code arrayType} is a null reference
1035 * @throws IllegalArgumentException if {@code arrayType} is not an array type
1036 * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
1037 * or {@code arrayLength} is not a legal array size,
1038 * or the resulting method handle's type would have
1039 * <a href="MethodHandle.html#maxarity">too many parameters</a>
1040 * @throws WrongMethodTypeException if the implied {@code asType} call fails
1041 * @see #asSpreader
1042 * @see #asVarargsCollector
1043 */
1044 public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
1045 return asCollector(type().parameterCount() - 1, arrayType, arrayLength);
1046 }
1047
1048 /**
1049 * Makes an <em>array-collecting</em> method handle, which accepts a given number of positional arguments starting
1050 * at a given position, and collects them into an array argument. The new method handle adapts, as its
1051 * <i>target</i>, the current method handle. The type of the adapter will be the same as the type of the target,
1052 * except that the parameter at the position indicated by {@code collectArgPos} (usually of type {@code arrayType})
1053 * is replaced by {@code arrayLength} parameters whose type is element type of {@code arrayType}.
1054 * <p>
1055 * This method behaves very much like {@link #asCollector(Class, int)}, but differs in that its {@code
1056 * collectArgPos} argument indicates at which position in the parameter list arguments should be collected. This
1057 * index is zero-based.
1058 * <p>
1059 * @apiNote Examples:
1060 * <blockquote><pre>{@code
1061 StringWriter swr = new StringWriter();
1062 MethodHandle swWrite = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, char[].class, int.class, int.class)).bindTo(swr);
1063 MethodHandle swWrite4 = swWrite.asCollector(0, char[].class, 4);
1064 swWrite4.invoke('A', 'B', 'C', 'D', 1, 2);
1065 assertEquals("BC", swr.toString());
1066 swWrite4.invoke('P', 'Q', 'R', 'S', 0, 4);
1067 assertEquals("BCPQRS", swr.toString());
1068 swWrite4.invoke('W', 'X', 'Y', 'Z', 3, 1);
1069 assertEquals("BCPQRSZ", swr.toString());
1070 * }</pre></blockquote>
1071 * @param collectArgPos the zero-based position in the parameter list at which to start collecting.
1072 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1073 * @param arrayLength the number of arguments to collect into a new array argument
1074 * @return a new method handle which collects some arguments
1075 * into an array, before calling the original method handle
1076 * @throws NullPointerException if {@code arrayType} is a null reference
1077 * @throws IllegalArgumentException if {@code arrayType} is not an array type
1078 * or {@code arrayType} is not assignable to this method handle's array parameter type,
1079 * or {@code arrayLength} is not a legal array size,
1080 * or {@code collectArgPos} has an illegal value (negative, or greater than the number of arguments),
1081 * or the resulting method handle's type would have
1082 * <a href="MethodHandle.html#maxarity">too many parameters</a>
1083 * @throws WrongMethodTypeException if the implied {@code asType} call fails
1084 *
1085 * @see #asCollector(Class, int)
1086 * @since 9
1087 */
1088 public MethodHandle asCollector(int collectArgPos, Class<?> arrayType, int arrayLength) {
1089 asCollectorChecks(arrayType, collectArgPos, arrayLength);
1090 BoundMethodHandle mh = rebind();
1091 MethodType resultType = type().asCollectorType(arrayType, collectArgPos, arrayLength);
1092 MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1093 LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
1094 if (lform != null) {
1095 return mh.copyWith(resultType, lform);
1096 }
1097 lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
1098 return mh.copyWithExtendL(resultType, lform, newArray);
1099 }
1100
1101 /**
1102 * See if {@code asCollector} can be validly called with the given arguments.
1103 * Return false if the last parameter is not an exact match to arrayType.
1104 */
1105 /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int pos, int arrayLength) {
1106 spreadArrayChecks(arrayType, arrayLength);
1107 int nargs = type().parameterCount();
1108 if (pos < 0 || pos >= nargs) {
1109 throw newIllegalArgumentException("bad collect position");
1110 }
1111 if (nargs != 0) {
1112 Class<?> param = type().parameterType(pos);
1113 if (param == arrayType) return true;
1114 if (param.isAssignableFrom(arrayType)) return false;
1115 }
1116 throw newIllegalArgumentException("array type not assignable to argument", this, arrayType);
1117 }
1118
1119 /**
1120 * Makes a <em>variable arity</em> adapter which is able to accept
1121 * any number of trailing positional arguments and collect them
1122 * into an array argument.
1123 * <p>
1124 * The type and behavior of the adapter will be the same as
1125 * the type and behavior of the target, except that certain
1126 * {@code invoke} and {@code asType} requests can lead to
1127 * trailing positional arguments being collected into target's
1128 * trailing parameter.
1129 * Also, the last parameter type of the adapter will be
1130 * {@code arrayType}, even if the target has a different
1131 * last parameter type.
1132 * <p>
1133 * This transformation may return {@code this} if the method handle is
1134 * already of variable arity and its trailing parameter type
1135 * is identical to {@code arrayType}.
1136 * <p>
1251 * special role of the final argument, and of the effect of a
1252 * type match on that final argument, which determines whether
1253 * or not a single trailing argument is interpreted as a whole
1254 * array or a single element of an array to be collected.
1255 * Note that the dynamic type of the trailing argument has no
1256 * effect on this decision, only a comparison between the symbolic
1257 * type descriptor of the call site and the type descriptor of the method handle.)
1258 *
1259 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1260 * @return a new method handle which can collect any number of trailing arguments
1261 * into an array, before calling the original method handle
1262 * @throws NullPointerException if {@code arrayType} is a null reference
1263 * @throws IllegalArgumentException if {@code arrayType} is not an array type
1264 * or {@code arrayType} is not assignable to this method handle's trailing parameter type
1265 * @see #asCollector
1266 * @see #isVarargsCollector
1267 * @see #asFixedArity
1268 */
1269 public MethodHandle asVarargsCollector(Class<?> arrayType) {
1270 Objects.requireNonNull(arrayType);
1271 boolean lastMatch = asCollectorChecks(arrayType, type().parameterCount() - 1, 0);
1272 if (isVarargsCollector() && lastMatch)
1273 return this;
1274 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1275 }
1276
1277 /**
1278 * Determines if this method handle
1279 * supports {@linkplain #asVarargsCollector variable arity} calls.
1280 * Such method handles arise from the following sources:
1281 * <ul>
1282 * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
1283 * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
1284 * which resolves to a variable arity Java method or constructor
1285 * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
1286 * which resolves to a variable arity Java method or constructor
1287 * </ul>
1288 * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
1289 * @see #asVarargsCollector
1290 * @see #asFixedArity
1291 */
1414 }
1415
1416 /*non-public*/
1417 MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1418 if (!member.isVarargs()) return this;
1419 Class<?> arrayType = type().lastParameterType();
1420 if (arrayType.isArray()) {
1421 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1422 }
1423 throw member.makeAccessException("cannot make variable arity", null);
1424 }
1425
1426 /*non-public*/
1427 MethodHandle viewAsType(MethodType newType, boolean strict) {
1428 // No actual conversions, just a new view of the same method.
1429 // Note that this operation must not produce a DirectMethodHandle,
1430 // because retyped DMHs, like any transformed MHs,
1431 // cannot be cracked into MethodHandleInfo.
1432 assert viewAsTypeChecks(newType, strict);
1433 BoundMethodHandle mh = rebind();
1434 return mh.copyWith(newType, mh.form);
1435 }
1436
1437 /*non-public*/
1438 boolean viewAsTypeChecks(MethodType newType, boolean strict) {
1439 if (strict) {
1440 assert(type().isViewableAs(newType, true))
1441 : Arrays.asList(this, newType);
1442 } else {
1443 assert(type().basicType().isViewableAs(newType.basicType(), true))
1444 : Arrays.asList(this, newType);
1445 }
1446 return true;
1447 }
1448
1449 // Decoding
1450
1451 /*non-public*/
1452 LambdaForm internalForm() {
1453 return form;
|