An injection point specifies a position inside the body of a target method to operate on. Where to @Inject, which method to @Redirect, etc.

@At

Injection points are created with the @At annotation, which takes a String value consisting of one of the following:

name position target? ordinal? opcode? args?
HEAD top of a method
CTOR_HEAD top of a constructor, after initializers and super/this delegation
RETURN before a return yes
TAIL before the final return
LOAD before reading a local variable or argument yes
STORE after writing a local variable or argument yes
NEW before an object creation yes yes
INVOKE before a method invocation yes yes
INVOKE_ASSIGN after a method invocation, and after it's assigned to a local yes yes
FIELD before getting or setting a field yes yes yes
CONSTANT before a literal yes yes
INVOKE_STRING before a method invocation with a single string literal arg yes yes yes
JUMP before a jump yes yes

Each of these injection points refers to every point that matches its description. So, it's often necessary to narrow down the results with the additional specifiers I've noted at the end of the table.

It also might be necessary to shift the injection point back or forward instruction-wise. @At takes At.Shift shift, which can be AFTER, BEFORE (note that most injection points are already directly before their target. this will shift them one further), or BY, which requires the additional argument int by, an offset.

@Slice

Injection points are also used to limit the region of the body to search. The annotations that accept at = @At(…) also optionally accept slice = @Slice(from = @At(…), to = @At(…)). If present, a slice will prevent injection points outside it from being matched.