/** * Create a new signature returning the given type. * * @param retval the return type for the new signature * @return the new signature */ public static Signature returning(Class<?> retval) { Signature sig = new Signature(retval); return sig; }
/** * Create a new signature based on the given return value, argument types, and argument names * * @param retval the type of the return value * @param argTypes the types of the arguments * @param argNames the names of the arguments * @return a new Signature */ public static Signature from(Class<?> retval, Class<?>[] argTypes, String... argNames) { assert argTypes.length == argNames.length; return new Signature(retval, argTypes, argNames); }
/** * Create a new signature based on this one with a different return type. * * @param retval the class for the new signature's return type * @return the new signature with modified return value */ public Signature changeReturn(Class<?> retval) { return new Signature(methodType.changeReturnType(retval), argNames); }
/** * Drop the specified number of first arguments from this signature. * * @param n number of arguments to drop * @return a new signature */ public Signature dropFirst(int n) { return new Signature( methodType.dropParameterTypes(0, n), Arrays.copyOfRange(argNames, n, argNames.length)); }
/** * Produce a new signature based on this one with a different return type. * * @param retval the new return type for the new signature * @return a new signature with the added argument */ public Signature asFold(Class<?> retval) { return new Signature(methodType.changeReturnType(retval), argNames); }
/** * Prepend arguments (names + types) to the signature. * * @param names the names of the arguments * @param types the types of the arguments * @return a new signature with the added arguments */ public Signature prependArgs(String[] names, Class<?>... types) { String[] newArgNames = new String[argNames.length + names.length]; System.arraycopy(argNames, 0, newArgNames, names.length, argNames.length); System.arraycopy(names, 0, newArgNames, 0, names.length); MethodType newMethodType = methodType.insertParameterTypes(0, types); return new Signature(newMethodType, newArgNames); }
/** * Prepend an argument (name + type) to the signature. * * @param name the name of the argument * @param type the type of the argument * @return a new signature with the added arguments */ public Signature prependArg(String name, Class<?> type) { String[] newArgNames = new String[argNames.length + 1]; System.arraycopy(argNames, 0, newArgNames, 1, argNames.length); newArgNames[0] = name; MethodType newMethodType = methodType.insertParameterTypes(0, type); return new Signature(newMethodType, newArgNames); }
/** * Append an argument (name + type) to the signature. * * @param names the names of the arguments * @param types the types of the argument * @return a new signature with the added arguments */ public Signature appendArgs(String[] names, Class<?>... types) { assert names.length == types.length : "names and types must be of the same length"; String[] newArgNames = new String[argNames.length + names.length]; System.arraycopy(argNames, 0, newArgNames, 0, argNames.length); System.arraycopy(names, 0, newArgNames, argNames.length, names.length); MethodType newMethodType = methodType.appendParameterTypes(types); return new Signature(newMethodType, newArgNames); }
/** * Append an argument (name + type) to the signature. * * @param name the name of the argument * @param type the type of the argument * @return a new signature with the added arguments */ public Signature appendArg(String name, Class<?> type) { String[] newArgNames = new String[argNames.length + 1]; System.arraycopy(argNames, 0, newArgNames, 0, argNames.length); newArgNames[argNames.length] = name; MethodType newMethodType = methodType.appendParameterTypes(type); return new Signature(newMethodType, newArgNames); }
/** * Drops the argument at the given index. * * @param index the index of the argument to drop * @return a new signature */ public Signature dropArg(int index) { assert index < argNames.length; String[] newArgNames = new String[argNames.length - 1]; if (index > 0) System.arraycopy(argNames, 0, newArgNames, 0, index); if (index < argNames.length - 1) System.arraycopy(argNames, index + 1, newArgNames, index, argNames.length - (index + 1)); MethodType newType = methodType.dropParameterTypes(index, index + 1); return new Signature(newType, newArgNames); }
/** * Insert arguments (names + types) into the signature. * * @param index the index at which to insert * @param names the names of the new arguments * @param types the types of the new arguments * @return a new signature with the added arguments */ public Signature insertArgs(int index, String[] names, Class<?>... types) { assert names.length == types.length : "names and types must be of the same length"; String[] newArgNames = new String[argNames.length + names.length]; System.arraycopy(names, 0, newArgNames, index, names.length); if (index != 0) System.arraycopy(argNames, 0, newArgNames, 0, index); if (argNames.length - index != 0) System.arraycopy(argNames, index, newArgNames, index + names.length, argNames.length - index); MethodType newMethodType = methodType.insertParameterTypes(index, types); return new Signature(newMethodType, newArgNames); }
/** * 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)); }
/** * 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)); }
/** * Drop the specified number of last arguments from this signature. * * @param n number of arguments to drop * @return a new signature */ public Signature dropLast(int n) { return new Signature( methodType.dropParameterTypes(methodType.parameterCount() - n, methodType.parameterCount()), Arrays.copyOfRange(argNames, 0, argNames.length - n)); }
/** * 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)); }
/** * 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); }
/** * Replace the named argument with a new name and type. * * @param oldName the old name of the argument * @param newName the new name of the argument; can be the same as old * @param newType the new type of the argument; can be the same as old * @return a new signature with the modified argument */ public Signature replaceArg(String oldName, String newName, Class<?> newType) { int offset = argOffset(oldName); String[] newArgNames = argNames; if (!oldName.equals(newName)) { newArgNames = Arrays.copyOf(argNames, argNames.length); newArgNames[offset] = newName; } Class<?> oldType = methodType.parameterType(offset); MethodType newMethodType = methodType; if (!oldType.equals(newType)) newMethodType = methodType.changeParameterType(offset, newType); return new Signature(newMethodType, newArgNames); }
/** * 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()); }
/** * Spread the trailing [] argument into its component type assigning given names. * * @param names names to use for the decomposed arguments * @param types types to use for the decomposed arguments * @return a new signature with decomposed arguments in place of the trailing array */ public Signature spread(String[] names, Class<?>... types) { assert names.length == types.length : "names and types must be of the same length"; String[] newArgNames = new String[argNames.length - 1 + names.length]; System.arraycopy(names, 0, newArgNames, newArgNames.length - names.length, names.length); System.arraycopy(argNames, 0, newArgNames, 0, argNames.length - 1); MethodType newMethodType = methodType .dropParameterTypes(methodType.parameterCount() - 1, methodType.parameterCount()) .appendParameterTypes(types); return new Signature(newMethodType, newArgNames); }