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>>()
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <DIAGNOSTIC_PSI : PsiElement, reified DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>> registerPsiQuickFix(
|
||||
quickFixFactory: QuickFixesPsiBasedFactory<DIAGNOSTIC_PSI>
|
||||
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>> registerPsiQuickFixes(
|
||||
diagnosticClass: KClass<DIAGNOSTIC>,
|
||||
vararg quickFixFactories: QuickFixesPsiBasedFactory<in DIAGNOSTIC_PSI>
|
||||
) {
|
||||
registerPsiQuickFix(DIAGNOSTIC::class, quickFixFactory)
|
||||
for (quickFixFactory in quickFixFactories) {
|
||||
registerPsiQuickFix(diagnosticClass, quickFixFactory)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
@@ -72,7 +75,7 @@ class KtQuickFixesListBuilder private constructor() {
|
||||
@PrivateForInline
|
||||
fun <DIAGNOSTIC_PSI : PsiElement, DIAGNOSTIC : KtDiagnosticWithPsi<DIAGNOSTIC_PSI>> registerPsiQuickFix(
|
||||
diagnosticClass: KClass<DIAGNOSTIC>,
|
||||
quickFixFactory: QuickFixesPsiBasedFactory<DIAGNOSTIC_PSI>
|
||||
quickFixFactory: QuickFixesPsiBasedFactory<in DIAGNOSTIC_PSI>
|
||||
) {
|
||||
quickFixes.getOrPut(diagnosticClass) { mutableListOf() }.add(HLQuickFixFactory.HLQuickFixesPsiBasedFactory(quickFixFactory))
|
||||
}
|
||||
@@ -118,4 +121,4 @@ private fun <K, V> List<Map<K, List<V>>>.merge(): Map<K, List<V>> {
|
||||
}
|
||||
|
||||
@RequiresOptIn
|
||||
annotation class ForKtQuickFixesListBuilder()
|
||||
annotation class ForKtQuickFixesListBuilder()
|
||||
|
||||
@@ -5,24 +5,22 @@
|
||||
|
||||
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.KtQuickFixesList
|
||||
import org.jetbrains.kotlin.idea.fir.api.fixes.KtQuickFixesListBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic
|
||||
import org.jetbrains.kotlin.idea.quickfix.fixes.ChangeTypeQuickFix
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
class MainKtQuickFixRegistrar : KtQuickFixRegistrar() {
|
||||
private val modifiers = KtQuickFixesListBuilder.registerPsiQuickFix {
|
||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.RedundantModifier>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true))
|
||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.IncompatibleModifiers>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false))
|
||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.RepeatedModifier>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false))
|
||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.DeprecatedModifierPair>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true))
|
||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.TypeParametersInEnum>(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true))
|
||||
registerPsiQuickFix<KtModifierListOwner, KtFirDiagnostic.RedundantOpenInInterface>(
|
||||
registerPsiQuickFixes(KtFirDiagnostic.RedundantModifier::class, RemoveModifierFix.removeRedundantModifier)
|
||||
registerPsiQuickFixes(KtFirDiagnostic.IncompatibleModifiers::class, RemoveModifierFix.removeNonRedundantModifier)
|
||||
registerPsiQuickFixes(KtFirDiagnostic.RepeatedModifier::class, RemoveModifierFix.removeNonRedundantModifier)
|
||||
registerPsiQuickFixes(KtFirDiagnostic.DeprecatedModifierPair::class, RemoveModifierFix.removeRedundantModifier)
|
||||
registerPsiQuickFixes(KtFirDiagnostic.TypeParametersInEnum::class, RemoveModifierFix.removeRedundantModifier)
|
||||
registerPsiQuickFixes(
|
||||
KtFirDiagnostic.RedundantOpenInInterface::class,
|
||||
RemoveModifierFix.createRemoveModifierFromListOwnerFactoryByModifierListOwner(
|
||||
modifier = KtTokens.OPEN_KEYWORD,
|
||||
isRedundant = true
|
||||
@@ -37,9 +35,9 @@ class MainKtQuickFixRegistrar : KtQuickFixRegistrar() {
|
||||
}
|
||||
|
||||
private val mutability = KtQuickFixesListBuilder.registerPsiQuickFix {
|
||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.VarOverriddenByVal>(ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY)
|
||||
registerPsiQuickFix<KtParameter, KtFirDiagnostic.VarAnnotationParameter>(ChangeVariableMutabilityFix.VAR_ANNOTATION_PARAMETER_FACTORY)
|
||||
registerPsiQuickFix<KtModifierListOwner, KtFirDiagnostic.InapplicableLateinitModifier>(ChangeVariableMutabilityFix.LATEINIT_VAL_FACTORY)
|
||||
registerPsiQuickFixes(KtFirDiagnostic.VarOverriddenByVal::class, ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY)
|
||||
registerPsiQuickFixes(KtFirDiagnostic.VarAnnotationParameter::class, ChangeVariableMutabilityFix.VAR_ANNOTATION_PARAMETER_FACTORY)
|
||||
registerPsiQuickFixes(KtFirDiagnostic.InapplicableLateinitModifier::class, ChangeVariableMutabilityFix.LATEINIT_VAL_FACTORY)
|
||||
}
|
||||
|
||||
override val list: KtQuickFixesList = KtQuickFixesList.createCombined(
|
||||
@@ -47,4 +45,4 @@ class MainKtQuickFixRegistrar : KtQuickFixRegistrar() {
|
||||
overrides,
|
||||
mutability,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -51,6 +51,9 @@ class RemoveModifierFix(
|
||||
}
|
||||
|
||||
companion object {
|
||||
val removeRedundantModifier = createRemoveModifierFactory(isRedundant = true)
|
||||
val removeNonRedundantModifier = createRemoveModifierFactory(isRedundant = false)
|
||||
|
||||
@Deprecated(
|
||||
"For binary compatibility",
|
||||
replaceWith = ReplaceWith("createRemoveModifierFromListOwnerPsiBasedFactory(modifier, isRedundant)")
|
||||
@@ -79,7 +82,7 @@ class RemoveModifierFix(
|
||||
listOf(RemoveModifierFix(it, modifier, isRedundant))
|
||||
}
|
||||
|
||||
fun createRemoveModifierFactory(isRedundant: Boolean = false): QuickFixesPsiBasedFactory<PsiElement> {
|
||||
private fun createRemoveModifierFactory(isRedundant: Boolean = false): QuickFixesPsiBasedFactory<PsiElement> {
|
||||
return quickFixesPsiBasedFactory { psiElement: PsiElement ->
|
||||
val elementType = psiElement.node.elementType as? KtModifierKeywordToken ?: return@quickFixesPsiBasedFactory emptyList()
|
||||
val modifierListOwner = psiElement.getStrictParentOfType<KtModifierListOwner>()
|
||||
|
||||
@@ -116,14 +116,14 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
USELESS_ELVIS.registerFactory(RemoveUselessElvisFix)
|
||||
USELESS_ELVIS_RIGHT_IS_NULL.registerFactory(RemoveUselessElvisFix)
|
||||
|
||||
val removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFactory(true)
|
||||
val removeRedundantModifierFactory = RemoveModifierFix.removeRedundantModifier
|
||||
REDUNDANT_MODIFIER.registerFactory(removeRedundantModifierFactory)
|
||||
REDUNDANT_OPEN_IN_INTERFACE.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD, true))
|
||||
REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE.registerFactory(RemoveModifierFix.createRemoveSuspendFactory())
|
||||
UNNECESSARY_LATEINIT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(LATEINIT_KEYWORD))
|
||||
|
||||
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())
|
||||
|
||||
val removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD)
|
||||
@@ -133,27 +133,26 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
)
|
||||
NON_FINAL_MEMBER_IN_OBJECT.registerFactory(removeOpenModifierFactory)
|
||||
|
||||
val removeModifierFactory = RemoveModifierFix.createRemoveModifierFactory()
|
||||
GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory)
|
||||
SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory)
|
||||
PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY.registerFactory(removeModifierFactory)
|
||||
GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
PRIVATE_SETTER_FOR_OPEN_PROPERTY.registerFactory(
|
||||
AddModifierFixMpp.createFactory(FINAL_KEYWORD, KtProperty::class.java),
|
||||
removeModifierFactory
|
||||
RemoveModifierFix.removeNonRedundantModifier
|
||||
)
|
||||
REDUNDANT_MODIFIER_IN_GETTER.registerFactory(removeRedundantModifierFactory)
|
||||
WRONG_MODIFIER_TARGET.registerFactory(removeModifierFactory, ConstValFactory)
|
||||
WRONG_MODIFIER_TARGET.registerFactory(RemoveModifierFix.removeNonRedundantModifier, ConstValFactory)
|
||||
DEPRECATED_MODIFIER.registerFactory(ReplaceModifierFix)
|
||||
REDUNDANT_MODIFIER_FOR_TARGET.registerFactory(removeModifierFactory)
|
||||
WRONG_MODIFIER_CONTAINING_DECLARATION.registerFactory(removeModifierFactory)
|
||||
REPEATED_MODIFIER.registerFactory(removeModifierFactory)
|
||||
NON_PRIVATE_CONSTRUCTOR_IN_ENUM.registerFactory(removeModifierFactory)
|
||||
NON_PRIVATE_CONSTRUCTOR_IN_SEALED.registerFactory(removeModifierFactory)
|
||||
NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED.registerFactory(removeModifierFactory)
|
||||
TYPE_CANT_BE_USED_FOR_CONST_VAL.registerFactory(removeModifierFactory)
|
||||
DEPRECATED_BINARY_MOD.registerFactory(removeModifierFactory)
|
||||
REDUNDANT_MODIFIER_FOR_TARGET.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
WRONG_MODIFIER_CONTAINING_DECLARATION.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
REPEATED_MODIFIER.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
NON_PRIVATE_CONSTRUCTOR_IN_ENUM.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
NON_PRIVATE_CONSTRUCTOR_IN_SEALED.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
TYPE_CANT_BE_USED_FOR_CONST_VAL.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
DEPRECATED_BINARY_MOD.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
DEPRECATED_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
|
||||
FORBIDDEN_BINARY_MOD.registerFactory(removeModifierFactory)
|
||||
FORBIDDEN_BINARY_MOD.registerFactory(RemoveModifierFix.removeNonRedundantModifier)
|
||||
FORBIDDEN_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
|
||||
|
||||
NO_EXPLICIT_VISIBILITY_IN_API_MODE.registerFactory(ChangeVisibilityFix.SetExplicitVisibilityFactory)
|
||||
@@ -604,7 +603,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT.registerFactory(
|
||||
MoveMemberToCompanionObjectIntention,
|
||||
RemoveModifierFix.createRemoveModifierFactory()
|
||||
RemoveModifierFix.removeNonRedundantModifier
|
||||
)
|
||||
|
||||
NO_COMPANION_OBJECT.registerFactory(AddIsToWhenConditionFix)
|
||||
@@ -614,7 +613,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ private val errorsFixingDiagnosticBasedPostProcessingGroup =
|
||||
Errors.INVISIBLE_MEMBER
|
||||
),
|
||||
diagnosticBasedProcessing(
|
||||
RemoveModifierFix.createRemoveModifierFactory(),
|
||||
RemoveModifierFix.removeNonRedundantModifier,
|
||||
Errors.WRONG_MODIFIER_TARGET
|
||||
),
|
||||
diagnosticBasedProcessing(
|
||||
@@ -302,4 +302,4 @@ private val processings: List<NamedPostProcessingGroup> = listOf(
|
||||
FormatCodeProcessing()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user