Package org.spongepowered.asm.mixin.injection

## Annotation Type At

    @Target({})
    @Retention(RUNTIME)
    public @interface At

Annotation for specifying the type of `InjectionPoint` to use to perform an `Inject` process. This annotation allows the `InjectionPoint` class to be specified, as well as arguments to be passed to the `InjectionPoint` instance to configure it. The data contained in the annotation are wrapped into a `InjectionInfo` object before being passed to the `InjectionPoint` for parsing. All values are optional apart from `value()`, which specifies the type of `InjectionPoint` to use. All other parameters depend on the InjectionPoint chosen, and the javadoc for each `InjectionPoint` class should be consulted for the meaning of the argument to that particular class. A general description of each parameter is provided below.

### Required Element Summary

Required Elements
`java.lang.String` `value` Type of `InjectionPoint` to use.

### Optional Element Summary

Optional Elements
`java.lang.String[]` `args` The named arguments list is used to expand the scope of the annotation beyond the fixed values below in order to accommodate the needs of custom injection point classes.
`int` `by` If `shift()` is specified as `BY`, specifies the number of opcodes to shift by (negative numbers are allowed).
`Desc` `desc` Target descriptor used in place of string-based descriptors for `target()`
`java.lang.String` `id` The identifier for this injection point, can be retrieved via the `CallbackInfo.getId()` accessor.
`int` `opcode` Target opcode for FIELD and JUMP InjectionPoints.
`int` `ordinal` Ordinal offset.
`boolean` `remap` By default, the annotation processor will attempt to locate an obfuscation mapping for the `target()` member and any other `args()` known to contain potentially obfuscated references, since it is anticipated that in general the target of an `At` annotation will be an obfuscated method or field.
`At.Shift` `shift` Shift type for returned opcodes.
`java.lang.String` `slice` For `Inject` queries, this specifies the ID of the slice to use for this query.
`java.lang.String` `target` Target identifier used by INVOKE, INVOKE_STRING, INVOKE_ASSIGN, FIELD and NEW.

`boolean`

`unsafe`

In general, injecting into constructors should be treated with care, since compiled constructors - unlike regular methods - contain other structural elements of the class, including implied (when not explicit) superconstructor calls, explicit superconstructor or other delegated constructor calls, field initialisers and code from initialiser blocks, and of course the code from the original "constructor".

### Element Detail

#### value

    java.lang.String value

Type of `InjectionPoint` to use. Can be a built-in class or the fully-qualified name of a custom class which extends `InjectionPoint`.

Built-in types are `HEAD`, `RETURN`, `TAIL`, `INVOKE`, `INVOKE_ASSIGN`, `FIELD`, `NEW`, `INVOKE_STRING`, `JUMP` and `CONSTANT`. See the javadoc for each type for more details on the scheme used by each injection point.

Returns:
  Injection point specifier or fully-qualified class name

#### id

    java.lang.String id

The identifier for this injection point, can be retrieved via the `CallbackInfo.getId()` accessor. If specified, the ID is appended to the value specified in the outer annotion. Eg. specifying "foo" for this attribute and "bar" for the `Inject.`Inject.id()`` attribute will result in a combined id of `"bar:foo"`. Note that if no id is specified for the outer injector, the name of the calling method is used.

Returns:
  the injection point id to use

Default:
  ""

#### slice

    java.lang.String slice

For `Inject` queries, this specifies the ID of the slice to use for this query. For other injector types it is ignored because only one slice is supported.

For more details see the `Slice.id()`

Returns:
  the slice identifier, or empty string to use the default slice

Default:
  ""

#### shift

    At.Shift shift

Shift type for returned opcodes. For example use `AFTER` with an INVOKE InjectionPoint to move the returned opcodes to after the invoation. Use `BY` in conjunction with the `by()` parameter to shift by an arbitrary number of opcodes.

Returns:
  Type of shift to apply

