diff --git a/checkstyle.xml b/checkstyle.xml index 534f91c5d..6ba29b3a9 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -12,7 +12,6 @@ - @@ -31,9 +30,7 @@ - - - + @@ -146,9 +143,9 @@ + - diff --git a/gradle.properties b/gradle.properties index 19f5622d9..da067e16b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ packaging=jar description=Mixin url=https://www.spongepowered.org organization=SpongePowered -buildVersion=0.7.8 +buildVersion=0.7.9 buildType=SNAPSHOT diff --git a/src/ap/java/org/spongepowered/tools/obfuscation/AnnotatedMixinElementHandlerAccessor.java b/src/ap/java/org/spongepowered/tools/obfuscation/AnnotatedMixinElementHandlerAccessor.java index 9f3c55230..71c6fae85 100644 --- a/src/ap/java/org/spongepowered/tools/obfuscation/AnnotatedMixinElementHandlerAccessor.java +++ b/src/ap/java/org/spongepowered/tools/obfuscation/AnnotatedMixinElementHandlerAccessor.java @@ -156,6 +156,11 @@ public AnnotatedMixinElementHandlerAccessor(IMixinAnnotationProcessor ap, Annota public ReferenceMapper getReferenceMapper() { return null; } + + @Override + public String getClassName() { + return this.mixin.getClassRef().replace('/', '.'); + } @Override public String getClassRef() { diff --git a/src/main/java/org/spongepowered/asm/launch/MixinBootstrap.java b/src/main/java/org/spongepowered/asm/launch/MixinBootstrap.java index 39d6dd049..e47428bfb 100644 --- a/src/main/java/org/spongepowered/asm/launch/MixinBootstrap.java +++ b/src/main/java/org/spongepowered/asm/launch/MixinBootstrap.java @@ -60,7 +60,7 @@ public abstract class MixinBootstrap { /** * Subsystem version */ - public static final String VERSION = "0.7.8"; + public static final String VERSION = "0.7.9"; /** * Log all the things diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/InjectionPoint.java b/src/main/java/org/spongepowered/asm/mixin/injection/InjectionPoint.java index 7300e848b..eb8284475 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/InjectionPoint.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/InjectionPoint.java @@ -215,6 +215,22 @@ public Selector getSelector() { public String getId() { return this.id; } + + /** + * Runs a priority check in the context of this injection point. A priority + * check should return true if the injection point is allowed to + * inject given the relative priorities of the target (a method + * merged by another mixin with targetPriority) and the incoming + * mixin with priority mixinPriority. + * + * @param targetPriority Priority of the mixin which originally merged the + * target method in question + * @param mixinPriority Priority of the mixin which owns the owning injector + * @return true if the priority check succeeds + */ + public boolean checkPriority(int targetPriority, int mixinPriority) { + return targetPriority < mixinPriority; + } /** * Find injection points in the supplied insn list diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/code/Injector.java b/src/main/java/org/spongepowered/asm/mixin/injection/code/Injector.java index 0b06e901b..54c5b04fc 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/code/Injector.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/code/Injector.java @@ -51,6 +51,7 @@ import org.spongepowered.asm.mixin.injection.struct.Target; import org.spongepowered.asm.mixin.injection.struct.InjectionNodes.InjectionNode; import org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException; +import org.spongepowered.asm.mixin.refmap.IMixinContext; import org.spongepowered.asm.mixin.transformer.ClassInfo; import org.spongepowered.asm.util.Bytecode; @@ -214,12 +215,21 @@ public final void inject(Target target, List nodes) { * @return Target insn nodes in the target method */ private Collection findTargetNodes(InjectorTarget injectorTarget, List injectionPoints) { + IMixinContext mixin = this.info.getContext(); MethodNode method = injectorTarget.getMethod(); Map targetNodes = new TreeMap(); Collection nodes = new ArrayList(32); - + for (InjectionPoint injectionPoint : injectionPoints) { nodes.clear(); + + if (injectorTarget.isMerged() + && !mixin.getClassName().equals(injectorTarget.getMergedBy()) + && !injectionPoint.checkPriority(injectorTarget.getMergedPriority(), mixin.getPriority())) { + throw new InvalidInjectionException(this.info, String.format( + "%s on %s with priority %d cannot inject into %s merged by %s with priority %d", injectionPoint, this, mixin.getPriority(), + injectorTarget, injectorTarget.getMergedBy(), injectorTarget.getMergedPriority())); + } if (this.findTargetNodes(method, injectionPoint, injectorTarget.getSlice(injectionPoint), nodes)) { for (AbstractInsnNode insn : nodes) { diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/code/InjectorTarget.java b/src/main/java/org/spongepowered/asm/mixin/injection/code/InjectorTarget.java index a9ca082bb..3d45dbf12 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/code/InjectorTarget.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/code/InjectorTarget.java @@ -27,10 +27,14 @@ import java.util.HashMap; import java.util.Map; +import org.spongepowered.asm.lib.tree.AnnotationNode; import org.spongepowered.asm.lib.tree.InsnList; import org.spongepowered.asm.lib.tree.MethodNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfig; import org.spongepowered.asm.mixin.injection.InjectionPoint; import org.spongepowered.asm.mixin.injection.struct.Target; +import org.spongepowered.asm.mixin.transformer.meta.MixinMerged; +import org.spongepowered.asm.util.Annotations; /** * Couples {@link MethodSlice method slices} to a {@link Target} for injection @@ -52,6 +56,10 @@ public class InjectorTarget { * Target method data */ private final Target target; + + private final String mergedBy; + + private final int mergedPriority; /** * ctor @@ -62,6 +70,15 @@ public class InjectorTarget { public InjectorTarget(ISliceContext context, Target target) { this.context = context; this.target = target; + + AnnotationNode merged = Annotations.getVisible(target.method, MixinMerged.class); + this.mergedBy = Annotations.getValue(merged, "mixin"); + this.mergedPriority = Annotations.getValue(merged, "priority", IMixinConfig.DEFAULT_PRIORITY); + } + + @Override + public String toString() { + return this.target.toString(); } /** @@ -78,6 +95,29 @@ public MethodNode getMethod() { return this.target.method; } + /** + * Get whether this target method was merged by another mixin + */ + public boolean isMerged() { + return this.mergedBy != null; + } + + /** + * Get the name of the mixin which merged this method, returns null for non- + * mixin methods + */ + public String getMergedBy() { + return this.mergedBy; + } + + /** + * Get the priority of the mixin which merged this method, or default + * priority for non-mixin methods + */ + public int getMergedPriority() { + return this.mergedPriority; + } + /** * Get the slice instructions for the specified slice id * diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeFinalReturn.java b/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeFinalReturn.java index 961641908..3d41aa4f7 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeFinalReturn.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeFinalReturn.java @@ -65,6 +65,11 @@ public BeforeFinalReturn(InjectionPointData data) { this.context = data.getContext(); } + + @Override + public boolean checkPriority(int targetPriority, int ownerPriority) { + return true; + } @Override public boolean find(String desc, InsnList insns, Collection nodes) { diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeReturn.java b/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeReturn.java index a704ec1c3..41c2ef447 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeReturn.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeReturn.java @@ -78,6 +78,11 @@ public BeforeReturn(InjectionPointData data) { this.ordinal = data.getOrdinal(); } + + @Override + public boolean checkPriority(int targetPriority, int ownerPriority) { + return true; + } @Override public boolean find(String desc, InsnList insns, Collection nodes) { diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/points/MethodHead.java b/src/main/java/org/spongepowered/asm/mixin/injection/points/MethodHead.java index 5761cd18a..172a6948a 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/points/MethodHead.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/points/MethodHead.java @@ -49,6 +49,11 @@ public class MethodHead extends InjectionPoint { public MethodHead(InjectionPointData data) { super(data); } + + @Override + public boolean checkPriority(int targetPriority, int ownerPriority) { + return true; + } @Override public boolean find(String desc, InsnList insns, Collection nodes) { diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/struct/InjectionInfo.java b/src/main/java/org/spongepowered/asm/mixin/injection/struct/InjectionInfo.java index 179c3ee75..4f02efd84 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/struct/InjectionInfo.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/struct/InjectionInfo.java @@ -430,17 +430,9 @@ private void checkTarget(MethodNode target) { return; } - String owner = Annotations.getValue(merged, "mixin"); - int priority = Annotations.getValue(merged, "priority"); - - if (priority >= this.mixin.getPriority() && !owner.equals(this.mixin.getClassName())) { - throw new InvalidInjectionException(this, String.format("%s cannot inject into %s::%s%s merged by %s with priority %d", this, - this.classNode.name, target.name, target.desc, owner, priority)); - } - if (Annotations.getVisible(target, Final.class) != null) { throw new InvalidInjectionException(this, String.format("%s cannot inject into @Final method %s::%s%s merged by %s", this, - this.classNode.name, target.name, target.desc, owner)); + this.classNode.name, target.name, target.desc, Annotations.getValue(merged, "mixin"))); } } diff --git a/src/main/java/org/spongepowered/asm/mixin/refmap/IMixinContext.java b/src/main/java/org/spongepowered/asm/mixin/refmap/IMixinContext.java index b523fc867..e0935d946 100644 --- a/src/main/java/org/spongepowered/asm/mixin/refmap/IMixinContext.java +++ b/src/main/java/org/spongepowered/asm/mixin/refmap/IMixinContext.java @@ -44,6 +44,13 @@ public interface IMixinContext { * Get the mixin transformer extension manager */ public abstract Extensions getExtensions(); + + /** + * Get the mixin class name + * + * @return the mixin class name + */ + public abstract String getClassName(); /** * Get the internal mixin class name diff --git a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java index 33ec75e7f..6812c9522 100644 --- a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java +++ b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java @@ -288,6 +288,7 @@ public ClassNode getClassNode() { * * @return the mixin class name */ + @Override public String getClassName() { return this.mixin.getClassName(); }