/** * Set the argument name at the given index. * * @param index the index at which to set the argument name * @param name the name to set * @return a new signature with the given name at the given index */ public Signature argName(int index, String name) { String[] argNames = Arrays.copyOf(argNames(), argNames().length); argNames[index] = name; return new Signature(type(), argNames); }
/** * Set the argument type at the given index. * * @param index the index at which to set the argument type * @param type the type to set * @return a new signature with the given type at the given index */ public Signature argType(int index, Class<?> type) { return new Signature(type().changeParameterType(index, type), argNames()); }
/** * Create a new SmartHandle that converts arguments from the given type to * the current signature's type, using the same argument names. This conversion * is equivalent to MethodHandle#asType. * * @param incoming the target MethodType from which arguments will be converted * @return a new SmartHandle that accepts the given argument types */ public SmartHandle convert(MethodType incoming) { return new SmartHandle(new Signature(incoming, signature.argNames()), handle.asType(incoming)); }
/** * Create a new SmartHandle that casts arguments from the given type to * the current signature's type, using the same argument names. This casting * is equivalent to MethodHandles#explicitCastArguments. * * @param incoming the target MethodType from which arguments will be converted * @return a new SmartHandle that accepts the given argument types */ public SmartHandle cast(MethodType incoming) { return new SmartHandle(new Signature(incoming, signature.argNames()), MethodHandles.explicitCastArguments(handle, incoming)); }
/** * Pass all arguments to the given function and drop any result. * * @param function a function which will receive all arguments and have its * return value inserted into the call chain * @return a new SmartBinder with the fold applied */ public SmartBinder foldVoid(SmartHandle function) { if (Arrays.equals(signature().argNames(), function.signature().argNames())) { return foldVoid(function.handle()); } else { return foldVoid(signature().asFold(void.class).permuteWith(function).handle()); } }
/** * Produce a new SmartHandle by permuting this Signature's arguments to the * Signature of a target SmartHandle. The new SmartHandle's signature will * match this one, permuting those arguments and invoking the target handle. * * @param target the SmartHandle to use as a permutation target * @return a new SmartHandle that permutes this Signature's args into a call * to the target SmartHandle. * @see Signature#permuteWith(java.lang.invoke.MethodHandle, java.lang.String[]) */ public SmartHandle permuteWith(SmartHandle target) { String[] argNames = target.signature().argNames(); return new SmartHandle(this, permuteWith(target.handle(), argNames)); }
/** * Cast the incoming arguments to the return and argument types given. The * argument count must match. * * @param returnType the return type for the casted signature * @param argTypes the types of the arguments for the casted signature * @return a new SmartBinder with the cast applied */ public SmartBinder cast(Class<?> returnType, Class<?>... argTypes) { return new SmartBinder(this, new Signature(returnType, argTypes, signature().argNames()), binder.cast(returnType, argTypes)); }
/** * Filter the arguments matching the given pattern using the given filter function. * * @param pattern the regular expression pattern to match arguments * @param filter the MethodHandle to use to filter the arguments * @return a new SmartBinder with the filter applied */ public SmartBinder filter(String pattern, MethodHandle filter) { String[] argNames = signature().argNames(); Pattern pat = Pattern.compile(pattern); Binder newBinder = binder(); Signature newSig = signature(); for (int i = 0; i < argNames.length; i++) { if (pat.matcher(argNames[i]).matches()) { newBinder = newBinder.filter(i, filter); newSig = newSig.argType(i, filter.type().returnType()); } } return new SmartBinder(newSig, newBinder); }
/** * Cast the incoming arguments to the return, first argument type, and * remaining argument types. Provide for convenience when dealing with * virtual method argument lists, which frequently omit the target * object. * * @param returnType the return type for the casted signature * @param firstArg the type of the first argument for the casted signature * @param restArgs the types of the remaining arguments for the casted signature * @return a new SmartBinder with the cast applied. */ public SmartBinder castVirtual(Class<?> returnType, Class<?> firstArg, Class<?>... restArgs) { return new SmartBinder(this, new Signature(returnType, firstArg, restArgs, signature().argNames()), binder.castVirtual(returnType, firstArg, restArgs)); }
/** * Pass all arguments to the given function and insert the resulting value * as newName into the argument list. * * @param newName the name of the new first argument where the fold * function's result will be passed * @param function a function which will receive all arguments and have its * return value inserted into the call chain * @return a new SmartBinder with the fold applied */ public SmartBinder fold(String newName, SmartHandle function) { if (Arrays.equals(signature().argNames(), function.signature().argNames())) { return fold(newName, function.handle()); } else { return fold(newName, signature().changeReturn(function.signature().type().returnType()).permuteWith(function).handle()); } }