Class Signature

java.lang.Object
com.headius.invokebinder.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.
  • Field Details

    • methodType

      private final MethodType methodType
    • argNames

      private final String[] argNames
  • Constructor Details

    • Signature

      Signature(Class retval)
      Construct a new signature with the given return value.
      Parameters:
      retval - the return value for the new signature
    • Signature

      Signature(Class retval, Class[] argTypes, String... argNames)
      Construct a new signature with the given return value, argument types, and argument names.
      Parameters:
      retval - the return value for the new signature
      argTypes - the argument types for the new signature
      argNames - the argument names for the new signature
    • Signature

      Signature(MethodType methodType, String... argNames)
      Construct a new signature with the given method type and argument names.
      Parameters:
      methodType - the method type for the new signature
      argNames - the argument names for the new signature
  • Method Details

    • 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
    • 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
    • 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:
      the new signature
    • 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
    • appendArgs

      public Signature appendArgs(String[] names, Class... types)
      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
    • 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
    • prependArgs

      public Signature prependArgs(String[] names, Class[] types)
      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
    • 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
    • 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
    • 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
    • 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:
    • 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
    • dropFirst

      public Signature dropFirst()
      Drop the first argument from this signature.
      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
      oldName - the new type of the argument; can be the same as old
    • spread

      public Signature spread(String[] names, Class... types)
      Spread the trailing [] argument into the given argument types
    • spread

      public Signature spread(String... names)
      Spread the trailing [] argument into its component type assigning given names.
    • spread

      public Signature spread(String baseName, int count)
      Spread the trailing [] argument into its component type assigning given names.
    • type

      public MethodType type()
      The current java.lang.invoke.MethodType for this Signature.
      Returns:
      the current method type
    • 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:
      name - 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
    • 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
    • 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:
    • 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
    • nonMatchingTo

      private int[] nonMatchingTo(String... otherArgNames)