From 2b1d60397d3ca9b34ed444eb353e46531c3ddc3e Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Mon, 11 Jan 2016 16:31:40 +0300 Subject: [PATCH] Object to lambda intention is inapplicable when reference to this is used #KT-10202 In Progress --- .../ObjectLiteralToLambdaIntention.kt | 15 ++++++++- .../objectLiteralToLambda/ThisReference.kt | 33 +++++++++++++++++++ .../ThisReference.kt.after | 29 ++++++++++++++++ .../inspectionData/expected.xml | 16 +++++++++ .../intentions/IntentionTestGenerated.java | 6 ++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 idea/testData/intentions/objectLiteralToLambda/ThisReference.kt create mode 100644 idea/testData/intentions/objectLiteralToLambda/ThisReference.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt index 03e8e2af77b..ecd089d61a1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType import org.jetbrains.kotlin.psi.psiUtil.contentRange import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset @@ -60,8 +61,20 @@ class ObjectLiteralToLambdaIntention : SelfTargetingRangeIntention { it !is KtClassOrObject } + for (thisReference in thisReferences) { + val context = thisReference.analyze(BodyResolveMode.PARTIAL) + val thisDescriptor = context[BindingContext.REFERENCE_TARGET, thisReference.instanceReference] + if (thisDescriptor == functionDescriptor.containingDeclaration) { + return null + } + } + // Recursive call, skip labels - if (ReferencesSearch.search(singleFunction, LocalSearchScope(singleFunction.bodyExpression!!)).any { it.element !is KtLabelReferenceExpression }) { + if (ReferencesSearch.search(singleFunction, LocalSearchScope(bodyExpression)).any { it.element !is KtLabelReferenceExpression }) { return null } diff --git a/idea/testData/intentions/objectLiteralToLambda/ThisReference.kt b/idea/testData/intentions/objectLiteralToLambda/ThisReference.kt new file mode 100644 index 00000000000..8c52864332c --- /dev/null +++ b/idea/testData/intentions/objectLiteralToLambda/ThisReference.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME + +class Test { + fun foo() { + bar(object : Runnable { + override fun run() { + println(this) + } + }) + + // Applicable + bar(object : Runnable { + override fun run() { + println(this@Test) + } + }) + + // Applicable + bar(object : Runnable { + override fun run() { + bar(object : Runnable { + override fun run() { + println(this) + } + }) + } + }) + } + + private fun bar(b: Runnable) { + + } +} \ No newline at end of file diff --git a/idea/testData/intentions/objectLiteralToLambda/ThisReference.kt.after b/idea/testData/intentions/objectLiteralToLambda/ThisReference.kt.after new file mode 100644 index 00000000000..39bea5de510 --- /dev/null +++ b/idea/testData/intentions/objectLiteralToLambda/ThisReference.kt.after @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +class Test { + fun foo() { + bar(object : Runnable { + override fun run() { + println(this) + } + }) + + // Applicable + bar(Runnable { println(this@Test) }) + + // Applicable + bar(object : Runnable { + override fun run() { + bar(object : Runnable { + override fun run() { + println(this) + } + }) + } + }) + } + + private fun bar(b: Runnable) { + + } +} \ No newline at end of file diff --git a/idea/testData/intentions/objectLiteralToLambda/inspectionData/expected.xml b/idea/testData/intentions/objectLiteralToLambda/inspectionData/expected.xml index 68282e6ebdc..7b4651615d3 100644 --- a/idea/testData/intentions/objectLiteralToLambda/inspectionData/expected.xml +++ b/idea/testData/intentions/objectLiteralToLambda/inspectionData/expected.xml @@ -150,4 +150,20 @@ Convert object literal to lambda Convert to lambda + + ThisReference.kt + 12 + light_idea_test_case + + Convert object literal to lambda + Convert to lambda + + + ThisReference.kt + 19 + light_idea_test_case + + Convert object literal to lambda + Convert to lambda + \ 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 88c5080457c..7b1f2f300d5 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -6600,6 +6600,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("ThisReference.kt") + public void testThisReference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/objectLiteralToLambda/ThisReference.kt"); + doTest(fileName); + } + @TestMetadata("TwoFunctions.kt") public void testTwoFunctions() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/objectLiteralToLambda/TwoFunctions.kt");