Package org.spongepowered.asm.mixin.injection

## Annotation Type Redirect

-     @Documented
      @Retention(RUNTIME)
      @Target(METHOD)
      public @interface Redirect

  The `Redirect` annotation redirects a method call to the mixin implementation. The method on whom the annotation is applied is referenced within the micromixin documentation as the redirect handler.

  ## Handler signature and arguments

  The redirect handler must consume all arguments of the redirected method in the order they appear within the redirected method. In case the redirected method is not static, the redirect handler must also consume the instance type of the owner of the redirected method at the first position. If the redirected method returns a value,

  The redirect handler must be static regardless of the static-ness of the redirected method. As a logical consequence the redirect handler must also be private. These steps are required as `Redirect` does not modify the stack and replaces a single instruction with another single instruction.

  Locals capture in the style of `Inject` is not supported when using `Redirect`. Capture of the arguments of the target method can be performed by appending the arguments of the target method to the arguments of the handler method. Trailing arguments may be omitted, however there may be no 'jumps' in the arguments nor may leading arguments be omitted. Note that internally redirect uses a different scheme for handling argument capture than with other injectors such as `ModifyVariable`, which is why more sophisticated argument capture using @Local or @Share is not supported in the micromixin-transform implementation (although at the point of writing, so 2024-07-03 such capture is not supported regardless of injector).

  ## Field redirects

  Aside from redirecting methods which is the main use of this annotation, `Redirect` is also capable of redirecting read as well as write references to fields - static or not. Regardless, the signature of the handler would behave much as if the GETFIELD, GETSTATIC, PUTFIELD or PUTSTATIC were replaced with appropriate getter or setter methods. The integrity of the operand stack must be preserved.

  Field redirect handler signature matrix
  Target method static | Field static | Instruction opcode | Signature
  --- | --- | --- | ---
  Yes | Yes | GETSTATIC | static {type} handler()
  Yes | Yes | PUTSTATIC | static void handler({type})
  No | Yes | GETSTATIC | {type} handler()
  No | Yes | PUTSTATIC | void handler({type})
  Yes | No | GETFIELD | static {type} handler({owner})
  Yes | No | PUTFIELD | static void handler({owner}, {type})
  No | No | GETFIELD | {type} handler({owner})
  No | No | PUTFIELD | void handler({owner}, {type})

  For a call such as `object.field = ...` the type of `object` will generally be the `{owner}` type.

  ## Array access redirects

  Furthermore `Redirect` is capable of redirecting array accesses via the xALOAD and xASTORE opcode families. This is also not yet implemented in micromixin at the point of writing (8th of May 2024).

  When redirecting read access to an array of type `{type}`, the signature of the redirect handler is as follows: `private static {type} handlerName({type}[] array, int index)`. Likewise write access would have following signature: `private static void handlerName({type}[] array, int index, {type} element)`.

- - ### Required Element Summary

    Required Elements
    Modifier and Type | Required Element | Description
    --- | --- | ---
    `At` | `at` | The injection point where the injection should occur.

  - ### Optional Element Summary

    Optional Elements
    Modifier and Type | Optional Element | Description
    --- | --- | ---
    `int` | `allow` | The maximum amount of injection points that should be allowed.
    `int` | `expect` | The expected amount of injection points.
    `java.lang.String[]` | `method` | The targeted method selectors.
    `int` | `require` | The minimum amount of injection points.
    `Slice` | `slice` | The slice to make use for the injection points defined by `at()`.
    `Desc[]` | `target` | The targeted methods.Only one method is picked from the list of provided methods.

