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();
}