From 26b03113cca4afbadf75d1e6286005964b93c9bb Mon Sep 17 00:00:00 2001 From: LlamaLad7 Date: Tue, 24 Mar 2026 18:12:27 +0000 Subject: [PATCH 1/2] New: Support `@Shadow` constructors. Will be introduced in FabricMixin along with enum extensions. We don't need to bother checking whether the feature is supported on the current Mixin, because the user will already get a compile error about Shadow not being applicable to constructors. --- src/main/kotlin/platform/mixin/handlers/ShadowHandler.kt | 9 ++++++--- src/main/kotlin/util/bytecode-utils.kt | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/platform/mixin/handlers/ShadowHandler.kt b/src/main/kotlin/platform/mixin/handlers/ShadowHandler.kt index 012ca162d..e248976f2 100644 --- a/src/main/kotlin/platform/mixin/handlers/ShadowHandler.kt +++ b/src/main/kotlin/platform/mixin/handlers/ShadowHandler.kt @@ -48,7 +48,7 @@ class ShadowHandler : MixinMemberAnnotationHandler { override fun resolveTarget(annotation: PsiAnnotation, targetClass: ClassNode): List { if (hasAliases(annotation)) return emptyList() val member = annotation.parentOfType() ?: return emptyList() - val name = stripPrefix(annotation, member) ?: return emptyList() + val name = getEffectiveName(annotation, member) ?: return emptyList() return when (member) { is PsiMethod -> listOfNotNull( targetClass.findMethod(MemberReference(name, member.descriptor)) @@ -75,7 +75,7 @@ class ShadowHandler : MixinMemberAnnotationHandler { is PsiField -> "field" else -> return null } - return "Unresolved $type ${member.name} in target class" + return "Unresolved $type ${getEffectiveName(annotation, member)} in target class" } fun findFirstShadowTargetForNavigation(member: PsiMember): SmartPsiElementPointer? { @@ -94,7 +94,10 @@ class ShadowHandler : MixinMemberAnnotationHandler { private fun hasAliases(shadow: PsiAnnotation) = shadow.findDeclaredAttributeValue("aliases").isNotEmpty() - private fun stripPrefix(shadow: PsiAnnotation, member: PsiMember): String? { + private fun getEffectiveName(shadow: PsiAnnotation, member: PsiMember): String? { + if (member is PsiMethod && member.isConstructor) { + return "" + } // Strip prefix val prefix = shadow.findDeclaredAttributeValue("prefix")?.constantStringValue ?: MixinConstants.DEFAULT_SHADOW_PREFIX diff --git a/src/main/kotlin/util/bytecode-utils.kt b/src/main/kotlin/util/bytecode-utils.kt index eceb4b87d..085d672db 100644 --- a/src/main/kotlin/util/bytecode-utils.kt +++ b/src/main/kotlin/util/bytecode-utils.kt @@ -172,9 +172,12 @@ private fun PsiMethod.appendDescriptor(builder: StringBuilder): StringBuilder { builder.append('(') if (isConstructor) { containingClass?.let { containingClass -> - if (containingClass.hasModifierProperty(PsiModifier.STATIC)) return@let - val outerClass = containingClass.containingClass - outerClass?.type()?.appendDescriptor(builder) + if (containingClass.isEnum) { + builder.append("Ljava/lang/String;I") + } else if (!containingClass.hasModifierProperty(PsiModifier.STATIC)) { + val outerClass = containingClass.containingClass + outerClass?.type()?.appendDescriptor(builder) + } } } for (parameter in parameterList.parameters) { From a73c53491f4925fd189c710d8424a540f932b327 Mon Sep 17 00:00:00 2001 From: LlamaLad7 Date: Thu, 2 Apr 2026 19:28:24 +0100 Subject: [PATCH 2/2] New: Support Enum extensions. --- .../platform/mixin/inspection/MixinClassTypeInspection.kt | 3 ++- .../platform/mixin/inspection/StaticMemberInspection.kt | 3 ++- .../addedMembers/MissingUniqueAnnotationInspection.kt | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/platform/mixin/inspection/MixinClassTypeInspection.kt b/src/main/kotlin/platform/mixin/inspection/MixinClassTypeInspection.kt index 474c4be00..d88daf59e 100644 --- a/src/main/kotlin/platform/mixin/inspection/MixinClassTypeInspection.kt +++ b/src/main/kotlin/platform/mixin/inspection/MixinClassTypeInspection.kt @@ -22,6 +22,7 @@ package com.demonwav.mcdev.platform.mixin.inspection import com.demonwav.mcdev.platform.mixin.util.hasAccess import com.demonwav.mcdev.platform.mixin.util.isAccessorMixin +import com.demonwav.mcdev.platform.mixin.util.isFabricMixin import com.demonwav.mcdev.platform.mixin.util.isMixin import com.demonwav.mcdev.platform.mixin.util.mixinTargets import com.intellij.codeInspection.LocalQuickFix @@ -68,7 +69,7 @@ class MixinClassTypeInspection : MixinInspection() { } } - if (mixinClass.isEnum) { + if (mixinClass.isEnum && !mixinClass.isFabricMixin) { holder.registerProblem(problemElement, "Mixins cannot be enums", *fixes.toTypedArray()) return } diff --git a/src/main/kotlin/platform/mixin/inspection/StaticMemberInspection.kt b/src/main/kotlin/platform/mixin/inspection/StaticMemberInspection.kt index 1756252e1..14bbd9c11 100644 --- a/src/main/kotlin/platform/mixin/inspection/StaticMemberInspection.kt +++ b/src/main/kotlin/platform/mixin/inspection/StaticMemberInspection.kt @@ -30,6 +30,7 @@ import com.intellij.codeInsight.intention.QuickFixFactory import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.JavaElementVisitor import com.intellij.psi.PsiElementVisitor +import com.intellij.psi.PsiEnumConstant import com.intellij.psi.PsiField import com.intellij.psi.PsiMember import com.intellij.psi.PsiMethod @@ -71,7 +72,7 @@ class StaticMemberInspection : MixinInspection() { private fun isProblematic(member: PsiMember): Boolean { val containingClass = member.containingClass ?: return false - if (!containingClass.isMixin) { + if (!containingClass.isMixin || member is PsiEnumConstant) { return false } diff --git a/src/main/kotlin/platform/mixin/inspection/addedMembers/MissingUniqueAnnotationInspection.kt b/src/main/kotlin/platform/mixin/inspection/addedMembers/MissingUniqueAnnotationInspection.kt index e070c37cd..1d9216ab3 100644 --- a/src/main/kotlin/platform/mixin/inspection/addedMembers/MissingUniqueAnnotationInspection.kt +++ b/src/main/kotlin/platform/mixin/inspection/addedMembers/MissingUniqueAnnotationInspection.kt @@ -24,6 +24,7 @@ import com.demonwav.mcdev.platform.mixin.util.MixinConstants import com.intellij.codeInsight.intention.AddAnnotationModCommandAction import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.ProblemsHolder +import com.intellij.psi.PsiEnumConstant import com.intellij.psi.PsiField import com.intellij.psi.PsiMethod @@ -31,6 +32,9 @@ class MissingUniqueAnnotationInspection : AbstractAddedMembersInspection() { override fun getStaticDescription() = "Reports missing @Unique annotations" override fun visitAddedField(holder: ProblemsHolder, field: PsiField) { + if (field is PsiEnumConstant) { + return + } if (!field.hasAnnotation(MixinConstants.Annotations.UNIQUE)) { holder.registerProblem( field.nameIdentifier,