diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideImplementMembersHandler.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideImplementMembersHandler.kt index f1655aa393b..cdafa0b3eec 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideImplementMembersHandler.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideImplementMembersHandler.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.core.overrideImplement import com.intellij.codeInsight.hint.HintManager import com.intellij.ide.util.MemberChooser import com.intellij.lang.LanguageCodeInsightActionHandler +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.openapi.ui.DialogWrapper @@ -83,7 +84,9 @@ public abstract class OverrideImplementMembersHandler : LanguageCodeInsightActio generateMembers(editor, classOrObject, selectedElements) } - override fun invoke(project: Project, editor: Editor, file: PsiFile) = invoke(project, editor, file, false) + override fun invoke(project: Project, editor: Editor, file: PsiFile) { + invoke(project, editor, file, implementAll = ApplicationManager.getApplication().isUnitTestMode) + } override fun startInWriteAction(): Boolean = false diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 9f866aecd9d..bd12e79ab17 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -20,8 +20,8 @@ import com.intellij.codeInsight.intention.IntentionAction import org.jetbrains.kotlin.diagnostics.DiagnosticFactory import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler -import org.jetbrains.kotlin.idea.inspections.AddReflectionQuickFix import org.jetbrains.kotlin.idea.inspections.AddModifierFixFactory +import org.jetbrains.kotlin.idea.inspections.AddReflectionQuickFix import org.jetbrains.kotlin.idea.intentions.IntroduceBackingPropertyFix import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.* import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory @@ -65,7 +65,7 @@ public class QuickFixRegistrar : QuickFixContributor { MUST_BE_INITIALIZED_OR_BE_ABSTRACT.registerFactory(addAbstractModifierFactory) ABSTRACT_MEMBER_NOT_IMPLEMENTED.registerFactory(addAbstractModifierFactory) - MANY_IMPL_MEMBER_NOT_IMPLEMENTED.registerFactory(addAbstractModifierFactory) + ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.registerFactory(addAbstractModifierFactory) val removeFinalModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(FINAL_KEYWORD) val addAbstractToClassFactory = AddModifierFix.createFactory(ABSTRACT_KEYWORD, javaClass()) @@ -151,7 +151,8 @@ public class QuickFixRegistrar : QuickFixContributor { val implementMethodsHandler = ImplementMembersHandler() ABSTRACT_MEMBER_NOT_IMPLEMENTED.registerActions(implementMethodsHandler) - MANY_IMPL_MEMBER_NOT_IMPLEMENTED.registerActions(implementMethodsHandler) + ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.registerActions(implementMethodsHandler) + MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED.registerActions(implementMethodsHandler) VAL_WITH_SETTER.registerFactory(ChangeVariableMutabilityFix.VAL_WITH_SETTER_FACTORY) VAL_REASSIGNMENT.registerFactory(ChangeVariableMutabilityFix.VAL_REASSIGNMENT_FACTORY) diff --git a/idea/testData/quickfix/abstract/manyImpl.kt b/idea/testData/quickfix/abstract/manyImpl.kt new file mode 100644 index 00000000000..ed4b121318b --- /dev/null +++ b/idea/testData/quickfix/abstract/manyImpl.kt @@ -0,0 +1,20 @@ +// "Make 'A' abstract" "false" +// ERROR: Class 'X' must override public open fun foo(): kotlin.Unit defined in X
because it inherits many implementations of it +// ACTION: Create Test +// ACTION: Make internal +// ACTION: Make private +// ACTION: Move 'X' to separate file + +interface D { + fun foo() +} + +interface E { + fun foo() {} +} + +object Impl : D, E { + override fun foo() {} +} + +class X : D by Impl, E by Impl {} \ No newline at end of file diff --git a/idea/testData/quickfix/abstract/notImplementedMember.kt b/idea/testData/quickfix/abstract/notImplementedMember.kt new file mode 100644 index 00000000000..37648b2d10c --- /dev/null +++ b/idea/testData/quickfix/abstract/notImplementedMember.kt @@ -0,0 +1,7 @@ +// "Make 'A' abstract" "true" +interface I { + fun foo() +} + +class A : I { +} diff --git a/idea/testData/quickfix/abstract/notImplementedMember.kt.after b/idea/testData/quickfix/abstract/notImplementedMember.kt.after new file mode 100644 index 00000000000..d8ca62bb8a4 --- /dev/null +++ b/idea/testData/quickfix/abstract/notImplementedMember.kt.after @@ -0,0 +1,7 @@ +// "Make 'A' abstract" "true" +interface I { + fun foo() +} + +abstract class A : I { +} diff --git a/idea/testData/quickfix/abstract/notImplementedMemberFromAbstractClass.kt b/idea/testData/quickfix/abstract/notImplementedMemberFromAbstractClass.kt new file mode 100644 index 00000000000..c92c5384456 --- /dev/null +++ b/idea/testData/quickfix/abstract/notImplementedMemberFromAbstractClass.kt @@ -0,0 +1,7 @@ +// "Make 'B' abstract" "true" +abstract class A { + abstract fun foo() +} + +class B : A() { +} diff --git a/idea/testData/quickfix/abstract/notImplementedMemberFromAbstractClass.kt.after b/idea/testData/quickfix/abstract/notImplementedMemberFromAbstractClass.kt.after new file mode 100644 index 00000000000..19492a0d37c --- /dev/null +++ b/idea/testData/quickfix/abstract/notImplementedMemberFromAbstractClass.kt.after @@ -0,0 +1,7 @@ +// "Make 'B' abstract" "true" +abstract class A { + abstract fun foo() +} + +abstract class B : A() { +} diff --git a/idea/testData/quickfix/override/implementMember.kt b/idea/testData/quickfix/override/implementMember.kt new file mode 100644 index 00000000000..843d7360844 --- /dev/null +++ b/idea/testData/quickfix/override/implementMember.kt @@ -0,0 +1,6 @@ +// "Implement members" "true" +interface I { + fun foo() +} + +class A : I diff --git a/idea/testData/quickfix/override/implementMember.kt.after b/idea/testData/quickfix/override/implementMember.kt.after new file mode 100644 index 00000000000..63aedb94579 --- /dev/null +++ b/idea/testData/quickfix/override/implementMember.kt.after @@ -0,0 +1,10 @@ +// "Implement members" "true" +interface I { + fun foo() +} + +class A : I { + override fun foo() { + throw UnsupportedOperationException() + } +} diff --git a/idea/testData/quickfix/override/implementMemberFromAbstractClass.kt b/idea/testData/quickfix/override/implementMemberFromAbstractClass.kt new file mode 100644 index 00000000000..be78ca4258b --- /dev/null +++ b/idea/testData/quickfix/override/implementMemberFromAbstractClass.kt @@ -0,0 +1,7 @@ +// "Implement members" "true" +abstract class A { + abstract fun foo() +} + +class B : A() { +} diff --git a/idea/testData/quickfix/override/implementMemberFromAbstractClass.kt.after b/idea/testData/quickfix/override/implementMemberFromAbstractClass.kt.after new file mode 100644 index 00000000000..1f1014a99a4 --- /dev/null +++ b/idea/testData/quickfix/override/implementMemberFromAbstractClass.kt.after @@ -0,0 +1,10 @@ +// "Implement members" "true" +abstract class A { + abstract fun foo() +} + +class B : A() { + override fun foo() { + throw UnsupportedOperationException() + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index eae5d7e1972..e5cb57f621c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -139,6 +139,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/abstract"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); } + @TestMetadata("manyImpl.kt") + public void testManyImpl() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/abstract/manyImpl.kt"); + doTest(fileName); + } + @TestMetadata("mustBeInitializedOrBeAbstract.kt") public void testMustBeInitializedOrBeAbstract() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/abstract/mustBeInitializedOrBeAbstract.kt"); @@ -163,6 +169,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("notImplementedMember.kt") + public void testNotImplementedMember() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/abstract/notImplementedMember.kt"); + doTest(fileName); + } + + @TestMetadata("notImplementedMemberFromAbstractClass.kt") + public void testNotImplementedMemberFromAbstractClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/abstract/notImplementedMemberFromAbstractClass.kt"); + doTest(fileName); + } + @TestMetadata("redundantAbstract.kt") public void testRedundantAbstract() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/abstract/redundantAbstract.kt"); @@ -4761,6 +4779,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("implementMember.kt") + public void testImplementMember() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/override/implementMember.kt"); + doTest(fileName); + } + + @TestMetadata("implementMemberFromAbstractClass.kt") + public void testImplementMemberFromAbstractClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/override/implementMemberFromAbstractClass.kt"); + doTest(fileName); + } + @TestMetadata("overriddingMultipleFinalMethods.kt") public void testOverriddingMultipleFinalMethods() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/override/overriddingMultipleFinalMethods.kt");