Annotation Type At
-
@Target({}) @Retention(RUNTIME) public @interface AtAnnotation for specifying the type ofInjectionPointto use to perform anInjectprocess. This annotation allows theInjectionPointclass to be specified, as well as arguments to be passed to theInjectionPointinstance to configure it. The data contained in the annotation are wrapped into aInjectionInfoobject before being passed to theInjectionPointfor parsing. All values are optional apart fromvalue(), which specifies the type ofInjectionPointto use. All other parameters depend on the InjectionPoint chosen, and the javadoc for eachInjectionPointclass 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 Modifier and Type Required Element Description java.lang.StringvalueType ofInjectionPointto use.
-
Optional Element Summary
Optional Elements Modifier and Type Optional Element Description java.lang.String[]argsThe 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.intbyDescdescTarget descriptor used in place of string-based descriptors fortarget()java.lang.StringidThe identifier for this injection point, can be retrieved via theCallbackInfo.getId()accessor.intopcodeTarget opcode for FIELD and JUMP InjectionPoints.intordinalOrdinal offset.booleanremapAt.ShiftshiftShift type for returned opcodes.java.lang.StringsliceForInjectqueries, this specifies the ID of the slice to use for this query.java.lang.StringtargetTarget identifier used by INVOKE, INVOKE_STRING, INVOKE_ASSIGN, FIELD and NEW.booleanunsafeIn 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
InjectionPointto use. Can be a built-in class or the fully-qualified name of a custom class which extendsInjectionPoint.Built-in types are
HEAD,RETURN,TAIL,INVOKE,INVOKE_ASSIGN,FIELD,NEW,INVOKE_STRING,JUMPandCONSTANT. 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 theCallbackInfo.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
ForInjectqueries, 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 useAFTERwith an INVOKE InjectionPoint to move the returned opcodes to after the invoation. UseBYin conjunction with theby()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
Ifshift()is specified asBY, 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 ofInjectionPoint.MAX_ALLOWED_SHIFT_BY)- Returns:
- Amount of shift to apply for the
BYshift
- Default:
- 0
-
-
-
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:
- ""
-
-
-
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
-
-
-
remap
boolean remap
By default, the annotation processor will attempt to locate an obfuscation mapping for thetarget()member and any otherargs()known to contain potentially obfuscated references, since it is anticipated that in general the target of anAtannotation 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
-
-