< prev index next >
src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Print this page
rev 15544 : imported patch fold_select
@@ -3941,10 +3941,37 @@
if (!ok)
throw misMatchedTypes("target and combiner types", targetType, combinerType);
return rtype;
}
+ private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType, int ... argPos) {
+ int foldArgs = combinerType.parameterCount();
+ if (argPos.length != foldArgs) {
+ throw newIllegalArgumentException("combiner and argument map must be equal size", combinerType, argPos.length);
+ }
+ Class<?> rtype = combinerType.returnType();
+ int foldVals = rtype == void.class ? 0 : 1;
+ boolean ok = true;
+ for (int i = 0; i < foldArgs; i++) {
+ int arg = argPos[i];
+ if (arg < 0 || arg > targetType.parameterCount()) {
+ throw newIllegalArgumentException("arg outside of target parameterRange", targetType, arg);
+ }
+ if (combinerType.parameterType(i) != targetType.parameterType(arg)) {
+ throw newIllegalArgumentException("target argument type at position " + arg
+ + " must match combiner argument type at index " + i + ": " + targetType
+ + " -> " + combinerType + ", map: " + Arrays.toString(argPos));
+ }
+ }
+ if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos)) {
+ ok = false;
+ }
+ if (!ok)
+ throw misMatchedTypes("target and combiner types", targetType, combinerType);
+ return rtype;
+ }
+
/**
* Makes a method handle which adapts a target method handle,
* by guarding it with a test, a boolean-valued method handle.
* If the guard fails, a fallback handle is called instead.
* All three method handles must have the same corresponding
@@ -4947,10 +4974,32 @@
}
result = result.copyWithExtendL(newType, lform, combiner);
return result;
}
+ /**
+ *
+ * @param target
+ * @param pos
+ * @param combiner
+ * @param argPositions
+ * @return
+ */
+ static MethodHandle foldArguments(MethodHandle target, int pos, MethodHandle combiner, int ... argPositions) {
+ MethodType targetType = target.type();
+ MethodType combinerType = combiner.type();
+ Class<?> rtype = foldArgumentChecks(pos, targetType, combinerType, argPositions);
+ BoundMethodHandle result = target.rebind();
+ boolean dropResult = rtype == void.class;
+ LambdaForm lform = result.editor().foldArgumentsForm(1 + pos, dropResult, combinerType.basicType(), argPositions);
+ MethodType newType = targetType;
+ if (!dropResult) {
+ newType = newType.dropParameterTypes(pos, pos + 1);
+ }
+ result = result.copyWithExtendL(newType, lform, combiner);
+ return result;
+ }
private static void checkLoop0(MethodHandle[][] clauses) {
if (clauses == null || clauses.length == 0) {
throw newIllegalArgumentException("null or no clauses passed");
}
< prev index next >