mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
KTIJ-30535 [kotlin] Migrate quickfixes used in SuspiciousCollectionReassignmentInspection to ModCommand API
This allows to exclude the corresponding fixes from the `allowResolveInWriteAction` whitelist, because ModCommand actions are performed in the background GitOrigin-RevId: b551e1381d196e3b0e3d5078fe91c3445dbb81ff
This commit is contained in:
committed by
intellij-monorepo-bot
parent
de33eef5e2
commit
03fa8a890f
+18
-19
@@ -4,17 +4,19 @@ package org.jetbrains.kotlin.idea.inspections
|
||||
|
||||
import com.intellij.codeInsight.intention.FileModifier.SafeFieldForPreview
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.base.psi.replaced
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections.KotlinModCommandQuickFix
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.idea.project.builtIns
|
||||
import org.jetbrains.kotlin.idea.quickfix.ChangeToMutableCollectionFix
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
@@ -33,9 +35,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.findExistingEditor
|
||||
|
||||
class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
|
||||
binaryExpressionVisitor(fun(binaryExpression) {
|
||||
@@ -75,19 +74,19 @@ class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
||||
)
|
||||
})
|
||||
|
||||
private class ChangeTypeToMutableFix(@SafeFieldForPreview private val type: KotlinType) : LocalQuickFix {
|
||||
private class ChangeTypeToMutableFix(@SafeFieldForPreview private val type: KotlinType) : KotlinModCommandQuickFix<KtOperationReferenceExpression>() {
|
||||
override fun getName() = KotlinBundle.message("change.type.to.mutable.fix.text")
|
||||
|
||||
override fun getFamilyName() = name
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val operationReference = descriptor.psiElement as? KtOperationReferenceExpression ?: return
|
||||
override fun applyFix(project: Project, element: KtOperationReferenceExpression, updater: ModPsiUpdater) {
|
||||
val operationReference = element
|
||||
val binaryExpression = operationReference.parent as? KtBinaryExpression ?: return
|
||||
val left = binaryExpression.left ?: return
|
||||
val property = left.mainReference?.resolve() as? KtProperty ?: return
|
||||
ChangeToMutableCollectionFix.applyFix(property, type)
|
||||
property.valOrVarKeyword.replace(KtPsiFactory(project).createValKeyword())
|
||||
binaryExpression.findExistingEditor()?.caretModel?.moveToOffset(property.endOffset)
|
||||
updater.moveCaretTo(property.endOffset)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -97,13 +96,13 @@ class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
||||
}
|
||||
}
|
||||
|
||||
private class ReplaceWithFilterFix : LocalQuickFix {
|
||||
private class ReplaceWithFilterFix : KotlinModCommandQuickFix<KtOperationReferenceExpression>() {
|
||||
override fun getName() = KotlinBundle.message("replace.with.filter.fix.text")
|
||||
|
||||
override fun getFamilyName() = name
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val operationReference = descriptor.psiElement as? KtOperationReferenceExpression ?: return
|
||||
override fun applyFix(project: Project, element: KtOperationReferenceExpression, updater: ModPsiUpdater) {
|
||||
val operationReference = element
|
||||
val binaryExpression = operationReference.parent as? KtBinaryExpression ?: return
|
||||
val left = binaryExpression.left ?: return
|
||||
val right = binaryExpression.right ?: return
|
||||
@@ -121,13 +120,13 @@ class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
||||
}
|
||||
}
|
||||
|
||||
private class ReplaceWithAssignmentFix : LocalQuickFix {
|
||||
private class ReplaceWithAssignmentFix : KotlinModCommandQuickFix<KtOperationReferenceExpression>() {
|
||||
override fun getName() = KotlinBundle.message("replace.with.assignment.fix.text")
|
||||
|
||||
override fun getFamilyName() = name
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val operationReference = descriptor.psiElement as? KtOperationReferenceExpression ?: return
|
||||
override fun applyFix(project: Project, element: KtOperationReferenceExpression, updater: ModPsiUpdater) {
|
||||
val operationReference = element
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
operationReference.replace(psiFactory.createOperationName(KtTokens.EQ.value))
|
||||
}
|
||||
@@ -161,13 +160,13 @@ class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
||||
}
|
||||
}
|
||||
|
||||
private class JoinWithInitializerFix(@SafeFieldForPreview private val op: KtSingleValueToken) : LocalQuickFix {
|
||||
private class JoinWithInitializerFix(@SafeFieldForPreview private val op: KtSingleValueToken) : KotlinModCommandQuickFix<KtOperationReferenceExpression>() {
|
||||
override fun getName() = KotlinBundle.message("join.with.initializer.fix.text")
|
||||
|
||||
override fun getFamilyName() = name
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val operationReference = descriptor.psiElement as? KtOperationReferenceExpression ?: return
|
||||
override fun applyFix(project: Project, element: KtOperationReferenceExpression, updater: ModPsiUpdater) {
|
||||
val operationReference = element
|
||||
val binaryExpression = operationReference.parent as? KtBinaryExpression ?: return
|
||||
val left = binaryExpression.left ?: return
|
||||
val right = binaryExpression.right ?: return
|
||||
@@ -178,7 +177,7 @@ class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
||||
val newOp = if (op == KtTokens.PLUSEQ) KtTokens.PLUS else KtTokens.MINUS
|
||||
val replaced = initializer.replaced(psiFactory.createExpressionByPattern("$0 $1 $2", initializer, newOp.value, right))
|
||||
binaryExpression.delete()
|
||||
property.findExistingEditor()?.caretModel?.moveToOffset(replaced.endOffset)
|
||||
updater.moveCaretTo(replaced.endOffset)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+23
-11
@@ -2,8 +2,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInspection.util.IntentionFamilyName
|
||||
import com.intellij.modcommand.ActionContext
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.modcommand.Presentation
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
@@ -11,7 +14,7 @@ import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.idea.base.psi.replaced
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.quickfixes.KotlinQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.KotlinPsiUpdateModCommandAction
|
||||
import org.jetbrains.kotlin.idea.project.builtIns
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -21,21 +24,30 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class ChangeToMutableCollectionFix(property: KtProperty, private val type: String) : KotlinQuickFixAction<KtProperty>(property) {
|
||||
override fun getText() = KotlinBundle.message("fix.change.to.mutable.type.text", "Mutable$type")
|
||||
class ChangeToMutableCollectionFix(property: KtProperty, context: ElementContext) :
|
||||
KotlinPsiUpdateModCommandAction.ElementBased<KtProperty, ChangeToMutableCollectionFix.ElementContext>(property, context) {
|
||||
|
||||
override fun getFamilyName() = text
|
||||
class ElementContext(
|
||||
val typeName: String,
|
||||
)
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val property = element ?: return
|
||||
override fun getPresentation(context: ActionContext, element: KtProperty): Presentation {
|
||||
val elementContext = getElementContext(context, element)
|
||||
return Presentation.of(KotlinBundle.message("fix.change.to.mutable.type.text", "Mutable${elementContext.typeName}"))
|
||||
}
|
||||
|
||||
override fun getFamilyName(): @IntentionFamilyName String = KotlinBundle.message("fix.change.to.mutable.type.family")
|
||||
|
||||
override fun invoke(actionContext: ActionContext, element: KtProperty, elementContext: ElementContext, updater: ModPsiUpdater) {
|
||||
val property = element
|
||||
val context = property.analyze(BodyResolveMode.PARTIAL)
|
||||
val type = property.initializer?.getType(context) ?: return
|
||||
applyFix(property, type)
|
||||
editor?.caretModel?.moveToOffset(property.endOffset)
|
||||
updater.moveCaretTo(property.endOffset)
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtProperty>? {
|
||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||
val element = Errors.NO_SET_METHOD.cast(diagnostic).psiElement as? KtArrayAccessExpression ?: return null
|
||||
val arrayExpr = element.arrayExpression ?: return null
|
||||
val context = arrayExpr.analyze(BodyResolveMode.PARTIAL)
|
||||
@@ -44,7 +56,7 @@ class ChangeToMutableCollectionFix(property: KtProperty, private val type: Strin
|
||||
val property = arrayExpr.mainReference?.resolve() as? KtProperty ?: return null
|
||||
if (!isApplicable(property)) return null
|
||||
val typeName = type.constructor.declarationDescriptor?.name?.asString() ?: return null
|
||||
return ChangeToMutableCollectionFix(property, typeName)
|
||||
return ChangeToMutableCollectionFix(property, ElementContext(typeName)).asIntention()
|
||||
}
|
||||
|
||||
private fun KotlinType.isReadOnlyListOrMap(builtIns: KotlinBuiltIns): Boolean {
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@
|
||||
// WITH_STDLIB
|
||||
fun test() {
|
||||
val list = mutableListOf(1)<caret>
|
||||
list <selection>+=</selection> 2
|
||||
list += 2
|
||||
}
|
||||
// OFFLINE_REPORT: "'+=' on a read-only list creates a new list under the hood"
|
||||
@@ -9,8 +9,6 @@ org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.IntentionBasedInsp
|
||||
org.jetbrains.kotlin.idea.codeInsight.inspections.shared.KotlinOptimizeImportsQuickFix
|
||||
org.jetbrains.kotlin.idea.inspections.migration.ObsoleteCoroutinesDelegateQuickFix
|
||||
org.jetbrains.kotlin.idea.inspections.SafeDeleteFix
|
||||
org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection$ChangeTypeToMutableFix
|
||||
org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection$JoinWithInitializerFix
|
||||
org.jetbrains.kotlin.idea.inspections.UnusedReceiverParameterInspection$RemoveReceiverFix
|
||||
org.jetbrains.kotlin.idea.intentions.AddPropertyAccessorsIntention
|
||||
org.jetbrains.kotlin.idea.intentions.AddPropertyGetterIntention
|
||||
@@ -37,7 +35,6 @@ org.jetbrains.kotlin.idea.quickfix.ChangeFunctionLiteralSignatureFix
|
||||
org.jetbrains.kotlin.idea.quickfix.ChangeFunctionLiteralReturnTypeFix
|
||||
org.jetbrains.kotlin.idea.quickfix.ChangeFunctionSignatureFix$Companion$RemoveParameterFix
|
||||
org.jetbrains.kotlin.idea.quickfix.ChangeParameterTypeFix
|
||||
org.jetbrains.kotlin.idea.quickfix.ChangeToMutableCollectionFix
|
||||
org.jetbrains.kotlin.idea.quickfix.ChangeVariableTypeFix
|
||||
org.jetbrains.kotlin.idea.quickfix.ChangeVariableTypeFix$ForOverridden
|
||||
org.jetbrains.kotlin.idea.quickfix.ChangeVisibilityFix$ChangeToInternalFix
|
||||
|
||||
Reference in New Issue
Block a user