Annotation Interface ModifyArgs
method()
.
This type of injector provides a powerful but inefficient method for
modifying multiple arguments of a method at once without making use of a
Redirect
injector. In general it is better to use redirectors where
possible, however this type of injector can also function where Redirect
cannot, such as modifying arguments of a super-constructor call. To
modify a single method argument, use ModifyArg
instead.
This injector works by creating an argument bundle in the form of
Args
which is passed to your handler method. You can manipulate the
method arguments via the bundle in your handler method. The bundle is then
unpacked and the original subject method is called with the modified
arguments.
Since the argument bundle is created for every invocation of the target method, and primitive types must undergo boxing and unboxing, this injector is intrinsically less efficient than other methods. However for certain uses this injector is more powerful:
- For modifying arguments of a superconstructor call, it would normally
be necessary to employ multiple
ModifyArg
callbacks (one for each argument you wish to modify). However access to the enclosing scope is not provided byModifyArg
, which can be problematic. - This injector can be used to target multiple methods with differing argument types and counts.
Methods decorated with this injector should return void and consume either:
-
Required Element Summary
Required ElementsModifier and TypeRequired ElementDescriptionAnAt
annotation which describes theInjectionPoint
in the target method. -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionint
Injection points are in general expected to match every candidate instruction in the target method or slice, except in cases where options such asAt.ordinal()
are specified which naturally limit the number of results.Returns constraints which must be validated for this injector to succeed.int
Likerequire()
but only enabled if themixin.debug.countInjections
option is set to true and defaults to 1.String[]
String representation of one or moretarget selectors
which identify the target methods.boolean
By default, the annotation processor will attempt to locate an obfuscation mapping for allModifyArgs
methods since it is anticipated that in general the target of aModifyArgs
annotation will be an obfuscated method in the target class.int
In general, injectors are intended to "fail soft" in that a failure to locate the injection point in the target method is not considered an error condition.Desc[]
Literal representation of one or more@Desc
annotations which identify the target methods.
-
Element Details
-
at
At atAnAt
annotation which describes theInjectionPoint
in the target method. The specifiedInjectionPoint
must only returnMethodInsnNode
instances and an exception will be thrown if this is not the case.- Returns:
At
which identifies the target method invocation
-
-
-
method
String[] methodString representation of one or moretarget selectors
which identify the target methods.- Returns:
- target method(s) for this injector
- Default:
- {}
-
target
Desc[] targetLiteral representation of one or more@Desc
annotations which identify the target methods.- Returns:
- target method(s) for this injector as descriptors
- Default:
- {}
-
slice
Slice slice- Returns:
- slice
- Default:
- @org.spongepowered.asm.mixin.injection.Slice
-
remap
boolean remapBy default, the annotation processor will attempt to locate an obfuscation mapping for allModifyArgs
methods since it is anticipated that in general the target of aModifyArgs
annotation will be an obfuscated method in the target class. However since it is possible to also apply mixins to non-obfuscated targets (or non- obfuscated methods in obfuscated targets, such as methods added by Forge) 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
-
require
int requireIn general, injectors are intended to "fail soft" in that a failure to locate the injection point in the target method is not considered an error condition. Another transformer may have changed the method structure or any number of reasons may cause an injection to fail. This also makes it possible to define several injections to achieve the same task given expected mutation of the target class and the injectors which fail are simply ignored.However, this behaviour is not always desirable. For example, if your application depends on a particular injection succeeding you may wish to detect the injection failure as an error condition. This argument is thus provided to allow you to stipulate a minimum number of successful injections for this callback handler. If the number of injections specified is not achieved then an
InjectionError
is thrown at application time. Use this option with care.- Returns:
- Minimum required number of injected callbacks, default specified by the containing config
- Default:
- -1
-
expect
int expectLikerequire()
but only enabled if themixin.debug.countInjections
option is set to true and defaults to 1. Use this option during debugging to perform simple checking of your injectors. Causes the injector to throw aInvalidInjectionException
if the expected number of injections is not realised.- Returns:
- Minimum number of expected callbacks, default 1
- Default:
- 1
-
allow
int allowInjection points are in general expected to match every candidate instruction in the target method or slice, except in cases where options such asAt.ordinal()
are specified which naturally limit the number of results.This option allows for sanity-checking to be performed on the results of an injection point by specifying a maximum allowed number of matches, similar to that afforded by
Group.max()
. For example if your injection is expected to match 4 invocations of a target method, but instead matches 5, this can become a detectable tamper condition by setting this value to 4.Setting any value 1 or greater is allowed. Values less than 1 or less than
require()
are ignored.require()
supercedes this argument such that if allow is less than require the value of require is always used.Note that this option is not a limit on the query behaviour of this injection point. It is only a sanity check used to ensure that the number of matches is not too high
- Returns:
- Maximum allowed number of injections for this
- Default:
- -1
-
constraints
String constraintsReturns constraints which must be validated for this injector to succeed. SeeConstraintParser.Constraint
for details of constraint formats.- Returns:
- Constraints for this annotation
- Default:
- ""
-