User: llamalad7 Date: 19 Jan 25 00:51 Revision: 5c6891ed3927a2fbb2459960e9e86c9d839f36e9 Summary: Support for MixinExtras 0.5.0-beta.5 (#2431) * Build: Bump MixinExtras Expressions. * Fix: Get ME Expressions string constants from the flows not the bytecode. Things like string concat expansion will result in nodes that weren't there originally. * Change: Allow `@Coerce` on `@WrapMethod` params. * New: Support `mixinextras` entry in mixin configs. TeamCity URL: https://ci.mcdev.io/viewModification.html?tab=vcsModificationFiles&modId=9812&personal=false Index: gradle/libs.versions.toml =================================================================== --- gradle/libs.versions.toml (revision f3e34dfecf54753f3354b256002718c4b43063b8) +++ gradle/libs.versions.toml (revision 5c6891ed3927a2fbb2459960e9e86c9d839f36e9) @@ -31,7 +31,7 @@ coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" } mappingIo = "net.fabricmc:mapping-io:0.2.1" -mixinExtras-expressions = "io.github.llamalad7:mixinextras-expressions:0.0.1" +mixinExtras-expressions = "io.github.llamalad7:mixinextras-expressions:0.0.3" # GrammarKit jflex-lib = "org.jetbrains.idea:jflex:1.7.0-b7f882a" Index: src/main/kotlin/platform/mixin/config/reference/ConfigProperty.kt =================================================================== --- src/main/kotlin/platform/mixin/config/reference/ConfigProperty.kt (revision f3e34dfecf54753f3354b256002718c4b43063b8) +++ src/main/kotlin/platform/mixin/config/reference/ConfigProperty.kt (revision 5c6891ed3927a2fbb2459960e9e86c9d839f36e9) @@ -23,10 +23,13 @@ import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Classes.MIXIN_CONFIG import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Classes.MIXIN_SERIALIZED_NAME import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Classes.SERIALIZED_NAME +import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.MIXIN_EXTRAS_CONFIG +import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.MIXIN_EXTRAS_CONFIG_KEY +import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.MIXIN_EXTRAS_SERIALIZED_NAME import com.demonwav.mcdev.util.constantStringValue -import com.demonwav.mcdev.util.findAnnotation import com.demonwav.mcdev.util.ifEmpty import com.demonwav.mcdev.util.reference.InspectionReference +import com.demonwav.mcdev.util.toTypedArray import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.json.psi.JsonProperty import com.intellij.json.psi.JsonStringLiteral @@ -48,6 +51,10 @@ arrayOf(Reference(element as JsonStringLiteral)) fun resolveReference(element: JsonStringLiteral): PsiElement? { + val name = element.value + customSubConfigs[name]?.let { + return JavaPsiFacade.getInstance(element.project).findClass(it, element.resolveScope) + } val configClass = findConfigClass(element) ?: return null return findProperty(configClass, element.value) } @@ -55,12 +62,15 @@ private fun collectVariants(context: PsiElement): Array { val configClass = findConfigClass(context) ?: return ArrayUtil.EMPTY_OBJECT_ARRAY - val list = ArrayList() + val list = mutableListOf() forEachProperty(configClass) { _, name -> - list.add(LookupElementBuilder.create(name)) + list.add(name) } - return list.toArray() + if (configClass.qualifiedName == MIXIN_CONFIG) { + list.addAll(customSubConfigs.keys) - } + } + return list.asSequence().map { LookupElementBuilder.create(it) }.toTypedArray() + } private fun findProperty(configClass: PsiClass, name: String): PsiField? { forEachProperty(configClass) { field, fieldName -> @@ -73,15 +83,8 @@ } private inline fun forEachProperty(configClass: PsiClass, func: (PsiField, String) -> Unit) { - val mixinSerializedNameClass = - JavaPsiFacade.getInstance(configClass.project).findClass(MIXIN_SERIALIZED_NAME, configClass.resolveScope) - val serializedNameName = if (mixinSerializedNameClass != null) { - MIXIN_SERIALIZED_NAME - } else { - SERIALIZED_NAME - } for (field in configClass.fields) { - val annotation = field.findAnnotation(serializedNameName) + val annotation = field.annotations.find { it.qualifiedName in serializedNameAnnotations } val name = annotation?.findDeclaredAttributeValue(null)?.constantStringValue ?: continue func(field, name) } @@ -107,6 +110,14 @@ // Walk to correct class var currentClass = mixinConfig + + customSubConfigs[path.first()]?.let { newRoot -> + path.removeFirst() + currentClass = + JavaPsiFacade.getInstance(context.project).findClass(newRoot, context.resolveScope) + ?: return null + } + for (i in path.lastIndex downTo 0) { currentClass = (findProperty(currentClass, path[i])?.type as? PsiClassType)?.resolve() ?: return null } @@ -127,4 +138,14 @@ override fun getVariants() = collectVariants(element) override fun isReferenceTo(element: PsiElement) = element is PsiField && super.isReferenceTo(element) } + + private val customSubConfigs = mapOf( + MIXIN_EXTRAS_CONFIG_KEY to MIXIN_EXTRAS_CONFIG + ) + + private val serializedNameAnnotations = setOf( + SERIALIZED_NAME, + MIXIN_SERIALIZED_NAME, + MIXIN_EXTRAS_SERIALIZED_NAME + ) } Index: src/main/kotlin/platform/mixin/expression/MEExpressionCompletionUtil.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/MEExpressionCompletionUtil.kt (revision f3e34dfecf54753f3354b256002718c4b43063b8) +++ src/main/kotlin/platform/mixin/expression/MEExpressionCompletionUtil.kt (revision 5c6891ed3927a2fbb2459960e9e86c9d839f36e9) @@ -252,16 +252,23 @@ handler to annotation } ?: return emptyList() - return handler.resolveTarget(handlerAnnotation).flatMap { - (it as? MethodTargetMember)?.classAndMethod?.method?.instructions?.mapNotNull { insn -> + return handler.resolveTarget(handlerAnnotation).flatMap { member -> + (member as? MethodTargetMember)?.classAndMethod + ?.let { (clazz, method) -> MEExpressionMatchUtil.getFlowMap(project, clazz, method) } + ?.values + ?.asSequence() + ?.filterNot { it.isComplex } + ?.map { it.insn } + ?.mapNotNull { insn -> - if (insn is LdcInsnNode && insn.cst is String) { - LookupElementBuilder.create(insn.cst) - } else { - null - } + if (insn is LdcInsnNode && insn.cst is String) { + LookupElementBuilder.create(insn.cst) + } else { + null + } - } ?: emptyList() - } + } + .orEmpty() - } + } + } fun getCompletionVariantsFromBytecode(project: Project, contextElement: PsiElement): List { val statement = contextElement.parentOfType() ?: return emptyList() Index: src/main/kotlin/platform/mixin/handlers/mixinextras/WrapMethodHandler.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/mixinextras/WrapMethodHandler.kt (revision f3e34dfecf54753f3354b256002718c4b43063b8) +++ src/main/kotlin/platform/mixin/handlers/mixinextras/WrapMethodHandler.kt (revision 5c6891ed3927a2fbb2459960e9e86c9d839f36e9) @@ -36,6 +36,8 @@ import org.objectweb.asm.tree.MethodNode class WrapMethodHandler : InjectorAnnotationHandler() { + override val allowCoerce get() = true + override fun expectedMethodSignature( annotation: PsiAnnotation, targetClass: ClassNode, Index: src/main/kotlin/platform/mixin/util/MixinConstants.kt =================================================================== --- src/main/kotlin/platform/mixin/util/MixinConstants.kt (revision f3e34dfecf54753f3354b256002718c4b43063b8) +++ src/main/kotlin/platform/mixin/util/MixinConstants.kt (revision 5c6891ed3927a2fbb2459960e9e86c9d839f36e9) @@ -93,6 +93,9 @@ const val LOCAL_REF_PACKAGE = "com.llamalad7.mixinextras.sugar.ref." const val EXPRESSION = "com.llamalad7.mixinextras.expression.Expression" const val DEFINITION = "com.llamalad7.mixinextras.expression.Definition" + const val MIXIN_EXTRAS_CONFIG = "com.llamalad7.mixinextras.config.MixinExtrasConfig" + const val MIXIN_EXTRAS_CONFIG_KEY = "mixinextras" + const val MIXIN_EXTRAS_SERIALIZED_NAME = "com.llamalad7.mixinextras.lib.gson.annotations.SerializedName" fun PsiType.unwrapLocalRef(): PsiType { if (this !is PsiClassType) {