diff --git a/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/after.kt.template b/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/after.kt.template
new file mode 100644
index 00000000000..45a9b7d4aa5
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/after.kt.template
@@ -0,0 +1,3 @@
+class A {
+ val foo: Int = 1
+}
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/before.kt.template b/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/before.kt.template
new file mode 100644
index 00000000000..57717f73075
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/before.kt.template
@@ -0,0 +1,4 @@
+class A {
+ val foo: Int
+ get() = 1
+}
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/description.html b/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/description.html
new file mode 100644
index 00000000000..bb3401bdc9c
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ConvertPropertyGetterToInitializerIntention/description.html
@@ -0,0 +1,5 @@
+
+
+This intention converts a property getter to to a initializer.
+
+
\ No newline at end of file
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 94a9dab6b3b..4708368f36f 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -1676,6 +1676,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
+ Kotlin
+
+
(
+ KtPropertyAccessor::class.java, "Convert property getter to initializer"
+) {
+
+ override fun isApplicableTo(element: KtPropertyAccessor, caretOffset: Int): Boolean {
+ if (!element.isGetter || element.singleExpression() == null) return false
+
+ val property = element.parent as? KtProperty ?: return false
+ if (property.hasInitializer()
+ || property.receiverTypeReference != null
+ || property.containingClass()?.isInterface() == true
+ || (property.descriptor as? PropertyDescriptor)?.isExpect == true
+ ) return false
+
+ return true
+ }
+
+ override fun applyTo(element: KtPropertyAccessor, editor: Editor?) {
+ val property = element.parent as? KtProperty ?: return
+ val commentSaver = CommentSaver(property)
+ property.initializer = element.singleExpression()
+ property.deleteChildRange(property.initializer?.nextSibling, element)
+ editor?.caretModel?.moveToOffset(property.endOffset)
+ commentSaver.restore(property)
+ }
+}
+
+private fun KtPropertyAccessor.singleExpression(): KtExpression? {
+ val bodyExpression = this.bodyExpression
+ return if (bodyExpression is KtBlockExpression)
+ (bodyExpression.statements.singleOrNull() as? KtReturnExpression)?.returnedExpression
+ else
+ bodyExpression
+}
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/.intention b/idea/testData/intentions/convertPropertyGetterToInitializer/.intention
new file mode 100644
index 00000000000..514a3e8b68a
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.ConvertPropertyGetterToInitializerIntention
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/block.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/block.kt
new file mode 100644
index 00000000000..9fef4a2a399
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/block.kt
@@ -0,0 +1,4 @@
+val p: Int
+ get() {
+ return 1
+ }
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/block.kt.after b/idea/testData/intentions/convertPropertyGetterToInitializer/block.kt.after
new file mode 100644
index 00000000000..fdb21f903ac
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/block.kt.after
@@ -0,0 +1 @@
+val p: Int = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/extentionProperty.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/extentionProperty.kt
new file mode 100644
index 00000000000..364c4bdfff5
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/extentionProperty.kt
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: false
+class C
+
+val C.p: Int
+ get() = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment.kt
new file mode 100644
index 00000000000..9aa8d6cc95b
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment.kt
@@ -0,0 +1,2 @@
+val p: Int // comment
+ get() = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment.kt.after b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment.kt.after
new file mode 100644
index 00000000000..f54ecd58ed1
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment.kt.after
@@ -0,0 +1,2 @@
+val p: Int // comment
+ = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment2.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment2.kt
new file mode 100644
index 00000000000..01b29ea9a81
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment2.kt
@@ -0,0 +1,3 @@
+val p2: Int
+// comment
+ get() = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment2.kt.after b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment2.kt.after
new file mode 100644
index 00000000000..cee32b2edcb
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment2.kt.after
@@ -0,0 +1,2 @@
+val p2: Int// comment
+ = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment3.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment3.kt
new file mode 100644
index 00000000000..3d9ce5bba3d
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment3.kt
@@ -0,0 +1,2 @@
+val p3: Int
+ get() = 1 // comment
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment3.kt.after b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment3.kt.after
new file mode 100644
index 00000000000..cc44eb9151d
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/hasComment3.kt.after
@@ -0,0 +1 @@
+val p3: Int = 1 // comment
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/hasInitializer.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/hasInitializer.kt
new file mode 100644
index 00000000000..69709f1fc65
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/hasInitializer.kt
@@ -0,0 +1,3 @@
+// IS_APPLICABLE: false
+var hasInitializer: Int = 0
+ get() = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/inInterface.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/inInterface.kt
new file mode 100644
index 00000000000..03f94f89426
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/inInterface.kt
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: false
+interface I {
+ val p: Int
+ get() = 1
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/multiStatementBlock.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/multiStatementBlock.kt
new file mode 100644
index 00000000000..f83127639c6
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/multiStatementBlock.kt
@@ -0,0 +1,6 @@
+// IS_APPLICABLE: false
+val multiStatementBlock: Int
+ get() {
+ val a = 1
+ return 6
+ }
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/run.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/run.kt
new file mode 100644
index 00000000000..90053a9a9eb
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/run.kt
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+val p: Int
+ get() = run { 1 }
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/run.kt.after b/idea/testData/intentions/convertPropertyGetterToInitializer/run.kt.after
new file mode 100644
index 00000000000..5943b502252
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/run.kt.after
@@ -0,0 +1,2 @@
+// WITH_RUNTIME
+val p: Int = run { 1 }
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/simple.kt b/idea/testData/intentions/convertPropertyGetterToInitializer/simple.kt
new file mode 100644
index 00000000000..7206ca94870
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/simple.kt
@@ -0,0 +1,2 @@
+val p: Int
+ get() = 1
\ No newline at end of file
diff --git a/idea/testData/intentions/convertPropertyGetterToInitializer/simple.kt.after b/idea/testData/intentions/convertPropertyGetterToInitializer/simple.kt.after
new file mode 100644
index 00000000000..75b2b28a0fe
--- /dev/null
+++ b/idea/testData/intentions/convertPropertyGetterToInitializer/simple.kt.after
@@ -0,0 +1 @@
+val p: Int = 1
\ No newline at end of file
diff --git a/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/header/header.kt b/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/header/header.kt
new file mode 100644
index 00000000000..89432bb2523
--- /dev/null
+++ b/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/header/header.kt
@@ -0,0 +1,7 @@
+// "Convert property getter to initializer" "false"
+// ERROR: Expected declaration must not have a body
+// ACTION: Convert to block body
+expect class C {
+ val p: Int
+ get() = 1
+}
\ No newline at end of file
diff --git a/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/js/js.kt b/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/js/js.kt
new file mode 100644
index 00000000000..181da9fd38f
--- /dev/null
+++ b/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/js/js.kt
@@ -0,0 +1,3 @@
+actual class C {
+ actual val p: Int = 1
+}
\ No newline at end of file
diff --git a/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/jvm/jvm.kt b/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/jvm/jvm.kt
new file mode 100644
index 00000000000..181da9fd38f
--- /dev/null
+++ b/idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/jvm/jvm.kt
@@ -0,0 +1,3 @@
+actual class C {
+ actual val p: Int = 1
+}
\ No newline at end of file
diff --git a/idea/testData/quickfix/surroundWithNullCheck/unsafeCallInGetter.kt b/idea/testData/quickfix/surroundWithNullCheck/unsafeCallInGetter.kt
index ed8e32f3618..f3704618a4d 100644
--- a/idea/testData/quickfix/surroundWithNullCheck/unsafeCallInGetter.kt
+++ b/idea/testData/quickfix/surroundWithNullCheck/unsafeCallInGetter.kt
@@ -1,5 +1,6 @@
// "Surround with null check" "false"
// ACTION: Add non-null asserted (!!) call
+// ACTION: Convert property getter to initializer
// ACTION: Convert to block body
// ACTION: Introduce local variable
// ACTION: Replace with safe (?.) call
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index cd652a7a174..9d5dadfa725 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -5816,6 +5816,69 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
+ @TestMetadata("idea/testData/intentions/convertPropertyGetterToInitializer")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ConvertPropertyGetterToInitializer extends AbstractIntentionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInConvertPropertyGetterToInitializer() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/convertPropertyGetterToInitializer"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/block.kt");
+ }
+
+ @TestMetadata("extentionProperty.kt")
+ public void testExtentionProperty() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/extentionProperty.kt");
+ }
+
+ @TestMetadata("hasComment.kt")
+ public void testHasComment() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/hasComment.kt");
+ }
+
+ @TestMetadata("hasComment2.kt")
+ public void testHasComment2() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/hasComment2.kt");
+ }
+
+ @TestMetadata("hasComment3.kt")
+ public void testHasComment3() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/hasComment3.kt");
+ }
+
+ @TestMetadata("hasInitializer.kt")
+ public void testHasInitializer() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/hasInitializer.kt");
+ }
+
+ @TestMetadata("inInterface.kt")
+ public void testInInterface() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/inInterface.kt");
+ }
+
+ @TestMetadata("multiStatementBlock.kt")
+ public void testMultiStatementBlock() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/multiStatementBlock.kt");
+ }
+
+ @TestMetadata("run.kt")
+ public void testRun() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/run.kt");
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ runTest("idea/testData/intentions/convertPropertyGetterToInitializer/simple.kt");
+ }
+ }
+
@TestMetadata("idea/testData/intentions/convertPropertyInitializerToGetter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java
index 299508a247d..fa098b7f314 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiModuleTestGenerated.java
@@ -144,6 +144,11 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul
runTest("idea/testData/multiModuleQuickFix/convertExpectSealedClassToEnum/");
}
+ @TestMetadata("convertPropertyGetterToInitializer")
+ public void testConvertPropertyGetterToInitializer() throws Exception {
+ runTest("idea/testData/multiModuleQuickFix/convertPropertyGetterToInitializer/");
+ }
+
@TestMetadata("createFunInExpectClass")
public void testCreateFunInExpectClass() throws Exception {
runTest("idea/testData/multiModuleQuickFix/createFunInExpectClass/");