FIR IDE: Simplify registerPsiQuickFixes
This change makes it possible to register multiple fixes for a diagnostic. Also, the previous registerPsiQuickFix that relies compiler to infer the KtFirDiagnostic type parameter is dangerous since it can silently register fixes on interface `KtDiagnosticWithPsi` if caller doesn't specify it explicitly.
This commit is contained in:
committed by
Ilya Kirillov
parent
cacd84390e
commit
51da54ce66
@@ -56,10 +56,13 @@ class KtQuickFixesListBuilder private constructor() {
|
|||||||
private val quickFixes = mutableMapOf<KClass<out KtDiagnosticWithPsi<*>>, MutableList<HLQuickFixFactory>>()
|
private val quickFixes = mutableMapOf<KClass<out KtDiagnosticWithPsi<*>>, MutableList<HLQuickFixFactory>>()
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
inline fun <DIAGNOSTIC_PSI : PsiElement, reified DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>> registerPsiQuickFix(
|
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>> registerPsiQuickFixes(
|
||||||
quickFixFactory: QuickFixesPsiBasedFactory<DIAGNOSTIC_PSI>
|
diagnosticClass: KClass<DIAGNOSTIC>,
|
||||||
|
vararg quickFixFactories: QuickFixesPsiBasedFactory<in DIAGNOSTIC_PSI>
|
||||||
) {
|
) {
|
||||||
registerPsiQuickFix(DIAGNOSTIC::class, quickFixFactory)
|
for (quickFixFactory in quickFixFactories) {
|
||||||
|
registerPsiQuickFix(diagnosticClass, quickFixFactory)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
@@ -72,7 +75,7 @@ class KtQuickFixesListBuilder private constructor() {
|
|||||||
@PrivateForInline
|
@PrivateForInline
|
||||||
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>> registerPsiQuickFix(
|
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>> registerPsiQuickFix(
|
||||||
diagnosticClass: KClass<DIAGNOSTIC>,
|
diagnosticClass: KClass<DIAGNOSTIC>,
|
||||||
quickFixFactory: QuickFixesPsiBasedFactory<DIAGNOSTIC_PSI>
|
quickFixFactory: QuickFixesPsiBasedFactory<in DIAGNOSTIC_PSI>
|
||||||
) {
|
) {
|
||||||
quickFixes.getOrPut(diagnosticClass) { mutableListOf() }.add(HLQuickFixFactory.HLQuickFixesPsiBasedFactory(quickFixFactory))
|
quickFixes.getOrPut(diagnosticClass) { mutableListOf() }.add(HLQuickFixFactory.HLQuickFixesPsiBasedFactory(quickFixFactory))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,24 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.quickfix
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import org.jetbrains.kotlin.idea.fir.api.fixes.KtQuickFixRegistrar
|
import org.jetbrains.kotlin.idea.fir.api.fixes.KtQuickFixRegistrar
|
||||||
import org.jetbrains.kotlin.idea.fir.api.fixes.KtQuickFixesList
|
import org.jetbrains.kotlin.idea.fir.api.fixes.KtQuickFixesList
|
||||||
import org.jetbrains.kotlin.idea.fir.api.fixes.KtQuickFixesListBuilder
|
import org.jetbrains.kotlin.idea.fir.api.fixes.KtQuickFixesListBuilder
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic
|
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic
|
||||||
import org.jetbrains.kotlin.idea.quickfix.fixes.ChangeTypeQuickFix
|
import org.jetbrains.kotlin.idea.quickfix.fixes.ChangeTypeQuickFix
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
|
||||||
|
|
||||||
class MainKtQuickFixRegistrar : KtQuickFixRegistrar() {
|
class MainKtQuickFixRegistrar : KtQuickFixRegistrar() {
|
||||||
private val modifiers = KtQuickFixesListBuilder.registerPsiQuickFix {
|
private val modifiers = KtQuickFixesListBuilder.registerPsiQuickFix {
|
||||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.RedundantModifier>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true))
|
registerPsiQuickFixes(KtFirDiagnostic.RedundantModifier::class, RemoveModifierFix.removeRedundantModifier)
|
||||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.IncompatibleModifiers>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false))
|
registerPsiQuickFixes(KtFirDiagnostic.IncompatibleModifiers::class, RemoveModifierFix.removeNonRedundantModifier)
|
||||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.RepeatedModifier>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false))
|
registerPsiQuickFixes(KtFirDiagnostic.RepeatedModifier::class, RemoveModifierFix.removeNonRedundantModifier)
|
||||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.DeprecatedModifierPair>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true))
|
registerPsiQuickFixes(KtFirDiagnostic.DeprecatedModifierPair::class, RemoveModifierFix.removeRedundantModifier)
|
||||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.TypeParametersInEnum>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true))
|
registerPsiQuickFixes(KtFirDiagnostic.TypeParametersInEnum::class, RemoveModifierFix.removeRedundantModifier)
|
||||||
registerPsiQuickFix<KtModifierListOwner, KtFirDiagnostic.RedundantOpenInInterface>(
|
registerPsiQuickFixes(
|
||||||
|
KtFirDiagnostic.RedundantOpenInInterface::class,
|
||||||
RemoveModifierFix.createRemoveModifierFromListOwnerFactoryByModifierListOwner(
|
RemoveModifierFix.createRemoveModifierFromListOwnerFactoryByModifierListOwner(
|
||||||
modifier = KtTokens.OPEN_KEYWORD,
|
modifier = KtTokens.OPEN_KEYWORD,
|
||||||
isRedundant = true
|
isRedundant = true
|
||||||
@@ -37,9 +35,9 @@ class MainKtQuickFixRegistrar : KtQuickFixRegistrar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val mutability = KtQuickFixesListBuilder.registerPsiQuickFix {
|
private val mutability = KtQuickFixesListBuilder.registerPsiQuickFix {
|
||||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.VarOverriddenByVal>(ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY)
|
registerPsiQuickFixes(KtFirDiagnostic.VarOverriddenByVal::class, ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY)
|
||||||
registerPsiQuickFix<KtParameter, KtFirDiagnostic.VarAnnotationParameter>(ChangeVariableMutabilityFix.VAR_ANNOTATION_PARAMETER_FACTORY)
|
registerPsiQuickFixes(KtFirDiagnostic.VarAnnotationParameter::class, ChangeVariableMutabilityFix.VAR_ANNOTATION_PARAMETER_FACTORY)
|
||||||
registerPsiQuickFix<KtModifierListOwner, KtFirDiagnostic.InapplicableLateinitModifier>(ChangeVariableMutabilityFix.LATEINIT_VAL_FACTORY)
|
registerPsiQuickFixes(KtFirDiagnostic.InapplicableLateinitModifier::class, ChangeVariableMutabilityFix.LATEINIT_VAL_FACTORY)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val list: KtQuickFixesList = KtQuickFixesList.createCombined(
|
override val list: KtQuickFixesList = KtQuickFixesList.createCombined(
|
||||||
|
|||||||
+4
-1
@@ -51,6 +51,9 @@ class RemoveModifierFix(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
val removeRedundantModifier = createRemoveModifierFactory(isRedundant = true)
|
||||||
|
val removeNonRedundantModifier = createRemoveModifierFactory(isRedundant = false)
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"For binary compatibility",
|
"For binary compatibility",
|
||||||
replaceWith = ReplaceWith("createRemoveModifierFromListOwnerPsiBasedFactory(modifier, isRedundant)")
|
replaceWith = ReplaceWith("createRemoveModifierFromListOwnerPsiBasedFactory(modifier, isRedundant)")
|
||||||
@@ -79,7 +82,7 @@ class RemoveModifierFix(
|
|||||||
listOf(RemoveModifierFix(it, modifier, isRedundant))
|
listOf(RemoveModifierFix(it, modifier, isRedundant))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createRemoveModifierFactory(isRedundant: Boolean = false): QuickFixesPsiBasedFactory<PsiElement> {
|
private fun createRemoveModifierFactory(isRedundant: Boolean = false): QuickFixesPsiBasedFactory<PsiElement> {
|
||||||
return quickFixesPsiBasedFactory { psiElement: PsiElement ->
|
return quickFixesPsiBasedFactory { psiElement: PsiElement ->
|
||||||
val elementType = psiElement.node.elementType as? KtModifierKeywordToken ?: return@quickFixesPsiBasedFactory emptyList()
|
val elementType = psiElement.node.elementType as? KtModifierKeywordToken ?: return@quickFixesPsiBasedFactory emptyList()
|
||||||
val modifierListOwner = psiElement.getStrictParentOfType<KtModifierListOwner>()
|
val modifierListOwner = psiElement.getStrictParentOfType<KtModifierListOwner>()
|
||||||
|
|||||||
@@ -116,14 +116,14 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
USELESS_ELVIS.registerFactory(RemoveUselessElvisFix)
|
USELESS_ELVIS.registerFactory(RemoveUselessElvisFix)
|
||||||
USELESS_ELVIS_RIGHT_IS_NULL.registerFactory(RemoveUselessElvisFix)
|
USELESS_ELVIS_RIGHT_IS_NULL.registerFactory(RemoveUselessElvisFix)
|
||||||
|
|
||||||
val removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFactory(true)
|
val removeRedundantModifierFactory = RemoveModifierFix.removeRedundantModifier
|
||||||
REDUNDANT_MODIFIER.registerFactory(removeRedundantModifierFactory)
|
REDUNDANT_MODIFIER.registerFactory(removeRedundantModifierFactory)
|
||||||
REDUNDANT_OPEN_IN_INTERFACE.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD, true))
|
REDUNDANT_OPEN_IN_INTERFACE.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD, true))
|
||||||
REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE.registerFactory(RemoveModifierFix.createRemoveSuspendFactory())
|
REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE.registerFactory(RemoveModifierFix.createRemoveSuspendFactory())
|
||||||
UNNECESSARY_LATEINIT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(LATEINIT_KEYWORD))
|
UNNECESSARY_LATEINIT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(LATEINIT_KEYWORD))
|
||||||
|
|
||||||
REDUNDANT_PROJECTION.registerFactory(RemoveModifierFix.createRemoveProjectionFactory(true))
|
REDUNDANT_PROJECTION.registerFactory(RemoveModifierFix.createRemoveProjectionFactory(true))
|
||||||
INCOMPATIBLE_MODIFIERS.registerFactory(RemoveModifierFix.createRemoveModifierFactory(false))
|
INCOMPATIBLE_MODIFIERS.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED.registerFactory(RemoveModifierFix.createRemoveVarianceFactory())
|
VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED.registerFactory(RemoveModifierFix.createRemoveVarianceFactory())
|
||||||
|
|
||||||
val removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD)
|
val removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD)
|
||||||
@@ -133,27 +133,26 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
)
|
)
|
||||||
NON_FINAL_MEMBER_IN_OBJECT.registerFactory(removeOpenModifierFactory)
|
NON_FINAL_MEMBER_IN_OBJECT.registerFactory(removeOpenModifierFactory)
|
||||||
|
|
||||||
val removeModifierFactory = RemoveModifierFix.createRemoveModifierFactory()
|
GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory)
|
SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory)
|
PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY.registerFactory(removeModifierFactory)
|
|
||||||
PRIVATE_SETTER_FOR_OPEN_PROPERTY.registerFactory(
|
PRIVATE_SETTER_FOR_OPEN_PROPERTY.registerFactory(
|
||||||
AddModifierFixMpp.createFactory(FINAL_KEYWORD, KtProperty::class.java),
|
AddModifierFixMpp.createFactory(FINAL_KEYWORD, KtProperty::class.java),
|
||||||
removeModifierFactory
|
RemoveModifierFix.removeNonRedundantModifier
|
||||||
)
|
)
|
||||||
REDUNDANT_MODIFIER_IN_GETTER.registerFactory(removeRedundantModifierFactory)
|
REDUNDANT_MODIFIER_IN_GETTER.registerFactory(removeRedundantModifierFactory)
|
||||||
WRONG_MODIFIER_TARGET.registerFactory(removeModifierFactory, ConstValFactory)
|
WRONG_MODIFIER_TARGET.registerFactory(RemoveModifierFix.removeNonRedundantModifier, ConstValFactory)
|
||||||
DEPRECATED_MODIFIER.registerFactory(ReplaceModifierFix)
|
DEPRECATED_MODIFIER.registerFactory(ReplaceModifierFix)
|
||||||
REDUNDANT_MODIFIER_FOR_TARGET.registerFactory(removeModifierFactory)
|
REDUNDANT_MODIFIER_FOR_TARGET.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
WRONG_MODIFIER_CONTAINING_DECLARATION.registerFactory(removeModifierFactory)
|
WRONG_MODIFIER_CONTAINING_DECLARATION.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
REPEATED_MODIFIER.registerFactory(removeModifierFactory)
|
REPEATED_MODIFIER.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
NON_PRIVATE_CONSTRUCTOR_IN_ENUM.registerFactory(removeModifierFactory)
|
NON_PRIVATE_CONSTRUCTOR_IN_ENUM.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
NON_PRIVATE_CONSTRUCTOR_IN_SEALED.registerFactory(removeModifierFactory)
|
NON_PRIVATE_CONSTRUCTOR_IN_SEALED.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED.registerFactory(removeModifierFactory)
|
NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
TYPE_CANT_BE_USED_FOR_CONST_VAL.registerFactory(removeModifierFactory)
|
TYPE_CANT_BE_USED_FOR_CONST_VAL.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
DEPRECATED_BINARY_MOD.registerFactory(removeModifierFactory)
|
DEPRECATED_BINARY_MOD.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
DEPRECATED_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
|
DEPRECATED_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
|
||||||
FORBIDDEN_BINARY_MOD.registerFactory(removeModifierFactory)
|
FORBIDDEN_BINARY_MOD.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
FORBIDDEN_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
|
FORBIDDEN_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
|
||||||
|
|
||||||
NO_EXPLICIT_VISIBILITY_IN_API_MODE.registerFactory(ChangeVisibilityFix.SetExplicitVisibilityFactory)
|
NO_EXPLICIT_VISIBILITY_IN_API_MODE.registerFactory(ChangeVisibilityFix.SetExplicitVisibilityFactory)
|
||||||
@@ -604,7 +603,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
|
|
||||||
CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT.registerFactory(
|
CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT.registerFactory(
|
||||||
MoveMemberToCompanionObjectIntention,
|
MoveMemberToCompanionObjectIntention,
|
||||||
RemoveModifierFix.createRemoveModifierFactory()
|
RemoveModifierFix.removeNonRedundantModifier
|
||||||
)
|
)
|
||||||
|
|
||||||
NO_COMPANION_OBJECT.registerFactory(AddIsToWhenConditionFix)
|
NO_COMPANION_OBJECT.registerFactory(AddIsToWhenConditionFix)
|
||||||
@@ -614,7 +613,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
|
|
||||||
RESOLUTION_TO_CLASSIFIER.registerFactory(ConvertToAnonymousObjectFix)
|
RESOLUTION_TO_CLASSIFIER.registerFactory(ConvertToAnonymousObjectFix)
|
||||||
|
|
||||||
NOTHING_TO_INLINE.registerFactory(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false))
|
NOTHING_TO_INLINE.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||||
|
|
||||||
DECLARATION_CANT_BE_INLINED.registerFactory(DeclarationCantBeInlinedFactory)
|
DECLARATION_CANT_BE_INLINED.registerFactory(DeclarationCantBeInlinedFactory)
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ private val errorsFixingDiagnosticBasedPostProcessingGroup =
|
|||||||
Errors.INVISIBLE_MEMBER
|
Errors.INVISIBLE_MEMBER
|
||||||
),
|
),
|
||||||
diagnosticBasedProcessing(
|
diagnosticBasedProcessing(
|
||||||
RemoveModifierFix.createRemoveModifierFactory(),
|
RemoveModifierFix.removeNonRedundantModifier,
|
||||||
Errors.WRONG_MODIFIER_TARGET
|
Errors.WRONG_MODIFIER_TARGET
|
||||||
),
|
),
|
||||||
diagnosticBasedProcessing(
|
diagnosticBasedProcessing(
|
||||||
|
|||||||
Reference in New Issue
Block a user