Package org.spongepowered.asm.mixin.injection

## Annotation Type Inject

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

  The `Inject` annotation can be applied to methods that need to be called by the given target method. The point(s) where the target method calls the annotated method are called Injection points and are defined by `at()`. Meanwhile the annotated method is called the handler.

  If the target method returns a void, the method should have a `CallbackInfo` as it's argument. A sample method head would thus look like follows:

  > `private void handleCallback(CallbackInfo ci)`

  For non-void target methods, `CallbackInfoReturnable` should be used instead. The generic of that argument should be the same as the return type of the target method. For primitive return types, the wrapper class should be used instead. Thus a method head could look as follows:

  > `private void handleCallback(CallbackInfoReturnable<String> cir)`

  If a `CallbackInfo` is used where a `CallbackInfoReturnable` is expected (or vice-versa), an exception will be thrown during transformation. As such the transformation does not occur. Similarly if no `CallbackInfo` or `CallbackInfoReturnable` are present in the arguments of the handler method, an exception is thrown during transformation.

  ### Non-void returning handlers

  A handler method should return `void` at all times. However, the Micromixin implementation supports non-void return types - but they won't have any effect. Instead, they are `POP`/`POP2`'d off the operand stack. Be aware that the spongeian Mixin implementation also supports non-void handler methods, but it does not pop the return value off. Depending on the method, that can lead to a `VerifyError` once the target method is ran. This behaviour is also "working as intended".

  ### Argument capture

  Arguments can be captured irrespective of local capture. Arguments that need to be captured can simply be added in front of the `CallbackInfo` or `CallbackInfoReturnable`. However, be aware that Micromixin captures arguments rather naively, that is it does not expect local variable reuse. As the local variable table is left ignored by Micromixin (but not the spongeian implementation), a transformer must be applied before the Mixin that untangles the local variables (mostly be rewriting the XLOAD and XSTORE indices).

  Neither the spongeian nor the Micromixin implementation support argument capture underflows or overflows. As such the captured arguments must exactly be the arguments present in the targeted method. However, this does not apply if the handler does not capture any arguments.

- - ### Required Element Summary

    Required Elements
    Modifier and Type | Required Element | Description
    --- | --- | ---
    `At[]` | `at` | The injection points 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.
    `boolean` | `cancellable` | Defines whether `CallbackInfo.cancel()` and `CallbackInfo.cancel()` are valid - or better said: It defines the state of `CallbackInfo.isCancellable()` and `CallbackInfo.isCancellable()`.
    `int` | `expect` | The expected amount of injection points.
    `LocalCapture` | `locals` | Obtains whether and how locals are captured, or whether locals should just be printed.
    `java.lang.String[]` | `method` | The targeted method selectors.
    `int` | `require` | The minimum amount of injection points.
    `Slice[]` | `slice` | The available slices used for bisecting the available injection points declared by `at()`.
    `Desc[]` | `target` | The targeted methods.

- - ### Element Detail

    - #### at

          At[] at

      The injection points where the injection should occur. If none of the injection points apply 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 many other annotations such as `Redirect` or `ModifyArg`, each `At` annotation may at most represent a single instruction - that is if multiple instructions were to match the requirements set by the annotation, only the first matching instruction will be used and the others are discarded.

      Returns:
        The injection points.

  - - #### 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

  - - #### cancellable

          boolean cancellable

      Defines whether `CallbackInfo.cancel()` and `CallbackInfo.cancel()` are valid - or better said: It defines the state of `CallbackInfo.isCancellable()` and `CallbackInfo.isCancellable()`.

      By default all injectors are not cancellable. Setting this to `true` allows to cancel injectors.

      Cancelled callbacks will return from the method, for `CallbackInfoReturnable` it will return the appropriate (previously set) return value, although the return does not happen until the handler has finished running (i.e. calling cancel does not interrupt the handler).

      Returns:
        True in order for the handler to be able to cancel the method, false otherwise.
      Default:
        false

  - - #### 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

  - - #### locals

          LocalCapture locals

      Obtains whether and how locals are captured, or whether locals should just be printed. By default, local variables are not captured, as the capture requires analysis of the method. Such analysis can be performance intensive and is not suited in a performance-intensive situation such as classloading. Local capture happens irrespective of the local variable table (LVT) of the method. Instead ASM's Verifier is used to obtain the local variables at any given instruction.

      The local variables that can be captured can easily be viewed through `LocalCapture.PRINT`, which prints the local variables that can be captured. However, when doing so the injector is ignored. `LocalCapture.PRINT` also prints the recommended method signature with whom all local variables can be captured. Unneeded trailing arguments can be removed (up to the `CallbackInfo`/ `CallbackInfoReturnable`). Leading arguments cannot be removed, nor any arguments in between.

      Arguments can be captured regardless of the local capture. Captured arguments need to be added before the `CallbackInfo` or `CallbackInfoReturnable` argument, captured locals need to be added after that argument.

      Local capture cannot capture arguments - for that argument capture should be used. In medium to highly obfuscated environments, where local variables share the same index as arguments, that can be an issue. In that case another transformer must run before the mixin transformation step. Said transformer must remove collisions with local variables.

      Returns:
        The `LocalCapture` type that describes how locals should be captured - if at all.
      Default:
        org.spongepowered.asm.mixin.injection.callback.LocalCapture.NO_CAPTURE

  - - #### 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 available slices used for bisecting the available injection points declared by `at()`.
      Returns:
        An array of declared slices.
      Default:
        {}

  - - #### 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:
        {}