From bace881463da348e2d81fe7e20c5be089df0d137 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 14 Mar 2016 17:05:42 +0300 Subject: [PATCH] Quick fix to make var with private setter final #KT-10859 Fixed --- .../org/jetbrains/kotlin/psi/addRemoveModifier.kt | 15 +++++++++++++-- .../kotlin/idea/quickfix/AddModifierFix.kt | 6 ++++-- .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 4 +++- .../modifiers/openVarWithPrivateSetter.kt | 5 +++++ .../modifiers/openVarWithPrivateSetter.kt.after | 5 +++++ .../modifiers/overrideWithPrivateSetter.kt | 9 +++++++++ .../modifiers/overrideWithPrivateSetter.kt.after | 9 +++++++++ .../idea/quickfix/QuickFixTestGenerated.java | 12 ++++++++++++ 8 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt create mode 100644 idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt.after create mode 100644 idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt create mode 100644 idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt.after diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/addRemoveModifier.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/addRemoveModifier.kt index 7be614297b9..78a87bf9f7c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/addRemoveModifier.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/addRemoveModifier.kt @@ -20,6 +20,7 @@ import com.intellij.psi.PsiComment import com.intellij.psi.PsiElement import com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.siblings @@ -61,6 +62,15 @@ internal fun addModifier(modifierList: KtModifierList, modifier: KtModifierKeywo ?.mapNotNull { modifierList.getModifier(it) } ?.firstOrNull() + if (modifier == FINAL_KEYWORD && !modifierList.hasModifier(OVERRIDE_KEYWORD)) { + if (modifierToReplace != null) { + modifierToReplace.delete() + if (modifierList.firstChild == null) { + modifierList.delete() + } + } + return + } if (modifierToReplace != null) { modifierToReplace.replace(newModifier) } @@ -99,9 +109,10 @@ fun removeModifier(owner: KtModifierListOwner, modifier: KtModifierKeywordToken) } private val MODIFIERS_TO_REPLACE = mapOf( - ABSTRACT_KEYWORD to listOf(OPEN_KEYWORD, FINAL_KEYWORD), OVERRIDE_KEYWORD to listOf(OPEN_KEYWORD), - OPEN_KEYWORD to listOf(FINAL_KEYWORD), + ABSTRACT_KEYWORD to listOf(OPEN_KEYWORD, FINAL_KEYWORD), + OPEN_KEYWORD to listOf(FINAL_KEYWORD, ABSTRACT_KEYWORD), + FINAL_KEYWORD to listOf(ABSTRACT_KEYWORD, OPEN_KEYWORD), PUBLIC_KEYWORD to listOf(PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD), PROTECTED_KEYWORD to listOf(PUBLIC_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD), PRIVATE_KEYWORD to listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, INTERNAL_KEYWORD), diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt index f1a45773714..9e4f1420afc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt @@ -28,7 +28,7 @@ import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil import org.jetbrains.kotlin.idea.refactoring.canRefactor import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.lexer.KtTokens.ABSTRACT_KEYWORD +import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils @@ -40,7 +40,7 @@ open class AddModifierFix( ) : KotlinQuickFixAction(element) { override fun getText(): String { - if (modifier == ABSTRACT_KEYWORD || modifier == KtTokens.OPEN_KEYWORD) { + if (modifier in modalityModifiers) { return "Make ${getElementName(element)} ${modifier.value}" } return "Add '${modifier.value}' modifier" @@ -57,6 +57,8 @@ open class AddModifierFix( } companion object { + private val modalityModifiers = setOf(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD) + fun getElementName(modifierListOwner: KtModifierListOwner): String { var name: String? = null if (modifierListOwner is PsiNameIdentifierOwner) { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index a72ee0a142e..5dc65252146 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.idea.quickfix.replaceWith.DeprecatedSymbolUsageInWho import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.NO_REFLECTION_IN_CLASS_PATH import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION @@ -118,7 +119,8 @@ class QuickFixRegistrar : QuickFixContributor { GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory) SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory) PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY.registerFactory(removeModifierFactory) - PRIVATE_SETTER_FOR_OPEN_PROPERTY.registerFactory(removeModifierFactory) + PRIVATE_SETTER_FOR_OPEN_PROPERTY.registerFactory(AddModifierFix.createFactory(FINAL_KEYWORD, KtProperty::class.java), + removeModifierFactory) REDUNDANT_MODIFIER_IN_GETTER.registerFactory(removeRedundantModifierFactory) WRONG_MODIFIER_TARGET.registerFactory(removeModifierFactory) REDUNDANT_MODIFIER_FOR_TARGET.registerFactory(removeModifierFactory) diff --git a/idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt b/idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt new file mode 100644 index 00000000000..f691212adef --- /dev/null +++ b/idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt @@ -0,0 +1,5 @@ +// "Make 'foo' final" "true" +open class My { + open var foo = 42 + private set +} \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt.after b/idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt.after new file mode 100644 index 00000000000..47dcb607231 --- /dev/null +++ b/idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt.after @@ -0,0 +1,5 @@ +// "Make 'foo' final" "true" +open class My { + var foo = 42 + private set +} \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt b/idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt new file mode 100644 index 00000000000..4032e4d1ddc --- /dev/null +++ b/idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt @@ -0,0 +1,9 @@ +// "Make 'bar' final" "true" +interface Foo { + val bar: String +} + +open class FooImpl : Foo { + override var bar: String = "" + private set +} \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt.after b/idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt.after new file mode 100644 index 00000000000..84e4daded22 --- /dev/null +++ b/idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt.after @@ -0,0 +1,9 @@ +// "Make 'bar' final" "true" +interface Foo { + val bar: String +} + +open class FooImpl : Foo { + final override var bar: String = "" + private set +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index ac6e832c2be..2d579f87e9b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -5166,6 +5166,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("openVarWithPrivateSetter.kt") + public void testOpenVarWithPrivateSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/openVarWithPrivateSetter.kt"); + doTest(fileName); + } + @TestMetadata("operatorModifier.kt") public void testOperatorModifier() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/operatorModifier.kt"); @@ -5196,6 +5202,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("overrideWithPrivateSetter.kt") + public void testOverrideWithPrivateSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/overrideWithPrivateSetter.kt"); + doTest(fileName); + } + @TestMetadata("packageMemberCannotBeProtected.kt") public void testPackageMemberCannotBeProtected() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/packageMemberCannotBeProtected.kt");