From e76d8bc7933ee0003cc68d385ff849c53e2ab6fe Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 14 Sep 2017 21:09:59 +0900 Subject: [PATCH] "Convert object literal to class" should create inner class if necessary #KT-20091 Fixed --- .../ConvertObjectLiteralToClassIntention.kt | 19 ++++++++++++++- .../convertObjectLiteralToClass/inClass.kt | 8 +++++++ .../inClass.kt.after | 10 ++++++++ .../inClassHasMethodReference.kt | 11 +++++++++ .../inClassHasMethodReference.kt.after | 13 ++++++++++ .../inClassHasPropertyReference.kt | 11 +++++++++ .../inClassHasPropertyReference.kt.after | 13 ++++++++++ .../convertObjectLiteralToClass/inFunction.kt | 11 +++++++++ .../inFunction.kt.after | 13 ++++++++++ .../intentions/IntentionTestGenerated.java | 24 +++++++++++++++++++ 10 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inClass.kt create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inClass.kt.after create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt.after create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt.after create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt create mode 100644 idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt index 403d13d2cb7..bb3fb5dd787 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt @@ -19,7 +19,9 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project +import com.intellij.psi.PsiComment import com.intellij.psi.codeStyle.CodeStyleManager +import com.intellij.psi.search.searches.ReferencesSearch import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.replaced @@ -33,6 +35,9 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.allChildren +import org.jetbrains.kotlin.psi.psiUtil.containingClass +import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.resolve.calls.callUtil.getType import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -65,6 +70,13 @@ class ConvertObjectLiteralToClassIntention : SelfTargetingRangeIntention()?.takeIf { + it.text == "// TARGET_BLOCK:" + } + val target = containers.firstOrNull { it == targetComment?.parent } ?: containers.last() + return doApply(editor, element, target) } chooseContainerElementIfNecessary( diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inClass.kt b/idea/testData/intentions/convertObjectLiteralToClass/inClass.kt new file mode 100644 index 00000000000..432da65e059 --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inClass.kt @@ -0,0 +1,8 @@ +class Test { // TARGET_BLOCK: + fun foo() { + object : Runnable { + override fun run() { + } + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inClass.kt.after b/idea/testData/intentions/convertObjectLiteralToClass/inClass.kt.after new file mode 100644 index 00000000000..42f40196450 --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inClass.kt.after @@ -0,0 +1,10 @@ +class Test { // TARGET_BLOCK: + fun foo() { + O() + } + + class O : Runnable { + override fun run() { + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt new file mode 100644 index 00000000000..1f3f9d9a6a2 --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt @@ -0,0 +1,11 @@ +class Test { // TARGET_BLOCK: + fun method() = 1 + + fun foo() { + object : Runnable { + override fun run() { + method() + } + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt.after b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt.after new file mode 100644 index 00000000000..1efdd271470 --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt.after @@ -0,0 +1,13 @@ +class Test { // TARGET_BLOCK: + fun method() = 1 + + fun foo() { + O() + } + + inner class O : Runnable { + override fun run() { + method() + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt new file mode 100644 index 00000000000..7a02d3f5ae1 --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt @@ -0,0 +1,11 @@ +class Test { // TARGET_BLOCK: + var field = 1 + + fun foo() { + object : Runnable { + override fun run() { + field = 2 + } + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt.after b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt.after new file mode 100644 index 00000000000..8587f3cc459 --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt.after @@ -0,0 +1,13 @@ +class Test { // TARGET_BLOCK: + var field = 1 + + fun foo() { + O() + } + + inner class O : Runnable { + override fun run() { + field = 2 + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt b/idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt new file mode 100644 index 00000000000..5ebf9f57245 --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt @@ -0,0 +1,11 @@ +class Test { + var field = 1 + + fun foo() { // TARGET_BLOCK: + object : Runnable { + override fun run() { + field = 2 + } + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt.after b/idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt.after new file mode 100644 index 00000000000..80d4236319a --- /dev/null +++ b/idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt.after @@ -0,0 +1,13 @@ +class Test { + var field = 1 + + fun foo() { // TARGET_BLOCK: + class O : Runnable { + override fun run() { + field = 2 + } + } + + O() + } +} \ 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 a4a4edf5459..4b4621a6a37 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -5390,6 +5390,30 @@ public class IntentionTestGenerated extends AbstractIntentionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/convertObjectLiteralToClass"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("inClass.kt") + public void testInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertObjectLiteralToClass/inClass.kt"); + doTest(fileName); + } + + @TestMetadata("inClassHasMethodReference.kt") + public void testInClassHasMethodReference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertObjectLiteralToClass/inClassHasMethodReference.kt"); + doTest(fileName); + } + + @TestMetadata("inClassHasPropertyReference.kt") + public void testInClassHasPropertyReference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertObjectLiteralToClass/inClassHasPropertyReference.kt"); + doTest(fileName); + } + + @TestMetadata("inFunction.kt") + public void testInFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertObjectLiteralToClass/inFunction.kt"); + doTest(fileName); + } + @TestMetadata("objectLiteralNoCapture.kt") public void testObjectLiteralNoCapture() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertObjectLiteralToClass/objectLiteralNoCapture.kt");