User: rednesto Date: 08 May 23 14:00 Revision: fba57df81658e5afcf439108c4ae75d6ba4d527f Summary: Fix #1818 At NEW targets parsing is incorrect Also fixes the class At arg not being matched properly TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=8496&personal=false Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/NewInsnInjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/injectionPoint/NewInsnInjectionPoint.kt (revision b02d7c4800913e2eaa67039a6d5c5447c432ba32) +++ src/main/kotlin/platform/mixin/handlers/injectionPoint/NewInsnInjectionPoint.kt (revision fba57df81658e5afcf439108c4ae75d6ba4d527f) @@ -22,14 +22,12 @@ import com.demonwav.mcdev.platform.mixin.reference.MixinSelector import com.demonwav.mcdev.platform.mixin.reference.MixinSelectorParser -import com.demonwav.mcdev.platform.mixin.reference.toMixinString import com.demonwav.mcdev.platform.mixin.util.MixinConstants.Annotations.AT import com.demonwav.mcdev.platform.mixin.util.shortName import com.demonwav.mcdev.util.MemberReference import com.demonwav.mcdev.util.constantStringValue import com.demonwav.mcdev.util.descriptor import com.demonwav.mcdev.util.fullQualifiedName -import com.demonwav.mcdev.util.getQualifiedMemberReference import com.demonwav.mcdev.util.internalName import com.demonwav.mcdev.util.mapToArray import com.demonwav.mcdev.util.shortName @@ -91,9 +89,11 @@ } is PsiMethod -> { val ownerName = result.qualifier?.substringAfterLast('.')?.replace('$', '.') ?: targetClass.shortName + val descriptorArgs = target.descriptor?.dropLast(1) ?: return null + val qualifierInternalName = result.qualifier?.replace('.', '/') return JavaLookupElementBuilder.forMethod( target, - target.getQualifiedMemberReference(result.qualifier).toMixinString(), + "${descriptorArgs}L$qualifierInternalName;", PsiSubstitutor.EMPTY, null, ) @@ -193,10 +193,31 @@ if (!at.hasQualifiedName(AT)) return null if (at.findAttributeValue("value")?.constantStringValue != "NEW") return null - return classToMemberReference(value) + return NewInsnSelector(value) } } +private class NewInsnSelector( + override val methodDescriptor: String, +) : MixinSelector { + override fun matchField(owner: String, name: String, desc: String): Boolean = false + + override fun matchMethod(owner: String, name: String, desc: String): Boolean { + if (name != "" || desc.last() != 'V') { + return false + } + + val lastParen = methodDescriptor.lastIndexOf(')') + val argsDesc = methodDescriptor.substring(0, lastParen + 1) + val descRet = methodDescriptor.substringAfterLast(')').removeSurrounding("L", ";") + return desc.dropLast(1) == argsDesc && descRet == owner + } + + override val owner = null + override val fieldDescriptor = null + override val displayName = methodDescriptor +} + private fun classToMemberReference(value: String): MemberReference? { val fqn = value.replace('/', '.').replace('$', '.') if (fqn.isNotEmpty() && !fqn.startsWith('.') && !fqn.endsWith('.') && !fqn.contains("..")) { Index: src/main/kotlin/util/MemberReference.kt =================================================================== --- src/main/kotlin/util/MemberReference.kt (revision b02d7c4800913e2eaa67039a6d5c5447c432ba32) +++ src/main/kotlin/util/MemberReference.kt (revision fba57df81658e5afcf439108c4ae75d6ba4d527f) @@ -64,7 +64,7 @@ private fun matchOwner(clazz: String): Boolean { assert(!clazz.contains('.')) - return this.owner == null || this.owner == clazz.replace('/', '.') + return this.owner == null || this.owner == clazz.replace('/', '.').replace('$', '.') } override fun matchField(owner: String, name: String, desc: String): Boolean {