diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt index 4e18f322f61..0650662d589 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt @@ -411,7 +411,6 @@ public fun KtStringTemplateExpression.isPlain() = entries.all { it is KtLiteralS public val KtDeclaration.containingClassOrObject: KtClassOrObject? get() = (parent as? KtClassBody)?.parent as? KtClassOrObject - public fun KtExpression.getOutermostParenthesizerOrThis(): KtExpression { return (parentsWithSelf zip parents).firstOrNull { val (element, parent) = it diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt index 17b0ef97910..50767c6e0ed 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt @@ -183,3 +183,12 @@ public fun KtDeclaration.setVisibility(visibilityModifier: KtModifierKeywordToke addModifier(visibilityModifier) } + +fun KtSecondaryConstructor.getOrCreateBody(): KtBlockExpression { + bodyExpression?.let { return it } + + val delegationCall = getDelegationCall() + val anchor = if (delegationCall.isImplicit) valueParameterList else delegationCall + val newBody = KtPsiFactory(this).createEmptyBody() + return addAfter(newBody, anchor) as KtBlockExpression +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt index 9a6e9633e5d..4ea060d993d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt @@ -26,20 +26,26 @@ import com.intellij.psi.PsiElement import com.intellij.psi.search.searches.MethodReferencesSearch import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.idea.core.CollectingNameValidator +import org.jetbrains.kotlin.idea.core.KotlinNameSuggester +import org.jetbrains.kotlin.idea.core.appendElement +import org.jetbrains.kotlin.idea.core.getOrCreateBody +import org.jetbrains.kotlin.idea.core.refactoring.runRefactoringWithPostprocessing import org.jetbrains.kotlin.idea.refactoring.changeSignature.* import org.jetbrains.kotlin.idea.util.application.runWriteAction -import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.source.getPsi import java.util.* object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() { @@ -79,9 +85,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() { } } - override fun performSilently(affectedFunctions: Collection): Boolean { - return affectedFunctions.flatMap { it.toLightMethods() }.all { MethodReferencesSearch.search(it).findFirst() == null } - } + override fun performSilently(affectedFunctions: Collection) = noUsagesExist(affectedFunctions) } } @@ -113,6 +117,83 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() { } } + class InitializeWithConstructorParameter(property: KtProperty) : KotlinQuickFixAction(property) { + override fun getText() = "Initialize with constructor parameter" + override fun getFamilyName() = text + + private fun configureChangeSignature(propertyDescriptor: PropertyDescriptor): KotlinChangeSignatureConfiguration { + return object : KotlinChangeSignatureConfiguration { + override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor { + return originalDescriptor.modify { + val classDescriptor = propertyDescriptor.containingDeclaration as ClassDescriptorWithResolutionScopes + val constructorScope = classDescriptor.scopeForClassHeaderResolution + val validator = CollectingNameValidator(originalDescriptor.parameters.map { it.name }) { name -> + constructorScope.getContributedDescriptors(DescriptorKindFilter.VARIABLES, { it.asString() == name }).isEmpty() + } + val initializerText = CodeInsightUtils.defaultInitializer(propertyDescriptor.type) ?: "null" + val newParam = KotlinParameterInfo( + callableDescriptor = originalDescriptor.baseDescriptor, + name = KotlinNameSuggester.suggestNameByName(propertyDescriptor.name.asString(), validator), + type = propertyDescriptor.type, + defaultValueForCall = KtPsiFactory(element.project).createExpression(initializerText) + ) + it.addParameter(newParam) + } + } + + override fun performSilently(affectedFunctions: Collection): Boolean = noUsagesExist(affectedFunctions) + } + } + + // TODO: Allow processing of multiple functions in Change Signature so that Start/Finish Mark can be used here + private fun processConstructors( + project: Project, + propertyDescriptor: PropertyDescriptor, + descriptorsToProcess: Iterator, + visitedElements: MutableSet = HashSet() + ) { + if (!descriptorsToProcess.hasNext()) return + val descriptor = descriptorsToProcess.next() + val constructorPointer = descriptor.source.getPsi()?.createSmartPointer() + val config = configureChangeSignature(propertyDescriptor) + val changeSignature = { runChangeSignature(project, descriptor, config, element, text) } + + changeSignature.runRefactoringWithPostprocessing(project, "refactoring.changeSignature") { + val constructorOrClass = constructorPointer?.element + val constructor = constructorOrClass as? KtConstructor<*> ?: (constructorOrClass as? KtClass)?.getPrimaryConstructor() + if (constructor == null || !visitedElements.add(constructor)) return@runRefactoringWithPostprocessing + constructor.getValueParameters().lastOrNull()?.let { newParam -> + val psiFactory = KtPsiFactory(project) + if (constructor is KtSecondaryConstructor) { + constructor.getOrCreateBody().appendElement(psiFactory.createExpression("this.${element.name} = ${newParam.name!!}")) + } + else { + element.setInitializer(psiFactory.createExpression(newParam.name!!)) + } + } + processConstructors(project, propertyDescriptor, descriptorsToProcess) + } + } + + override fun invoke(project: Project, editor: Editor?, file: KtFile) { + val propertyDescriptor = element.resolveToDescriptorIfAny() as? PropertyDescriptor ?: return + val classDescriptor = propertyDescriptor.containingDeclaration as? ClassDescriptorWithResolutionScopes ?: return + val klass = element.containingClassOrObject ?: return + val constructorDescriptors = if (klass.hasExplicitPrimaryConstructor() || klass.getSecondaryConstructors().isEmpty()) { + listOf(classDescriptor.unsubstitutedPrimaryConstructor!!) + } + else { + classDescriptor.secondaryConstructors + } + + processConstructors(project, propertyDescriptor, constructorDescriptors.iterator()) + } + } + + private fun noUsagesExist(affectedFunctions: Collection): Boolean { + return affectedFunctions.flatMap { it.toLightMethods() }.all { MethodReferencesSearch.search(it).findFirst() == null } + } + override fun doCreateActions(diagnostic: Diagnostic): List { val property = diagnostic.psiElement as? KtProperty ?: return emptyList() if (property.receiverTypeReference != null) return emptyList() @@ -123,10 +204,13 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() { (property.containingClassOrObject as? KtClass)?.let { klass -> if (klass.isAnnotation() || klass.isInterface()) return@let - if (property.accessors.isNotEmpty()) return@let - if (klass.getSecondaryConstructors().any { !it.getDelegationCall().isCallToThis }) return@let - actions.add(MoveToConstructorParameters(property)) + if (property.accessors.isNotEmpty() || klass.getSecondaryConstructors().any { !it.getDelegationCall().isCallToThis }) { + actions.add(InitializeWithConstructorParameter(property)) + } + else { + actions.add(MoveToConstructorParameters(property)) + } } return actions diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/localVar.kt b/idea/testData/quickfix/initializeWithConstructorParameter/localVar.kt new file mode 100644 index 00000000000..817bcb29206 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/localVar.kt @@ -0,0 +1,4 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +fun test() { + val n: Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInPrimaryConstructor.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInPrimaryConstructor.kt new file mode 100644 index 00000000000..f84889c8fa1 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInPrimaryConstructor.kt @@ -0,0 +1,11 @@ +// "Initialize with constructor parameter" "true" +open class A(n: Int) { + var n: Int + get() = 1 +} + +class B : A(0) + +fun test() { + val a = A(0) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInPrimaryConstructor.kt.after b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInPrimaryConstructor.kt.after new file mode 100644 index 00000000000..8185492d4f1 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInPrimaryConstructor.kt.after @@ -0,0 +1,11 @@ +// "Initialize with constructor parameter" "true" +open class A(n: Int, n1: Int) { + var n: Int = n1 + get() = 1 +} + +class B : A(0, 0) + +fun test() { + val a = A(0, 0) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInSecondaryConstructor.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInSecondaryConstructor.kt new file mode 100644 index 00000000000..2c96b0c75fb --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInSecondaryConstructor.kt @@ -0,0 +1,12 @@ +// "Initialize with constructor parameter" "true" +open class A { + val n: Int + + constructor(n: Int) +} + +class B : A(1) + +fun test() { + val a = A(1) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInSecondaryConstructor.kt.after b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInSecondaryConstructor.kt.after new file mode 100644 index 00000000000..c99428a6143 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInSecondaryConstructor.kt.after @@ -0,0 +1,14 @@ +// "Initialize with constructor parameter" "true" +open class A { + val n: Int + + constructor(n: Int, n1: Int) { + this.n = n1 + } +} + +class B : A(1, 0) + +fun test() { + val a = A(1, 0) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNoConstructors.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNoConstructors.kt new file mode 100644 index 00000000000..2dabc2aec31 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNoConstructors.kt @@ -0,0 +1,11 @@ +// "Initialize with constructor parameter" "true" +open class A { + var n: Int + get() = 1 +} + +class B : A() + +fun test() { + val a = A() +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNoConstructors.kt.after b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNoConstructors.kt.after new file mode 100644 index 00000000000..92691578147 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNoConstructors.kt.after @@ -0,0 +1,11 @@ +// "Initialize with constructor parameter" "true" +open class A(n: Int) { + var n: Int = n + get() = 1 +} + +class B : A(0) + +fun test() { + val a = A(0) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryAndSecondaryConstructors.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryAndSecondaryConstructors.kt new file mode 100644 index 00000000000..fb57df0067f --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryAndSecondaryConstructors.kt @@ -0,0 +1,14 @@ +// "Initialize with constructor parameter" "true" +open class A(s: String) { + var n: Int + get() = 1 + + constructor(): this("") + constructor(a: Int): this("" + a) +} + +class B : A("") + +fun test() { + val a = A("") +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryAndSecondaryConstructors.kt.after b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryAndSecondaryConstructors.kt.after new file mode 100644 index 00000000000..9a87b372994 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryAndSecondaryConstructors.kt.after @@ -0,0 +1,14 @@ +// "Initialize with constructor parameter" "true" +open class A(s: String, n: Int) { + var n: Int = n + get() = 1 + + constructor(): this("", 0) + constructor(a: Int): this("" + a, 0) +} + +class B : A("", 0) + +fun test() { + val a = A("", 0) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryConstructorOnly.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryConstructorOnly.kt new file mode 100644 index 00000000000..f1d023ceb58 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryConstructorOnly.kt @@ -0,0 +1,11 @@ +// "Initialize with constructor parameter" "true" +open class A(s: String) { + var n: Int + get() = 1 +} + +class B : A("") + +fun test() { + val a = A("") +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryConstructorOnly.kt.after b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryConstructorOnly.kt.after new file mode 100644 index 00000000000..01176b649e6 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryConstructorOnly.kt.after @@ -0,0 +1,11 @@ +// "Initialize with constructor parameter" "true" +open class A(s: String, n: Int) { + var n: Int = n + get() = 1 +} + +class B : A("", 0) + +fun test() { + val a = A("", 0) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassSecondaryConstructorsOnly.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassSecondaryConstructorsOnly.kt new file mode 100644 index 00000000000..489487120cd --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassSecondaryConstructorsOnly.kt @@ -0,0 +1,19 @@ +// "Initialize with constructor parameter" "true" +open class A { + val n: Int + + constructor(s: String) + + constructor(a: Int) { + val t = 1 + } +} + +class B : A("") + +class C : A(1) + +fun test() { + val a = A("") + val aa = A(1) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassSecondaryConstructorsOnly.kt.after b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassSecondaryConstructorsOnly.kt.after new file mode 100644 index 00000000000..8add538b656 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassSecondaryConstructorsOnly.kt.after @@ -0,0 +1,22 @@ +// "Initialize with constructor parameter" "true" +open class A { + val n: Int + + constructor(s: String, n: Int) { + this.n = n + } + + constructor(a: Int, n: Int) { + val t = 1 + this.n = n + } +} + +class B : A("", 0) + +class C : A(1, 0) + +fun test() { + val a = A("", 0) + val aa = A(1, 0) +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInInterface.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInInterface.kt new file mode 100644 index 00000000000..b6e3e508db0 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInInterface.kt @@ -0,0 +1,7 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +// ACTION: Make internal +// ACTION: Make private +// ACTION: Make protected +interface A { + val n: Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInObject.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInObject.kt new file mode 100644 index 00000000000..209deda6b88 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInObject.kt @@ -0,0 +1,9 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +// ACTION: Initialize property 'n' +// ACTION: Make 'n' abstract +// ACTION: Make internal +// ACTION: Make private +// ERROR: Property must be initialized or be abstract +object A { + val n: Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassNoConstructors.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassNoConstructors.kt new file mode 100644 index 00000000000..0c9c892c734 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassNoConstructors.kt @@ -0,0 +1,11 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +// ERROR: Property must be initialized or be abstract +open class A { + val n: Int +} + +class B : A() + +fun test() { + val a = A() +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryAndSecondaryConstructors.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryAndSecondaryConstructors.kt new file mode 100644 index 00000000000..4eb56f80da1 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryAndSecondaryConstructors.kt @@ -0,0 +1,14 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +// ERROR: Property must be initialized or be abstract +open class A(s: String) { + val n: Int + + constructor(): this("") + constructor(a: Int): this("" + a) +} + +class B : A("") + +fun test() { + val a = A("") +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryConstructorOnly.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryConstructorOnly.kt new file mode 100644 index 00000000000..d9d6c937989 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryConstructorOnly.kt @@ -0,0 +1,11 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +// ERROR: Property must be initialized or be abstract +open class A(s: String) { + val n: Int +} + +class B : A("") + +fun test() { + val a = A("") +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyWithDelegateRuntime.kt b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyWithDelegateRuntime.kt new file mode 100644 index 00000000000..fb2ac5ae7d6 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyWithDelegateRuntime.kt @@ -0,0 +1,7 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +// ACTION: Make internal +// ACTION: Make private +// ACTION: Make protected +class A { + val n: Int by lazy { 0 } +} \ No newline at end of file diff --git a/idea/testData/quickfix/initializeWithConstructorParameter/topLevelProperty.kt b/idea/testData/quickfix/initializeWithConstructorParameter/topLevelProperty.kt new file mode 100644 index 00000000000..ffd16f875d7 --- /dev/null +++ b/idea/testData/quickfix/initializeWithConstructorParameter/topLevelProperty.kt @@ -0,0 +1,6 @@ +// "class org.jetbrains.kotlin.idea.quickfix.InitializePropertyQuickFixFactory$InitializeWithConstructorParameter" "false" +// ACTION: Initialize property 'n' +// ACTION: Make internal +// ACTION: Make private +// ERROR: Property must be initialized +val n: Int \ No newline at end of file diff --git a/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithConstructorDelegatingToSuper.kt b/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithConstructorDelegatingToSuper.kt index 8a91684bbbd..0dc0e413840 100644 --- a/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithConstructorDelegatingToSuper.kt +++ b/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithConstructorDelegatingToSuper.kt @@ -4,6 +4,7 @@ // ACTION: Make internal // ACTION: Make private // ACTION: Make protected +// ACTION: Initialize with constructor parameter // ERROR: Property must be initialized or be abstract open class A(x: Int) diff --git a/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithImplicitlyDelegatingConstructor.kt b/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithImplicitlyDelegatingConstructor.kt index 19cfebf2f50..c2f08773798 100644 --- a/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithImplicitlyDelegatingConstructor.kt +++ b/idea/testData/quickfix/moveToConstructorParameters/memberPropertyInClassWithImplicitlyDelegatingConstructor.kt @@ -4,6 +4,7 @@ // ACTION: Make internal // ACTION: Make private // ACTION: Make protected +// ACTION: Initialize with constructor parameter // ERROR: Property must be initialized or be abstract open class A diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 432444a59cd..b2c82cca941 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -4293,6 +4293,99 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/initializeWithConstructorParameter") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InitializeWithConstructorParameter extends AbstractQuickFixTest { + public void testAllFilesPresentInInitializeWithConstructorParameter() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/initializeWithConstructorParameter"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("localVar.kt") + public void testLocalVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/localVar.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInClassNameClashInPrimaryConstructor.kt") + public void testMemberPropertyInClassNameClashInPrimaryConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInPrimaryConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInClassNameClashInSecondaryConstructor.kt") + public void testMemberPropertyInClassNameClashInSecondaryConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNameClashInSecondaryConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInClassNoConstructors.kt") + public void testMemberPropertyInClassNoConstructors() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassNoConstructors.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInClassPrimaryAndSecondaryConstructors.kt") + public void testMemberPropertyInClassPrimaryAndSecondaryConstructors() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryAndSecondaryConstructors.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInClassPrimaryConstructorOnly.kt") + public void testMemberPropertyInClassPrimaryConstructorOnly() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassPrimaryConstructorOnly.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInClassSecondaryConstructorsOnly.kt") + public void testMemberPropertyInClassSecondaryConstructorsOnly() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInClassSecondaryConstructorsOnly.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInInterface.kt") + public void testMemberPropertyInInterface() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInInterface.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyInObject.kt") + public void testMemberPropertyInObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyInObject.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyNoAccessorsInClassNoConstructors.kt") + public void testMemberPropertyNoAccessorsInClassNoConstructors() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassNoConstructors.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyNoAccessorsInClassPrimaryAndSecondaryConstructors.kt") + public void testMemberPropertyNoAccessorsInClassPrimaryAndSecondaryConstructors() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryAndSecondaryConstructors.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyNoAccessorsInClassPrimaryConstructorOnly.kt") + public void testMemberPropertyNoAccessorsInClassPrimaryConstructorOnly() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyNoAccessorsInClassPrimaryConstructorOnly.kt"); + doTest(fileName); + } + + @TestMetadata("memberPropertyWithDelegateRuntime.kt") + public void testMemberPropertyWithDelegateRuntime() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/memberPropertyWithDelegateRuntime.kt"); + doTest(fileName); + } + + @TestMetadata("topLevelProperty.kt") + public void testTopLevelProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/initializeWithConstructorParameter/topLevelProperty.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/insertDelegationCall") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)