From a41064295b92e93c1ece56f4cbfd8665400323a7 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Tue, 29 Aug 2017 04:43:54 +0300 Subject: [PATCH] "Convert to primary constructor": do not move `init` section down So #KT-19629 Fixed --- ...vertSecondaryConstructorToPrimaryIntention.kt | 16 +++++++++++++--- .../convertSecondaryConstructorToPrimary/init.kt | 2 ++ .../init.kt.after | 1 + .../varArg.kt | 2 ++ .../varArg.kt.after | 1 + 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt index ef319f673d3..badf75ef4a8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.openapi.editor.Editor import com.intellij.openapi.util.TextRange +import com.intellij.psi.search.searches.ReferencesSearch import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection @@ -181,10 +182,19 @@ class ConvertSecondaryConstructorToPrimaryIntention : SelfTargetingRangeIntentio with (constructorInClass.replace(constructor)) { constructorCommentSaver.restore(this) } - element.delete() - if ((initializer.body as? KtBlockExpression)?.statements?.isNotEmpty() ?: false) { - klass.addDeclaration(initializer) + if ((initializer.body as? KtBlockExpression)?.statements?.isNotEmpty() == true) { + val hasPropertyAfterInitializer = element.parent.children.takeLastWhile { it !== element }.any { + it is KtProperty && ReferencesSearch.search(it, initializer.useScope).findFirst() != null + } + if (hasPropertyAfterInitializer) { + // In this case we must move init {} down, because it uses a property declared below + klass.addDeclaration(initializer) + } else { + klass.addDeclarationAfter(initializer, element) + } } + + element.delete() } } \ No newline at end of file diff --git a/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt b/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt index c9ae0215d00..899f83bd734 100644 --- a/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt +++ b/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt @@ -7,4 +7,6 @@ class ConvertToInit { foo() bar() } + + fun baz() {} } \ No newline at end of file diff --git a/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt.after b/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt.after index 106e0bbf1fb..fab95bc1b3a 100644 --- a/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt.after +++ b/idea/testData/intentions/convertSecondaryConstructorToPrimary/init.kt.after @@ -8,4 +8,5 @@ class ConvertToInit() { bar() } + fun baz() {} } \ No newline at end of file diff --git a/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt b/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt index d2418f0e5c0..18c1bf7528b 100644 --- a/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt +++ b/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt @@ -7,4 +7,6 @@ class WithVarArg { constructor(vararg zz: String) { x = listOf(*zz) } + + fun foo() {} } \ No newline at end of file diff --git a/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt.after b/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt.after index 2db8b688dc4..83af7fb03f4 100644 --- a/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt.after +++ b/idea/testData/intentions/convertSecondaryConstructorToPrimary/varArg.kt.after @@ -8,4 +8,5 @@ class WithVarArg(vararg zz: String) { x = listOf(*zz) } + fun foo() {} } \ No newline at end of file