Package org.stianloader.micromixin.annotations

## Annotation Type CanonicalOverwrite

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

  ## Abstract

  The `CanonicalOverwrite` is a micromixin-specific derivation of the traditional `Overwrite` annotation. This annotation has the same behavioural semantics as `Overwrite` in the absence of a remapper or refmaps. However, when a remapper is used, the handler method keeps its "canonical" name, and a new helper method is spawned to keep the semantics of `Overwrite`. Hence, this method is in a sense of hybrid of `Unique` (which makes a method keep it's name for public methods), and `Overwrite`.

  It may not be applied on non-public or static methods, see the illegal usecases for further details.

  ## Semantic approximation

  The semantic approximation is an approximation of how the behaviour of this annotation can be replicated using other annotations, but may not mirror the inner workings of the annotation behind the scenes.

  In it's purest form, the behaviour of this annotation can be replicated using a default/implicit overwrite + explicit `Overwrite` pair. Henceforth you get the following two methods:

  >      // Note: No annotation here!
  >      public void methodName() {
  >          // Method logic goes here.
  >          // This is the "canonical" part of the handler.
  >      }

  >      @Overwrite
  >      public void methodName() {
  >          ((MyInterface) this).methodName();
  >      }

  The keen might realize that while this cannot be emulated with a single mixin class, this behaviour can be achieved using two or more mixin classes. This effect might make this annotation redundant, and it may be the only way to replicate the behaviour of `CanonicalOverwrite` if the annotation is not guaranteed to be supported under a given environment (please check out the documentation of your environment and dependencies you rely on for hints about this support). That being said, this requires the `Overwrite` to be applied before the implicit overwrite. However, as the implicit overwrite does not have strongly defined behaviour, it is possible for this emulation to not work under certain environments. Further, the chance of mistakes is high and the intended behaviour might be obfuscated by the boilerplate, ultimately making maintenance more costly. Henceforth, `CanonicalOverwrite` should be used for this exact usecase.

  ## Technical details

  This paragraph is mostly specific to the implementation within micromixin-transformer, other implementations may derive slightly from the implementation details. However, the behaviour must be kept the same. This is especially crucial to overrides in conjunction with subclassing.

  Within the remapper process, the handler method may not be renamed. Instead, only `method()` and `target()` are renamed. If neither `method()` nor `target()` are defined, then `target()` will be set to correspond to the method's current name and descriptor, and the new `target()` value will be remapped from then on. The handler method's name stays constant as established earlier.

  ## Important limitations & words of warning

  Usages of this annotation that are either discouraged or environments in which this annotation might show unintended behaviour (though this behaviour not being intended per-se but rather being a byproduct of other constraints).

  This annotation is unlikely to behave as intended outside of the stianloader toolchain. Especially, the remapping semantics described by this annotation are unlikely to be supported by tiny-remapper (although tiny-remapper could easily be extended to support this annotation) and are completely ignored when making use of the annotation processor and/or refmaps. In general, only micromixin-remapper can be reliably expected to process this annotation.

  This annotation has the potential of polluting the target class if it is used too frequently for little reason. Use `Overwrite` instead whenever applicable. Do note that like `Overwrite`, `CanonicalOverwrite` completely overwrites the target method. Thus it should not be used when an `Overwrite` is inappropriate, that is, `CanonicalOverwrite` ought not replace one or more `Inject`, `ModifyArg`, or similar. Further this annotation should not be used as an alternative to `Unique`.

  ## Illegal usecases

  Usages of this annotation that are invalid and thus will raise either a remap-time failure or a runtime failure. Implementors are encouraged to check against these uses.

  Methods annotated with `CanonicalOverwrite` MUST be `public`. All other visibility modifiers (such as protected, package-private or private) are considered illegal within the scope of this constraint. This constraint is at its core arbitrary, but is necessary to reduce the possibility of misuse of this annotation, as the ABI (application binary interface) guarantees provided are only relevant when this constraint is applied.

  A method annotated with `CanonicalOverwrite` MUST implement a definition defined by at least one interface implemented in the target class. As a logical consequence, it is invalid to apply this annotation on a `static` method. This constraint is at its core arbitrary, but is necessary to reduce the possibility of misuse of this annotation, as the ABI (application binary interface) guarantees provided are only relevant when this constraint is applied.

  The handler method (that is the method annotated with `CanonicalOverwrite`) and the target method (that is the method that should be overwritten) must have the same descriptor. It is not valid for them to differ in the descriptor, which means that the return value and the argument types must match. However, the generic signatures may differ due to generic erasure (but do note that mismatches may be dangerous nonetheless).

- - ### Optional Element Summary

    Optional Elements
    Modifier and Type | Optional Element | Description
    --- | --- | ---
    `java.lang.String` | `method` | The target selector string defining the method that should be overwritten.
    `org.spongepowered.asm.mixin.injection.Desc` | `target` | The `@Desc` definition referring to the method that should be overwritten.

- - ### Element Detail

    - #### method

          java.lang.String method

      The target selector string defining the method that should be overwritten. That is, the selected method will delegate all it's calls to the handler method.

      This parameter is mutually exclusive with `target()`. Only one of the two may be defined. However, it is also valid for none of the elements to be set, in which case the overwritten method is assumed to have the same descriptor and name as the annotated handler method.

      Note: Like many other mixin annotations, the transformer can differ between explicitly setting the value to `""` and not setting the value at all. This is because javac omits undefined element values and ignores the default value. The default value advertised here is only required due to how optional elements need to be defined in java source code but truth be told there is no such default value in practice.

      Returns:
        The target selector string defining the method to overwrite.
      Default:
        ""

  - - #### target

          org.spongepowered.asm.mixin.injection.Desc target

      The `@Desc` definition referring to the method that should be overwritten. That is, the selected method will delegate all it's calls to the handler method.

      This parameter is mutually exclusive with `method()`. Only one of the two may be defined. However, it is also valid for none of the elements to be set, in which case the overwritten method is assumed to have the same descriptor and name as the annotated handler method.

      Like in all other annotations, the default descriptor of the `Desc` is implicitly set to `void.class`. If a non-void method is overwritten, the descriptor must be explicitly set as a logical consequence of this constant (i.e. blind) default. The descriptor of the overwritten method and the descriptor of the target method must be the same, as defined by the illegal usecases of `CanonicalOverwrite`.

      Note: Like many other mixin annotations, the transformer can differ between explicitly setting the value to `@Desc("")` and not setting the value at all. This is because javac omits undefined element values and ignores the default value. The default value advertised here is only required due to how optional elements need to be defined in java source code but truth be told there is no such default value in practice.

      Returns:
        The method to overwrite.
      Default:
        @org.spongepowered.asm.mixin.injection.Desc("")