From cf72b7981903814f1a6afb5c1f9edcb9e1b7024a Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Sun, 28 Apr 2024 12:16:58 +0200 Subject: Fix party tab completion (#1571) --- .../mixins/init/BeforeForLoopInjectionPoint.java | 59 ++++++++++++++++++++++ .../skyhanni/mixins/init/SkyhanniMixinPlugin.java | 3 +- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java (limited to 'src/main/java/at/hannibal2/skyhanni/mixins/init') diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java b/src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java new file mode 100644 index 000000000..5316a8258 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java @@ -0,0 +1,59 @@ +package at.hannibal2.skyhanni.mixins.init; + +import org.spongepowered.asm.lib.Opcodes; +import org.spongepowered.asm.lib.tree.AbstractInsnNode; +import org.spongepowered.asm.lib.tree.InsnList; +import org.spongepowered.asm.lib.tree.VarInsnNode; +import org.spongepowered.asm.mixin.injection.InjectionPoint; +import org.spongepowered.asm.mixin.injection.struct.InjectionPointData; + +import java.util.Collection; + +/** + * Inject just before a for loop which iterates over a local variable containing an array. + * + *
{@code
+ * String [] s = new String[10];
+ *
+ * // <-- Injection point here
+ * for (String e : s) {
+ *
+ * }
+ * }
+ * 
+ * Does not work for more complex instructions which call functions or do other operations inside of the for loop header. + * Does not work for {@link java.util.Iterator iterators}. + * + *

Set the lvIndex arg to specify which lvIndex to search for when selecting the loop.

+ * + * + *
{@code
+ * @Inject(method = "...", at = @At(value = "SKYHANNI_FORLOOP_LOCAL_VAR", args = "lvIndex=1"))
+ * }
+ */ +@InjectionPoint.AtCode("SKYHANNI_FORLOOP_LOCAL_VAR") +public class BeforeForLoopInjectionPoint extends InjectionPoint { + private final int lvIndex; + + public BeforeForLoopInjectionPoint(InjectionPointData data) { + lvIndex = data.get("lvIndex", -1); + } + + @Override + public boolean find(String s, InsnList insnList, Collection collection) { + for (AbstractInsnNode p = insnList.getFirst(); p != null; p = p.getNext()) { + if (p.getOpcode() != Opcodes.ARRAYLENGTH) { + continue; + } + AbstractInsnNode loadLoopVar = p.getPrevious(); + if (loadLoopVar == null || loadLoopVar.getOpcode() != Opcodes.ALOAD) continue; + AbstractInsnNode storeLoopVar = loadLoopVar.getPrevious(); + if (storeLoopVar == null || storeLoopVar.getOpcode() != Opcodes.ASTORE) continue; + AbstractInsnNode loadLoopArg = storeLoopVar.getPrevious(); + if (loadLoopArg == null || loadLoopArg.getOpcode() != Opcodes.ALOAD) continue; + if (lvIndex != -1 && ((VarInsnNode) loadLoopArg).var != lvIndex) continue; + collection.add(loadLoopArg); + } + return false; + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java b/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java index 1f1b0e1fe..9dd4cc6f8 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java @@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.mixins.init; import org.spongepowered.asm.lib.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; +import org.spongepowered.asm.mixin.injection.InjectionPoint; import java.io.IOException; import java.net.MalformedURLException; @@ -21,7 +22,7 @@ import java.util.zip.ZipInputStream; public class SkyhanniMixinPlugin implements IMixinConfigPlugin { @Override public void onLoad(String mixinPackage) { - + InjectionPoint.register(BeforeForLoopInjectionPoint.class); } @Override -- cgit