User: joe
Date: 09 Nov 21 00:24
Revision: 3cd48917d95de70970e3d30d22ebb6d91265d3ed
Summary:
Add inspection for injecting into a constructor at a non-return instruction
TeamCity URL: https://ci.denwav.dev/viewModification.html?tab=vcsModificationFiles&modId=7834&personal=false
Index: src/main/kotlin/platform/mixin/inspection/injector/InjectIntoConstructorInspection.kt
===================================================================
--- src/main/kotlin/platform/mixin/inspection/injector/InjectIntoConstructorInspection.kt (revision 3cd48917d95de70970e3d30d22ebb6d91265d3ed)
+++ src/main/kotlin/platform/mixin/inspection/injector/InjectIntoConstructorInspection.kt (revision 3cd48917d95de70970e3d30d22ebb6d91265d3ed)
@@ -0,0 +1,80 @@
+/*
+ * Minecraft Dev for IntelliJ
+ *
+ * https://minecraftdev.org
+ *
+ * Copyright (c) 2021 minecraft-dev
+ *
+ * MIT License
+ */
+
+package com.demonwav.mcdev.platform.mixin.inspection.injector
+
+import com.demonwav.mcdev.facet.MinecraftFacet
+import com.demonwav.mcdev.platform.fabric.FabricModuleType
+import com.demonwav.mcdev.platform.mixin.handlers.InjectorAnnotationHandler
+import com.demonwav.mcdev.platform.mixin.handlers.MixinAnnotationHandler
+import com.demonwav.mcdev.platform.mixin.inspection.MixinInspection
+import com.demonwav.mcdev.platform.mixin.util.MethodTargetMember
+import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Annotations.INJECT
+import com.demonwav.mcdev.platform.mixin.util.isConstructor
+import com.demonwav.mcdev.util.findAnnotation
+import com.demonwav.mcdev.util.findModule
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.psi.JavaElementVisitor
+import com.intellij.psi.PsiElementVisitor
+import com.intellij.psi.PsiMethod
+import java.awt.FlowLayout
+import javax.swing.JCheckBox
+import javax.swing.JComponent
+import javax.swing.JPanel
+import org.objectweb.asm.Opcodes
+
+class InjectIntoConstructorInspection : MixinInspection() {
+ @JvmField
+ var ALLOW_ON_FABRIC = true
+
+ override fun createOptionsPanel(): JComponent {
+ val panel = JPanel(FlowLayout(FlowLayout.LEFT))
+ val checkbox = JCheckBox("Allow @Inject into constructors in Fabric", ALLOW_ON_FABRIC)
+ checkbox.addActionListener {
+ ALLOW_ON_FABRIC = checkbox.isSelected
+ }
+ panel.add(checkbox)
+ return panel
+ }
+
+ override fun buildVisitor(holder: ProblemsHolder): PsiElementVisitor {
+ val isFabric = holder.file.findModule()?.let { MinecraftFacet.getInstance(it) }?.isOfType(FabricModuleType)
+ ?: false
+ if (isFabric && ALLOW_ON_FABRIC) {
+ return PsiElementVisitor.EMPTY_VISITOR
+ }
+
+ return object : JavaElementVisitor() {
+ override fun visitMethod(method: PsiMethod) {
+ super.visitMethod(method)
+ val injectAnnotation = method.findAnnotation(INJECT) ?: return
+ val problemElement = injectAnnotation.nameReferenceElement ?: return
+ val handler = MixinAnnotationHandler.forMixinAnnotation(INJECT) as? InjectorAnnotationHandler ?: return
+ val targets = handler.resolveTarget(injectAnnotation)
+ for (target in targets) {
+ if (target !is MethodTargetMember || !target.classAndMethod.method.isConstructor) {
+ continue
+ }
+ val (targetClass, targetMethod) = target.classAndMethod
+ val instructions = handler.resolveInstructions(injectAnnotation, targetClass, targetMethod)
+ if (instructions.any { it.insn.opcode != Opcodes.RETURN }) {
+ holder.registerProblem(
+ problemElement,
+ "Cannot inject into constructors at non-return instructions"
+ )
+ return
+ }
+ }
+ }
+ }
+ }
+
+ override fun getStaticDescription() = "@Inject into Constructor"
+}
Index: src/main/resources/META-INF/plugin.xml
===================================================================
--- src/main/resources/META-INF/plugin.xml (revision 2e1faf136ef559c67ae05f5ecd3c98e6f3dfc3a0)
+++ src/main/resources/META-INF/plugin.xml (revision 3cd48917d95de70970e3d30d22ebb6d91265d3ed)
@@ -660,6 +660,14 @@
implementationClass="com.demonwav.mcdev.platform.mixin.inspection.implements.DuplicateInterfacePrefixInspection"/>
+