diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt index fc7e945caa7..0aba01a5d46 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtClassOrObject.kt @@ -22,7 +22,6 @@ import com.intellij.navigation.ItemPresentationProviders import com.intellij.psi.PsiElement import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.impl.CheckUtil -import com.intellij.psi.impl.source.codeStyle.CodeEditUtil import com.intellij.psi.stubs.IStubElementType import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.lexer.KtTokens @@ -64,8 +63,6 @@ abstract public class KtClassOrObject : public fun getBody(): KtClassBody? = getStubOrPsiChild(KtStubElementTypes.CLASS_BODY) - public fun getOrCreateBody(): KtClassBody = getBody() ?: add(KtPsiFactory(this).createEmptyClassBody()) as KtClassBody - public fun addDeclaration(declaration: KtDeclaration): KtDeclaration { val body = getOrCreateBody() val anchor = PsiTreeUtil.skipSiblingsBackward(body.rBrace ?: body.getLastChild()!!, javaClass()) @@ -117,3 +114,11 @@ abstract public class KtClassOrObject : } } } + +public fun KtClassOrObject.getOrCreateBody(): KtClassBody { + getBody()?.let { return it } + + val newBody = KtPsiFactory(this).createEmptyClassBody() + if (this is KtEnumEntry) return addAfter(newBody, initializerList ?: nameIdentifier) as KtClassBody + return add(newBody) as KtClassBody +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt index bcb8c9b9901..7b871cc9515 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt @@ -27,7 +27,9 @@ import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.SmartList import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.allChildren import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.utils.ifEmpty @@ -156,6 +158,22 @@ public fun insertMembersAfter( var afterAnchor = anchor ?: findInsertAfterAnchor(editor, body) ?: return@runWriteAction emptyList() val insertedMembers = members.mapTo(SmartList()) { + if (classOrObject is KtClass && classOrObject.isEnum()) { + val enumEntries = classOrObject.declarations.filterIsInstance() + val bound = (enumEntries.lastOrNull() ?: classOrObject.allChildren.firstOrNull { it.node.elementType == KtTokens.SEMICOLON }) + if (it !is KtEnumEntry) { + if (bound != null && afterAnchor.startOffset <= bound.startOffset) { + afterAnchor = bound + } + } + else if (bound == null && body.declarations.isNotEmpty()) { + afterAnchor = body.lBrace!! + } + else if (bound != null && afterAnchor.startOffset >= bound.startOffset) { + afterAnchor = bound.prevSibling!! + } + } + @Suppress("UNCHECKED_CAST") (body.addAfter(it, afterAnchor) as T).apply { afterAnchor = this } } 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 4731e65528a..24093dc0864 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 @@ -91,7 +91,7 @@ public abstract class OverrideImplementMembersHandler : LanguageCodeInsightActio override fun startInWriteAction(): Boolean = false companion object { - public fun generateMembers(editor: Editor, classOrObject: KtClassOrObject, selectedElements: Collection) { + public fun generateMembers(editor: Editor?, classOrObject: KtClassOrObject, selectedElements: Collection) { val project = classOrObject.project insertMembersAfter(editor, classOrObject, selectedElements.map { it.generateMember(project) }) } diff --git a/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/after.kt.template b/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/after.kt.template new file mode 100644 index 00000000000..d3388e38833 --- /dev/null +++ b/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/after.kt.template @@ -0,0 +1,9 @@ +interface A { + fun foo(): Int +} + +class B : A { + override fun foo(): Int { + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/before.kt.template b/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/before.kt.template new file mode 100644 index 00000000000..a40fb9f720d --- /dev/null +++ b/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/before.kt.template @@ -0,0 +1,7 @@ +interface A { + fun foo(): Int +} + +class B : A { + +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/description.html b/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/description.html new file mode 100644 index 00000000000..cb105e333c1 --- /dev/null +++ b/idea/resources/intentionDescriptions/ImplementAbstractMemberIntention/description.html @@ -0,0 +1,5 @@ + + +This intention searches for all classes that can implement selected abstract member, and creates default implementation there. + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 73691cc73ca..f4a68f12db9 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -1110,6 +1110,11 @@ Kotlin + + org.jetbrains.kotlin.idea.intentions.ImplementAbstractMemberIntention + Kotlin + + () - if (KtPsiUtil.skipTrailingWhitespacesAndComments(lastEntry ?: classBody.firstChild)?.node?.elementType == KtTokens.SEMICOLON) return + if (lastEntry != null && lastEntry.allChildren.any { it.node.elementType == KtTokens.SEMICOLON }) return + if (lastEntry == null && classBody.allChildren.any { it.node.elementType == KtTokens.SEMICOLON }) return val semicolon = KtPsiFactory(klass).createSemicolon() classBody.addAfter(semicolon, lastEntry) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt new file mode 100644 index 00000000000..1c8a6b9f2ff --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt @@ -0,0 +1,215 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.intentions + +import com.intellij.codeInsight.CodeInsightBundle +import com.intellij.codeInsight.FileModificationService +import com.intellij.ide.util.PsiClassListCellRenderer +import com.intellij.ide.util.PsiElementListCellRenderer +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.ui.popup.PopupChooserBuilder +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.ui.components.JBList +import com.intellij.util.IncorrectOperationException +import org.jetbrains.kotlin.asJava.KtLightClass +import org.jetbrains.kotlin.asJava.KtLightClassForExplicitDeclaration +import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideImplementMembersHandler +import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject +import org.jetbrains.kotlin.idea.refactoring.canRefactor +import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass +import org.jetbrains.kotlin.idea.refactoring.runSynchronouslyWithProgress +import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest +import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors +import org.jetbrains.kotlin.idea.util.application.executeCommand +import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject +import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.substitutions.getTypeSubstitutor +import org.jetbrains.kotlin.util.findCallableMemberBySignature +import org.jetbrains.kotlin.utils.addToStdlib.singletonList +import java.util.* +import javax.swing.ListSelectionModel + +class ImplementAbstractMemberIntention : + SelfTargetingRangeIntention(KtNamedDeclaration::class.java, "", "Implement abstract member") { + companion object { + private val LOG = Logger.getInstance("#${ImplementAbstractMemberIntention::class.java.canonicalName}") + } + + private fun isAbstract(element: KtNamedDeclaration): Boolean { + if (element.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return true + if (!(element.containingClassOrObject?.isInterfaceClass() ?: false)) return false + return when (element) { + is KtProperty -> element.initializer == null && element.delegate == null && element.accessors.isEmpty() + is KtNamedFunction -> !element.hasBody() + else -> false + } + } + + private fun findExistingImplementation( + subClass: ClassDescriptor, + superMember: CallableMemberDescriptor + ): CallableMemberDescriptor? { + val superClass = superMember.containingDeclaration as? ClassDescriptor ?: return null + val substitutor = getTypeSubstitutor(superClass.defaultType, subClass.defaultType) ?: TypeSubstitutor.EMPTY + val subMember = subClass.findCallableMemberBySignature(superMember.substitute(substitutor) as CallableMemberDescriptor) + if (subMember?.kind?.isReal ?: false) return subMember else return null + } + + private fun findClassesToProcess(member: KtNamedDeclaration): Sequence { + val baseClass = member.containingClassOrObject as? KtClass ?: return emptySequence() + val memberDescriptor = member.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return emptySequence() + + fun acceptSubClass(classOrObject: KtClassOrObject): Boolean { + val classDescriptor = classOrObject.resolveToDescriptorIfAny() as? ClassDescriptor ?: return false + return classDescriptor.kind != ClassKind.INTERFACE && findExistingImplementation(classDescriptor, memberDescriptor) == null + } + + if (baseClass.isEnum()) { + return baseClass.declarations + .asSequence() + .filterIsInstance() + .filter(::acceptSubClass) + } + + return HierarchySearchRequest(baseClass, baseClass.useScope, false) + .searchInheritors() + .asSequence() + .mapNotNull { (it as? KtLightClassForExplicitDeclaration)?.getOrigin() } + .filter(::acceptSubClass) + } + + override fun applicabilityRange(element: KtNamedDeclaration): TextRange? { + if (!isAbstract(element)) return null + + text = when(element) { + is KtProperty -> "Implement abstract property" + is KtNamedFunction -> "Implement abstract function" + else -> return null + } + + if (!findClassesToProcess(element).any()) return null + + return element.nameIdentifier?.textRange + } + + private fun implementInClass(member: KtNamedDeclaration, targetClasses: List) { + val project = member.project + project.executeCommand(CodeInsightBundle.message("intention.implement.abstract.method.command.name")) { + if (!FileModificationService.getInstance().preparePsiElementsForWrite(targetClasses)) return@executeCommand + runWriteAction { + for (targetClass in targetClasses) { + try { + val subClass = (targetClass as? KtLightClass)?.getOrigin() ?: targetClass as? KtClassOrObject ?: continue + val subClassDescriptor = subClass.resolveToDescriptorIfAny() as? ClassDescriptor ?: continue + val superMemberDescriptor = member.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: continue + val superClassDescriptor = superMemberDescriptor.containingDeclaration as? ClassDescriptor ?: continue + val substitutor = getTypeSubstitutor(superClassDescriptor.defaultType, subClassDescriptor.defaultType) + ?: TypeSubstitutor.EMPTY + val descriptorToImplement = superMemberDescriptor.substitute(substitutor) as CallableMemberDescriptor + val chooserObject = OverrideMemberChooserObject.create(project, + descriptorToImplement, + descriptorToImplement, + OverrideMemberChooserObject.BodyType.EMPTY) + OverrideImplementMembersHandler.generateMembers(null, subClass, chooserObject.singletonList()) + } + catch(e: IncorrectOperationException) { + LOG.error(e) + } + } + } + } + } + + private class ClassRenderer : PsiElementListCellRenderer() { + private val psiClassRenderer = PsiClassListCellRenderer() + + override fun getComparator(): Comparator { + val baseComparator = psiClassRenderer.comparator + return Comparator { o1, o2 -> + when { + o1 is KtEnumEntry && o2 is KtEnumEntry -> o1.name!!.compareTo(o2.name!!) + o1 is KtEnumEntry -> -1 + o2 is KtEnumEntry -> 1 + o1 is PsiClass && o2 is PsiClass -> baseComparator.compare(o1 as PsiClass, o2 as PsiClass) + else -> 0 + } + } + } + + override fun getIconFlags() = 0 + + override fun getElementText(element: PsiElement?): String? { + return when (element) { + is KtEnumEntry -> element.name + is PsiClass -> psiClassRenderer.getElementText(element) + else -> null + } + } + + override fun getContainerText(element: PsiElement?, name: String?): String? { + return when (element) { + is KtEnumEntry -> element.containingClassOrObject?.fqName?.asString() + is PsiClass -> PsiClassListCellRenderer.getContainerTextStatic(element) + else -> null + } + } + } + + override fun applyTo(element: KtNamedDeclaration, editor: Editor) { + val project = element.project + + val classesToProcess = project.runSynchronouslyWithProgress( + CodeInsightBundle.message("intention.implement.abstract.method.searching.for.descendants.progress"), + true + ) { findClassesToProcess(element).map { it.toLightClass() ?: it }.toList() } ?: return + if (classesToProcess.isEmpty()) return + + classesToProcess.singleOrNull()?.let { return implementInClass(element, it.singletonList()) } + + if (ApplicationManager.getApplication().isUnitTestMode) return implementInClass(element, classesToProcess) + + val renderer = ClassRenderer() + val list = JBList(classesToProcess.sortedWith(renderer.comparator)).apply { + selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION + cellRenderer = renderer + } + val builder = PopupChooserBuilder(list) + renderer.installSpeedSearch(builder) + builder + .setTitle(CodeInsightBundle.message("intention.implement.abstract.method.class.chooser.title")) + .setItemChoosenCallback { + val index = list.selectedIndex + if (index < 0) return@setItemChoosenCallback + @Suppress("UNCHECKED_CAST") + implementInClass(element, list.selectedValues.toList() as List) + } + .createPopup() + .showInBestPositionFor(editor) + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt index 0b8492f0238..039bbcdaccc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt @@ -34,10 +34,7 @@ import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.application.executeWriteCommand -import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.supertypes diff --git a/idea/testData/intentions/implementAbstractMember/function/.intention b/idea/testData/intentions/implementAbstractMember/function/.intention new file mode 100644 index 00000000000..5cfe1e20de8 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.intentions.ImplementAbstractMemberIntention diff --git a/idea/testData/intentions/implementAbstractMember/function/enumClass.kt b/idea/testData/intentions/implementAbstractMember/function/enumClass.kt new file mode 100644 index 00000000000..42a2c6453c7 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumClass.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +enum class E : T { + A, B, C +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumClass.kt.after b/idea/testData/intentions/implementAbstractMember/function/enumClass.kt.after new file mode 100644 index 00000000000..82023d3745f --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumClass.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +enum class E : T { + A, B, C; + + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolon.kt b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolon.kt new file mode 100644 index 00000000000..1bcc503f9a3 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolon.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +enum class E : T { + A, B, C; +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolon.kt.after b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolon.kt.after new file mode 100644 index 00000000000..82023d3745f --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolon.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +enum class E : T { + A, B, C; + + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolonAndMembers.kt b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolonAndMembers.kt new file mode 100644 index 00000000000..8c66f1db999 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolonAndMembers.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +enum class E : T { + A, B, C; + + val bar = 1 + + fun baz() = 2 +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolonAndMembers.kt.after b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolonAndMembers.kt.after new file mode 100644 index 00000000000..024114e7827 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolonAndMembers.kt.after @@ -0,0 +1,17 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +enum class E : T { + A, B, C; + + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + + val bar = 1 + + fun baz() = 2 +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumEntries.kt b/idea/testData/intentions/implementAbstractMember/function/enumEntries.kt new file mode 100644 index 00000000000..f626b655bf2 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumEntries.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E { + A, B, C; + + abstract fun foo(x: Int): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumEntries.kt.after b/idea/testData/intentions/implementAbstractMember/function/enumEntries.kt.after new file mode 100644 index 00000000000..81b1f4754d9 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumEntries.kt.after @@ -0,0 +1,19 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E { + A { + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + }, B { + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + }, C { + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + }; + + abstract fun foo(x: Int): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumEntriesWithArgs.kt b/idea/testData/intentions/implementAbstractMember/function/enumEntriesWithArgs.kt new file mode 100644 index 00000000000..cad86562253 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumEntriesWithArgs.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E(n: Int) { + A(1), B(2), C(3); + + abstract fun foo(x: Int): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/enumEntriesWithArgs.kt.after b/idea/testData/intentions/implementAbstractMember/function/enumEntriesWithArgs.kt.after new file mode 100644 index 00000000000..1555a2e96dd --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/enumEntriesWithArgs.kt.after @@ -0,0 +1,19 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E(n: Int) { + A(1) { + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + }, B(2) { + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + }, C(3) { + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + }; + + abstract fun foo(x: Int): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/implementAll.kt b/idea/testData/intentions/implementAbstractMember/function/implementAll.kt new file mode 100644 index 00000000000..6466368ea2c --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/implementAll.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +class U : T { + +} + +class V : T { + +} + +class Z : T by V() { + +} + +class W : T { + override fun foo(x: Boolean): Boolean { + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/implementAll.kt.after b/idea/testData/intentions/implementAbstractMember/function/implementAll.kt.after new file mode 100644 index 00000000000..0866782b48e --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/implementAll.kt.after @@ -0,0 +1,29 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + fun foo(x: X): X +} + +class U : T { + override fun foo(x: String): String { + throw UnsupportedOperationException() + } + +} + +class V : T { + override fun foo(x: Int): Int { + throw UnsupportedOperationException() + } + +} + +class Z : T by V() { + +} + +class W : T { + override fun foo(x: Boolean): Boolean { + throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/inFinalClass.kt b/idea/testData/intentions/implementAbstractMember/function/inFinalClass.kt new file mode 100644 index 00000000000..a10ee12978f --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/inFinalClass.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +// ERROR: Abstract function 'foo' in non-abstract class 'A' +class A { + abstract fun foo(): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/inObject.kt b/idea/testData/intentions/implementAbstractMember/function/inObject.kt new file mode 100644 index 00000000000..487a52b5546 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/inObject.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +// ERROR: Abstract function 'foo' in non-abstract class 'A' +object A { + abstract fun foo(): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/noDirectOverridesNeeded.kt b/idea/testData/intentions/implementAbstractMember/function/noDirectOverridesNeeded.kt new file mode 100644 index 00000000000..7a8bec60cae --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/noDirectOverridesNeeded.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// ERROR: Class 'C' must be declared abstract or implement abstract base class member public abstract fun foo(): kotlin.Int defined in B +interface A { + fun foo(): Int +} + +class X : A { + override fun foo() = 1 +} + +abstract class B : A { + abstract override fun foo(): Int +} + +class C: B() { + +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/noInheritors.kt b/idea/testData/intentions/implementAbstractMember/function/noInheritors.kt new file mode 100644 index 00000000000..a14013aa617 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/noInheritors.kt @@ -0,0 +1,4 @@ +// IS_APPLICABLE: false +interface A { + fun foo(): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/notAbstractInClass.kt b/idea/testData/intentions/implementAbstractMember/function/notAbstractInClass.kt new file mode 100644 index 00000000000..4a908de134b --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/notAbstractInClass.kt @@ -0,0 +1,4 @@ +// IS_APPLICABLE: false +open class A { + fun foo() = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/notAbstractInInterface.kt b/idea/testData/intentions/implementAbstractMember/function/notAbstractInInterface.kt new file mode 100644 index 00000000000..6e60e6ee7ee --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/notAbstractInInterface.kt @@ -0,0 +1,4 @@ +// IS_APPLICABLE: false +interface A { + fun foo() = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/function/notAbstractNoBodyInClass.kt b/idea/testData/intentions/implementAbstractMember/function/notAbstractNoBodyInClass.kt new file mode 100644 index 00000000000..915c6a43a86 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/function/notAbstractNoBodyInClass.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +// ERROR: Function 'foo' without a body must be abstract +open class A { + fun foo(): Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/.intention b/idea/testData/intentions/implementAbstractMember/property/.intention new file mode 100644 index 00000000000..5cfe1e20de8 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.intentions.ImplementAbstractMemberIntention diff --git a/idea/testData/intentions/implementAbstractMember/property/enumClass.kt b/idea/testData/intentions/implementAbstractMember/property/enumClass.kt new file mode 100644 index 00000000000..5b6934a5560 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumClass.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +enum class E : T { + A, B, C +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumClass.kt.after b/idea/testData/intentions/implementAbstractMember/property/enumClass.kt.after new file mode 100644 index 00000000000..4f16ab4e0c4 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumClass.kt.after @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +enum class E : T { + A, B, C; + + override val foo: Int + get() = throw UnsupportedOperationException() +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolon.kt b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolon.kt new file mode 100644 index 00000000000..c959392b05a --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolon.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +enum class E : T { + A, B, C; +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolon.kt.after b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolon.kt.after new file mode 100644 index 00000000000..4f16ab4e0c4 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolon.kt.after @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +enum class E : T { + A, B, C; + + override val foo: Int + get() = throw UnsupportedOperationException() +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolonAndMembers.kt b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolonAndMembers.kt new file mode 100644 index 00000000000..5ea254418a7 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolonAndMembers.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +enum class E : T { + A, B, C; + + val bar = 1 + + fun baz() = 2 +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolonAndMembers.kt.after b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolonAndMembers.kt.after new file mode 100644 index 00000000000..d4d29eed592 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolonAndMembers.kt.after @@ -0,0 +1,16 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +enum class E : T { + A, B, C; + + override val foo: Int + get() = throw UnsupportedOperationException() + + val bar = 1 + + fun baz() = 2 +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumEntries.kt b/idea/testData/intentions/implementAbstractMember/property/enumEntries.kt new file mode 100644 index 00000000000..e5c4c1573ff --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumEntries.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E { + A, B, C; + + abstract val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumEntries.kt.after b/idea/testData/intentions/implementAbstractMember/property/enumEntries.kt.after new file mode 100644 index 00000000000..a5e1f6290ad --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumEntries.kt.after @@ -0,0 +1,16 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E { + A { + override val foo: Int + get() = throw UnsupportedOperationException() + }, B { + override val foo: Int + get() = throw UnsupportedOperationException() + }, C { + override val foo: Int + get() = throw UnsupportedOperationException() + }; + + abstract val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumEntriesWithArgs.kt b/idea/testData/intentions/implementAbstractMember/property/enumEntriesWithArgs.kt new file mode 100644 index 00000000000..2613a019f87 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumEntriesWithArgs.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E(n: Int) { + A(1), B(2), C(3); + + abstract val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/enumEntriesWithArgs.kt.after b/idea/testData/intentions/implementAbstractMember/property/enumEntriesWithArgs.kt.after new file mode 100644 index 00000000000..ef1cc54e48e --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/enumEntriesWithArgs.kt.after @@ -0,0 +1,16 @@ +// WITH_RUNTIME +//DISABLE-ERRORS +enum class E(n: Int) { + A(1) { + override val foo: Int + get() = throw UnsupportedOperationException() + }, B(2) { + override val foo: Int + get() = throw UnsupportedOperationException() + }, C(3) { + override val foo: Int + get() = throw UnsupportedOperationException() + }; + + abstract val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/implementAll.kt b/idea/testData/intentions/implementAbstractMember/property/implementAll.kt new file mode 100644 index 00000000000..5cb2d1c9cef --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/implementAll.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +class U : T { + +} + +class V : T { + +} + +class Z : T by V() { + +} + +class W : T { + override val foo: Boolean + get() = throw UnsupportedOperationException() +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/implementAll.kt.after b/idea/testData/intentions/implementAbstractMember/property/implementAll.kt.after new file mode 100644 index 00000000000..4a670cfc3a3 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/implementAll.kt.after @@ -0,0 +1,26 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +interface T { + val foo: X +} + +class U : T { + override val foo: String + get() = throw UnsupportedOperationException() + +} + +class V : T { + override val foo: Int + get() = throw UnsupportedOperationException() + +} + +class Z : T by V() { + +} + +class W : T { + override val foo: Boolean + get() = throw UnsupportedOperationException() +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/inFinalClass.kt b/idea/testData/intentions/implementAbstractMember/property/inFinalClass.kt new file mode 100644 index 00000000000..50cf88e5e58 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/inFinalClass.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +// ERROR: Abstract property 'foo' in non-abstract class 'A' +class A { + abstract val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/inObject.kt b/idea/testData/intentions/implementAbstractMember/property/inObject.kt new file mode 100644 index 00000000000..ea8c3b061fb --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/inObject.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +// ERROR: Abstract property 'foo' in non-abstract class 'A' +object A { + abstract val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/noDirectOverridesNeeded.kt b/idea/testData/intentions/implementAbstractMember/property/noDirectOverridesNeeded.kt new file mode 100644 index 00000000000..5572887325f --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/noDirectOverridesNeeded.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// ERROR: Class 'C' must be declared abstract or implement abstract base class member public abstract val foo: kotlin.Int defined in B +interface A { + val foo: Int +} + +class X : A { + override val foo = 1 +} + +abstract class B : A { + abstract override val foo: Int +} + +class C: B() { + +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/noInheritors.kt b/idea/testData/intentions/implementAbstractMember/property/noInheritors.kt new file mode 100644 index 00000000000..327c42b24e0 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/noInheritors.kt @@ -0,0 +1,4 @@ +// IS_APPLICABLE: false +interface A { + val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/notAbstractInClass.kt b/idea/testData/intentions/implementAbstractMember/property/notAbstractInClass.kt new file mode 100644 index 00000000000..1f777f9e8e8 --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/notAbstractInClass.kt @@ -0,0 +1,4 @@ +// IS_APPLICABLE: false +open class A { + val foo = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/notAbstractNoBodyInClass.kt b/idea/testData/intentions/implementAbstractMember/property/notAbstractNoBodyInClass.kt new file mode 100644 index 00000000000..a022ffd6c7e --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/notAbstractNoBodyInClass.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +// ERROR: Property must be initialized or be abstract +open class A { + val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/implementAbstractMember/property/notAbstractWithGetterInInterface.kt b/idea/testData/intentions/implementAbstractMember/property/notAbstractWithGetterInInterface.kt new file mode 100644 index 00000000000..71669d65eaa --- /dev/null +++ b/idea/testData/intentions/implementAbstractMember/property/notAbstractWithGetterInInterface.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +interface A { + val foo: Int + get() = 1 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 34f207eef7e..bf7eab21b2a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -5230,6 +5230,189 @@ public class IntentionTestGenerated extends AbstractIntentionTest { } } + @TestMetadata("idea/testData/intentions/implementAbstractMember") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ImplementAbstractMember extends AbstractIntentionTest { + public void testAllFilesPresentInImplementAbstractMember() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/implementAbstractMember"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("idea/testData/intentions/implementAbstractMember/function") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Function extends AbstractIntentionTest { + public void testAllFilesPresentInFunction() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/implementAbstractMember/function"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("enumClass.kt") + public void testEnumClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/enumClass.kt"); + doTest(fileName); + } + + @TestMetadata("enumClassWithSemicolon.kt") + public void testEnumClassWithSemicolon() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolon.kt"); + doTest(fileName); + } + + @TestMetadata("enumClassWithSemicolonAndMembers.kt") + public void testEnumClassWithSemicolonAndMembers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/enumClassWithSemicolonAndMembers.kt"); + doTest(fileName); + } + + @TestMetadata("enumEntries.kt") + public void testEnumEntries() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/enumEntries.kt"); + doTest(fileName); + } + + @TestMetadata("enumEntriesWithArgs.kt") + public void testEnumEntriesWithArgs() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/enumEntriesWithArgs.kt"); + doTest(fileName); + } + + @TestMetadata("implementAll.kt") + public void testImplementAll() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/implementAll.kt"); + doTest(fileName); + } + + @TestMetadata("inFinalClass.kt") + public void testInFinalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/inFinalClass.kt"); + doTest(fileName); + } + + @TestMetadata("inObject.kt") + public void testInObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/inObject.kt"); + doTest(fileName); + } + + @TestMetadata("noDirectOverridesNeeded.kt") + public void testNoDirectOverridesNeeded() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/noDirectOverridesNeeded.kt"); + doTest(fileName); + } + + @TestMetadata("noInheritors.kt") + public void testNoInheritors() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/noInheritors.kt"); + doTest(fileName); + } + + @TestMetadata("notAbstractInClass.kt") + public void testNotAbstractInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/notAbstractInClass.kt"); + doTest(fileName); + } + + @TestMetadata("notAbstractInInterface.kt") + public void testNotAbstractInInterface() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/notAbstractInInterface.kt"); + doTest(fileName); + } + + @TestMetadata("notAbstractNoBodyInClass.kt") + public void testNotAbstractNoBodyInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/function/notAbstractNoBodyInClass.kt"); + doTest(fileName); + } + } + + @TestMetadata("idea/testData/intentions/implementAbstractMember/property") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Property extends AbstractIntentionTest { + public void testAllFilesPresentInProperty() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/implementAbstractMember/property"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("enumClass.kt") + public void testEnumClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/enumClass.kt"); + doTest(fileName); + } + + @TestMetadata("enumClassWithSemicolon.kt") + public void testEnumClassWithSemicolon() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolon.kt"); + doTest(fileName); + } + + @TestMetadata("enumClassWithSemicolonAndMembers.kt") + public void testEnumClassWithSemicolonAndMembers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/enumClassWithSemicolonAndMembers.kt"); + doTest(fileName); + } + + @TestMetadata("enumEntries.kt") + public void testEnumEntries() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/enumEntries.kt"); + doTest(fileName); + } + + @TestMetadata("enumEntriesWithArgs.kt") + public void testEnumEntriesWithArgs() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/enumEntriesWithArgs.kt"); + doTest(fileName); + } + + @TestMetadata("implementAll.kt") + public void testImplementAll() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/implementAll.kt"); + doTest(fileName); + } + + @TestMetadata("inFinalClass.kt") + public void testInFinalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/inFinalClass.kt"); + doTest(fileName); + } + + @TestMetadata("inObject.kt") + public void testInObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/inObject.kt"); + doTest(fileName); + } + + @TestMetadata("noDirectOverridesNeeded.kt") + public void testNoDirectOverridesNeeded() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/noDirectOverridesNeeded.kt"); + doTest(fileName); + } + + @TestMetadata("noInheritors.kt") + public void testNoInheritors() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/noInheritors.kt"); + doTest(fileName); + } + + @TestMetadata("notAbstractInClass.kt") + public void testNotAbstractInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/notAbstractInClass.kt"); + doTest(fileName); + } + + @TestMetadata("notAbstractNoBodyInClass.kt") + public void testNotAbstractNoBodyInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/notAbstractNoBodyInClass.kt"); + doTest(fileName); + } + + @TestMetadata("notAbstractWithGetterInInterface.kt") + public void testNotAbstractWithGetterInInterface() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAbstractMember/property/notAbstractWithGetterInInterface.kt"); + doTest(fileName); + } + } + } + @TestMetadata("idea/testData/intentions/importAllMembers") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)