Default:
  org.spongepowered.asm.mixin.injection.At.Shift.NONE

#### by

    int by

If `shift()` is specified as `BY`, specifies the number of opcodes to shift by (negative numbers are allowed). Note that values above `3` should be avoided and in general either replaced with a custom injection point or with sliced injection points. The warning/error threshold is defined by the config (with a hard limit on value of `InjectionPoint.MAX_ALLOWED_SHIFT_BY`)

Returns:
  Amount of shift to apply for the `BY` shift

Default:
  0

#### args

    java.lang.String[] args

The named arguments list is used to expand the scope of the annotation beyond the fixed values below in order to accommodate the needs of custom injection point classes.

Returns:
  Named arguments for the injection point

Default:
  {}

#### target

    java.lang.String target

Target identifier used by INVOKE, INVOKE_STRING, INVOKE_ASSIGN, FIELD and NEW. This must be specified as a fully-qualified member path including the class name and signature. Failing to fully-qualify the target member will result in an error at obfuscation time.

Returns:
  target reference for supported InjectionPoint types

Default:
  ""

#### desc

    Desc desc

Target descriptor used in place of string-based descriptors for `target()`

Default:
  @org.spongepowered.asm.mixin.injection.Desc("")

#### ordinal

    int ordinal

Ordinal offset. Many InjectionPoints will return every opcode matching their criteria, specifying ordinal allows a particular opcode to be identified from the returned list. The default value of -1 does not alter the behaviour and returns all matching opcodes. Specifying a value of 0 or higher returns only the requested opcode (if one exists: for example specifying an ordinal of 4 when only 2 opcodes are matched by the InjectionPoint is not going to work particularly well!)

Returns:
  ordinal value for supported InjectionPoint types

Default:
  -1

#### opcode

    int opcode

Target opcode for FIELD and JUMP InjectionPoints. See the javadoc for the relevant injection point for more details.

Returns:
  Bytecode opcode for supported InjectionPoints

Default:
  -1

#### remap

    boolean remap

By default, the annotation processor will attempt to locate an obfuscation mapping for the `target()` member and any other `args()` known to contain potentially obfuscated references, since it is anticipated that in general the target of an `At` annotation will be an obfuscated method or field. However since it is also possible that the target is a non-obfuscated reference it may be necessary to suppress the compiler error which would otherwise be generated. Setting this value to false will cause the annotation processor to skip this annotation when attempting to build the obfuscation table for the mixin.

Returns:
  True to instruct the annotation processor to search for obfuscation mappings for this annotation

Default:
  true

#### unsafe

    boolean unsafe

In general, injecting into constructors should be treated with care, since compiled constructors - unlike regular methods - contain other structural elements of the class, including implied (when not explicit) superconstructor calls, explicit superconstructor or other delegated constructor calls, field initialisers and code from initialiser blocks, and of course the code from the original "constructor".

This means that unlike targetting a regular method, where it's often possible to derive a reasonable injection point from the Java source, in a constructor such assumptions can be dangerous. For example the `HEAD` of a regular method will always mean "before the first instruction", however in a constructor it's not possible to reasonably ascertain what the first instruction will actually be without inspecting the bytecode. This will certainly be prior to the delegate constructor call, which might come as a surprise if the delegate constructor is not explicit. Ultimately this means that for constructor code which appears before the regular constructor body, the class can be in a partially-initialised state (during initialisers) or in a fully-uninitialised state (prior to the delegate constructor call).

Because of this, by default certain injectors restrict usage to only `RETURN` opcodes when targetting a constructor, in order to ensure that the consumers are properly aware of the potential pitfalls. Whilst it was previously necessary to create a custom injection point in order to bypass this restriction, setting this option to `true` will also allow other injectors to act upon constructors, though care should be taken to ensure that the target is properly specified and attention is paid to the structure of the target bytecode.

FABRIC CHANGE: true by default.

Default:
  true