User: joe Date: 22 Jun 25 21:01 Revision: 9cd279d90e768ecb380f71058ea608bfabea9f13 Summary: Smarter handling of shift discouraging for ME expressions TeamCity URL: https://ci.mcdev.io/viewModification.html?tab=vcsModificationFiles&modId=10082&personal=false Index: src/main/kotlin/platform/mixin/expression/psi/MEMatchableElement.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/MEMatchableElement.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/MEMatchableElement.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -28,4 +28,10 @@ fun matchesJava(java: PsiElement, context: MESourceMatchContext): Boolean fun getInputExprs(): List + + /** + * Whether an injector shifting after this expression should be discouraged. Generally implemented as whether the + * expression could have (non-exceptional) side effects. + */ + val isShiftDiscouraged: Boolean } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEArrayAccessExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEArrayAccessExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEArrayAccessExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -53,6 +53,8 @@ override fun getInputExprs() = listOfNotNull(arrayExpr, indexExpr) + override val isShiftDiscouraged get() = !MEPsiUtil.isAccessedForWriting(this) + protected abstract val arrayExpr: MEExpression protected abstract val indexExpr: MEExpression? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEAssignStatementImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEAssignStatementImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEAssignStatementImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -51,6 +51,8 @@ override fun getInputExprs() = targetExpr.getInputExprs() + listOfNotNull(rightExpr) + override val isShiftDiscouraged = false + protected abstract val targetExpr: MEExpression protected abstract val rightExpr: MEExpression? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEBinaryExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEBinaryExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEBinaryExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -95,6 +95,8 @@ listOfNotNull(leftExpr, rightExpr) } + override val isShiftDiscouraged = true + protected abstract val leftExpr: MEExpression protected abstract val rightExpr: MEExpression? Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEBoundReferenceExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEBoundReferenceExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEBoundReferenceExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -59,6 +59,8 @@ override fun getInputExprs() = listOf(receiverExpr) + override val isShiftDiscouraged = true + abstract val receiverExpr: MEExpression abstract val memberName: MEName? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MECapturingExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MECapturingExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MECapturingExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -34,5 +34,7 @@ override fun getInputExprs() = listOfNotNull(expression) + override val isShiftDiscouraged get() = expression?.isShiftDiscouraged == true + protected abstract val expression: MEExpression? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MECastExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MECastExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MECastExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -61,5 +61,7 @@ override fun getInputExprs() = listOfNotNull(castedExpr) + override val isShiftDiscouraged = true + protected abstract val expressionList: List } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEClassConstantExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEClassConstantExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEClassConstantExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -56,5 +56,7 @@ override fun getInputExprs() = emptyList() + override val isShiftDiscouraged = true + protected abstract val type: METype } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEConstructorReferenceExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEConstructorReferenceExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEConstructorReferenceExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -43,5 +43,7 @@ override fun getInputExprs() = emptyList() + override val isShiftDiscouraged = true + abstract val className: METype } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -35,4 +35,9 @@ override fun getInputExprs(): List { throw UnsupportedOperationException("Please implement getInputExprs for your expression type") } + + override val isShiftDiscouraged: Boolean + get() { + throw UnsupportedOperationException("Please implement isShiftDiscouraged for your expression type") -} + } +} Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEExpressionStatementImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEExpressionStatementImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEExpressionStatementImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -33,5 +33,7 @@ override fun getInputExprs() = listOf(expression) + override val isShiftDiscouraged get() = expression.isShiftDiscouraged + protected abstract val expression: MEExpression } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEFreeMethodReferenceExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEFreeMethodReferenceExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEFreeMethodReferenceExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -56,5 +56,7 @@ override fun getInputExprs() = emptyList() + override val isShiftDiscouraged = true + abstract val memberName: MEName? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MELitExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MELitExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MELitExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -115,6 +115,8 @@ override fun getInputExprs() = emptyList() + override val isShiftDiscouraged = true + private val Any?.widened: Any? get() = when (this) { is Int -> toLong() is Float -> toDouble() Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEMemberAccessExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEMemberAccessExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEMemberAccessExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -24,6 +24,7 @@ import com.demonwav.mcdev.platform.mixin.expression.gen.psi.MEExpression import com.demonwav.mcdev.platform.mixin.expression.gen.psi.MEName import com.demonwav.mcdev.platform.mixin.expression.gen.psi.impl.MEExpressionImpl +import com.demonwav.mcdev.platform.mixin.expression.psi.MEPsiUtil import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.QualifiedMember import com.intellij.lang.ASTNode import com.intellij.psi.JavaPsiFacade @@ -66,6 +67,8 @@ override fun getInputExprs() = listOf(receiverExpr) + override val isShiftDiscouraged get() = !MEPsiUtil.isAccessedForWriting(this) + protected abstract val receiverExpr: MEExpression protected abstract val memberName: MEName } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEMethodCallExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEMethodCallExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEMethodCallExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -71,6 +71,8 @@ override fun getInputExprs() = listOf(receiverExpr) + (arguments?.expressionList ?: emptyList()) + override val isShiftDiscouraged = false + protected abstract val receiverExpr: MEExpression protected abstract val memberName: MEName protected abstract val arguments: MEArguments? Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MENameExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MENameExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MENameExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -24,6 +24,7 @@ import com.demonwav.mcdev.platform.mixin.expression.gen.psi.MEExpression import com.demonwav.mcdev.platform.mixin.expression.gen.psi.MEName import com.demonwav.mcdev.platform.mixin.expression.gen.psi.impl.MEExpressionImpl +import com.demonwav.mcdev.platform.mixin.expression.psi.MEPsiUtil import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.QualifiedMember import com.demonwav.mcdev.platform.mixin.util.LocalVariables import com.intellij.lang.ASTNode @@ -73,6 +74,8 @@ override fun getInputExprs() = emptyList() + override val isShiftDiscouraged get() = !MEPsiUtil.isAccessedForWriting(this) + @Suppress("PropertyName") protected abstract val MEName: MEName } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MENewExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MENewExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MENewExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -132,6 +132,8 @@ override fun getInputExprs() = dimExprs + (arguments?.expressionList ?: emptyList()) + override val isShiftDiscouraged = false + protected abstract val type: MEName protected abstract val dimExprs: List protected abstract val arguments: MEArguments? Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEParenthesizedExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEParenthesizedExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEParenthesizedExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -33,5 +33,7 @@ override fun getInputExprs() = listOfNotNull(expression) + override val isShiftDiscouraged get() = expression?.isShiftDiscouraged == true + protected abstract val expression: MEExpression? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEReturnStatementImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEReturnStatementImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEReturnStatementImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -39,5 +39,7 @@ override fun getInputExprs() = listOfNotNull(valueExpr) + override val isShiftDiscouraged = true + protected abstract val valueExpr: MEExpression? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEStatementImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEStatementImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEStatementImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -35,4 +35,9 @@ override fun getInputExprs(): List { throw UnsupportedOperationException("Please implement getInputExprs for your statement type") } + + override val isShiftDiscouraged: Boolean + get() { + throw UnsupportedOperationException("Please implement isShiftDiscouraged for your statement type") -} + } +} Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEStaticMethodCallExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEStaticMethodCallExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEStaticMethodCallExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -55,6 +55,8 @@ override fun getInputExprs() = arguments?.expressionList ?: emptyList() + override val isShiftDiscouraged = false + protected abstract val memberName: MEName protected abstract val arguments: MEArguments? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MESuperCallExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MESuperCallExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MESuperCallExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -55,6 +55,8 @@ override fun getInputExprs() = arguments?.expressionList ?: emptyList() + override val isShiftDiscouraged = false + protected abstract val memberName: MEName? protected abstract val arguments: MEArguments? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/METhisExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/METhisExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/METhisExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -33,4 +33,6 @@ } override fun getInputExprs() = emptyList() + + override val isShiftDiscouraged = true } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/METhrowStatementImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/METhrowStatementImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/METhrowStatementImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -40,5 +40,7 @@ override fun getInputExprs() = listOfNotNull(valueExpr) + override val isShiftDiscouraged = true + protected abstract val valueExpr: MEExpression? } Index: src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEUnaryExpressionImplMixin.kt =================================================================== --- src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEUnaryExpressionImplMixin.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/expression/psi/mixins/impl/MEUnaryExpressionImplMixin.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -61,5 +61,7 @@ override fun getInputExprs() = listOfNotNull(expression) + override val isShiftDiscouraged = true + protected abstract val expression: MEExpression? } Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/ConstantStringMethodInjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/injectionPoint/ConstantStringMethodInjectionPoint.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/handlers/injectionPoint/ConstantStringMethodInjectionPoint.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -86,7 +86,7 @@ editor.caretModel.moveToOffset(cursorElement.textRange.endOffset - 1) } - override fun isShiftDiscouraged(shift: Int): Boolean { + override fun isShiftDiscouraged(shift: Int, at: PsiAnnotation): Boolean { // allow shifting after the INVOKE_STRING return shift != 0 && shift != 1 } Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/FieldInjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/injectionPoint/FieldInjectionPoint.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/handlers/injectionPoint/FieldInjectionPoint.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -59,7 +59,7 @@ completeExtraStringAtAttribute(editor, reference, "target") } - override fun isShiftDiscouraged(shift: Int): Boolean { + override fun isShiftDiscouraged(shift: Int, at: PsiAnnotation): Boolean { // allow shift after the field access return shift != 0 && shift != 1 } Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/InjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/injectionPoint/InjectionPoint.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/handlers/injectionPoint/InjectionPoint.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -108,7 +108,7 @@ open val discouragedMessage: String? = null - open fun isShiftDiscouraged(shift: Int): Boolean = shift != 0 + open fun isShiftDiscouraged(shift: Int, at: PsiAnnotation): Boolean = shift != 0 abstract fun createNavigationVisitor( at: PsiAnnotation, Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/InvokeAssignInjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/injectionPoint/InvokeAssignInjectionPoint.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/handlers/injectionPoint/InvokeAssignInjectionPoint.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -81,7 +81,7 @@ override fun getArgValueListDelimiter(at: PsiAnnotation, key: String) = SKIP_LIST_DELIMITER.takeIf { key == "skip" } - override fun isShiftDiscouraged(shift: Int): Boolean { + override fun isShiftDiscouraged(shift: Int, at: PsiAnnotation): Boolean { // Allow shifting before INVOKE_ASSIGN return shift != 0 && shift != -1 } Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/InvokeInjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/injectionPoint/InvokeInjectionPoint.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/handlers/injectionPoint/InvokeInjectionPoint.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -44,7 +44,7 @@ completeExtraStringAtAttribute(editor, reference, "target") } - override fun isShiftDiscouraged(shift: Int): Boolean { + override fun isShiftDiscouraged(shift: Int, at: PsiAnnotation): Boolean { // Allow shifting after INVOKE return shift != 0 && shift != 1 } Index: src/main/kotlin/platform/mixin/handlers/injectionPoint/LoadInjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/injectionPoint/LoadInjectionPoint.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/handlers/injectionPoint/LoadInjectionPoint.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -67,7 +67,7 @@ return LocalInfo.fromAnnotation(localType, modifyVariable) } - override fun isShiftDiscouraged(shift: Int): Boolean { + override fun isShiftDiscouraged(shift: Int, at: PsiAnnotation): Boolean { if (shift == 0) { return false } Index: src/main/kotlin/platform/mixin/handlers/mixinextras/ExpressionInjectionPoint.kt =================================================================== --- src/main/kotlin/platform/mixin/handlers/mixinextras/ExpressionInjectionPoint.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/handlers/mixinextras/ExpressionInjectionPoint.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -24,6 +24,7 @@ import com.demonwav.mcdev.platform.mixin.expression.MEExpressionMatchUtil import com.demonwav.mcdev.platform.mixin.expression.MESourceMatchContext import com.demonwav.mcdev.platform.mixin.expression.gen.psi.MECapturingExpression +import com.demonwav.mcdev.platform.mixin.expression.gen.psi.MEExpressionStatement import com.demonwav.mcdev.platform.mixin.expression.gen.psi.MEStatement import com.demonwav.mcdev.platform.mixin.expression.meExpressionElementFactory import com.demonwav.mcdev.platform.mixin.expression.psi.MEExpressionFile @@ -35,13 +36,14 @@ import com.demonwav.mcdev.platform.mixin.util.LocalInfo import com.demonwav.mcdev.platform.mixin.util.MixinConstants import com.demonwav.mcdev.util.MemberReference +import com.demonwav.mcdev.util.cached +import com.demonwav.mcdev.util.childrenOfType import com.demonwav.mcdev.util.computeStringArray import com.demonwav.mcdev.util.constantStringValue import com.demonwav.mcdev.util.descriptor import com.demonwav.mcdev.util.findAnnotations import com.demonwav.mcdev.util.findContainingModifierList import com.demonwav.mcdev.util.findModule -import com.demonwav.mcdev.util.findMultiInjectionHost import com.demonwav.mcdev.util.ifEmpty import com.demonwav.mcdev.util.parseArray import com.demonwav.mcdev.util.resolveType @@ -58,6 +60,7 @@ import com.intellij.psi.PsiModifierList import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.JavaCodeStyleManager +import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.parentOfType import com.llamalad7.mixinextras.expression.impl.ast.expressions.Expression import com.llamalad7.mixinextras.expression.impl.point.ExpressionContext @@ -93,6 +96,30 @@ editor.caretModel.moveToOffset(exprLiteral.textRange.startOffset + 1) } + override fun isShiftDiscouraged(shift: Int, at: PsiAnnotation): Boolean { + if (shift == 0) { + return false + } + if (shift != 1) { + return true + } + + val atId = at.findDeclaredAttributeValue("id")?.constantStringValue ?: "" + val injectorAnnotation = AtResolver.findInjectorAnnotation(at) ?: return false + val modifierList = injectorAnnotation.parent as? PsiModifierList ?: return false + val parsedExprs = parseExpressions(at.project, modifierList, atId).ifEmpty { return false } + + return parsedExprs.any { (_, expr) -> + val captures = expr.childrenOfType() + if (captures.any { it.parent !is MEExpressionStatement }) { + // if there is a capture that's not at the root, discourage shifting, because that shift could likely be + // translated into a different capture + return@any true + } + expr.isShiftDiscouraged + } + } + override fun createNavigationVisitor( at: PsiAnnotation, target: MixinSelector?, @@ -199,8 +226,13 @@ } ?: project.meExpressionElementFactory.createFile("do {$text}").statements.singleOrNull() ?: project.meExpressionElementFactory.createStatement("empty") - MEExpressionMatchUtil.createExpression(text)?.let { it to rootStatementPsi } + val expr = expressionElement.cached(PsiModificationTracker.MODIFICATION_COUNT) { + // re-get the text because cached doesn't like it when the text changes + val exprText = expressionElement.constantStringValue ?: return@cached null + MEExpressionMatchUtil.createExpression(exprText) - } + } + expr?.let { expr to rootStatementPsi } + } .toList() } Index: src/main/kotlin/platform/mixin/inspection/injector/DiscouragedShiftInspection.kt =================================================================== --- src/main/kotlin/platform/mixin/inspection/injector/DiscouragedShiftInspection.kt (revision 8360b831e95e44630ed3d742ea285e6f1a1f910c) +++ src/main/kotlin/platform/mixin/inspection/injector/DiscouragedShiftInspection.kt (revision 9cd279d90e768ecb380f71058ea608bfabea9f13) @@ -46,18 +46,18 @@ val atValue = annotation.findDeclaredAttributeValue("value") ?: return val atCode = atValue.constantStringValue ?: return val shift = AtResolver.getShift(annotation) - if (isShiftDiscouraged(shift, injector, atCode)) { + if (isShiftDiscouraged(shift, annotation, injector, atCode)) { val shiftElement = annotation.findDeclaredAttributeValue("shift") ?: return holder.registerProblem(shiftElement, "Shifting like this is discouraged because it's brittle") } } } - private fun isShiftDiscouraged(shift: Int, injector: InjectorAnnotationHandler, atCode: String): Boolean { + private fun isShiftDiscouraged(shift: Int, at: PsiAnnotation, injector: InjectorAnnotationHandler, atCode: String): Boolean { if (injector.isShiftAlwaysDiscouraged) { return shift != 0 } - return InjectionPoint.byAtCode(atCode)?.isShiftDiscouraged(shift) == true + return InjectionPoint.byAtCode(atCode)?.isShiftDiscouraged(shift, at) == true } }