Skip to content

Commit

Permalink
Fix/expressions int like types (#2261)
Browse files Browse the repository at this point in the history
* Mixin: Combine parameter and return type inspections.

* MixinExtras: Offer a choice between all valid int-like types.

* Mixin: Fix tests for handler signature inspection.
  • Loading branch information
LlamaLad7 authored Mar 10, 2024
1 parent daffb72 commit 37ef16c
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ abstract class MixinExtrasInjectorAnnotationHandler : InjectorAnnotationHandler(
target: TargetInsn,
): Pair<ParameterGroup, PsiType>?

open fun intLikeTypePositions(
target: TargetInsn
): List<MethodSignature.TypePosition> = emptyList()

override val allowCoerce = true

override fun expectedMethodSignature(
Expand All @@ -115,21 +119,75 @@ abstract class MixinExtrasInjectorAnnotationHandler : InjectorAnnotationHandler(
}
val firstMatch = signatures[0] ?: return emptyList()
if (signatures.drop(1).any { it != firstMatch }) return emptyList()
return listOf(
MethodSignature(
listOf(
firstMatch.first,
ParameterGroup(
collectTargetMethodParameters(annotation.project, targetClass, targetMethod),
required = ParameterGroup.RequiredLevel.OPTIONAL,
isVarargs = true,
),
),
firstMatch.second
)
val intLikeTypePositions = insns.map { intLikeTypePositions(it) }.distinct().singleOrNull().orEmpty()
return allPossibleSignatures(
annotation,
targetClass,
targetMethod,
firstMatch.first,
firstMatch.second,
intLikeTypePositions
)
}

private fun allPossibleSignatures(
annotation: PsiAnnotation,
targetClass: ClassNode,
targetMethod: MethodNode,
params: ParameterGroup,
returnType: PsiType,
intLikeTypePositions: List<MethodSignature.TypePosition>
): List<MethodSignature> {
if (intLikeTypePositions.isEmpty()) {
return listOf(
makeSignature(annotation, targetClass, targetMethod, params, returnType, intLikeTypePositions)
)
}
return buildList {
for (actualType in intLikePsiTypes) {
val newParams = params.parameters.toMutableList()
var newReturnType = returnType
for (pos in intLikeTypePositions) {
when (pos) {
is MethodSignature.TypePosition.Return -> newReturnType = actualType
is MethodSignature.TypePosition.Param ->
newParams[pos.index] = newParams[pos.index].copy(type = actualType)
}
}
add(
makeSignature(
annotation,
targetClass,
targetMethod,
ParameterGroup(newParams),
newReturnType,
intLikeTypePositions
)
)
}
}
}

private fun makeSignature(
annotation: PsiAnnotation,
targetClass: ClassNode,
targetMethod: MethodNode,
params: ParameterGroup,
returnType: PsiType,
intLikeTypePositions: List<MethodSignature.TypePosition>
) = MethodSignature(
listOf(
params,
ParameterGroup(
collectTargetMethodParameters(annotation.project, targetClass, targetMethod),
required = ParameterGroup.RequiredLevel.OPTIONAL,
isVarargs = true,
),
),
returnType,
intLikeTypePositions
)

protected fun getInsnReturnType(insn: AbstractInsnNode): Type? {
return when {
insn is MethodInsnNode -> Type.getReturnType(insn.desc)
Expand Down Expand Up @@ -365,3 +423,7 @@ private fun getConstantType(insn: AbstractInsnNode?): Type? {
}
}
}

private val intLikePsiTypes = listOf(
PsiTypes.intType(), PsiTypes.booleanType(), PsiTypes.charType(), PsiTypes.byteType(), PsiTypes.shortType()
)
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@

package com.demonwav.mcdev.platform.mixin.handlers.mixinextras

import com.demonwav.mcdev.platform.mixin.inspection.injector.MethodSignature
import com.demonwav.mcdev.platform.mixin.inspection.injector.ParameterGroup
import com.demonwav.mcdev.platform.mixin.util.toPsiType
import com.demonwav.mcdev.util.Parameter
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiType
import com.llamalad7.mixinextras.utils.Decorations
import com.llamalad7.mixinextras.utils.TypeUtils
import org.objectweb.asm.Type
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.ClassNode
Expand All @@ -53,6 +55,14 @@ class ModifyExpressionValueHandler : MixinExtrasInjectorAnnotationHandler() {
return ParameterGroup(listOf(Parameter("original", psiType))) to psiType
}

override fun intLikeTypePositions(target: TargetInsn): List<MethodSignature.TypePosition> {
val expressionType = target.getDecoration<Type>(Decorations.SIMPLE_EXPRESSION_TYPE)
if (expressionType == TypeUtils.INTLIKE_TYPE) {
return listOf(MethodSignature.TypePosition.Return, MethodSignature.TypePosition.Param(0))
}
return emptyList()
}

private fun getReturnType(
target: TargetInsn,
annotation: PsiAnnotation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.demonwav.mcdev.platform.mixin.handlers.mixinextras

import com.demonwav.mcdev.platform.mixin.inspection.injector.MethodSignature
import com.demonwav.mcdev.platform.mixin.inspection.injector.ParameterGroup
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.OPERATION
import com.demonwav.mcdev.platform.mixin.util.toPsiType
Expand All @@ -30,6 +31,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPrimitiveType
import com.intellij.psi.PsiType
import com.llamalad7.mixinextras.utils.Decorations
import com.llamalad7.mixinextras.utils.TypeUtils
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.MethodNode
Expand Down Expand Up @@ -58,6 +60,17 @@ class WrapOperationHandler : MixinExtrasInjectorAnnotationHandler() {
) to returnType
}

override fun intLikeTypePositions(target: TargetInsn) = buildList {
if (target.getDecoration<Type>(Decorations.SIMPLE_OPERATION_RETURN_TYPE) == TypeUtils.INTLIKE_TYPE) {
add(MethodSignature.TypePosition.Return)
}
target.getDecoration<Array<Type>>(Decorations.SIMPLE_OPERATION_ARGS)?.forEachIndexed { i, it ->
if (it == TypeUtils.INTLIKE_TYPE) {
add(MethodSignature.TypePosition.Param(i))
}
}
}

private fun getParameterTypes(
target: TargetInsn,
targetClass: ClassNode,
Expand Down
Loading

0 comments on commit 37ef16c

Please sign in to comment.