diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt index cd2574e026d..82369aa9eb0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt @@ -33,6 +33,7 @@ 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.containingClass import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils @@ -56,6 +57,14 @@ open class AddModifierFix( override fun invoke(project: Project, editor: Editor?, file: KtFile) { element?.addModifier(modifier) + + if (modifier == KtTokens.ABSTRACT_KEYWORD && (element is KtProperty || element is KtNamedFunction)) { + element?.containingClass()?.run { + if (!hasModifier(KtTokens.ABSTRACT_KEYWORD) && !hasModifier(KtTokens.SEALED_KEYWORD)) { + addModifier(KtTokens.ABSTRACT_KEYWORD) + } + } + } } override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { diff --git a/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInFinalClass.kt b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInFinalClass.kt new file mode 100644 index 00000000000..bb35dd2090c --- /dev/null +++ b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInFinalClass.kt @@ -0,0 +1,4 @@ +// "Make 'i' abstract" "true" +class A() { + var i : Int +} diff --git a/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInFinalClass.kt.after b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInFinalClass.kt.after new file mode 100644 index 00000000000..bdefbb28222 --- /dev/null +++ b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInFinalClass.kt.after @@ -0,0 +1,4 @@ +// "Make 'i' abstract" "true" +abstract class A() { + abstract var i : Int +} diff --git a/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInOpenClass.kt b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInOpenClass.kt new file mode 100644 index 00000000000..b3ca05521a4 --- /dev/null +++ b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInOpenClass.kt @@ -0,0 +1,4 @@ +// "Make 'i' abstract" "true" +open class A() { + var i : Int +} diff --git a/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInOpenClass.kt.after b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInOpenClass.kt.after new file mode 100644 index 00000000000..bdefbb28222 --- /dev/null +++ b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInOpenClass.kt.after @@ -0,0 +1,4 @@ +// "Make 'i' abstract" "true" +abstract class A() { + abstract var i : Int +} diff --git a/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInSealedClass.kt b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInSealedClass.kt new file mode 100644 index 00000000000..e87c0dd4e91 --- /dev/null +++ b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInSealedClass.kt @@ -0,0 +1,4 @@ +// "Make 'i' abstract" "true" +sealed class A() { + fun i() : Int +} diff --git a/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInSealedClass.kt.after b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInSealedClass.kt.after new file mode 100644 index 00000000000..9565204056e --- /dev/null +++ b/idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInSealedClass.kt.after @@ -0,0 +1,4 @@ +// "Make 'i' abstract" "true" +sealed class A() { + abstract fun i() : Int +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 2f453f88c21..0276ae2e96d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -182,6 +182,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("mustBeInitializedOrBeAbstractInFinalClass.kt") + public void testMustBeInitializedOrBeAbstractInFinalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInFinalClass.kt"); + doTest(fileName); + } + + @TestMetadata("mustBeInitializedOrBeAbstractInOpenClass.kt") + public void testMustBeInitializedOrBeAbstractInOpenClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInOpenClass.kt"); + doTest(fileName); + } + + @TestMetadata("mustBeInitializedOrBeAbstractInSealedClass.kt") + public void testMustBeInitializedOrBeAbstractInSealedClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstractInSealedClass.kt"); + doTest(fileName); + } + @TestMetadata("nonAbstractFunctionWithNoBody.kt") public void testNonAbstractFunctionWithNoBody() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/nonAbstractFunctionWithNoBody.kt");