Class Signature


  • public class Signature
    extends Object
    Signature represents a series of method arguments plus their symbolic names. In order to make it easier to permute arguments, track their flow, and debug cases where reordering or permuting fails to work properly, the Signature class also tracks symbolic names for all arguments. This allows permuting by name or by name pattern, avoiding the error-prone juggling of int[] for the standard MethodHandles.permuteArguments call. A Signature is created starting using #thatReturns method, and expanded using #withArgument for each named argument in sequence. Order is preserved. A Signature can be mutated into another by manipuating the argument list as with java.lang.invoke.MethodType, but using argument names and name patterns instead of integer offsets. Two signatures can be used to produce a permute array suitable for use in java.lang.invoke.MethodHandles#permuteArguments using the #to methods. The #to method can also accept a list of argument names, as a shortcut.
    Author:
    headius
    • Method Detail

      • toString

        public String toString()
        Produce a human-readable representation of this signature. This representation uses Class#getSimpleName to improve readability.
        Overrides:
        toString in class Object
        Returns:
        a human-readable representation of the signature
      • returning

        public static Signature returning​(Class<?> retval)
        Create a new signature returning the given type.
        Parameters:
        retval - the return type for the new signature
        Returns:
        the new signature
      • from

        public static Signature from​(Class<?> retval,
                                     Class<?>[] argTypes,
                                     String... argNames)
        Create a new signature based on the given return value, argument types, and argument names
        Parameters:
        retval - the type of the return value
        argTypes - the types of the arguments
        argNames - the names of the arguments
        Returns:
        a new Signature
      • changeReturn

        public Signature changeReturn​(Class<?> retval)
        Create a new signature based on this one with a different return type.
        Parameters:
        retval - the class for the new signature's return type
        Returns:
        the new signature with modified return value
      • asFold

        public Signature asFold​(Class<?> retval)
        Produce a new signature based on this one with a different return type.
        Parameters:
        retval - the new return type for the new signature
        Returns:
        a new signature with the added argument
      • appendArg

        public Signature appendArg​(String name,
                                   Class<?> type)
        Append an argument (name + type) to the signature.
        Parameters:
        name - the name of the argument
        type - the type of the argument
        Returns:
        a new signature with the added arguments
      • appendArgs

        public Signature appendArgs​(String[] names,
                                    Class<?>... types)
        Append an argument (name + type) to the signature.
        Parameters:
        names - the names of the arguments
        types - the types of the argument
        Returns:
        a new signature with the added arguments
      • prependArg

        public Signature prependArg​(String name,
                                    Class<?> type)
        Prepend an argument (name + type) to the signature.
        Parameters:
        name - the name of the argument
        type - the type of the argument
        Returns:
        a new signature with the added arguments
      • prependArgs

        public Signature prependArgs​(String[] names,
                                     Class<?>... types)
        Prepend arguments (names + types) to the signature.
        Parameters:
        names - the names of the arguments
        types - the types of the arguments
        Returns:
        a new signature with the added arguments
      • insertArg

        public Signature insertArg​(int index,
                                   String name,
                                   Class<?> type)
        Insert an argument (name + type) into the signature.
        Parameters:
        index - the index at which to insert
        name - the name of the new argument
        type - the type of the new argument
        Returns:
        a new signature with the added arguments
      • insertArg

        public Signature insertArg​(String beforeName,
                                   String name,
                                   Class<?> type)
        Insert an argument (name + type) into the signature before the argument with the given name.
        Parameters:
        beforeName - the name of the argument before which to insert
        name - the name of the new argument
        type - the type of the new argument
        Returns:
        a new signature with the added arguments
      • insertArgs

        public Signature insertArgs​(int index,
                                    String[] names,
                                    Class<?>... types)
        Insert arguments (names + types) into the signature.
        Parameters:
        index - the index at which to insert
        names - the names of the new arguments
        types - the types of the new arguments
        Returns:
        a new signature with the added arguments
      • insertArgs

        public Signature insertArgs​(String beforeName,
                                    String[] names,
                                    Class<?>... types)
        Insert arguments (names + types) into the signature before the argument with the given name.
        Parameters:
        beforeName - the name of the argument before which to insert
        names - the names of the new arguments
        types - the types of the new arguments
        Returns:
        a new Signature with the added arguments
      • dropArg

        public Signature dropArg​(String name)
        Drops the first argument with the given name.
        Parameters:
        name - the name of the argument to drop
        Returns:
        a new signature
      • dropArg

        public Signature dropArg​(int index)
        Drops the argument at the given index.
        Parameters:
        index - the index of the argument to drop
        Returns:
        a new signature
      • dropLast

        public Signature dropLast()
        Drop the last argument from this signature.
        Returns:
        a new signature
      • dropLast

        public Signature dropLast​(int n)
        Drop the specified number of last arguments from this signature.
        Parameters:
        n - number of arguments to drop
        Returns:
        a new signature
      • dropFirst

        public Signature dropFirst()
        Drop the first argument from this signature.
        Returns:
        a new signature
      • dropFirst

        public Signature dropFirst​(int n)
        Drop the specified number of first arguments from this signature.
        Parameters:
        n - number of arguments to drop
        Returns:
        a new signature
      • replaceArg

        public Signature replaceArg​(String oldName,
                                    String newName,
                                    Class<?> newType)
        Replace the named argument with a new name and type.
        Parameters:
        oldName - the old name of the argument
        newName - the new name of the argument; can be the same as old
        newType - the new type of the argument; can be the same as old
        Returns:
        a new signature with the modified argument
      • spread

        public Signature spread​(String[] names,
                                Class<?>... types)
        Spread the trailing [] argument into its component type assigning given names.
        Parameters:
        names - names to use for the decomposed arguments
        types - types to use for the decomposed arguments
        Returns:
        a new signature with decomposed arguments in place of the trailing array
      • spread

        public Signature spread​(String... names)
        Spread the trailing [] argument into its component type assigning given names.
        Parameters:
        names - names to use for the decomposed arguments
        Returns:
        a new signature with decomposed arguments in place of the trailing array
      • spread

        public Signature spread​(String baseName,
                                int count)
        Spread the trailing [] argument into its component type assigning given names.
        Parameters:
        baseName - base name of the spread arguments
        count - number of arguments into which the last argument will decompose
        Returns:
        a new signature with decomposed arguments in place of the trailing array
      • collect

        public Signature collect​(String newName,
                                 String oldPattern)
        Collect sequential arguments matching pattern into an array. They must have the same type.
        Parameters:
        newName - the name of the new array argument
        oldPattern - the pattern of arguments to collect
        Returns:
        a new signature with an array argument where the collected arguments were
      • type

        public MethodType type()
        The current java.lang.invoke.MethodType for this Signature.
        Returns:
        the current method type
      • argCount

        public int argCount()
        The current argument count.
        Returns:
        argument count of this signature
      • argNames

        public String[] argNames()
        The current argument names for this signature.
        Returns:
        the current argument names
      • argName

        public String argName​(int index)
        Retrieve the name of the argument at the given index.
        Parameters:
        index - the index from which to get the argument name
        Returns:
        the argument name
      • argOffset

        public int argOffset​(String name)
        Retrieve the offset of the given argument name in this signature's arguments. If the argument name is not in the argument list, returns -1.
        Parameters:
        name - the argument name to search for
        Returns:
        the offset at which the argument name was found or -1
      • argOffsets

        public int argOffsets​(String pattern)
        Retrieve the offset of the given argument name in this signature's arguments. If the argument name is not in the argument list, returns -1.
        Parameters:
        pattern - the argument name to search for
        Returns:
        the offset at which the argument name was found or -1
      • firstArgName

        public String firstArgName()
        Get the first argument name.
        Returns:
        the first argument name
      • lastArgName

        public String lastArgName()
        Get the last argument name.
        Returns:
        the last argument name
      • argName

        public Signature argName​(int index,
                                 String name)
        Set the argument name at the given index.
        Parameters:
        index - the index at which to set the argument name
        name - the name to set
        Returns:
        a new signature with the given name at the given index
      • argType

        public Class<?> argType​(int index)
        Get the argument type at the given index.
        Parameters:
        index - the index from which to get the argument type
        Returns:
        the argument type
      • firstArgType

        public Class<?> firstArgType()
        Get the first argument type.
        Returns:
        the first argument type
      • lastArgType

        public Class<?> lastArgType()
        Get the last argument type.
        Returns:
        the last argument type
      • argType

        public Signature argType​(int index,
                                 Class<?> type)
        Set the argument type at the given index.
        Parameters:
        index - the index at which to set the argument type
        type - the type to set
        Returns:
        a new signature with the given type at the given index
      • permute

        public Signature permute​(String... permuteArgs)
        Create a new signature containing the same return value as this one, but only the specified arguments.
        Parameters:
        permuteArgs - the names of the arguments to preserve
        Returns:
        the new signature
      • exclude

        public Signature exclude​(String... excludeArgs)
        Create a new signature containing the same return value as this one, but omitting the specified arguments. Blacklisting to #permute's whitelisting.
        Parameters:
        excludeArgs - the names of the arguments to exclude
        Returns:
        the new signature
      • permuteWith

        public MethodHandle permuteWith​(MethodHandle target,
                                        String... permuteArgs)
        Produce a method handle permuting the arguments in this signature using the given permute arguments and targeting the given java.lang.invoke.MethodHandle. Example:
         Signature sig = Signature.returning(String.class).appendArg("a", int.class).appendArg("b", int.class);
         MethodHandle handle = handleThatTakesOneInt();
         MethodHandle newHandle = sig.permuteTo(handle, "b");
         
        Parameters:
        target - the method handle to target
        permuteArgs - the arguments to permute
        Returns:
        a new handle that permutes appropriate positions based on the given permute args
      • permuteWith

        public SmartHandle permuteWith​(SmartHandle target)
        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.
        Parameters:
        target - the SmartHandle to use as a permutation target
        Returns:
        a new SmartHandle that permutes this Signature's args into a call to the target SmartHandle.
        See Also:
        permuteWith(java.lang.invoke.MethodHandle, java.lang.String[])
      • to

        public int[] to​(Signature other)
        Generate an array of argument offsets based on permuting this signature to the given signature.
        Parameters:
        other - the signature to target
        Returns:
        an array of argument offsets that will permute to the given signature
      • to

        public int[] to​(String... otherArgPatterns)
        Generate an array of argument offsets based on permuting this signature to the given signature. Repeats are permitted, and the patterns will be matched against actual argument names using regex matching.
        Parameters:
        otherArgPatterns - the argument name patterns to permute
        Returns:
        an array of argument offsets that will permute to the matching argument names
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class Object