From 51da54ce669ae5ad0024ffc4ec329888dd8ff23b Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Wed, 17 Feb 2021 15:29:57 -0800 Subject: [PATCH] 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. --- .../idea/fir/api/fixes/KtQuickFixesList.kt | 13 ++++--- .../idea/quickfix/MainKtQuickFixRegistrar.kt | 24 ++++++------ .../kotlin/idea/quickfix/RemoveModifierFix.kt | 5 ++- .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 37 +++++++++---------- .../nj2k/postProcessing/J2kPostProcessor.kt | 4 +- 5 files changed, 43 insertions(+), 40 deletions(-) diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt index 511342d768b..75a2a5aef84 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt @@ -56,10 +56,13 @@ class KtQuickFixesListBuilder private constructor() { private val quickFixes = mutableMapOf>, MutableList>() @OptIn(PrivateForInline::class) - inline fun > registerPsiQuickFix( - quickFixFactory: QuickFixesPsiBasedFactory + fun > registerPsiQuickFixes( + diagnosticClass: KClass, + vararg quickFixFactories: QuickFixesPsiBasedFactory ) { - registerPsiQuickFix(DIAGNOSTIC::class, quickFixFactory) + for (quickFixFactory in quickFixFactories) { + registerPsiQuickFix(diagnosticClass, quickFixFactory) + } } @OptIn(PrivateForInline::class) @@ -72,7 +75,7 @@ class KtQuickFixesListBuilder private constructor() { @PrivateForInline fun > registerPsiQuickFix( diagnosticClass: KClass, - quickFixFactory: QuickFixesPsiBasedFactory + quickFixFactory: QuickFixesPsiBasedFactory ) { quickFixes.getOrPut(diagnosticClass) { mutableListOf() }.add(HLQuickFixFactory.HLQuickFixesPsiBasedFactory(quickFixFactory)) } @@ -118,4 +121,4 @@ private fun List>>.merge(): Map> { } @RequiresOptIn -annotation class ForKtQuickFixesListBuilder() \ No newline at end of file +annotation class ForKtQuickFixesListBuilder() diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt index d0f59fb5b8f..0df8f195949 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt @@ -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(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true)) - registerPsiQuickFix(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false)) - registerPsiQuickFix(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false)) - registerPsiQuickFix(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true)) - registerPsiQuickFix(RemoveModifierFix.createRemoveModifierFactory(isRedundant = true)) - registerPsiQuickFix( + 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(ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY) - registerPsiQuickFix(ChangeVariableMutabilityFix.VAR_ANNOTATION_PARAMETER_FACTORY) - registerPsiQuickFix(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, ) -} \ No newline at end of file +} diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt index 334b64845d7..c401253ba2d 100644 --- a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt @@ -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 { + private fun createRemoveModifierFactory(isRedundant: Boolean = false): QuickFixesPsiBasedFactory { return quickFixesPsiBasedFactory { psiElement: PsiElement -> val elementType = psiElement.node.elementType as? KtModifierKeywordToken ?: return@quickFixesPsiBasedFactory emptyList() val modifierListOwner = psiElement.getStrictParentOfType() diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index b8410695ca2..07c4e400838 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -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) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt index 721e0d8e395..a8c0edf099b 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt @@ -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 = listOf( FormatCodeProcessing() ) ) -) \ No newline at end of file +)