- - ### Element Detail

    - #### at

          At at

      The injection point where the injection should occur. If the injection point does not match anything no exception is thrown by default (this default can be changed through `require()`), however transformation does still partially occur (Micromixin still copies the handler into the target class anyways).

      Unlike `Inject`, `Redirect`'s `at()` is able to match multiple instructions with a single `At`.

      Returns:
        The injection point.

  - - #### allow

          int allow

      The maximum amount of injection points that should be allowed. If the value of this element is below 1 or if the value is below the `minimum amount` of allowable injection points then the limit is not being enforced. However, `expect()` has no influence on `allow()`.

      Furthermore this limit is only valid per target class. That is, if multiple target classes are defined as per `Mixin.value()` or `Mixin.targets()` then this limit is only applicable for all the injection points in the targeted class. This limitation is caused due to the fact that the targeted classes are not known until they are loaded in by the classloader, at which point all the injection logic occurs.

      This limit is shared across all methods (as defined by `method()` or `target()`) targeted by the handler within a class.

      Returns:
        The maximum amount targeted of injection points within the target class.
      Default:
        -1

  - - #### expect

          int expect

      The expected amount of injection points. This behaves similar to `require()`, however while `require()` will cause a class file transformation failure, `expect()` is a weaker form of it. Under the spongeian implementation, this attribute behaves like `require()` if and only if the appropriate debug flags are activated. The micromixin transformer will meanwhile "just" unconditionally write a warning to the logger.

      This attribute should be used to identify potentially outdated injectors.

      Returns:
        The expected amount of injection points
      Default:
        -1

  - - #### method

          java.lang.String[] method

      The targeted method selectors. The amounts of methods that may match and are selected is not bound to any hard value and as such it should be limited by setting attributes such as `require()` or `expect()` as otherwise the injector might accidentally not match anything with no way of knowing what exactly went wrong.

      The following are all valid formats of explicit target selectors:

      - `targetMethod`
      - `targetMethod(Lcom/example/Argument;)V`
      - `(Lcom/example/Argument;)V`
      - `targetMethod(I)Lcom/example/ReturnValue;`
      - `targetMethod()Z`
      - `Lcom/example/Target;targetMethod(Lcom/example/Argument;)V`
      - `Lcom/example/Target;(Lcom/example/Argument;)V`
      - `Lcom/example/Target;targetMethod(Lcom/example/Argument;) V`
      - `Lcom/example/Target;target Method(Lcom/example/Argument;)V`
      - `Lcom/example/Target;targetMethod(Lcom/exam ple/Argument;)V`

      The parts of the explicit target selector (owner, name, descriptor) must always have the same order, but the individual parts must not necessarily be present.

      While permissible, it is strongly discouraged to make use of whitespace in explicit target selectors. When they are used, the spongeian mixin implementation (and also micromixin) will discard all whitespace characters (tabs included). This is documented behaviour (in both micromixin and sponge's mixin) and is unlikely to change in the future. This discouragement exists as this feature may cause target selectors to be illegible.

      It is generally recommended to not be lazy when it comes to explicit selectors, the more information is provided the better. Information that is not supplied is comparable to a wildcard - the first matching method will be targeted, even if nonsense. It is especially not recommended to discard the method name, even if that is theoretically valid.

      The spongeian implementation also supports schemes other than the explicit selectors. However the Micromixin implementation only supports explicit selectors as documented above. Where as the spongeian implementation supports quantifiers in explicit selectors, Micromixin does not support them (yet). As such, quantifiers are not included in the documentation.

      It is rather advisable to use `target()` over `method()`, especially for beginners, since latter provides behaviour that can more easily be anticipated.

      Returns:
        The target selectors that define the target method of the handler.
      Default:
        {}

  - - #### require

          int require

      The minimum amount of injection points. If less injection points are found (as per `at()`). an exception is thrown during transformation. The default amount of required injection points can be set by mixin configuration file, but by default that is no minimum amount of required injection points.
      Returns:
        The minimum amount of injection points
      Default:
        -1

  - - #### slice

          Slice slice

      The slice to make use for the injection points defined by `at()`.

      The id of the slice is ignored as per the spongeian documentation, but this behaviour may not be reflected by micromixin-transformer. It is as such not recommended to depend on this behaviour. See `At.slice()` and `Slice.id()` for further information.

      Returns:
        The slice used to filter the possible instructions matched by injection points.
      Default:
        @org.spongepowered.asm.mixin.injection.Slice

  - - #### target

          Desc[] target

      The targeted methods.Only one method is picked from the list of provided methods. As such the list should generally only be used to mark method aliases among others.
      Returns:
        The target selectors that define the target method of the handler.
      Default:
        {}