Object to lambda intention is inapplicable when reference to this is used
#KT-10202 In Progress
This commit is contained in:
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.idea.util.ShortenReferences
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||||
import org.jetbrains.kotlin.psi.*
|
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.contentRange
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
@@ -60,8 +61,20 @@ class ObjectLiteralToLambdaIntention : SelfTargetingRangeIntention<KtObjectLiter
|
|||||||
if (!singleFunction.hasBody()) return null
|
if (!singleFunction.hasBody()) return null
|
||||||
if (singleFunction.valueParameters.any { it.name == null }) return null
|
if (singleFunction.valueParameters.any { it.name == null }) return null
|
||||||
|
|
||||||
|
val bodyExpression = singleFunction.bodyExpression!!
|
||||||
|
|
||||||
|
// this-reference
|
||||||
|
val thisReferences = bodyExpression.collectDescendantsOfType<KtThisExpression> { 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
|
// 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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
fun foo() {
|
||||||
|
bar(object : Runnable {
|
||||||
|
override fun run() {
|
||||||
|
println(this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Applicable
|
||||||
|
bar(<caret>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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -150,4 +150,20 @@
|
|||||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Convert object literal to lambda</problem_class>
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Convert object literal to lambda</problem_class>
|
||||||
<description>Convert to lambda</description>
|
<description>Convert to lambda</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>ThisReference.kt</file>
|
||||||
|
<line>12</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="ThisReference.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Convert object literal to lambda</problem_class>
|
||||||
|
<description>Convert to lambda</description>
|
||||||
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>ThisReference.kt</file>
|
||||||
|
<line>19</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="ThisReference.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Convert object literal to lambda</problem_class>
|
||||||
|
<description>Convert to lambda</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
@@ -6600,6 +6600,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("TwoFunctions.kt")
|
||||||
public void testTwoFunctions() throws Exception {
|
public void testTwoFunctions() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/objectLiteralToLambda/TwoFunctions.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/objectLiteralToLambda/TwoFunctions.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user