@Target(value=METHOD)
@Retention(value=RUNTIME)
public @interface Inject
method().| Modifier and Type | Required Element and Description |
|---|---|
At[] |
at
Array of
At annotations which describe the
InjectionPoints in the target method. |
java.lang.String[] |
method
String representation of one or more
MemberInfo which identify the target methods. |
| Modifier and Type | Optional Element and Description |
|---|---|
int |
allow
Injection points are in general expected to match every candidate
instruction in the target method or slice, except in cases where options
such as
At.ordinal() are specified which naturally limit the number
of results. |
boolean |
cancellable
Setting an injected callback to cancellable allows the injected
callback to inject optional RETURN opcodes into the target method, the
return behaviour can then be controlled from within the callback by
interacting with the supplied
CallbackInfo object. |
java.lang.String |
constraints
Returns constraints which must be validated for this injector to
succeed.
|
int |
expect
Like
require() but only enabled if the
mixin.debug.countInjections option is set
to true and defaults to 1. |
java.lang.String |
id
The identifier for this injector, can be retrieved via the
CallbackInfo.getId() accessor. |
LocalCapture |
locals
Specifies the local variable capture behaviour for this injector.
|
boolean |
remap
|
int |
require
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.
|
Slice[] |
slice
|
public abstract java.lang.String[] method
MemberInfo which identify the target methods.public abstract At[] at
At annotations which describe the
InjectionPoints in the target method. Allows one or more
callbacks to be injected in the target method.public abstract java.lang.String id
CallbackInfo.getId() accessor. If not specified, the ID defaults to
the target method name.public abstract boolean cancellable
CallbackInfo object.public abstract LocalCapture locals
When capturing local variables in scope, the variables are appended to
the callback invocation after the CallbackInfo argument.
Capturing local variables from the target scope requires careful planning because unlike other aspects of an injection (such as the target method name and signature), the local variable table is not safe from modification by other transformers which may be in use in the production environment. Even other injectors which target the same target method have the ability to modify the local variable table and thus it is in no way safe to assume that local variables in scope at development time will be so in production.
To provide some level of flexibility, especially where changes can be
anticipated (for example a well-known mod makes changes which result in a
particular structure for the local variable table) it is possible to
provide overloads for the handler method which will become
surrogate targets for the orphaned injector by annotating them with an
Surrogate annotation.
It is also important to nominate the failure behaviour to follow when
local capture fails and so all LocalCapture behaviours which
specify a capture action imply a particular behaviour for handling
failure. See the javadoc on the LocalCapture members for more
details.
Determining what local variables are available to you and in what
order can be somewhat tricky, and so a simple mechanism for enumerating
available locals is provided. By setting locals to
LocalCapture.PRINT, the injector writes the local capture state
to STDERR instead of injecting the callback. Using the output thus
obtained it is then a straightforward matter of altering the callback
method signature to match the signature proposed by the Callback
Injector.
public abstract boolean remap
Inject methods since it is
anticipated that in general the target of a Inject 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.public abstract int require
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.
public abstract int expect
require() but only enabled if the
mixin.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
a InvalidInjectionException if the expected number of injections
is not realised.public abstract int allow
At.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
public abstract java.lang.String constraints
ConstraintParser.Constraint for details of constraint formats.