KT-13111: lambda --> reference support methods called via this now

This commit is contained in:
Mikhail Glukhikh
2017-03-10 17:38:03 +03:00
parent 19db4869e6
commit 2c692de98f
4 changed files with 35 additions and 13 deletions
@@ -240,22 +240,30 @@ class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntentio
is KtNameReferenceExpression -> selector.getReferencedName()
else -> return null
}
val receiver = singleStatement.receiverExpression as? KtNameReferenceExpression ?: return null
val receiver = singleStatement.receiverExpression
val context = receiver.analyze()
val receiverDescriptor = context[REFERENCE_TARGET, receiver] ?: return null
val lambdaValueParameters = context[FUNCTION, lambdaExpression.functionLiteral]?.valueParameters ?: return null
if (receiverDescriptor is ParameterDescriptor && receiverDescriptor == lambdaValueParameters.firstOrNull()) {
val originalReceiverType = receiverDescriptor.type
val receiverType = originalReceiverType.approximateFlexibleTypes(preferNotNull = true)
if (shortTypes) {
"${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(receiverType)}::$selectorReferenceName"
when (receiver) {
is KtNameReferenceExpression -> {
val receiverDescriptor = context[REFERENCE_TARGET, receiver] ?: return null
val lambdaValueParameters = context[FUNCTION, lambdaExpression.functionLiteral]?.valueParameters ?: return null
if (receiverDescriptor is ParameterDescriptor && receiverDescriptor == lambdaValueParameters.firstOrNull()) {
val originalReceiverType = receiverDescriptor.type
val receiverType = originalReceiverType.approximateFlexibleTypes(preferNotNull = true)
if (shortTypes) {
"${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(receiverType)}::$selectorReferenceName"
}
else {
"${IdeDescriptorRenderers.SOURCE_CODE.renderType(receiverType)}::$selectorReferenceName"
}
}
else {
"${receiverDescriptor.name}::$selectorReferenceName"
}
}
else {
"${IdeDescriptorRenderers.SOURCE_CODE.renderType(receiverType)}::$selectorReferenceName"
is KtThisExpression -> {
"${receiver.text}::$selectorReferenceName"
}
}
else {
"${receiverDescriptor.name}::$selectorReferenceName"
else -> null
}
}
else -> null
@@ -0,0 +1,4 @@
class Owner(val z: Int) {
fun foo(y: Int) = y + z
val x = { y: Int -><caret> this.foo(y) }
}
@@ -0,0 +1,4 @@
class Owner(val z: Int) {
fun foo(y: Int) = y + z
val x = this::foo
}
@@ -4466,6 +4466,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("memberViaThis.kt")
public void testMemberViaThis() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/memberViaThis.kt");
doTest(fileName);
}
@TestMetadata("name.kt")
public void testName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/name.kt");