User: joe
Date: 21 Jul 24 16:22
Revision: 3f2c1217554a95475dca6c60060f0dbfa6506d7a
Summary:
Implement JUMP injection point (without source navigation)
TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=9492&personal=false
Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/JumpInjectionPoint.kt
===================================================================
--- src/main/kotlin/platform/mixin/handlers/injectionPoint/JumpInjectionPoint.kt (revision 3f2c1217554a95475dca6c60060f0dbfa6506d7a)
+++ src/main/kotlin/platform/mixin/handlers/injectionPoint/JumpInjectionPoint.kt (revision 3f2c1217554a95475dca6c60060f0dbfa6506d7a)
@@ -0,0 +1,102 @@
+/*
+ * Minecraft Development for IntelliJ
+ *
+ * https://mcdev.io/
+ *
+ * Copyright (C) 2024 minecraft-dev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, version 3.0 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.demonwav.mcdev.platform.mixin.handlers.injectionPoint
+
+import com.demonwav.mcdev.platform.mixin.reference.MixinSelector
+import com.demonwav.mcdev.platform.mixin.util.findOrConstructSourceMethod
+import com.demonwav.mcdev.util.constantValue
+import com.intellij.codeInsight.lookup.LookupElementBuilder
+import com.intellij.openapi.project.Project
+import com.intellij.psi.PsiAnnotation
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiElement
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.tree.JumpInsnNode
+import org.objectweb.asm.tree.MethodNode
+
+class JumpInjectionPoint : InjectionPoint() {
+ companion object {
+ private val VALID_OPCODES = setOf(
+ Opcodes.IFEQ,
+ Opcodes.IFNE,
+ Opcodes.IFLT,
+ Opcodes.IFGE,
+ Opcodes.IFGT,
+ Opcodes.IFLE,
+ Opcodes.IF_ICMPEQ,
+ Opcodes.IF_ICMPNE,
+ Opcodes.IF_ICMPLT,
+ Opcodes.IF_ICMPGE,
+ Opcodes.IF_ICMPGT,
+ Opcodes.IF_ICMPLE,
+ Opcodes.IF_ACMPEQ,
+ Opcodes.IF_ACMPNE,
+ Opcodes.GOTO,
+ Opcodes.JSR,
+ Opcodes.IFNULL,
+ Opcodes.IFNONNULL,
+ )
+ }
+
+ override fun createNavigationVisitor(
+ at: PsiAnnotation,
+ target: MixinSelector?,
+ targetClass: PsiClass
+ ): NavigationVisitor? {
+ // TODO: jump target source navigation? This would be extremely hard
+ return null
+ }
+
+ override fun doCreateCollectVisitor(
+ at: PsiAnnotation,
+ target: MixinSelector?,
+ targetClass: ClassNode,
+ mode: CollectVisitor.Mode
+ ): CollectVisitor {
+ val opcode = (at.findDeclaredAttributeValue("opcode")?.constantValue as? Int)
+ ?.takeIf { it in VALID_OPCODES } ?: -1
+ return MyCollectVisitor(at.project, targetClass, mode, opcode)
+ }
+
+ override fun createLookup(
+ targetClass: ClassNode,
+ result: CollectVisitor.Result
+ ): LookupElementBuilder? {
+ return null
+ }
+
+ private class MyCollectVisitor(
+ private val project: Project,
+ private val clazz: ClassNode,
+ mode: Mode,
+ private val opcode: Int
+ ) : CollectVisitor(mode) {
+ override fun accept(methodNode: MethodNode) {
+ val insns = methodNode.instructions ?: return
+ insns.iterator().forEachRemaining { insn ->
+ if (insn is JumpInsnNode && (opcode == -1 || insn.opcode == opcode)) {
+ addResult(insn, methodNode.findOrConstructSourceMethod(clazz, project))
+ }
+ }
+ }
+ }
+}
Index: src/main/resources/META-INF/plugin.xml
===================================================================
--- src/main/resources/META-INF/plugin.xml (revision 2293169cc59ae81f90be1ec2fb6216916473dcab)
+++ src/main/resources/META-INF/plugin.xml (revision 3f2c1217554a95475dca6c60060f0dbfa6506d7a)
@@ -195,6 +195,7 @@
+