Skip to content

Commit

Permalink
MixinExtras Expressions: Migrate to Expressions library.
Browse files Browse the repository at this point in the history
  • Loading branch information
LlamaLad7 committed Jul 2, 2024
1 parent 7b07722 commit 3ecde2d
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 32 deletions.
10 changes: 6 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ repositories {
mavenCentral()

// TODO: temporary waiting for MixinExtras expression library
maven("https://repo.spongepowered.org/")
maven("https://repo.spongepowered.org/maven/")
maven("https://jitpack.io/") {
content {
includeGroupByRegex("com\\.github\\..+")
Expand All @@ -101,9 +101,11 @@ dependencies {
// Add tools.jar for the JDI API
implementation(files(Jvm.current().toolsJar))

// TODO: temporary waiting for MixinExtras expression library
testLibs(implementation("com.github.LlamaLad7.MixinExtras:mixinextras-common:86c9835")!!)
implementation("org.spongepowered:mixin:0.8.4")
// TODO: temporary waiting for a release
fun mixinExtras(variant: String) = "com.github.LlamaLad7.MixinExtras:mixinextras-$variant:4d2e01e"

implementation(mixinExtras("expressions"))
testLibs(mixinExtras("common"))
implementation("org.ow2.asm:asm-util:9.3")

// Kotlin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ import com.llamalad7.mixinextras.expression.impl.flow.expansion.InsnExpander
import com.llamalad7.mixinextras.expression.impl.flow.postprocessing.InstantiationInfo
import com.llamalad7.mixinextras.expression.impl.point.ExpressionContext
import com.llamalad7.mixinextras.expression.impl.pool.IdentifierPool
import com.llamalad7.mixinextras.utils.Decorations
import com.llamalad7.mixinextras.expression.impl.utils.FlowDecorations
import org.apache.commons.lang3.mutable.MutableInt
import org.objectweb.asm.Handle
import org.objectweb.asm.Opcodes
Expand Down Expand Up @@ -770,15 +770,15 @@ object MEExpressionCompletionUtil {
lookup.withTail(
BracketsTailType(
1,
flows[insn]?.hasDecoration(Decorations.ARRAY_CREATION_INFO) == true,
flows[insn]?.hasDecoration(FlowDecorations.ARRAY_CREATION_INFO) == true,
)
)
.createEliminable("new [${insn.insn.desc}")
)
}
Opcodes.NEW -> {
val initCall = flows[insn]
?.getDecoration<InstantiationInfo>(Decorations.INSTANTIATION_INFO)
?.getDecoration<InstantiationInfo>(FlowDecorations.INSTANTIATION_INFO)
?.initCall
?.virtualInsnOrNull
?.insn as MethodInsnNode?
Expand Down Expand Up @@ -811,7 +811,7 @@ object MEExpressionCompletionUtil {
.withTail(
BracketsTailType(
1,
flows[insn]?.hasDecoration(Decorations.ARRAY_CREATION_INFO) == true,
flows[insn]?.hasDecoration(FlowDecorations.ARRAY_CREATION_INFO) == true,
)
)
.createEliminable("new $type[]")
Expand All @@ -827,7 +827,7 @@ object MEExpressionCompletionUtil {
.withTail(
BracketsTailType(
type.dimensions,
flows[insn]?.hasDecoration(Decorations.ARRAY_CREATION_INFO) == true
flows[insn]?.hasDecoration(FlowDecorations.ARRAY_CREATION_INFO) == true
)
)
.createEliminable("new ${insn.insn.desc}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiModifierList
import com.llamalad7.mixinextras.expression.impl.ExpressionParserFacade
import com.llamalad7.mixinextras.expression.impl.ExpressionService
import com.llamalad7.mixinextras.expression.impl.ast.expressions.Expression
import com.llamalad7.mixinextras.expression.impl.flow.ComplexDataException
import com.llamalad7.mixinextras.expression.impl.flow.FlowInterpreter
Expand Down Expand Up @@ -73,13 +74,17 @@ value class VirtualInsn(val insn: AbstractInsnNode)
object MEExpressionMatchUtil {
private val LOGGER = logger<MEExpressionMatchUtil>()

init {
ExpressionService.offerInstance(MEExpressionService)
}

fun getFlowMap(project: Project, classIn: ClassNode, methodIn: MethodNode): FlowMap? {
if (methodIn.instructions == null) {
return null
}

return methodIn.cached(classIn, project) { classNode, methodNode ->
val interpreter = object : FlowInterpreter(classNode, methodNode) {
val interpreter = object : FlowInterpreter(classNode, methodNode, MEFlowContext(project)) {
override fun newValue(type: Type?): FlowValue? {
ProgressManager.checkCanceled()
return super.newValue(type)
Expand Down
44 changes: 44 additions & 0 deletions src/main/kotlin/platform/mixin/expression/MEExpressionService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Minecraft Development for IntelliJ
*
* https://mcdev.io/
*
* Copyright (C) 2024 minecraft-dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 3.0 only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.demonwav.mcdev.platform.mixin.expression

import com.demonwav.mcdev.platform.mixin.util.toPsiType
import com.demonwav.mcdev.util.descriptor
import com.intellij.psi.GenericsUtil
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiManager
import com.llamalad7.mixinextras.expression.impl.ExpressionService
import com.llamalad7.mixinextras.expression.impl.flow.FlowContext
import org.objectweb.asm.Type

object MEExpressionService : ExpressionService() {
override fun getCommonSuperClass(ctx: FlowContext, type1: Type, type2: Type): Type {
ctx as MEFlowContext
val elementFactory = JavaPsiFacade.getElementFactory(ctx.project)
return Type.getType(
GenericsUtil.getLeastUpperBound(
type1.toPsiType(elementFactory),
type2.toPsiType(elementFactory),
PsiManager.getInstance(ctx.project)
)?.descriptor ?: error("Failed to merge types $type1 and $type2!")
)
}
}
26 changes: 26 additions & 0 deletions src/main/kotlin/platform/mixin/expression/MEFlowContext.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Minecraft Development for IntelliJ
*
* https://mcdev.io/
*
* Copyright (C) 2024 minecraft-dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 3.0 only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.demonwav.mcdev.platform.mixin.expression

import com.intellij.openapi.project.Project
import com.llamalad7.mixinextras.expression.impl.flow.FlowContext

class MEFlowContext(val project: Project) : FlowContext
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import com.intellij.psi.PsiTypes
import com.llamalad7.mixinextras.utils.Decorations
import com.llamalad7.mixinextras.expression.impl.utils.ExpressionDecorations
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.AbstractInsnNode
Expand Down Expand Up @@ -78,14 +78,16 @@ abstract class MixinExtrasInjectorAnnotationHandler : InjectorAnnotationHandler(
},
SIMPLE_OPERATION {
override fun matches(target: TargetInsn) =
target.hasDecoration(Decorations.SIMPLE_OPERATION_ARGS) &&
target.hasDecoration(Decorations.SIMPLE_OPERATION_RETURN_TYPE)
target.hasDecoration(ExpressionDecorations.SIMPLE_OPERATION_ARGS) &&
target.hasDecoration(ExpressionDecorations.SIMPLE_OPERATION_RETURN_TYPE)
},
SIMPLE_EXPRESSION {
override fun matches(target: TargetInsn) = target.hasDecoration(Decorations.SIMPLE_EXPRESSION_TYPE)
override fun matches(target: TargetInsn) =
target.hasDecoration(ExpressionDecorations.SIMPLE_EXPRESSION_TYPE)
},
STRING_CONCAT_EXPRESSION {
override fun matches(target: TargetInsn) = target.hasDecoration(Decorations.IS_STRING_CONCAT_EXPRESSION)
override fun matches(target: TargetInsn) =
target.hasDecoration(ExpressionDecorations.IS_STRING_CONCAT_EXPRESSION)
};

abstract fun matches(target: TargetInsn): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiType
import com.llamalad7.mixinextras.expression.impl.point.ExpressionContext
import com.llamalad7.mixinextras.utils.Decorations
import com.llamalad7.mixinextras.utils.TypeUtils
import com.llamalad7.mixinextras.expression.impl.utils.ExpressionASMUtils
import com.llamalad7.mixinextras.expression.impl.utils.ExpressionDecorations
import org.objectweb.asm.Type
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.ClassNode
Expand Down Expand Up @@ -57,8 +57,8 @@ class ModifyExpressionValueHandler : MixinExtrasInjectorAnnotationHandler() {
}

override fun intLikeTypePositions(target: TargetInsn): List<MethodSignature.TypePosition> {
val expressionType = target.getDecoration<Type>(Decorations.SIMPLE_EXPRESSION_TYPE)
if (expressionType == TypeUtils.INTLIKE_TYPE) {
val expressionType = target.getDecoration<Type>(ExpressionDecorations.SIMPLE_EXPRESSION_TYPE)
if (expressionType == ExpressionASMUtils.INTLIKE_TYPE) {
return listOf(MethodSignature.TypePosition.Return, MethodSignature.TypePosition.Param(0))
}
return emptyList()
Expand All @@ -68,12 +68,12 @@ class ModifyExpressionValueHandler : MixinExtrasInjectorAnnotationHandler() {
target: TargetInsn,
annotation: PsiAnnotation
): PsiType? {
if (target.hasDecoration(Decorations.IS_STRING_CONCAT_EXPRESSION)) {
if (target.hasDecoration(ExpressionDecorations.IS_STRING_CONCAT_EXPRESSION)) {
return PsiType.getJavaLangString(annotation.manager, annotation.resolveScope)
}
val psiReturnType = getPsiReturnType(target.insn, annotation)
val rawReturnType = getInsnReturnType(target.insn)
val exprType = target.getDecoration<Type>(Decorations.SIMPLE_EXPRESSION_TYPE)
val exprType = target.getDecoration<Type>(ExpressionDecorations.SIMPLE_EXPRESSION_TYPE)
if (exprType != null && rawReturnType != exprType) {
// The expression knows more than the standard logic does.
return exprType.toPsiType(JavaPsiFacade.getElementFactory(annotation.project))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiType
import com.llamalad7.mixinextras.expression.impl.point.ExpressionContext
import com.llamalad7.mixinextras.utils.Decorations
import com.llamalad7.mixinextras.utils.TypeUtils
import com.llamalad7.mixinextras.expression.impl.utils.ExpressionASMUtils
import com.llamalad7.mixinextras.expression.impl.utils.ExpressionDecorations
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.MethodNode
Expand Down Expand Up @@ -60,11 +60,14 @@ class WrapOperationHandler : MixinExtrasInjectorAnnotationHandler() {
}

override fun intLikeTypePositions(target: TargetInsn) = buildList {
if (target.getDecoration<Type>(Decorations.SIMPLE_OPERATION_RETURN_TYPE) == TypeUtils.INTLIKE_TYPE) {
if (
target.getDecoration<Type>(ExpressionDecorations.SIMPLE_OPERATION_RETURN_TYPE)
== ExpressionASMUtils.INTLIKE_TYPE
) {
add(MethodSignature.TypePosition.Return)
}
target.getDecoration<Array<Type>>(Decorations.SIMPLE_OPERATION_ARGS)?.forEachIndexed { i, it ->
if (it == TypeUtils.INTLIKE_TYPE) {
target.getDecoration<Array<Type>>(ExpressionDecorations.SIMPLE_OPERATION_ARGS)?.forEachIndexed { i, it ->
if (it == ExpressionASMUtils.INTLIKE_TYPE) {
add(MethodSignature.TypePosition.Param(i))
}
}
Expand All @@ -76,16 +79,19 @@ class WrapOperationHandler : MixinExtrasInjectorAnnotationHandler() {
annotation: PsiAnnotation
): List<Parameter>? {
getPsiParameters(target.insn, targetClass, annotation)?.let { return it }
val args = target.getDecoration<Array<Type>>(Decorations.SIMPLE_OPERATION_ARGS) ?: return null
return args.toList().toParameters(annotation, target.getDecoration(Decorations.SIMPLE_OPERATION_PARAM_NAMES))
val args = target.getDecoration<Array<Type>>(ExpressionDecorations.SIMPLE_OPERATION_ARGS) ?: return null
return args.toList().toParameters(
annotation,
target.getDecoration(ExpressionDecorations.SIMPLE_OPERATION_PARAM_NAMES)
)
}

private fun getReturnType(
target: TargetInsn,
annotation: PsiAnnotation
): PsiType? {
getPsiReturnType(target.insn, annotation)?.let { return it }
val type = target.getDecoration<Type>(Decorations.SIMPLE_OPERATION_RETURN_TYPE) ?: return null
val type = target.getDecoration<Type>(ExpressionDecorations.SIMPLE_OPERATION_RETURN_TYPE) ?: return null
return type.toPsiType(JavaPsiFacade.getElementFactory(annotation.project))
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/platform/mixin/util/AsmUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.PsiUtil
import com.intellij.refactoring.util.LambdaRefactoringUtil
import com.intellij.util.CommonJavaRefactoringUtil
import com.llamalad7.mixinextras.utils.TypeUtils
import com.llamalad7.mixinextras.expression.impl.utils.ExpressionASMUtils
import java.io.PrintWriter
import java.io.StringWriter
import java.lang.reflect.InvocationTargetException
Expand Down Expand Up @@ -143,7 +143,7 @@ private fun hasModifier(access: Int, @PsiModifier.ModifierConstant modifier: Str
}

fun Type.toPsiType(elementFactory: PsiElementFactory, context: PsiElement? = null): PsiType {
if (this == TypeUtils.INTLIKE_TYPE) {
if (this == ExpressionASMUtils.INTLIKE_TYPE) {
return PsiTypes.intType()
}
val javaClassName = className.replace("(\\$)(\\D)".toRegex()) { "." + it.groupValues[2] }
Expand Down
2 changes: 1 addition & 1 deletion src/test/kotlin/platform/mixin/BaseMixinTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ abstract class BaseMixinTest : BaseMinecraftTest(PlatformType.MIXIN) {
fun initMixin() {
runWriteTask {
mixinLibrary = createLibrary(project, "mixin")
mixinExtrasLibrary = createLibrary(project, "mixinextras-common") // TODO: this will probably change
mixinExtrasLibrary = createLibrary(project, "mixinextras-common")
testDataLibrary = createLibrary(project, "mixin-test-data")
}

Expand Down

0 comments on commit 3ecde2d

Please sign in to comment.