Skip to content

Commit

Permalink
Apply injectors in discrete phases, ensure Redirects always go last(ish)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mumfrey committed May 18, 2024
1 parent 0816867 commit a2751aa
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,7 @@ public static enum Feature {
/**
* Support for the use of injector annotations in interface mixins
*/
INJECTORS_IN_INTERFACE_MIXINS(false) {
INJECTORS_IN_INTERFACE_MIXINS {

@Override
public boolean isAvailable() {
Expand All @@ -1109,6 +1109,10 @@ public boolean isEnabled() {
*/
private boolean enabled;

private Feature() {
this(false);
}

private Feature(boolean enabled) {
this.enabled = enabled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import org.spongepowered.asm.mixin.injection.code.Injector;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.AnnotationType;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.InjectorOrder;
import org.spongepowered.asm.mixin.transformer.MixinTargetContext;
import org.spongepowered.asm.util.Annotations;

Expand All @@ -40,6 +41,7 @@
* Information about a callback to inject, usually specified by {@link Inject}
*/
@AnnotationType(Inject.class)
@InjectorOrder(InjectorOrder.BUILTIN_CALLBACKS)
public class CallbackInjectionInfo extends InjectionInfo {

protected CallbackInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,110 @@ public abstract class InjectionInfo extends SpecialMethodInfo implements ISliceC
@java.lang.annotation.Target(ElementType.TYPE)
public @interface HandlerPrefix {

/**
* Default conform prefix for handler methods
*/
public static final String DEFAULT = "handler";

/**
* String prefix for conforming handler methods
*/
public String value();

}

/**
* Decoration for subclasses which specifies the order (phase) in which the
* injector should be applied relative to other injectors. Built-in
* injectors all have predefined orders which allows custom injectors to
* specify their own order either as an explicit priority (eg. LATE) or
* relative to a known injector (eg. InjectorOrder.BUILTIN_REDIRECT - 100).
*
* <p>Built-in injectors are grouped into three separate phases rather than
* split into individual phases, in order to retain the existing behaviour
* of mixin priority. Injectors in the same order are sorted by mixin
* priority and declaration order within the mixin as always.</p>
*/
@Retention(RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(ElementType.TYPE)
public @interface InjectorOrder {

/**
* The lowest possible order, avoid using this unlesss you are insane
*/
public static final int FIRST = Integer.MIN_VALUE;

/**
* A very early injector, will run before injectors such as ModifyArgs
* and ModifyVariable, as well as before EARLY injectors
*/
public static final int VERY_EARLY = 100;

/**
* An early injector, will run before injectors suchs as ModifyArgs
* and ModifyVariable
*/
public static final int EARLY = 250;

/**
* Built-in order for ModifyArg injectors
*/
public static final int BUILTIN_MODIFYARG = 500;

/**
* Built-in order for ModifyArgs injectors
*/
public static final int BUILTIN_MODIFYARGS = 500;

/**
* Built-in order for ModifyVariable injectors
*/
public static final int BUILTIN_MODIFYVARIABLE = 500;

/**
* Default order
*/
public static final int DEFAULT = 1000;

/**
* Built-in order for Inject injectors
*/
public static final int BUILTIN_CALLBACKS = 1000;

/**
* Late injector, runs after most injectors except VERY_LATE and
* Redirect injectors
*/
public static final int LATE = 2000;

/**
* Built-in order for ModifyConstant injectors
*/
public static final int BUILTIN_MODIFYCONSTANT = 5000;

/**
* Built-in order for Redirect injectors
*/
public static final int BUILTIN_REDIRECT = 5000;

/**
* Very late injector, runs after nearly all injectors including
* Redirect injectors
*/
public static final int VERY_LATE = 10000;

/**
* The highest possible order, using this causes the universe to
* implode, bringing about the end of days.
*/
public static final int LAST = Integer.MAX_VALUE;

/**
* String prefix for conforming handler methods
*/
public int value() default InjectorOrder.DEFAULT;

}

/**
* An injector registration entry
Expand All @@ -137,7 +235,7 @@ static class InjectorEntry {
this.annotationDesc = Type.getDescriptor(annotationType);

HandlerPrefix handlerPrefix = type.<HandlerPrefix>getAnnotation(HandlerPrefix.class);
this.prefix = handlerPrefix != null ? handlerPrefix.value() : InjectionInfo.DEFAULT_PREFIX;
this.prefix = handlerPrefix != null ? handlerPrefix.value() : HandlerPrefix.DEFAULT;
}

InjectionInfo create(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand All @@ -156,11 +254,6 @@ InjectionInfo create(MixinTargetContext mixin, MethodNode method, AnnotationNode
}
}

/**
* Default conform prefix for handler methods
*/
public static final String DEFAULT_PREFIX = "handler";

/**
* Registry of subclasses
*/
Expand Down Expand Up @@ -387,6 +480,14 @@ public boolean isValid() {
return this.targets.size() > 0 && this.injectionPoints.size() > 0;
}

/**
* Get the application order for this injector type
*/
public int getOrder() {
InjectorOrder injectorOrder = this.getClass().<InjectorOrder>getAnnotation(InjectorOrder.class);
return injectorOrder != null ? injectorOrder.value() : InjectorOrder.DEFAULT;
}

/**
* Discover injection points
*/
Expand Down Expand Up @@ -624,7 +725,7 @@ public static AnnotationNode getInjectorAnnotation(IMixinInfo mixin, MethodNode
*/
public static String getInjectorPrefix(AnnotationNode annotation) {
if (annotation == null) {
return InjectionInfo.DEFAULT_PREFIX;
return HandlerPrefix.DEFAULT;
}

for (InjectorEntry injector : InjectionInfo.registry.values()) {
Expand All @@ -633,7 +734,7 @@ public static String getInjectorPrefix(AnnotationNode annotation) {
}
}

return InjectionInfo.DEFAULT_PREFIX;
return HandlerPrefix.DEFAULT;
}

static String describeInjector(IMixinContext mixin, AnnotationNode annotation, MethodNode method) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.spongepowered.asm.mixin.injection.invoke.ModifyArgInjector;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.AnnotationType;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.HandlerPrefix;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.InjectorOrder;
import org.spongepowered.asm.mixin.transformer.MixinTargetContext;
import org.spongepowered.asm.util.Annotations;

Expand All @@ -39,6 +40,7 @@
*/
@AnnotationType(ModifyArg.class)
@HandlerPrefix("modify")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYARG)
public class ModifyArgInjectionInfo extends InjectionInfo {

public ModifyArgInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
import org.spongepowered.asm.mixin.injection.invoke.ModifyArgsInjector;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.AnnotationType;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.HandlerPrefix;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.InjectorOrder;
import org.spongepowered.asm.mixin.transformer.MixinTargetContext;

/**
* Information about a {@link ModifyArgs} injector
*/
@AnnotationType(ModifyArgs.class)
@HandlerPrefix("args")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYARG)
public class ModifyArgsInjectionInfo extends InjectionInfo {

public ModifyArgsInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.spongepowered.asm.mixin.injection.points.BeforeConstant;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.AnnotationType;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.HandlerPrefix;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.InjectorOrder;
import org.spongepowered.asm.mixin.transformer.MixinTargetContext;

import com.google.common.base.Strings;
Expand All @@ -45,6 +46,7 @@
*/
@AnnotationType(ModifyConstant.class)
@HandlerPrefix("constant")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYCONSTANT)
public class ModifyConstantInjectionInfo extends InjectionInfo {

private static final String CONSTANT_ANNOTATION_CLASS = Constant.class.getName().replace('.', '/');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
import org.spongepowered.asm.mixin.injection.modify.ModifyVariableInjector;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.AnnotationType;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.HandlerPrefix;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.InjectorOrder;
import org.spongepowered.asm.mixin.transformer.MixinTargetContext;

/**
* Information about a {@link ModifyVariable} injector
*/
@AnnotationType(ModifyVariable.class)
@HandlerPrefix("localvar")
@InjectorOrder(InjectorOrder.BUILTIN_MODIFYVARIABLE)
public class ModifyVariableInjectionInfo extends InjectionInfo {

public ModifyVariableInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
import org.spongepowered.asm.mixin.injection.invoke.RedirectInjector;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.AnnotationType;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.HandlerPrefix;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo.InjectorOrder;
import org.spongepowered.asm.mixin.transformer.MixinTargetContext;

/**
* Information about a redirector injector
*/
@AnnotationType(Redirect.class)
@HandlerPrefix("redirect")
@InjectorOrder(InjectorOrder.BUILTIN_REDIRECT)
public class RedirectInjectionInfo extends InjectionInfo {

public RedirectInjectionInfo(MixinTargetContext mixin, MethodNode method, AnnotationNode annotation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ protected void prepareInjections(MixinTargetContext mixin) {
/* (non-Javadoc)
* @see org.spongepowered.asm.mixin.transformer.MixinApplicator
* #applyInjections(
* org.spongepowered.asm.mixin.transformer.MixinTargetContext)
* org.spongepowered.asm.mixin.transformer.MixinTargetContext, int)
*/
@Override
protected void applyInjections(MixinTargetContext mixin) {
protected void applyInjections(MixinTargetContext mixin, int injectorOrder) {
if (Feature.INJECTORS_IN_INTERFACE_MIXINS.isEnabled()) {
super.applyInjections(mixin);
super.applyInjections(mixin, injectorOrder);
return;
}
}
Expand Down
Loading

0 comments on commit a2751aa

Please sign in to comment.