From c3d2ce0c1faffa462d6a17e35032b6d4d3fc3d21 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Wed, 3 Mar 2021 20:34:03 +0000 Subject: [PATCH] FIR checker/IDE: Add checker and quickfix for WRONG_MODIFIER_TARGET. There are only simple checks for `external` and `const` for now. The rest of the checks (see ModifiersChecker in FE1.0) will be added later. --- .../diagnostics/FirDiagnosticsList.kt | 4 ++ .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../declaration/FirConstDeclarationChecker.kt | 36 +++++++++++++++++ .../FirExternalDeclarationChecker.kt | 39 +++++++++++++++++++ .../diagnostics/FirDefaultErrorMessages.kt | 2 + .../fir/checkers/CommonDeclarationCheckers.kt | 2 + .../modifiers/const/applicability.fir.kt | 2 +- .../tests/modifiers/const/types.fir.kt | 2 +- .../modifierOnParameterInFunctionType.fir.kt | 2 +- .../tests/modifiers/repeatedModifiers.fir.kt | 2 + .../tests/modifiers/repeatedModifiers.kt | 2 + .../tests/modifiers/repeatedModifiers.txt | 2 + .../testsWithStdLib/native/nonFunction.fir.kt | 8 ++-- .../idea/quickfix/MainKtQuickFixRegistrar.kt | 5 +++ .../diagnostics/KtFirDataClassConverters.kt | 8 ++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 6 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 9 +++++ .../quickfix/ChangeVariableMutabilityFix.kt | 8 ++++ .../quickfix/ChangeVariableMutabilityFix.kt | 10 ----- .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 2 +- .../changeMutability/canBeVal/const.kt | 3 +- .../changeMutability/canBeVal/const.kt.after | 3 +- 22 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstDeclarationChecker.kt create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExternalDeclarationChecker.kt diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index b43fcd8fa05..b9525462669 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -160,6 +160,10 @@ object DIAGNOSTICS_LIST : DiagnosticList() { parameter("modifier2") } val REDUNDANT_OPEN_IN_INTERFACE by warning(PositioningStrategy.OPEN_MODIFIER) + val WRONG_MODIFIER_TARGET by error { + parameter("modifier") + parameter("target") + } } val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 95822c4da12..f69a5adddbf 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -145,6 +145,7 @@ object FirErrors { val DEPRECATED_MODIFIER_PAIR by error2() val INCOMPATIBLE_MODIFIERS by error2() val REDUNDANT_OPEN_IN_INTERFACE by warning0(SourceElementPositioningStrategies.OPEN_MODIFIER) + val WRONG_MODIFIER_TARGET by error2() // Inline classes val INLINE_CLASS_NOT_TOP_LEVEL by error0(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstDeclarationChecker.kt new file mode 100644 index 00000000000..5a781d9bf25 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstDeclarationChecker.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.lexer.KtTokens + +object FirConstDeclarationChecker : FirBasicDeclarationChecker() { + override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration !is FirVariable<*>) return + val source = declaration.source ?: return + if (source.kind is FirFakeSourceElementKind) return + val modifierList = with(FirModifierList) { source.getModifierList() } + val constModifier = modifierList?.modifiers?.firstOrNull { it.token == KtTokens.CONST_KEYWORD } ?: return + + if (declaration.isVar) { + reporter.reportOn(constModifier.source, FirErrors.WRONG_MODIFIER_TARGET, constModifier.token, "vars", context) + } + + // TODO: Implement checkers for these errors (see ConstModifierChecker in FE1.0): + // - CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT + // - CONST_VAL_WITH_DELEGATE + // - CONST_VAL_WITH_GETTER + // - TYPE_CANT_BE_USED_FOR_CONST_VAL + // - CONST_VAL_WITHOUT_INITIALIZER + // - CONST_VAL_WITH_NON_CONST_INITIALIZER + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExternalDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExternalDeclarationChecker.kt new file mode 100644 index 00000000000..38275e7db59 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExternalDeclarationChecker.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.lexer.KtTokens + +object FirExternalDeclarationChecker : FirBasicDeclarationChecker() { + override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + val source = declaration.source ?: return + if (source.kind is FirFakeSourceElementKind) return + val modifierList = with(FirModifierList) { source.getModifierList() } + val externalModifier = modifierList?.modifiers?.firstOrNull { it.token == KtTokens.EXTERNAL_KEYWORD } ?: return + + // WRONG_MODIFIER_TARGET on external constructor is intentionally NOT covered in this checker. + if (declaration !is FirFunction<*>) { + val target = when (declaration) { + is FirProperty -> "property" + is FirRegularClass -> "class" + else -> "non-function declaration" + } + reporter.reportOn(externalModifier.source, FirErrors.WRONG_MODIFIER_TARGET, externalModifier.token, target, context) + } + + // TODO: Implement checkers for these JVM-specific errors (see ExternalFunChecker in FE1.0): + // - EXTERNAL_DECLARATION_IN_INTERFACE + // - EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT + // - EXTERNAL_DECLARATION_CANNOT_HAVE_BODY + // - EXTERNAL_DECLARATION_CANNOT_BE_INLINED + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 4e4ffed95d8..caca4ab74d3 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -214,6 +214,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_ANNOTATION_PA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_OVERRIDDEN_BY_VAL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_INVOCATION_KIND +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS @Suppress("unused") @@ -354,6 +355,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING) map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", TO_STRING, TO_STRING) map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members") + map.put(WRONG_MODIFIER_TARGET, "Modifier ''{0}'' is not applicable to ''{1}''", TO_STRING, TO_STRING) // Applicability map.put(NONE_APPLICABLE, "None of the following functions are applicable: {0}", SYMBOLS) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt index 8ebc705f4f2..bd2546a38f4 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt @@ -18,6 +18,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirModifierChecker, FirConflictsChecker, FirConflictingProjectionChecker, + FirExternalDeclarationChecker, + FirConstDeclarationChecker, ) override val memberDeclarationCheckers: Set = setOf( diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt index 1ef655c62fe..2c8398c8ee9 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt @@ -4,7 +4,7 @@ import kotlin.reflect.KProperty const val topLevel: Int = 0 const val topLevelInferred = 1 -const var topLeveLVar: Int = 2 +const var topLeveLVar: Int = 2 private val privateTopLevel = 3 diff --git a/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt b/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt index 6912e0322c6..6561f993d29 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt @@ -12,6 +12,6 @@ const val arrayConst: Array = arrayOf("1") const val intArrayConst: IntArray = intArrayOf() const val unresolvedConst1 = Unresolved -const var unresolvedConst2 = Unresolved +const var unresolvedConst2 = Unresolved const val unresolvedConst3 = Unresolved get() = 10 diff --git a/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt index 158233f2142..968af99d3e0 100644 --- a/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/modifierOnParameterInFunctionType.fir.kt @@ -26,7 +26,7 @@ val allProhibited: (abstract crossinline data enum - external + external final in inline diff --git a/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.fir.kt b/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.fir.kt index 984d56915a0..07fafacb782 100644 --- a/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.fir.kt @@ -39,3 +39,5 @@ fun test() { } } +external external val i = 0 +const const var x = 0 diff --git a/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.kt b/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.kt index 0c98e10cf6c..f5dd5b71105 100644 --- a/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.kt +++ b/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.kt @@ -39,3 +39,5 @@ fun test() { } } +external external val i = 0 +const const var x = 0 diff --git a/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.txt b/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.txt index e5d59c4ab9e..03ee448e798 100644 --- a/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.txt +++ b/compiler/testData/diagnostics/tests/modifiers/repeatedModifiers.txt @@ -1,6 +1,8 @@ package public val bar: kotlin.Int = 1 +public external val i: kotlin.Int = 0 +public const var x: kotlin.Int public fun foo(): kotlin.Int public fun test(): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/native/nonFunction.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/native/nonFunction.fir.kt index 1755e7f8d60..b04b563ed07 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/native/nonFunction.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/native/nonFunction.fir.kt @@ -1,9 +1,9 @@ -external class A +external class A -external val foo: Int = 23 +external val foo: Int = 23 class B { - external class A + external class A - external val foo: Int = 23 + external val foo: Int = 23 } \ No newline at end of file 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 c3c0d9c28d2..c29d4342589 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 @@ -48,6 +48,11 @@ class MainKtQuickFixRegistrar : KtQuickFixRegistrar() { KtFirDiagnostic.NestedClassNotAllowed::class, AddModifierFix.addInnerModifier ) + registerPsiQuickFixes( + KtFirDiagnostic.WrongModifierTarget::class, + RemoveModifierFix.removeNonRedundantModifier, + ChangeVariableMutabilityFix.CONST_VAL_FACTORY + ) } private val overrides = KtQuickFixesListBuilder.registerPsiQuickFix { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 08d588d5d8a..9a678dfe05d 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -628,6 +628,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.WRONG_MODIFIER_TARGET) { firDiagnostic -> + WrongModifierTargetImpl( + firDiagnostic.a, + firDiagnostic.b, + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.NONE_APPLICABLE) { firDiagnostic -> NoneApplicableImpl( firDiagnostic.a.map { abstractFirBasedSymbol -> diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 0aa468e0625..7aa178fa4d6 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -451,6 +451,12 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = ValueClassCannotBeCloneable::class } + abstract class WrongModifierTarget : KtFirDiagnostic() { + override val diagnosticClass get() = WrongModifierTarget::class + abstract val modifier: KtModifierKeywordToken + abstract val target: String + } + abstract class NoneApplicable : KtFirDiagnostic() { override val diagnosticClass get() = NoneApplicable::class abstract val candidates: List diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index ad898d5d55f..6787e35e5ae 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -725,6 +725,15 @@ internal class ValueClassCannotBeCloneableImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class WrongModifierTargetImpl( + override val modifier: KtModifierKeywordToken, + override val target: String, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.WrongModifierTarget(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class NoneApplicableImpl( override val candidates: List, firDiagnostic: FirPsiDiagnostic<*>, diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt index d3102c3dcb7..70becea2396 100644 --- a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType @@ -74,6 +75,13 @@ class ChangeVariableMutabilityFix( } } + val CONST_VAL_FACTORY: QuickFixesPsiBasedFactory = + quickFixesPsiBasedFactory { psiElement: PsiElement -> + if (psiElement.node.elementType as? KtModifierKeywordToken != KtTokens.CONST_KEYWORD) return@quickFixesPsiBasedFactory emptyList() + val property = psiElement.getStrictParentOfType() ?: return@quickFixesPsiBasedFactory emptyList() + listOf(ChangeVariableMutabilityFix(property, makeVar = false)) + } + val MUST_BE_INITIALIZED_FACTORY: QuickFixesPsiBasedFactory = quickFixesPsiBasedFactory { psiElement: PsiElement -> val property = psiElement as? KtProperty ?: return@quickFixesPsiBasedFactory emptyList() diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt index 779f7c39154..4d619d0faaf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt @@ -39,16 +39,6 @@ class ReassignmentActionFactory(val factory: DiagnosticFactory1<*, DeclarationDe } } -// TODO: Move this to idea-fir-independent -object ConstValFactory : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): IntentionAction? { - val (modifier, element) = Errors.WRONG_MODIFIER_TARGET.cast(diagnostic).run { a to psiElement } - if (modifier != KtTokens.CONST_KEYWORD) return null - val property = element.getStrictParentOfType() ?: return null - return ChangeVariableMutabilityFix(property, makeVar = false) - } -} - object DelegatedPropertyValFactory : KotlinSingleIntentionActionFactory() { override fun createAction(diagnostic: Diagnostic): IntentionAction? { val element = Errors.DELEGATE_SPECIAL_FUNCTION_MISSING.cast(diagnostic).psiElement diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 7d02be4e728..a82b72e91ad 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -137,7 +137,7 @@ class QuickFixRegistrar : QuickFixContributor { RemoveModifierFix.removeNonRedundantModifier ) REDUNDANT_MODIFIER_IN_GETTER.registerFactory(RemoveModifierFix.removeRedundantModifier) - WRONG_MODIFIER_TARGET.registerFactory(RemoveModifierFix.removeNonRedundantModifier, ConstValFactory) + WRONG_MODIFIER_TARGET.registerFactory(RemoveModifierFix.removeNonRedundantModifier, ChangeVariableMutabilityFix.CONST_VAL_FACTORY) DEPRECATED_MODIFIER.registerFactory(ReplaceModifierFix) REDUNDANT_MODIFIER_FOR_TARGET.registerFactory(RemoveModifierFix.removeNonRedundantModifier) WRONG_MODIFIER_CONTAINING_DECLARATION.registerFactory(RemoveModifierFix.removeNonRedundantModifier) diff --git a/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt b/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt index 88df7842d27..fca4b54b853 100644 --- a/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt +++ b/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt @@ -1,4 +1,5 @@ // "Change to val" "true" object Test { const var foo = "123" -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt.after b/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt.after index 9bdc2e4b909..d277769653a 100644 --- a/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt.after +++ b/idea/testData/quickfix/variables/changeMutability/canBeVal/const.kt.after @@ -1,4 +1,5 @@ // "Change to val" "true" object Test { const val foo = "123" -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file