Implement Abstract Member Intention: Support primary constructor parameters

#KT-8427 Fixed
This commit is contained in:
Alexey Sedunov
2015-12-24 17:13:53 +03:00
committed by Alexey
parent 2b4f03feef
commit aeefdffaab
34 changed files with 389 additions and 55 deletions
@@ -88,3 +88,19 @@ public open class KtClass : KtClassOrObject {
public fun getClassOrInterfaceKeyword(): PsiElement? = findChildByType(TokenSet.create(KtTokens.CLASS_KEYWORD, KtTokens.INTERFACE_KEYWORD))
}
public fun KtClass.createPrimaryConstructorIfAbsent(): KtPrimaryConstructor {
val constructor = getPrimaryConstructor()
if (constructor != null) return constructor
var anchor: PsiElement? = typeParameterList
if (anchor == null) anchor = nameIdentifier
if (anchor == null) anchor = lastChild
return addAfter(KtPsiFactory(project).createPrimaryConstructor(), anchor) as KtPrimaryConstructor
}
public fun KtClass.createPrimaryConstructorParameterListIfAbsent(): KtParameterList {
val constructor = createPrimaryConstructorIfAbsent()
val parameterList = constructor.valueParameterList
if (parameterList != null) return parameterList
return constructor.add(KtPsiFactory(project).createParameterList("()")) as KtParameterList
}
@@ -153,29 +153,42 @@ public fun <T : KtDeclaration> insertMembersAfter(
): List<T> {
members.ifEmpty { return emptyList() }
return runWriteAction<List<T>> {
val body = classOrObject.getOrCreateBody()
return runWriteAction {
val insertedMembers = SmartList<T>()
var afterAnchor = anchor ?: findInsertAfterAnchor(editor, body) ?: return@runWriteAction emptyList()
val insertedMembers = members.mapTo(SmartList<T>()) {
if (classOrObject is KtClass && classOrObject.isEnum()) {
val enumEntries = classOrObject.declarations.filterIsInstance<KtEnumEntry>()
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!!
}
}
val (parameters, otherMembers) = members.partition { it is KtParameter }
parameters.mapNotNullTo(insertedMembers) {
if (classOrObject !is KtClass) return@mapNotNullTo null
@Suppress("UNCHECKED_CAST")
(body.addAfter(it, afterAnchor) as T).apply { afterAnchor = this }
(classOrObject.createPrimaryConstructorParameterListIfAbsent().addParameter(it as KtParameter) as T)
}
if (otherMembers.isNotEmpty()) {
val body = classOrObject.getOrCreateBody()
var afterAnchor = anchor ?: findInsertAfterAnchor(editor, body) ?: return@runWriteAction emptyList()
otherMembers.mapNotNullTo(insertedMembers) {
if (classOrObject is KtClass && classOrObject.isEnum()) {
val enumEntries = classOrObject.declarations.filterIsInstance<KtEnumEntry>()
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 }
}
}
ShortenReferences.DEFAULT.process(insertedMembers)
@@ -0,0 +1,7 @@
interface A {
val foo: Int
}
class B(<spot>override val foo: Int</spot>) : A {
}
@@ -0,0 +1,7 @@
interface A {
<spot>val foo: Int</spot>
}
class B : A {
}
@@ -0,0 +1,5 @@
<html>
<body>
This intention searches for all classes that can implement selected abstract property, and creates corresponding property parameter there.
</body>
</html>
+5
View File
@@ -1115,6 +1115,11 @@
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.ImplementAbstractMemberAsConstructorParameterIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction$Intention</className>
<category>Kotlin</category>
@@ -24,7 +24,6 @@ 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.project.Project
import com.intellij.openapi.ui.popup.PopupChooserBuilder
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiClass
@@ -40,7 +39,6 @@ import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor
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
@@ -48,6 +46,7 @@ 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.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -57,10 +56,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.singletonList
import java.util.*
import javax.swing.ListSelectionModel
class ImplementAbstractMemberIntention :
abstract class ImplementAbstractMemberIntentionBase :
SelfTargetingRangeIntention<KtNamedDeclaration>(KtNamedDeclaration::class.java, "", "Implement abstract member") {
companion object {
private val LOG = Logger.getInstance("#${ImplementAbstractMemberIntention::class.java.canonicalName}")
private val LOG = Logger.getInstance("#${ImplementAbstractMemberIntentionBase::class.java.canonicalName}")
}
private fun isAbstract(element: KtNamedDeclaration): Boolean {
@@ -73,7 +72,7 @@ class ImplementAbstractMemberIntention :
}
}
private fun findExistingImplementation(
protected fun findExistingImplementation(
subClass: ClassDescriptor,
superMember: CallableMemberDescriptor
): CallableMemberDescriptor? {
@@ -83,6 +82,8 @@ class ImplementAbstractMemberIntention :
if (subMember?.kind?.isReal ?: false) return subMember else return null
}
protected abstract fun acceptSubClass(subClassDescriptor: ClassDescriptor, memberDescriptor: CallableMemberDescriptor): Boolean
private fun findClassesToProcess(member: KtNamedDeclaration): Sequence<PsiElement> {
val baseClass = member.containingClassOrObject as? KtClass ?: return emptySequence()
val memberDescriptor = member.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return emptySequence()
@@ -94,7 +95,7 @@ class ImplementAbstractMemberIntention :
is PsiClass -> subClass.getJavaClassDescriptor()
else -> null
} as? ClassDescriptor ?: return false
return classDescriptor.kind != ClassKind.INTERFACE && findExistingImplementation(classDescriptor, memberDescriptor) == null
return acceptSubClass(classDescriptor, memberDescriptor)
}
if (baseClass.isEnum()) {
@@ -110,20 +111,20 @@ class ImplementAbstractMemberIntention :
.filter(::acceptSubClass)
}
protected abstract fun computeText(element: KtNamedDeclaration): String?
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
}
text = computeText(element) ?: return null
if (!findClassesToProcess(element).any()) return null
return element.nameIdentifier?.textRange
}
protected abstract val preferConstructorParameters: Boolean
private fun implementInKotlinClass(member: KtNamedDeclaration, targetClass: KtClassOrObject) {
val subClassDescriptor = targetClass.resolveToDescriptorIfAny() as? ClassDescriptor ?: return
val superMemberDescriptor = member.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return
@@ -134,7 +135,8 @@ class ImplementAbstractMemberIntention :
val chooserObject = OverrideMemberChooserObject.create(member.project,
descriptorToImplement,
descriptorToImplement,
OverrideMemberChooserObject.BodyType.EMPTY)
OverrideMemberChooserObject.BodyType.EMPTY,
preferConstructorParameters)
OverrideImplementMembersHandler.generateMembers(null, targetClass, chooserObject.singletonList())
}
@@ -229,4 +231,43 @@ class ImplementAbstractMemberIntention :
.createPopup()
.showInBestPositionFor(editor)
}
}
class ImplementAbstractMemberIntention : ImplementAbstractMemberIntentionBase() {
override fun computeText(element: KtNamedDeclaration): String? {
return when(element) {
is KtProperty -> "Implement abstract property"
is KtNamedFunction -> "Implement abstract function"
else -> null
}
}
override fun acceptSubClass(subClassDescriptor: ClassDescriptor, memberDescriptor: CallableMemberDescriptor): Boolean {
return subClassDescriptor.kind != ClassKind.INTERFACE && findExistingImplementation(subClassDescriptor, memberDescriptor) == null
}
override val preferConstructorParameters: Boolean
get() = false
}
class ImplementAbstractMemberAsConstructorParameterIntention : ImplementAbstractMemberIntentionBase() {
override fun computeText(element: KtNamedDeclaration): String? {
if (element !is KtProperty) return null
return "Implement as constructor parameter"
}
override fun acceptSubClass(subClassDescriptor: ClassDescriptor, memberDescriptor: CallableMemberDescriptor): Boolean {
val kind = subClassDescriptor.kind
return (kind == ClassKind.CLASS || kind == ClassKind.ENUM_CLASS)
&& subClassDescriptor !is JavaClassDescriptor
&& findExistingImplementation(subClassDescriptor, memberDescriptor) == null
}
override val preferConstructorParameters: Boolean
get() = true
override fun applicabilityRange(element: KtNamedDeclaration): TextRange? {
if (element !is KtProperty) return null
return super.applicabilityRange(element)
}
}
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.core.isVisible
import org.jetbrains.kotlin.idea.refactoring.createPrimaryConstructorParameterListIfAbsent
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.ShortenReferences
@@ -26,15 +26,14 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
import org.jetbrains.kotlin.idea.refactoring.createPrimaryConstructorIfAbsent
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
import org.jetbrains.kotlin.idea.refactoring.replaceListPsiAndKeepDelimiters
import org.jetbrains.kotlin.idea.core.setVisibility
import org.jetbrains.kotlin.idea.core.toKeywordToken
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeInfo
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinParameterInfo
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
import org.jetbrains.kotlin.idea.refactoring.changeSignature.getCallableSubstitutor
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
import org.jetbrains.kotlin.idea.refactoring.replaceListPsiAndKeepDelimiters
import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.idea.util.ShortenReferences.Options
import org.jetbrains.kotlin.psi.*
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.refactoring.changeSignature.usages
import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
import org.jetbrains.kotlin.idea.refactoring.createPrimaryConstructorParameterListIfAbsent
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeInfo
import org.jetbrains.kotlin.idea.refactoring.changeSignature.getAffectedCallables
import org.jetbrains.kotlin.idea.refactoring.changeSignature.isInsideOfCallerBody
@@ -30,7 +30,6 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.ui.JBColor
import com.intellij.ui.NonFocusableCheckBox
import org.jetbrains.kotlin.idea.refactoring.createPrimaryConstructorParameterListIfAbsent
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
import org.jetbrains.kotlin.idea.refactoring.introduce.AbstractKotlinInplaceIntroducer
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinInplaceVariableIntroducer
@@ -701,22 +701,6 @@ public fun String.quoteIfNeeded(): String = if (KotlinNameSuggester.isIdentifier
public fun FqNameUnsafe.hasIdentifiersOnly(): Boolean = pathSegments().all { KotlinNameSuggester.isIdentifier(it.asString()) }
public fun KtClass.createPrimaryConstructorIfAbsent(): KtPrimaryConstructor {
val constructor = getPrimaryConstructor()
if (constructor != null) return constructor
var anchor: PsiElement? = typeParameterList
if (anchor == null) anchor = nameIdentifier
if (anchor == null) anchor = lastChild
return addAfter(KtPsiFactory(project).createPrimaryConstructor(), anchor) as KtPrimaryConstructor
}
public fun KtClass.createPrimaryConstructorParameterListIfAbsent(): KtParameterList {
val constructor = createPrimaryConstructorIfAbsent()
val parameterList = constructor.valueParameterList
if (parameterList != null) return parameterList
return constructor.add(KtPsiFactory(project).createParameterList("()")) as KtParameterList
}
fun PsiNamedElement.isInterfaceClass(): Boolean = this is KtClass && isInterface() || this is PsiClass && isInterface
fun <ListType : KtElement> replaceListPsiAndKeepDelimiters(
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
import org.jetbrains.kotlin.idea.core.dropDefaultValue
import org.jetbrains.kotlin.idea.intentions.setType
import org.jetbrains.kotlin.idea.refactoring.createJavaField
import org.jetbrains.kotlin.idea.refactoring.createPrimaryConstructorIfAbsent
import org.jetbrains.kotlin.idea.refactoring.safeDelete.removeOverrideModifier
import org.jetbrains.kotlin.idea.util.anonymousObjectSuperTypeOrNull
import org.jetbrains.kotlin.idea.util.psi.patternMatching.KotlinPsiUnifier
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.intentions.ImplementAbstractMemberAsConstructorParameterIntention
@@ -0,0 +1,9 @@
// WITH_RUNTIME
// DISABLE-ERRORS
interface T<X> {
val <caret>foo: X
}
enum class E : T<Int> {
A, B, C
}
@@ -0,0 +1,9 @@
// WITH_RUNTIME
// DISABLE-ERRORS
interface T<X> {
val <caret>foo: X
}
enum class E(override val foo: Int) : T<Int> {
A, B, C
}
@@ -0,0 +1,9 @@
// IS_APPLICABLE: false
// DISABLE-ERRORS
interface A {
abstract fun <caret>foo(): Int
}
class B : A {
}
@@ -0,0 +1,22 @@
// WITH_RUNTIME
// DISABLE-ERRORS
interface T<X> {
val <caret>foo: X
}
class U : T<String> {
}
class V : T<Int> {
}
class Z : T<Int> by V() {
}
class W : T<Boolean> {
override val foo: Boolean
get() = throw UnsupportedOperationException()
}
@@ -0,0 +1,22 @@
// WITH_RUNTIME
// DISABLE-ERRORS
interface T<X> {
val <caret>foo: X
}
class U(override val foo: String) : T<String> {
}
class V(override val foo: Int) : T<Int> {
}
class Z : T<Int> by V() {
}
class W : T<Boolean> {
override val foo: Boolean
get() = throw UnsupportedOperationException()
}
@@ -0,0 +1,7 @@
// IS_APPLICABLE: false
// DISABLE-ERRORS
enum class E {
A, B, C;
abstract val <caret>foo: Int
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
// ERROR: Abstract property 'foo' in non-abstract class 'A'
class A {
abstract val <caret>foo: Int
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
// ERROR: Abstract property 'foo' in non-abstract class 'A'
object A {
abstract val <caret>foo: Int
}
@@ -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 <caret>foo: Int
}
class X : A {
override val foo = 1
}
abstract class B : A {
abstract override val foo: Int
}
class C: B() {
}
@@ -0,0 +1,4 @@
// IS_APPLICABLE: false
interface A {
val <caret>foo: Int
}
@@ -0,0 +1,4 @@
// IS_APPLICABLE: false
open class A {
val <caret>foo = 1
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
// ERROR: Property must be initialized or be abstract
open class A {
val <caret>foo: Int
}
@@ -0,0 +1,5 @@
// IS_APPLICABLE: false
interface A {
val <caret>foo: Int
get() = 1
}
@@ -0,0 +1,20 @@
package source;
abstract class X<S> implements T<S> {
}
class Y implements T<String> {
}
class Z implements T<Boolean> {
@Override
public Boolean getFoo() {
return null;
}
}
interface U extends T<Object> {
}
@@ -0,0 +1,5 @@
package source
interface T<X> {
val foo: X
}
@@ -0,0 +1,20 @@
package source;
abstract class X<S> implements T<S> {
}
class Y implements T<String> {
}
class Z implements T<Boolean> {
@Override
public Boolean getFoo() {
return null;
}
}
interface U extends T<Object> {
}
@@ -0,0 +1,5 @@
package source
interface T<X> {
val <caret>foo: X
}
@@ -0,0 +1,6 @@
{
"mainFile": "source/test.kt",
"intentionClass": "org.jetbrains.kotlin.idea.intentions.ImplementAbstractMemberAsConstructorParameterIntention",
"isApplicable": "false",
"withRuntime": "true"
}
@@ -5464,6 +5464,81 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
@TestMetadata("idea/testData/intentions/implementAsConstructorParameter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ImplementAsConstructorParameter extends AbstractIntentionTest {
public void testAllFilesPresentInImplementAsConstructorParameter() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/implementAsConstructorParameter"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
}
@TestMetadata("enumClass.kt")
public void testEnumClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/enumClass.kt");
doTest(fileName);
}
@TestMetadata("function.kt")
public void testFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/function.kt");
doTest(fileName);
}
@TestMetadata("implementAll.kt")
public void testImplementAll() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/implementAll.kt");
doTest(fileName);
}
@TestMetadata("inEnumClass.kt")
public void testInEnumClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/inEnumClass.kt");
doTest(fileName);
}
@TestMetadata("inFinalClass.kt")
public void testInFinalClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/inFinalClass.kt");
doTest(fileName);
}
@TestMetadata("inObject.kt")
public void testInObject() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/inObject.kt");
doTest(fileName);
}
@TestMetadata("noDirectOverridesNeeded.kt")
public void testNoDirectOverridesNeeded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/noDirectOverridesNeeded.kt");
doTest(fileName);
}
@TestMetadata("noInheritors.kt")
public void testNoInheritors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/noInheritors.kt");
doTest(fileName);
}
@TestMetadata("notAbstractInClass.kt")
public void testNotAbstractInClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/notAbstractInClass.kt");
doTest(fileName);
}
@TestMetadata("notAbstractNoBodyInClass.kt")
public void testNotAbstractNoBodyInClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/notAbstractNoBodyInClass.kt");
doTest(fileName);
}
@TestMetadata("notAbstractWithGetterInInterface.kt")
public void testNotAbstractWithGetterInInterface() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/implementAsConstructorParameter/notAbstractWithGetterInInterface.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/intentions/importAllMembers")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -53,6 +53,12 @@ public class MultiFileIntentionTestGenerated extends AbstractMultiFileIntentionT
doTest(fileName);
}
@TestMetadata("implementAsConstructorParameter/implementValInJava/implementAllInJava.test")
public void testImplementAsConstructorParameter_implementValInJava_ImplementAllInJava() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/implementAsConstructorParameter/implementValInJava/implementAllInJava.test");
doTest(fileName);
}
@TestMetadata("moveDeclarationToSeparateFile/moveClassToExistingFile/moveClassToExistingFile.test")
public void testMoveDeclarationToSeparateFile_moveClassToExistingFile_MoveClassToExistingFile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToExistingFile/moveClassToExistingFile.test");