Package org.stianloader.micromixin.transform.api

## Class SlicedInjectionPointSelector

- java.lang.Object
- - org.stianloader.micromixin.transform.api.SlicedInjectionPointSelector

-     public class SlicedInjectionPointSelector
      extends java.lang.Object

- - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `SlicedInjectionPointSelector​(InjectionPointSelector selector, SlicedInjectionPointSelector from, SlicedInjectionPointSelector to, int shift, boolean unsafe)` |

  - ### Method Summary

    All Methods Instance Methods Concrete Methods Deprecated Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `org.objectweb.asm.tree.AbstractInsnNode` | `getFirstInsn​(org.objectweb.asm.tree.MethodNode method, SimpleRemapper remapper, java.lang.StringBuilder sharedBuilder)` | Obtains the first `AbstractInsnNode` that corresponds to the first applicable entrypoint within the provided method as defined by this `InjectionPointSelector`.
    `java.util.Collection<? extends org.objectweb.asm.tree.AbstractInsnNode>` | `getMatchedInstructions​(org.objectweb.asm.tree.MethodNode method, SimpleRemapper remapper, java.lang.StringBuilder sharedBuilder)` | Obtains the `AbstractInsnNodes` that correspond to every applicable entrypoint within the provided method as defined by this `SlicedInjectionPointSelector`.
    `int` | `getOffset()` | The offset (also commonly referred to as "shift") that the sliced injection point selector has compared to the target provided by the origin `InjectionPointSelector`.
    `java.lang.String` | `getQualifiedSelectorName()` | Obtains the fully qualified name of the selector that is backing this `SlicedInjectionPointSelector` as per `InjectionPointSelector.fullyQualifiedName`.
    `boolean` | `isUnsafe()` | Get whether this `SlicedInjectionPointSelector` allows use in an unsafe context, that is whether it can match instructions that when they are transformed unsafe behaviour could be the result therein.
    `boolean` | `supportsInstanceCaptureInConstructors()` | Whether to support the usage of implicitly capturing the local variable '`this`' while injecting into a constructor.
    `boolean` | `supportsRedirect()` | Deprecated. Redirect in theory (not implemented in micromixin-transformer as of now) also supports redirecting PUTFIELD/GETFIELD, PUTSTATIC/GETStATIC, xALOAD and the ARRAYLENGTH instructions.
    `java.lang.String` | `toString()` |
    `void` | `verifySlices​(java.util.Queue<java.lang.String> path, org.objectweb.asm.tree.MethodNode method, SimpleRemapper remapper, java.lang.StringBuilder sharedBuilder)` | Verify the integrity of a sliced injection point selector.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Constructor Detail

    - #### SlicedInjectionPointSelector

          public SlicedInjectionPointSelector​(@NotNull
                                              InjectionPointSelector selector,
                                              @Nullable
                                              SlicedInjectionPointSelector from,
                                              @Nullable
                                              SlicedInjectionPointSelector to,
                                              int shift,
                                              boolean unsafe)

  - ### Method Detail

    - #### getFirstInsn

          @Nullable
          public org.objectweb.asm.tree.AbstractInsnNode getFirstInsn​(@NotNull
                                                                      org.objectweb.asm.tree.MethodNode method,
                                                                      @NotNull
                                                                      SimpleRemapper remapper,
                                                                      @NotNull
                                                                      java.lang.StringBuilder sharedBuilder)

      Obtains the first `AbstractInsnNode` that corresponds to the first applicable entrypoint within the provided method as defined by this `InjectionPointSelector`. The `AbstractInsnNode` may not be virtual, that is it may not have an `opcode` value of -1.

      Implementations of this method are trusted to not go out of bounds when it comes to the slices. Failure to do so could have nasty consequences for user behaviour as micromixin-transformer or any other caller is not guaranteed to verify the location of the matched instruction (but inversely it is not guaranteed that such as check won't be introduced in the future).

      Parameters:
        `method` - The method to find the entrypoints in.
        `remapper` - The remapper instance to make use of. This is used to remap any references of the mixin class to the target class when applying injection point constraints.
        `sharedBuilder` - Shared `StringBuilder` instance to reduce `StringBuilder` allocations.
      Returns:
        The first matched instruction, or null if no instructions match.

    - #### getMatchedInstructions

          @NotNull
          public java.util.Collection<? extends org.objectweb.asm.tree.AbstractInsnNode> getMatchedInstructions​(@NotNull
                                                                                                                org.objectweb.asm.tree.MethodNode method,
                                                                                                                @NotNull
                                                                                                                SimpleRemapper remapper,
                                                                                                                @NotNull
                                                                                                                java.lang.StringBuilder sharedBuilder)

      Obtains the `AbstractInsnNodes` that correspond to every applicable entrypoint within the provided method as defined by this `SlicedInjectionPointSelector`.

      Implementations of this method are trusted to not go out of bounds when it comes to the slices. Failure to do so could have nasty consequences for user behaviour as micromixin-transformer or any other caller is not guaranteed to verify the location of the matched instructions (but inversely it is not guaranteed that such as check won't be introduced in the future).

      Parameters:
        `method` - The method to find the entrypoints in.
        `remapper` - The remapper instance to make use of. This is used to remap any references of the mixin class to the target class when applying injection point constraints.
        `sharedBuilder` - Shared `StringBuilder` instance to reduce `StringBuilder` allocations.
      Returns:
        The selected instruction nodes that correspond to this entry point.

    - #### getOffset

          @Contract(pure=true)
          public int getOffset()

      The offset (also commonly referred to as "shift") that the sliced injection point selector has compared to the target provided by the origin `InjectionPointSelector`.

      This offset is counted in "real" instructions. A positive value means that the injection point is `offset` instructions after the instruction initially targeted by the `selector`. A negative value means that the instruction of the `SlicedInjectionPointSelector` is shifted before the instruction of `selector`. An offset of 0 means no shift occurs. Real instructions are instructions where `AbstractInsnNode.getOpcode()` is a value above 0.

      The offset does not have any effect on the slices at this point in time, but this behaviour could change in the future if deemed necessary. Note: The offset of the slices themselves do still matter.

      Returns:
        The shift of this `SlicedInjectionPointSelector` from the underlying `injection point selector`
      Since:
        0.6.0

    - #### getQualifiedSelectorName

          @NotNull
          @Contract(pure=true)
          public java.lang.String getQualifiedSelectorName()

      Obtains the fully qualified name of the selector that is backing this `SlicedInjectionPointSelector` as per `InjectionPointSelector.fullyQualifiedName`.

      Note that the fully qualified name of the selectors that mark the `from` and `to` selectors are considered irrelevant. Further, `getOffset()` and `isUnsafe()` are ignored in the fully qualified name. As such, the returned string is insufficient of clearly denoting which @At annotation this `SlicedInjectionPointSelector` belongs to.

      Returns:
        The `fully qualified name` of the injection point selector used by this instance.
      Since:
        0.6.0

    - #### isUnsafe

          @Contract(pure=true)
          public boolean isUnsafe()

      Get whether this `SlicedInjectionPointSelector` allows use in an unsafe context, that is whether it can match instructions that when they are transformed unsafe behaviour could be the result therein.

      Unsafe injection points generally refer to injection points targeting instructions within the constructor before the final `RETURN` instruction, meaning that only the `TAIL` injection point can safely target instructions in a constructor while also capturing the `this` instance. All other injection points must set the unsafe flag in order to correctly target a constructor and capture the 'this' instance while doing so.

      If a injection point selector targets an unsafe instruction while not being allowed to do so via `isUnsafe()`, then an error will be emitted.

      Returns:
        True if unsafe targets are permitted, false otherwise.
      Since:
        0.6.0

    - #### supportsInstanceCaptureInConstructors

          public boolean supportsInstanceCaptureInConstructors()

      Whether to support the usage of implicitly capturing the local variable '`this`' while injecting into a constructor. In other terms, if this method returns `false`, then the handler method for this annotation must be `static` if the handler method injects into the `<init;gt;` method (i.e. the constructor).

      If this method returns true, then the handler method can still be `static`, but it being so is not required.

      The main reason this behaviour exists is because partially initialized instances shouldn't be leaked and in some cases (e.g. when injecting before the superconstructor) plainly cannot be leaked.

      By default, the final `RETURN` instruction is assumed to be the only point in time where an object is fully initialized, and henceforth only the `TAIL` injection point will be treated as a safe injection point. However, this method may still return `true` if `the selector's unsafe flag` is set.

      Returns:
        True to allow non-static handlers targeting constructors, false otherwise.
      Since:
        0.6.2

    - #### supportsRedirect

          @Deprecated
          @ScheduledForRemoval
          @Internal
          public boolean supportsRedirect()

      Deprecated.
      Redirect in theory (not implemented in micromixin-transformer as of now) also supports redirecting PUTFIELD/GETFIELD, PUTSTATIC/GETStATIC, xALOAD and the ARRAYLENGTH instructions. Added with the introduction of slices which make the semantics of the matched instruction type less predictable at first glance, this method has little sense going forward.
      WARNING WARNING WARNING The method was deprecated for removal in the 0.6.X lifecycle and will get removed at an unspecified point in time (this might fall within the 0.7.X lifecycle!). This method is no longer considered to be part of the public API.

      Checks whether the injection point can be used in conjunction with the Redirect-annotation. Generally should only be true if this injection point selector can select method instruction nodes.

      Returns:
        True if usable in redirects, false otherwise.

    - #### toString

          @NotNull
          public java.lang.String toString()

      Overrides:
        `toString` in class `java.lang.Object`

    - #### verifySlices

          public void verifySlices​(@NotNull
                                   java.util.Queue<java.lang.String> path,
                                   @NotNull
                                   org.objectweb.asm.tree.MethodNode method,
                                   @NotNull
                                   SimpleRemapper remapper,
                                   @NotNull
                                   java.lang.StringBuilder sharedBuilder)

      Verify the integrity of a sliced injection point selector. At the core this method is responsible for ensuring that the 'from' and the 'to' injection points exist and are in a valid order - that is 'to' may not match an instruction before 'from'.

      If the `SlicedInjectionPointSelector` is not valid, then an exception is thrown with adequate information that ensures that the root cause can be properly traced back or otherwise debugged adequately.

      Parameters:
        `path` - A LIFO `Queue` storing the path to this `SlicedInjectionPointSelector`, used to produce the debug message in case of a crash
        `method` - The `MethodNode` that should be probed by the `SlicedInjectionPointSelector`.
        `remapper` - A `SimpleRemapper` instance. This is used to remap any references of the mixin class to the target class when applying injection point constraints.
        `sharedBuilder` - Shared `StringBuilder` instance to reduce `StringBuilder` allocations.
      Throws:
        `java.lang.IllegalStateException` - If the validation fails.